rawsql-ts 0.1.0-beta.10 → 0.1.0-beta.12

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 (208) hide show
  1. package/README.md +165 -174
  2. package/dist/esm/index.js +17 -0
  3. package/dist/esm/index.js.map +1 -0
  4. package/dist/esm/models/BinarySelectQuery.js +137 -0
  5. package/dist/esm/models/BinarySelectQuery.js.map +1 -0
  6. package/dist/esm/models/Clause.js +289 -0
  7. package/dist/esm/models/Clause.js.map +1 -0
  8. package/dist/esm/models/KeywordTrie.js +48 -0
  9. package/dist/esm/models/KeywordTrie.js.map +1 -0
  10. package/dist/esm/models/Lexeme.js +18 -0
  11. package/dist/esm/models/Lexeme.js.map +1 -0
  12. package/dist/esm/models/SelectQuery.js +5 -0
  13. package/dist/esm/models/SelectQuery.js.map +1 -0
  14. package/dist/esm/models/SimpleSelectQuery.js +288 -0
  15. package/dist/esm/models/SimpleSelectQuery.js.map +1 -0
  16. package/dist/esm/models/SqlComponent.js +22 -0
  17. package/dist/esm/models/SqlComponent.js.map +1 -0
  18. package/dist/esm/models/ValueComponent.js +223 -0
  19. package/dist/esm/models/ValueComponent.js.map +1 -0
  20. package/dist/esm/models/ValuesQuery.js +12 -0
  21. package/dist/esm/models/ValuesQuery.js.map +1 -0
  22. package/dist/esm/parsers/CommandExpressionParser.js +120 -0
  23. package/dist/esm/parsers/CommandExpressionParser.js.map +1 -0
  24. package/dist/esm/parsers/CommonTableParser.js +58 -0
  25. package/dist/esm/parsers/CommonTableParser.js.map +1 -0
  26. package/dist/esm/parsers/ForClauseParser.js +54 -0
  27. package/dist/esm/parsers/ForClauseParser.js.map +1 -0
  28. package/dist/esm/parsers/FromClauseParser.js +43 -0
  29. package/dist/esm/parsers/FromClauseParser.js.map +1 -0
  30. package/dist/esm/parsers/FunctionExpressionParser.js +174 -0
  31. package/dist/esm/parsers/FunctionExpressionParser.js.map +1 -0
  32. package/dist/esm/parsers/GroupByParser.js +54 -0
  33. package/dist/esm/parsers/GroupByParser.js.map +1 -0
  34. package/dist/esm/parsers/HavingParser.js +32 -0
  35. package/dist/esm/parsers/HavingParser.js.map +1 -0
  36. package/dist/esm/parsers/IdentifierParser.js +35 -0
  37. package/dist/esm/parsers/IdentifierParser.js.map +1 -0
  38. package/dist/esm/parsers/JoinClauseParser.js +101 -0
  39. package/dist/esm/parsers/JoinClauseParser.js.map +1 -0
  40. package/dist/esm/parsers/KeywordParser.js +87 -0
  41. package/dist/esm/parsers/KeywordParser.js.map +1 -0
  42. package/dist/esm/parsers/LimitClauseParser.js +46 -0
  43. package/dist/esm/parsers/LimitClauseParser.js.map +1 -0
  44. package/dist/esm/parsers/LiteralParser.js +34 -0
  45. package/dist/esm/parsers/LiteralParser.js.map +1 -0
  46. package/dist/esm/parsers/OrderByClauseParser.js +73 -0
  47. package/dist/esm/parsers/OrderByClauseParser.js.map +1 -0
  48. package/dist/esm/parsers/OverExpressionParser.js +40 -0
  49. package/dist/esm/parsers/OverExpressionParser.js.map +1 -0
  50. package/dist/esm/parsers/ParameterExpressionParser.js +11 -0
  51. package/dist/esm/parsers/ParameterExpressionParser.js.map +1 -0
  52. package/dist/esm/parsers/ParenExpressionParser.js +29 -0
  53. package/dist/esm/parsers/ParenExpressionParser.js.map +1 -0
  54. package/dist/esm/parsers/PartitionByParser.js +49 -0
  55. package/dist/esm/parsers/PartitionByParser.js.map +1 -0
  56. package/dist/esm/parsers/SelectClauseParser.js +80 -0
  57. package/dist/esm/parsers/SelectClauseParser.js.map +1 -0
  58. package/dist/esm/parsers/SelectQueryParser.js +149 -0
  59. package/dist/esm/parsers/SelectQueryParser.js.map +1 -0
  60. package/dist/esm/parsers/SourceAliasExpressionParser.js +45 -0
  61. package/dist/esm/parsers/SourceAliasExpressionParser.js.map +1 -0
  62. package/dist/esm/parsers/SourceExpressionParser.js +31 -0
  63. package/dist/esm/parsers/SourceExpressionParser.js.map +1 -0
  64. package/dist/esm/parsers/SourceParser.js +115 -0
  65. package/dist/esm/parsers/SourceParser.js.map +1 -0
  66. package/dist/esm/parsers/SqlTokenizer.js +170 -0
  67. package/dist/esm/parsers/SqlTokenizer.js.map +1 -0
  68. package/dist/esm/parsers/StringSpecifierExpressionParser.js +18 -0
  69. package/dist/esm/parsers/StringSpecifierExpressionParser.js.map +1 -0
  70. package/dist/esm/parsers/UnaryExpressionParser.js +26 -0
  71. package/dist/esm/parsers/UnaryExpressionParser.js.map +1 -0
  72. package/dist/esm/parsers/ValueParser.js +132 -0
  73. package/dist/esm/parsers/ValueParser.js.map +1 -0
  74. package/dist/esm/parsers/ValuesQueryParser.js +82 -0
  75. package/dist/esm/parsers/ValuesQueryParser.js.map +1 -0
  76. package/dist/esm/parsers/WhereClauseParser.js +32 -0
  77. package/dist/esm/parsers/WhereClauseParser.js.map +1 -0
  78. package/dist/esm/parsers/WindowClauseParser.js +41 -0
  79. package/dist/esm/parsers/WindowClauseParser.js.map +1 -0
  80. package/dist/esm/parsers/WindowExpressionParser.js +159 -0
  81. package/dist/esm/parsers/WindowExpressionParser.js.map +1 -0
  82. package/dist/esm/parsers/WithClauseParser.js +53 -0
  83. package/dist/esm/parsers/WithClauseParser.js.map +1 -0
  84. package/dist/esm/tokenReaders/BaseTokenReader.js +78 -0
  85. package/dist/esm/tokenReaders/BaseTokenReader.js.map +1 -0
  86. package/dist/esm/tokenReaders/CommandTokenReader.js +141 -0
  87. package/dist/esm/tokenReaders/CommandTokenReader.js.map +1 -0
  88. package/dist/esm/tokenReaders/FunctionTokenReader.js +41 -0
  89. package/dist/esm/tokenReaders/FunctionTokenReader.js.map +1 -0
  90. package/dist/esm/tokenReaders/IdentifierTokenReader.js +66 -0
  91. package/dist/esm/tokenReaders/IdentifierTokenReader.js.map +1 -0
  92. package/dist/esm/tokenReaders/LiteralTokenReader.js +185 -0
  93. package/dist/esm/tokenReaders/LiteralTokenReader.js.map +1 -0
  94. package/dist/esm/tokenReaders/OperatorTokenReader.js +94 -0
  95. package/dist/esm/tokenReaders/OperatorTokenReader.js.map +1 -0
  96. package/dist/esm/tokenReaders/ParameterTokenReader.js +40 -0
  97. package/dist/esm/tokenReaders/ParameterTokenReader.js.map +1 -0
  98. package/dist/esm/tokenReaders/StringSpecifierTokenReader.js +27 -0
  99. package/dist/esm/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
  100. package/dist/esm/tokenReaders/SymbolTokenReader.js +31 -0
  101. package/dist/esm/tokenReaders/SymbolTokenReader.js.map +1 -0
  102. package/dist/esm/tokenReaders/TokenReaderManager.js +106 -0
  103. package/dist/esm/tokenReaders/TokenReaderManager.js.map +1 -0
  104. package/dist/esm/tokenReaders/TypeTokenReader.js +55 -0
  105. package/dist/esm/tokenReaders/TypeTokenReader.js.map +1 -0
  106. package/dist/esm/transformers/CTEBuilder.js +184 -0
  107. package/dist/esm/transformers/CTEBuilder.js.map +1 -0
  108. package/dist/esm/transformers/CTECollector.js +380 -0
  109. package/dist/esm/transformers/CTECollector.js.map +1 -0
  110. package/dist/esm/transformers/CTEDisabler.js +321 -0
  111. package/dist/esm/transformers/CTEDisabler.js.map +1 -0
  112. package/dist/esm/transformers/CTEInjector.js +79 -0
  113. package/dist/esm/transformers/CTEInjector.js.map +1 -0
  114. package/dist/esm/transformers/CTENormalizer.js +42 -0
  115. package/dist/esm/transformers/CTENormalizer.js.map +1 -0
  116. package/dist/esm/transformers/Formatter.js +463 -0
  117. package/dist/esm/transformers/Formatter.js.map +1 -0
  118. package/dist/esm/transformers/QueryConverter.js +115 -0
  119. package/dist/esm/transformers/QueryConverter.js.map +1 -0
  120. package/dist/esm/transformers/SelectValueCollector.js +245 -0
  121. package/dist/esm/transformers/SelectValueCollector.js.map +1 -0
  122. package/dist/esm/transformers/SelectableColumnCollector.js +304 -0
  123. package/dist/esm/transformers/SelectableColumnCollector.js.map +1 -0
  124. package/dist/esm/transformers/TableColumnResolver.js +2 -0
  125. package/dist/esm/transformers/TableColumnResolver.js.map +1 -0
  126. package/dist/esm/transformers/TableSourceCollector.js +380 -0
  127. package/dist/esm/transformers/TableSourceCollector.js.map +1 -0
  128. package/dist/esm/transformers/UpstreamSelectQueryFinder.js +125 -0
  129. package/dist/esm/transformers/UpstreamSelectQueryFinder.js.map +1 -0
  130. package/dist/esm/types/index.d.ts +14 -0
  131. package/dist/esm/types/models/BinarySelectQuery.d.ts +91 -0
  132. package/dist/esm/types/models/Clause.d.ts +189 -0
  133. package/dist/esm/types/models/KeywordTrie.d.ts +11 -0
  134. package/dist/esm/types/models/Lexeme.d.ts +25 -0
  135. package/dist/esm/types/models/SelectQuery.d.ts +5 -0
  136. package/dist/esm/types/models/SimpleSelectQuery.d.ts +167 -0
  137. package/dist/esm/types/models/SqlComponent.d.ts +18 -0
  138. package/dist/esm/types/models/ValueComponent.d.ts +158 -0
  139. package/dist/esm/types/models/ValuesQuery.d.ts +10 -0
  140. package/dist/esm/types/parsers/CommandExpressionParser.d.ts +15 -0
  141. package/dist/esm/types/parsers/CommonTableParser.d.ts +9 -0
  142. package/dist/esm/types/parsers/ForClauseParser.d.ts +9 -0
  143. package/dist/esm/types/parsers/FromClauseParser.d.ts +9 -0
  144. package/dist/esm/types/parsers/FunctionExpressionParser.d.ts +22 -0
  145. package/dist/esm/types/parsers/GroupByParser.d.ts +10 -0
  146. package/dist/esm/types/parsers/HavingParser.d.ts +9 -0
  147. package/dist/esm/types/parsers/IdentifierParser.d.ts +8 -0
  148. package/dist/esm/types/parsers/JoinClauseParser.d.ts +14 -0
  149. package/dist/esm/types/parsers/KeywordParser.d.ts +17 -0
  150. package/dist/esm/types/parsers/LimitClauseParser.d.ts +9 -0
  151. package/dist/esm/types/parsers/LiteralParser.d.ts +8 -0
  152. package/dist/esm/types/parsers/OrderByClauseParser.d.ts +10 -0
  153. package/dist/esm/types/parsers/OverExpressionParser.d.ts +9 -0
  154. package/dist/esm/types/parsers/ParameterExpressionParser.d.ts +8 -0
  155. package/dist/esm/types/parsers/ParenExpressionParser.d.ts +8 -0
  156. package/dist/esm/types/parsers/PartitionByParser.d.ts +9 -0
  157. package/dist/esm/types/parsers/SelectClauseParser.d.ts +10 -0
  158. package/dist/esm/types/parsers/SelectQueryParser.d.ts +13 -0
  159. package/dist/esm/types/parsers/SourceAliasExpressionParser.d.ts +8 -0
  160. package/dist/esm/types/parsers/SourceExpressionParser.d.ts +8 -0
  161. package/dist/esm/types/parsers/SourceParser.d.ts +13 -0
  162. package/dist/esm/types/parsers/SqlTokenizer.d.ts +64 -0
  163. package/dist/esm/types/parsers/StringSpecifierExpressionParser.d.ts +8 -0
  164. package/dist/esm/types/parsers/UnaryExpressionParser.d.ts +8 -0
  165. package/dist/esm/types/parsers/ValueParser.d.ts +14 -0
  166. package/dist/esm/types/parsers/ValuesQueryParser.d.ts +10 -0
  167. package/dist/esm/types/parsers/WhereClauseParser.d.ts +9 -0
  168. package/dist/esm/types/parsers/WindowClauseParser.d.ts +9 -0
  169. package/dist/esm/types/parsers/WindowExpressionParser.d.ts +12 -0
  170. package/dist/esm/types/parsers/WithClauseParser.d.ts +9 -0
  171. package/dist/esm/types/tokenReaders/BaseTokenReader.d.ts +43 -0
  172. package/dist/esm/types/tokenReaders/CommandTokenReader.d.ts +7 -0
  173. package/dist/esm/types/tokenReaders/FunctionTokenReader.d.ts +11 -0
  174. package/dist/esm/types/tokenReaders/IdentifierTokenReader.d.ts +15 -0
  175. package/dist/esm/types/tokenReaders/LiteralTokenReader.d.ts +23 -0
  176. package/dist/esm/types/tokenReaders/OperatorTokenReader.d.ts +5 -0
  177. package/dist/esm/types/tokenReaders/ParameterTokenReader.d.ts +11 -0
  178. package/dist/esm/types/tokenReaders/StringSpecifierTokenReader.d.ts +8 -0
  179. package/dist/esm/types/tokenReaders/SymbolTokenReader.d.ts +12 -0
  180. package/dist/esm/types/tokenReaders/TokenReaderManager.d.ts +53 -0
  181. package/dist/esm/types/tokenReaders/TypeTokenReader.d.ts +11 -0
  182. package/dist/esm/types/transformers/CTEBuilder.d.ts +52 -0
  183. package/dist/esm/types/transformers/CTECollector.d.ts +81 -0
  184. package/dist/esm/types/transformers/CTEDisabler.d.ts +77 -0
  185. package/dist/esm/types/transformers/CTEInjector.d.ts +40 -0
  186. package/dist/esm/types/transformers/CTENormalizer.d.ts +25 -0
  187. package/dist/esm/types/transformers/Formatter.d.ts +82 -0
  188. package/dist/esm/types/transformers/QueryConverter.d.ts +41 -0
  189. package/dist/esm/types/transformers/SelectValueCollector.d.ts +60 -0
  190. package/dist/esm/types/transformers/SelectableColumnCollector.d.ts +70 -0
  191. package/dist/esm/types/transformers/TableColumnResolver.d.ts +10 -0
  192. package/dist/esm/types/transformers/TableSourceCollector.d.ts +92 -0
  193. package/dist/esm/types/transformers/UpstreamSelectQueryFinder.d.ts +27 -0
  194. package/dist/esm/types/utils/charLookupTable.d.ts +11 -0
  195. package/dist/esm/types/utils/stringUtils.d.ts +43 -0
  196. package/dist/esm/utils/charLookupTable.js +69 -0
  197. package/dist/esm/utils/charLookupTable.js.map +1 -0
  198. package/dist/esm/utils/stringUtils.js +164 -0
  199. package/dist/esm/utils/stringUtils.js.map +1 -0
  200. package/dist/index.d.ts +1 -0
  201. package/dist/index.js +1 -0
  202. package/dist/index.js.map +1 -1
  203. package/dist/transformers/SelectValueCollector.d.ts +2 -4
  204. package/dist/transformers/SelectValueCollector.js.map +1 -1
  205. package/dist/transformers/TableColumnResolver.d.ts +10 -0
  206. package/dist/transformers/TableColumnResolver.js +3 -0
  207. package/dist/transformers/TableColumnResolver.js.map +1 -0
  208. package/package.json +17 -1
@@ -0,0 +1,185 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ import { CharLookupTable } from '../utils/charLookupTable';
4
+ import { KeywordParser } from '../parsers/KeywordParser';
5
+ import { KeywordTrie } from '../models/KeywordTrie';
6
+ /**
7
+ * Reads SQL literal tokens (numbers, strings)
8
+ */
9
+ const keywords = [
10
+ ["null"],
11
+ ["true"],
12
+ ["false"],
13
+ ["current_date"],
14
+ ["current_time"],
15
+ ["current_timestamp"],
16
+ ["localtime"],
17
+ ["localtimestamp"],
18
+ ["unbounded"],
19
+ ["normalized"],
20
+ ["nfc", "normalized"],
21
+ ["nfd", "normalized"],
22
+ ["nfkc", "normalized"],
23
+ ["nfkd", "normalized"],
24
+ ["nfc"],
25
+ ["nfd"],
26
+ ["nfkc"],
27
+ ["nfkd"],
28
+ ];
29
+ const trie = new KeywordTrie(keywords);
30
+ export const literalKeywordParser = new KeywordParser(trie);
31
+ export class LiteralTokenReader extends BaseTokenReader {
32
+ /**
33
+ * Try to read a literal token
34
+ */
35
+ tryRead(previous) {
36
+ if (this.isEndOfInput()) {
37
+ return null;
38
+ }
39
+ const char = this.input[this.position];
40
+ // Check for keyword literals
41
+ const keyword = this.tryReadKeyword();
42
+ if (keyword) {
43
+ return keyword;
44
+ }
45
+ // Decimal token starting with a dot
46
+ if (char === '.' && this.canRead(1) && CharLookupTable.isDigit(this.input[this.position + 1])) {
47
+ return this.createLexeme(TokenType.Literal, this.readDigit());
48
+ }
49
+ // String literal
50
+ if (char === '\'') {
51
+ const value = this.readSingleQuotedString(false);
52
+ return this.createLexeme(TokenType.Literal, value);
53
+ }
54
+ // Digit tokens
55
+ if (CharLookupTable.isDigit(char)) {
56
+ return this.createLexeme(TokenType.Literal, this.readDigit());
57
+ }
58
+ // Signed number
59
+ if ((char === '+' || char === '-') && this.isValidNumericPrefix(previous)) {
60
+ const sign = char;
61
+ this.position++;
62
+ // Skip whitespace after sign
63
+ const pos = this.position;
64
+ while (this.canRead() && CharLookupTable.isWhitespace(this.input[this.position])) {
65
+ this.position++;
66
+ }
67
+ if (this.canRead() && (CharLookupTable.isDigit(this.input[this.position]) ||
68
+ (this.input[this.position] === '.' &&
69
+ this.canRead(1) &&
70
+ CharLookupTable.isDigit(this.input[this.position + 1])))) {
71
+ return this.createLexeme(TokenType.Literal, sign === '-' ? sign + this.readDigit() : this.readDigit());
72
+ }
73
+ // Not a number, restore position
74
+ this.position = pos - 1; // Adjust for the increment at the beginning
75
+ }
76
+ return null;
77
+ }
78
+ tryReadKeyword() {
79
+ // Check for keyword literals
80
+ const result = literalKeywordParser.parse(this.input, this.position);
81
+ if (result) {
82
+ this.position = result.newPosition;
83
+ return this.createLexeme(TokenType.Literal, result.keyword);
84
+ }
85
+ return null;
86
+ }
87
+ /**
88
+ * Check if the current context allows for a signed number
89
+ */
90
+ isValidNumericPrefix(previous) {
91
+ return previous === null ||
92
+ (previous.type !== TokenType.Literal &&
93
+ previous.type !== TokenType.Identifier);
94
+ }
95
+ /**
96
+ * Read a numeric value
97
+ */
98
+ readDigit() {
99
+ const start = this.position;
100
+ let hasDot = false;
101
+ let hasExponent = false;
102
+ // Consider 0x, 0b, 0o
103
+ if (this.canRead(1) &&
104
+ this.input[this.position] === '0' &&
105
+ "xbo".includes(this.input[this.position + 1].toLowerCase())) {
106
+ const prefixType = this.input[this.position + 1].toLowerCase();
107
+ this.position += 2;
108
+ // Continue to get numeric and hexadecimal notation strings
109
+ const isHex = prefixType === 'x';
110
+ while (this.canRead()) {
111
+ const c = this.input[this.position];
112
+ if (CharLookupTable.isDigit(c) || (isHex && CharLookupTable.isHexChar(c))) {
113
+ this.position++;
114
+ }
115
+ else {
116
+ break;
117
+ }
118
+ }
119
+ return this.input.slice(start, this.position);
120
+ }
121
+ // If starting with dot, note it
122
+ if (this.input[start] === '.') {
123
+ hasDot = true;
124
+ this.position++;
125
+ }
126
+ // Consider decimal point and exponential notation
127
+ while (this.canRead()) {
128
+ const char = this.input[this.position];
129
+ if (char === '.' && !hasDot) {
130
+ hasDot = true;
131
+ }
132
+ else if ((char === 'e' || char === 'E') && !hasExponent) {
133
+ hasExponent = true;
134
+ if (this.canRead(1) && (this.input[this.position + 1] === '+' || this.input[this.position + 1] === '-')) {
135
+ this.position++;
136
+ }
137
+ }
138
+ else if (!CharLookupTable.isDigit(char)) {
139
+ break;
140
+ }
141
+ this.position++;
142
+ }
143
+ if (start === this.position) {
144
+ throw new Error(`Unexpected character. position: ${start}\n${this.getDebugPositionInfo(start)}`);
145
+ }
146
+ if (this.input[start] === '.') {
147
+ // If the number starts with a dot, add 0 to the front
148
+ return '0' + this.input.slice(start, this.position);
149
+ }
150
+ return this.input.slice(start, this.position);
151
+ }
152
+ /**
153
+ * Read a string literal
154
+ */
155
+ readSingleQuotedString(includeSingleQuote) {
156
+ const start = this.position;
157
+ let closed = false;
158
+ this.read("'");
159
+ while (this.canRead()) {
160
+ const char = this.input[this.position];
161
+ this.position++;
162
+ // escape character check
163
+ if (char === "\\" && this.canRead(1)) {
164
+ this.position++;
165
+ continue;
166
+ }
167
+ else if (char === '\'') {
168
+ closed = true;
169
+ break;
170
+ }
171
+ }
172
+ if (closed === false) {
173
+ throw new Error(`Single quote is not closed. position: ${start}\n${this.getDebugPositionInfo(start)}`);
174
+ }
175
+ if (includeSingleQuote) {
176
+ const value = this.input.slice(start, this.position);
177
+ return value;
178
+ }
179
+ else {
180
+ const value = this.input.slice(start + 1, this.position - 1);
181
+ return value;
182
+ }
183
+ }
184
+ }
185
+ //# sourceMappingURL=LiteralTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiteralTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/LiteralTokenReader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ import { CharLookupTable } from '../utils/charLookupTable';
4
+ import { KeywordParser } from '../parsers/KeywordParser';
5
+ import { KeywordTrie } from '../models/KeywordTrie';
6
+ const trie = new KeywordTrie([
7
+ // binary
8
+ ["and"],
9
+ ["or"],
10
+ ["is"],
11
+ ["is", "not"],
12
+ ["is", "distinct", "from"],
13
+ ["is", "not", "distinct", "from"],
14
+ ["like"],
15
+ ["in"],
16
+ ["exists"],
17
+ ["between"],
18
+ ["not", "like"],
19
+ ["not", "in"],
20
+ ["not", "exists"],
21
+ ["not", "between"],
22
+ ["escape"], // e.g. '10% OFF on all items' like '10\%%' escape '\'
23
+ ["uescape"], // e.g. U&'d!0061t!+000061' uescape '!'
24
+ ["similar"], // e.g. substring('abcdef' similar '%#"cd#"%' escape '#')
25
+ ["placing"], // e.g. overlay('abcdef' placing 'cd' from 3 for 2)
26
+ // unary
27
+ ["not"],
28
+ // unary - trim
29
+ ["both"],
30
+ ["leading"],
31
+ ["trailing"],
32
+ ["both", "from"], // Postgres
33
+ ["leading", "from"], // Postgres
34
+ ["trailing", "from"], // Postgres
35
+ // unary - extract
36
+ ["year", "from"],
37
+ ["month", "from"],
38
+ ["day", "from"],
39
+ ["hour", "from"],
40
+ ["minute", "from"],
41
+ ["second", "from"],
42
+ ["dow", "from"],
43
+ ["doy", "from"],
44
+ ["isodow", "from"],
45
+ ["quarter", "from"],
46
+ ["week", "from"],
47
+ ["epoch", "from"],
48
+ ["at", "time", "zone"],
49
+ ["interval"],
50
+ // The following are not considered operators.
51
+ // ["from"], can be used as an operator only within the substring function, but it cannot be distinguished from the Form Clause. This will be resolved with a dedicated substring parser.
52
+ // ["for"], can be used as an operator only within the substring function, but it cannot be distinguished from the For Clause. This will be resolved with a dedicated substring parser.
53
+ ]);
54
+ const keywordParser = new KeywordParser(trie);
55
+ export class OperatorTokenReader extends BaseTokenReader {
56
+ tryRead(previous) {
57
+ if (this.isEndOfInput()) {
58
+ return null;
59
+ }
60
+ /*
61
+ NOTE:
62
+ Asterisks could potentially be wildcard identifiers,
63
+ but since they're indistinguishable at this stage, they're treated as Operators at the token level.
64
+ The Parser needs to determine whether they are appropriate Operators or Identifiers.
65
+ */
66
+ const char = this.input[this.position];
67
+ if (CharLookupTable.isOperatorSymbol(char)) {
68
+ const start = this.position;
69
+ while (this.canRead() && CharLookupTable.isOperatorSymbol(this.input[this.position])) {
70
+ // check for `--` and `/*` comments
71
+ if (this.canRead(1)) {
72
+ const current = this.input[this.position];
73
+ if (current === '-' && this.input[this.position + 1] === '-') {
74
+ break;
75
+ }
76
+ else if (current === '/' && this.input[this.position + 1] === '*') {
77
+ break; // end of operator
78
+ }
79
+ }
80
+ this.position++;
81
+ }
82
+ const resut = this.input.slice(start, this.position);
83
+ return this.createLexeme(TokenType.Operator, resut);
84
+ }
85
+ // Logical operators
86
+ const result = keywordParser.parse(this.input, this.position);
87
+ if (result !== null) {
88
+ this.position = result.newPosition;
89
+ return this.createLexeme(TokenType.Operator, result.keyword);
90
+ }
91
+ return null;
92
+ }
93
+ }
94
+ //# sourceMappingURL=OperatorTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperatorTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/OperatorTokenReader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ import { CharLookupTable } from '../utils/charLookupTable';
4
+ /**
5
+ * Reads SQL parameter tokens (@param, :param, $param, ?)
6
+ */
7
+ export class ParameterTokenReader extends BaseTokenReader {
8
+ /**
9
+ * Try to read a parameter token
10
+ */
11
+ tryRead(previous) {
12
+ if (this.isEndOfInput()) {
13
+ return null;
14
+ }
15
+ const char = this.input[this.position];
16
+ // named parameter (@param, :param, $param)
17
+ if (CharLookupTable.isNamedParameterPrefix(char)) {
18
+ // However, do not recognize as a parameter if the next character is an operator symbol
19
+ // To avoid postgres `::`
20
+ if (this.canRead(1) && CharLookupTable.isOperatorSymbol(this.input[this.position + 1])) {
21
+ return null;
22
+ }
23
+ this.position++;
24
+ // Read the identifier part after the prefix
25
+ const start = this.position;
26
+ while (this.canRead() && !CharLookupTable.isDelimiter(this.input[this.position])) {
27
+ this.position++;
28
+ }
29
+ const identifier = this.input.slice(start, this.position);
30
+ return this.createLexeme(TokenType.Parameter, char + identifier);
31
+ }
32
+ // nameless parameter (?)
33
+ if (char === '?') {
34
+ this.position++;
35
+ return this.createLexeme(TokenType.Parameter, char);
36
+ }
37
+ return null;
38
+ }
39
+ }
40
+ //# sourceMappingURL=ParameterTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParameterTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/ParameterTokenReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IACrD;;OAEG;IACI,OAAO,CAAC,QAAuB;QAClC,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvC,2CAA2C;QAC3C,IAAI,eAAe,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;YAE/C,uFAAuF;YACvF,yBAAyB;YACzB,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrF,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YAEhB,4CAA4C;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAC/E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpB,CAAC;YAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,GAAG,UAAU,CAAC,CAAC;QACrE,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}
@@ -0,0 +1,27 @@
1
+ import { TokenType } from '../models/Lexeme';
2
+ import { BaseTokenReader } from './BaseTokenReader';
3
+ // Prefix sets for quick checks
4
+ const STRING_SPECIFIERS = new Set(['e\'', 'E\'', 'x\'', 'X\'', 'b\'', 'B\'']);
5
+ const UNICODE_STRING_SPECIFIERS = new Set(['u&\'', 'U&\'']);
6
+ export class StringSpecifierTokenReader extends BaseTokenReader {
7
+ /**
8
+ * Try to read an escaped literal like e'...', x'...', etc.
9
+ */
10
+ tryRead(previous) {
11
+ const start = this.position;
12
+ // Check for prefixed literals: e', x', b'
13
+ if (this.canRead(1) && STRING_SPECIFIERS.has(this.input.slice(start, start + 2))) {
14
+ this.position += 1;
15
+ const result = this.createLexeme(TokenType.StringSpecifier, this.input.slice(start, this.position));
16
+ return result;
17
+ }
18
+ // Check for unicode literal: u&'
19
+ if (this.canRead(2) && UNICODE_STRING_SPECIFIERS.has(this.input.slice(start, start + 3))) {
20
+ this.position += 2;
21
+ const result = this.createLexeme(TokenType.StringSpecifier, this.input.slice(start, this.position));
22
+ return result;
23
+ }
24
+ return null;
25
+ }
26
+ }
27
+ //# sourceMappingURL=StringSpecifierTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StringSpecifierTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/StringSpecifierTokenReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,+BAA+B;AAC/B,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9E,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,MAAM,OAAO,0BAA2B,SAAQ,eAAe;IAE3D;;OAEG;IACI,OAAO,CAAC,QAAuB;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAE5B,0CAA0C;QAC1C,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACpG,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACpG,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}
@@ -0,0 +1,31 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ /**
4
+ * Reads SQL symbol tokens (., ,, (, ))
5
+ */
6
+ export class SpecialSymbolTokenReader extends BaseTokenReader {
7
+ /**
8
+ * Try to read a symbol token
9
+ */
10
+ tryRead(previous) {
11
+ if (this.isEndOfInput()) {
12
+ return null;
13
+ }
14
+ const char = this.input[this.position];
15
+ // symbol tokens
16
+ if (char in SpecialSymbolTokenReader.SPECIAL_SYMBOL_TOKENS) {
17
+ this.position++;
18
+ return this.createLexeme(SpecialSymbolTokenReader.SPECIAL_SYMBOL_TOKENS[char], char);
19
+ }
20
+ return null;
21
+ }
22
+ }
23
+ SpecialSymbolTokenReader.SPECIAL_SYMBOL_TOKENS = {
24
+ '.': TokenType.Dot,
25
+ ',': TokenType.Comma,
26
+ '(': TokenType.OpenParen,
27
+ ')': TokenType.CloseParen,
28
+ '[': TokenType.OpenBracket,
29
+ ']': TokenType.CloseBracket,
30
+ };
31
+ //# sourceMappingURL=SymbolTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SymbolTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/SymbolTokenReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAErD;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,eAAe;IAUzD;;OAEG;IACI,OAAO,CAAC,QAAuB;QAClC,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvC,gBAAgB;QAChB,IAAI,IAAI,IAAI,wBAAwB,CAAC,qBAAqB,EAAE,CAAC;YACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,YAAY,CACpB,wBAAwB,CAAC,qBAAqB,CAAC,IAAI,CAAC,EACpD,IAAI,CACP,CAAC;QACN,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;;AA5BuB,8CAAqB,GAA8B;IACvE,GAAG,EAAE,SAAS,CAAC,GAAG;IAClB,GAAG,EAAE,SAAS,CAAC,KAAK;IACpB,GAAG,EAAE,SAAS,CAAC,SAAS;IACxB,GAAG,EAAE,SAAS,CAAC,UAAU;IACzB,GAAG,EAAE,SAAS,CAAC,WAAW;IAC1B,GAAG,EAAE,SAAS,CAAC,YAAY;CAC9B,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Manages and coordinates multiple token readers
3
+ */
4
+ export class TokenReaderManager {
5
+ constructor(input, position = 0) {
6
+ this.cacheHits = 0;
7
+ this.cacheMisses = 0;
8
+ this.input = input;
9
+ this.position = position;
10
+ this.readers = [];
11
+ this.tokenCache = new Map();
12
+ }
13
+ /**
14
+ * Register a token reader
15
+ * @param reader The reader to register
16
+ * @returns This manager instance for chaining
17
+ */
18
+ register(reader) {
19
+ this.readers.push(reader);
20
+ return this;
21
+ }
22
+ /**
23
+ * Register multiple token readers
24
+ * @param readers The readers to register
25
+ * @returns This manager instance for chaining
26
+ */
27
+ registerAll(readers) {
28
+ readers.forEach(reader => this.register(reader));
29
+ return this;
30
+ }
31
+ /**
32
+ * Update the position for all readers
33
+ */
34
+ setPosition(position) {
35
+ this.position = position;
36
+ for (const reader of this.readers) {
37
+ reader.setPosition(position);
38
+ }
39
+ }
40
+ /**
41
+ * Try to read a token using all registered readers
42
+ * @param position The position to read from
43
+ * @param previous The previous token, if any
44
+ * @returns The lexeme if a reader could read it, null otherwise
45
+ */
46
+ tryRead(position, previous) {
47
+ // Check cache - using position as the key
48
+ if (this.tokenCache.has(position)) {
49
+ // Cache hit
50
+ this.cacheHits++;
51
+ const lexeme = this.tokenCache.get(position) || null;
52
+ return lexeme;
53
+ }
54
+ // Cache miss - create new entry
55
+ this.cacheMisses++;
56
+ this.setPosition(position);
57
+ // Try to read with each reader
58
+ let lexeme = null;
59
+ for (const reader of this.readers) {
60
+ lexeme = reader.tryRead(previous);
61
+ if (lexeme) {
62
+ this.position = reader.getPosition();
63
+ break;
64
+ }
65
+ }
66
+ // Update all readers' positions
67
+ for (const reader of this.readers) {
68
+ reader.setPosition(this.position);
69
+ }
70
+ // Save to cache (even if null)
71
+ this.tokenCache.set(position, lexeme);
72
+ return lexeme;
73
+ }
74
+ /**
75
+ * Get the maximum position among all readers
76
+ */
77
+ getMaxPosition() {
78
+ let maxPosition = this.position;
79
+ for (const reader of this.readers) {
80
+ const position = reader.getPosition();
81
+ if (position > maxPosition) {
82
+ maxPosition = position;
83
+ }
84
+ }
85
+ return maxPosition;
86
+ }
87
+ /**
88
+ * Get the input string
89
+ */
90
+ getInput() {
91
+ return this.input;
92
+ }
93
+ /**
94
+ * Get cache statistics
95
+ */
96
+ getCacheStats() {
97
+ const total = this.cacheHits + this.cacheMisses;
98
+ const ratio = total > 0 ? this.cacheHits / total : 0;
99
+ return {
100
+ hits: this.cacheHits,
101
+ misses: this.cacheMisses,
102
+ ratio: ratio
103
+ };
104
+ }
105
+ }
106
+ //# sourceMappingURL=TokenReaderManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenReaderManager.js","sourceRoot":"","sources":["../../../src/tokenReaders/TokenReaderManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ import { StringUtils } from '../utils/stringUtils';
4
+ import { KeywordTrie } from '../models/KeywordTrie';
5
+ import { KeywordParser } from '../parsers/KeywordParser';
6
+ // Use KeywordTrie to identify type names composed of multiple words.
7
+ const trie = new KeywordTrie([
8
+ // type
9
+ ["double", "precision"],
10
+ ["character", "varying"],
11
+ ["time", "without", "time", "zone"],
12
+ ["time", "with", "time", "zone"],
13
+ ["timestamp", "without", "time", "zone"],
14
+ ["timestamp", "with", "time", "zone"],
15
+ ]);
16
+ const typeParser = new KeywordParser(trie);
17
+ /**
18
+ * Reads SQL identifier tokens
19
+ */
20
+ export class TypeTokenReader extends BaseTokenReader {
21
+ /**
22
+ * Try to read an identifier token
23
+ */
24
+ tryRead(previous) {
25
+ if (this.isEndOfInput()) {
26
+ return null;
27
+ }
28
+ // Check for keyword identifiers
29
+ const keyword = typeParser.parse(this.input, this.position);
30
+ if (keyword !== null) {
31
+ this.position = keyword.newPosition;
32
+ return this.createLexeme(TokenType.Type, keyword.keyword);
33
+ }
34
+ // check pervious token
35
+ if (previous === null) {
36
+ return null;
37
+ }
38
+ const result = StringUtils.tryReadRegularIdentifier(this.input, this.position);
39
+ if (!result) {
40
+ return null;
41
+ }
42
+ this.position = result.newPosition;
43
+ // type cast command
44
+ if (previous.type === TokenType.Command && previous.value === "as") {
45
+ // If the previous token is the `as` keyword, it could be a type cast or an identifier
46
+ return this.createLexeme(TokenType.Identifier, result.identifier, true);
47
+ }
48
+ // postgres type conversion
49
+ if (previous.type === TokenType.Operator && previous.value === "::") {
50
+ return this.createLexeme(TokenType.Type, result.identifier);
51
+ }
52
+ return null;
53
+ }
54
+ }
55
+ //# sourceMappingURL=TypeTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/TypeTokenReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,qEAAqE;AACrE,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC;IACzB,OAAO;IACP,CAAC,QAAQ,EAAE,WAAW,CAAC;IACvB,CAAC,WAAW,EAAE,SAAS,CAAC;IACxB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;IACnC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAChC,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;IACxC,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;CACxC,CAAC,CAAC;AACH,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,eAAe;IAChD;;OAEG;IACI,OAAO,CAAC,QAAuB;QAClC,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;YACpC,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QAED,uBAAuB;QACvB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC;QAEnC,oBAAoB;QACpB,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACjE,sFAAsF;YACtF,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QAED,2BAA2B;QAC3B,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}