circle-ir 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +200 -0
- package/configs/sinks/code_injection.yaml +672 -0
- package/configs/sinks/command.yaml +917 -0
- package/configs/sinks/deserialization.yaml +105 -0
- package/configs/sinks/ldap.yaml +136 -0
- package/configs/sinks/nodejs.json +629 -0
- package/configs/sinks/path.yaml +715 -0
- package/configs/sinks/python.json +501 -0
- package/configs/sinks/rust.json +339 -0
- package/configs/sinks/sql.yaml +233 -0
- package/configs/sinks/ssrf.yaml +160 -0
- package/configs/sinks/xpath.yaml +121 -0
- package/configs/sinks/xss.yaml +727 -0
- package/configs/sources/db_sources.yaml +90 -0
- package/configs/sources/env_sources.yaml +94 -0
- package/configs/sources/express.json +197 -0
- package/configs/sources/file_sources.yaml +164 -0
- package/configs/sources/http_sources.yaml +379 -0
- package/configs/sources/io_sources.yaml +519 -0
- package/configs/sources/network_sources.yaml +99 -0
- package/configs/sources/python.json +230 -0
- package/configs/sources/rust.json +286 -0
- package/configs/sources/spring.yaml +70 -0
- package/dist/analysis/advisory-db.d.ts +86 -0
- package/dist/analysis/advisory-db.js +104 -0
- package/dist/analysis/advisory-db.js.map +1 -0
- package/dist/analysis/cargo-parser.d.ts +42 -0
- package/dist/analysis/cargo-parser.js +102 -0
- package/dist/analysis/cargo-parser.js.map +1 -0
- package/dist/analysis/config-loader.d.ts +37 -0
- package/dist/analysis/config-loader.js +1561 -0
- package/dist/analysis/config-loader.js.map +1 -0
- package/dist/analysis/constant-propagation/ast-utils.d.ts +25 -0
- package/dist/analysis/constant-propagation/ast-utils.js +34 -0
- package/dist/analysis/constant-propagation/ast-utils.js.map +1 -0
- package/dist/analysis/constant-propagation/evaluator.d.ts +32 -0
- package/dist/analysis/constant-propagation/evaluator.js +296 -0
- package/dist/analysis/constant-propagation/evaluator.js.map +1 -0
- package/dist/analysis/constant-propagation/index.d.ts +62 -0
- package/dist/analysis/constant-propagation/index.js +152 -0
- package/dist/analysis/constant-propagation/index.js.map +1 -0
- package/dist/analysis/constant-propagation/patterns.d.ts +8 -0
- package/dist/analysis/constant-propagation/patterns.js +126 -0
- package/dist/analysis/constant-propagation/patterns.js.map +1 -0
- package/dist/analysis/constant-propagation/propagator.d.ts +180 -0
- package/dist/analysis/constant-propagation/propagator.js +1985 -0
- package/dist/analysis/constant-propagation/propagator.js.map +1 -0
- package/dist/analysis/constant-propagation/types.d.ts +63 -0
- package/dist/analysis/constant-propagation/types.js +5 -0
- package/dist/analysis/constant-propagation/types.js.map +1 -0
- package/dist/analysis/constant-propagation.d.ts +9 -0
- package/dist/analysis/constant-propagation.js +18 -0
- package/dist/analysis/constant-propagation.js.map +1 -0
- package/dist/analysis/dependency-scanner.d.ts +79 -0
- package/dist/analysis/dependency-scanner.js +122 -0
- package/dist/analysis/dependency-scanner.js.map +1 -0
- package/dist/analysis/dfg-verifier.d.ts +116 -0
- package/dist/analysis/dfg-verifier.js +399 -0
- package/dist/analysis/dfg-verifier.js.map +1 -0
- package/dist/analysis/findings.d.ts +11 -0
- package/dist/analysis/findings.js +228 -0
- package/dist/analysis/findings.js.map +1 -0
- package/dist/analysis/index.d.ts +16 -0
- package/dist/analysis/index.js +18 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/interprocedural.d.ts +99 -0
- package/dist/analysis/interprocedural.js +526 -0
- package/dist/analysis/interprocedural.js.map +1 -0
- package/dist/analysis/path-finder.d.ts +133 -0
- package/dist/analysis/path-finder.js +354 -0
- package/dist/analysis/path-finder.js.map +1 -0
- package/dist/analysis/rules.d.ts +75 -0
- package/dist/analysis/rules.js +332 -0
- package/dist/analysis/rules.js.map +1 -0
- package/dist/analysis/semver.d.ts +27 -0
- package/dist/analysis/semver.js +127 -0
- package/dist/analysis/semver.js.map +1 -0
- package/dist/analysis/taint-matcher.d.ts +15 -0
- package/dist/analysis/taint-matcher.js +634 -0
- package/dist/analysis/taint-matcher.js.map +1 -0
- package/dist/analysis/taint-propagation.d.ts +67 -0
- package/dist/analysis/taint-propagation.js +298 -0
- package/dist/analysis/taint-propagation.js.map +1 -0
- package/dist/analysis/unresolved.d.ts +14 -0
- package/dist/analysis/unresolved.js +202 -0
- package/dist/analysis/unresolved.js.map +1 -0
- package/dist/analyzer.d.ts +43 -0
- package/dist/analyzer.js +1010 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/browser/circle-ir.js +16576 -0
- package/dist/browser.d.ts +38 -0
- package/dist/browser.js +38 -0
- package/dist/browser.js.map +1 -0
- package/dist/core/circle-ir-core.cjs +13626 -0
- package/dist/core/circle-ir-core.d.ts +59 -0
- package/dist/core/circle-ir-core.js +13591 -0
- package/dist/core/extractors/calls.d.ts +13 -0
- package/dist/core/extractors/calls.js +1429 -0
- package/dist/core/extractors/calls.js.map +1 -0
- package/dist/core/extractors/cfg.d.ts +9 -0
- package/dist/core/extractors/cfg.js +519 -0
- package/dist/core/extractors/cfg.js.map +1 -0
- package/dist/core/extractors/dfg.d.ts +12 -0
- package/dist/core/extractors/dfg.js +1081 -0
- package/dist/core/extractors/dfg.js.map +1 -0
- package/dist/core/extractors/exports.d.ts +14 -0
- package/dist/core/extractors/exports.js +80 -0
- package/dist/core/extractors/exports.js.map +1 -0
- package/dist/core/extractors/imports.d.ts +9 -0
- package/dist/core/extractors/imports.js +739 -0
- package/dist/core/extractors/imports.js.map +1 -0
- package/dist/core/extractors/index.d.ts +10 -0
- package/dist/core/extractors/index.js +11 -0
- package/dist/core/extractors/index.js.map +1 -0
- package/dist/core/extractors/meta.d.ts +10 -0
- package/dist/core/extractors/meta.js +109 -0
- package/dist/core/extractors/meta.js.map +1 -0
- package/dist/core/extractors/types.d.ts +10 -0
- package/dist/core/extractors/types.js +1479 -0
- package/dist/core/extractors/types.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/parser.d.ts +84 -0
- package/dist/core/parser.js +250 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core-lib.d.ts +59 -0
- package/dist/core-lib.js +62 -0
- package/dist/core-lib.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/index.d.ts +11 -0
- package/dist/languages/index.js +14 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/plugins/base.d.ts +44 -0
- package/dist/languages/plugins/base.js +82 -0
- package/dist/languages/plugins/base.js.map +1 -0
- package/dist/languages/plugins/index.d.ts +14 -0
- package/dist/languages/plugins/index.js +25 -0
- package/dist/languages/plugins/index.js.map +1 -0
- package/dist/languages/plugins/java.d.ts +49 -0
- package/dist/languages/plugins/java.js +402 -0
- package/dist/languages/plugins/java.js.map +1 -0
- package/dist/languages/plugins/javascript.d.ts +48 -0
- package/dist/languages/plugins/javascript.js +445 -0
- package/dist/languages/plugins/javascript.js.map +1 -0
- package/dist/languages/plugins/python.d.ts +47 -0
- package/dist/languages/plugins/python.js +480 -0
- package/dist/languages/plugins/python.js.map +1 -0
- package/dist/languages/plugins/rust.d.ts +47 -0
- package/dist/languages/plugins/rust.js +405 -0
- package/dist/languages/plugins/rust.js.map +1 -0
- package/dist/languages/registry.d.ts +30 -0
- package/dist/languages/registry.js +80 -0
- package/dist/languages/registry.js.map +1 -0
- package/dist/languages/types.d.ts +184 -0
- package/dist/languages/types.js +8 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/resolution/cross-file.d.ts +146 -0
- package/dist/resolution/cross-file.js +439 -0
- package/dist/resolution/cross-file.js.map +1 -0
- package/dist/resolution/index.d.ts +12 -0
- package/dist/resolution/index.js +10 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/symbol-table.d.ts +136 -0
- package/dist/resolution/symbol-table.js +336 -0
- package/dist/resolution/symbol-table.js.map +1 -0
- package/dist/resolution/type-hierarchy.d.ts +124 -0
- package/dist/resolution/type-hierarchy.js +515 -0
- package/dist/resolution/type-hierarchy.js.map +1 -0
- package/dist/types/config.d.ts +45 -0
- package/dist/types/config.js +5 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +392 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +85 -0
- package/dist/utils/logger.js +198 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/wasm/tree-sitter-java.wasm +0 -0
- package/dist/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/wasm/tree-sitter-python.wasm +0 -0
- package/dist/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/wasm/web-tree-sitter.wasm +0 -0
- package/docs/SPEC.md +1021 -0
- package/examples/browser-example.html +610 -0
- package/examples/node-example.ts +215 -0
- package/package.json +107 -0
- package/wasm/tree-sitter-java.wasm +0 -0
- package/wasm/tree-sitter-javascript.wasm +0 -0
- package/wasm/tree-sitter-python.wasm +0 -0
- package/wasm/tree-sitter-rust.wasm +0 -0
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taint source/sink matcher
|
|
3
|
+
*
|
|
4
|
+
* Matches method calls and annotations against taint configurations.
|
|
5
|
+
*/
|
|
6
|
+
import { getDefaultConfig } from './config-loader.js';
|
|
7
|
+
/**
|
|
8
|
+
* Analyze code for taint sources, sinks, and sanitizers.
|
|
9
|
+
*/
|
|
10
|
+
export function analyzeTaint(calls, types, config = getDefaultConfig()) {
|
|
11
|
+
const sources = findSources(calls, types, config.sources);
|
|
12
|
+
const sinks = findSinks(calls, config.sinks);
|
|
13
|
+
const sanitizers = findSanitizers(calls, types, config.sanitizers);
|
|
14
|
+
return { sources, sinks, sanitizers };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find taint sources in method calls and annotated parameters.
|
|
18
|
+
*/
|
|
19
|
+
function findSources(calls, types, patterns) {
|
|
20
|
+
const sources = [];
|
|
21
|
+
// Check method calls
|
|
22
|
+
for (const call of calls) {
|
|
23
|
+
for (const pattern of patterns) {
|
|
24
|
+
if (matchesSourcePattern(call, pattern)) {
|
|
25
|
+
sources.push({
|
|
26
|
+
type: pattern.type,
|
|
27
|
+
location: formatCallLocation(call),
|
|
28
|
+
severity: pattern.severity,
|
|
29
|
+
line: call.location.line,
|
|
30
|
+
confidence: 1.0,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Check annotated parameters
|
|
36
|
+
for (const type of types) {
|
|
37
|
+
for (const method of type.methods) {
|
|
38
|
+
for (const param of method.parameters) {
|
|
39
|
+
for (const pattern of patterns) {
|
|
40
|
+
if (pattern.annotation && pattern.param_tainted) {
|
|
41
|
+
if (matchesAnnotation(param.annotations, pattern.annotation)) {
|
|
42
|
+
// Use parameter line if available, fallback to method start line
|
|
43
|
+
const paramLine = param.line ?? method.start_line;
|
|
44
|
+
sources.push({
|
|
45
|
+
type: pattern.type,
|
|
46
|
+
location: `@${pattern.annotation} ${param.name} in ${method.name}`,
|
|
47
|
+
severity: pattern.severity,
|
|
48
|
+
line: paramLine,
|
|
49
|
+
confidence: 1.0,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Inter-procedural: treat certain method parameters as potential taint sources
|
|
58
|
+
// This handles cases where tainted data flows from another class/method
|
|
59
|
+
for (const type of types) {
|
|
60
|
+
for (const method of type.methods) {
|
|
61
|
+
// Skip private methods (can only be called from within the class)
|
|
62
|
+
if (method.modifiers.includes('private'))
|
|
63
|
+
continue;
|
|
64
|
+
// Skip standard methods that are unlikely to receive tainted data
|
|
65
|
+
const skipMethods = ['toString', 'hashCode', 'equals', 'compareTo', 'getDescription', 'getVulnerabilityCount'];
|
|
66
|
+
if (skipMethods.includes(method.name))
|
|
67
|
+
continue;
|
|
68
|
+
for (const param of method.parameters) {
|
|
69
|
+
// Check if parameter type could carry tainted data
|
|
70
|
+
if (param.type && isInterproceduralTaintableType(param.type)) {
|
|
71
|
+
// Use parameter line if available, fallback to method start line
|
|
72
|
+
const paramLine = param.line ?? method.start_line;
|
|
73
|
+
sources.push({
|
|
74
|
+
type: 'interprocedural_param',
|
|
75
|
+
location: `${param.type} ${param.name} in ${method.name}`,
|
|
76
|
+
severity: 'medium',
|
|
77
|
+
line: paramLine,
|
|
78
|
+
confidence: 0.7, // Lower confidence since we don't know the call site
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// JavaScript/Node.js: Detect Express request property access patterns as sources
|
|
85
|
+
// This handles patterns like db.query("SELECT * FROM users WHERE id = " + req.params.id)
|
|
86
|
+
// Get property-based source patterns
|
|
87
|
+
const propertyPatterns = patterns.filter(p => p.property && p.object && p.property_tainted);
|
|
88
|
+
for (const call of calls) {
|
|
89
|
+
for (const arg of call.arguments) {
|
|
90
|
+
if (arg.expression) {
|
|
91
|
+
const taintCheck = isJavaScriptTaintedArgument(arg.expression, propertyPatterns.length > 0 ? patterns : undefined);
|
|
92
|
+
if (taintCheck.isTainted && taintCheck.sourceType) {
|
|
93
|
+
// Check if we already have a source at this line
|
|
94
|
+
const alreadyExists = sources.some(s => s.line === call.location.line && s.type === taintCheck.sourceType);
|
|
95
|
+
if (!alreadyExists) {
|
|
96
|
+
sources.push({
|
|
97
|
+
type: taintCheck.sourceType,
|
|
98
|
+
location: `${arg.expression} in ${call.in_method || 'anonymous'}`,
|
|
99
|
+
severity: 'high',
|
|
100
|
+
line: call.location.line,
|
|
101
|
+
confidence: 1.0,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return sources;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if a parameter type could carry tainted data in inter-procedural analysis.
|
|
112
|
+
* These are types commonly used to pass user-controlled data between methods.
|
|
113
|
+
*/
|
|
114
|
+
function isInterproceduralTaintableType(typeName) {
|
|
115
|
+
// Normalize type name (remove generics)
|
|
116
|
+
const baseType = typeName.split('<')[0].trim();
|
|
117
|
+
// Types that are already handled by regular taint source patterns
|
|
118
|
+
// These have specific methods that are taint sources (getParameter, getCookies, etc.)
|
|
119
|
+
// and should NOT be treated as interprocedural sources
|
|
120
|
+
const excludedTypes = [
|
|
121
|
+
// Servlet framework - taint comes from specific methods, not the parameter itself
|
|
122
|
+
'HttpServletRequest', 'HttpServletResponse',
|
|
123
|
+
'ServletRequest', 'ServletResponse',
|
|
124
|
+
'HttpSession', 'ServletContext',
|
|
125
|
+
// Spring framework
|
|
126
|
+
'Model', 'ModelMap', 'ModelAndView',
|
|
127
|
+
'WebRequest', 'NativeWebRequest',
|
|
128
|
+
// Other framework types
|
|
129
|
+
'FilterChain', 'RequestDispatcher',
|
|
130
|
+
];
|
|
131
|
+
if (excludedTypes.includes(baseType)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
// Types that could carry tainted user data
|
|
135
|
+
const taintableTypes = [
|
|
136
|
+
// Most generic
|
|
137
|
+
'Object',
|
|
138
|
+
// Java Strings
|
|
139
|
+
'String', 'CharSequence', 'StringBuilder', 'StringBuffer',
|
|
140
|
+
// Java Collections
|
|
141
|
+
'Collection', 'List', 'Set', 'Map', 'Queue', 'Deque',
|
|
142
|
+
'ArrayList', 'LinkedList', 'HashSet', 'TreeSet', 'HashMap', 'TreeMap',
|
|
143
|
+
'LinkedHashMap', 'LinkedHashSet', 'Vector', 'Stack',
|
|
144
|
+
'ConcurrentHashMap', 'CopyOnWriteArrayList',
|
|
145
|
+
// Arrays (handled by suffix check below)
|
|
146
|
+
// Streams
|
|
147
|
+
'Stream', 'Optional',
|
|
148
|
+
// Iterators
|
|
149
|
+
'Iterator', 'Iterable',
|
|
150
|
+
// Rust types
|
|
151
|
+
'&str', 'str', '&String', '&mut str', '&mut String',
|
|
152
|
+
'Vec', '&Vec', '&[u8]', '&[String]',
|
|
153
|
+
'Option', 'Result',
|
|
154
|
+
];
|
|
155
|
+
if (taintableTypes.includes(baseType)) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
// Check for array types
|
|
159
|
+
if (typeName.endsWith('[]')) {
|
|
160
|
+
const elementType = typeName.slice(0, -2);
|
|
161
|
+
// String arrays, Object arrays, and byte arrays are commonly tainted
|
|
162
|
+
if (elementType === 'String' || elementType === 'Object' || elementType === 'byte') {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Find taint sinks in method calls.
|
|
170
|
+
*/
|
|
171
|
+
function findSinks(calls, patterns) {
|
|
172
|
+
const sinks = [];
|
|
173
|
+
for (const call of calls) {
|
|
174
|
+
for (const pattern of patterns) {
|
|
175
|
+
if (matchesSinkPattern(call, pattern)) {
|
|
176
|
+
sinks.push({
|
|
177
|
+
type: pattern.type,
|
|
178
|
+
cwe: pattern.cwe,
|
|
179
|
+
location: formatCallLocation(call),
|
|
180
|
+
line: call.location.line,
|
|
181
|
+
confidence: calculateSinkConfidence(call, pattern),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return sinks;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Check if a call matches a source pattern.
|
|
190
|
+
*/
|
|
191
|
+
function matchesSourcePattern(call, pattern) {
|
|
192
|
+
// Method-based matching
|
|
193
|
+
if (pattern.method) {
|
|
194
|
+
if (call.method_name !== pattern.method) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
// If class is specified, check receiver
|
|
198
|
+
if (pattern.class && pattern.class !== 'constructor') {
|
|
199
|
+
// The receiver might be a variable name, not the class name
|
|
200
|
+
// For now, we do a simple match - in a full implementation,
|
|
201
|
+
// we'd need type inference
|
|
202
|
+
if (call.receiver && !receiverMightBeClass(call.receiver, pattern.class)) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return pattern.return_tainted === true;
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Check if a call's arguments contain tainted Express/Node.js property access patterns.
|
|
212
|
+
* This handles patterns like req.params.id, req.query.name, req.body.data
|
|
213
|
+
* Also handles binary expressions like 'str' + req.params.id
|
|
214
|
+
*/
|
|
215
|
+
function isJavaScriptTaintedArgument(argExpression, sourcePatterns) {
|
|
216
|
+
// Build patterns from config if provided - both exact and contained matches
|
|
217
|
+
const exactPatterns = [];
|
|
218
|
+
const containedPatterns = [];
|
|
219
|
+
if (sourcePatterns) {
|
|
220
|
+
// Use config-based property patterns
|
|
221
|
+
for (const sp of sourcePatterns) {
|
|
222
|
+
if (sp.property && sp.object && sp.property_tainted) {
|
|
223
|
+
// Create regex for exact match (direct argument)
|
|
224
|
+
const exactRegex = new RegExp(`^${sp.object}\\.${sp.property}\\b`);
|
|
225
|
+
exactPatterns.push({ pattern: exactRegex, sourceType: sp.type });
|
|
226
|
+
// Create regex for contained match (binary expressions like 'str' + req.params.id)
|
|
227
|
+
const containedRegex = new RegExp(`\\b${sp.object}\\.${sp.property}\\b`);
|
|
228
|
+
containedPatterns.push({ pattern: containedRegex, sourceType: sp.type });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Fallback hardcoded patterns (for backwards compatibility)
|
|
233
|
+
if (exactPatterns.length === 0) {
|
|
234
|
+
const basePatterns = [
|
|
235
|
+
{ base: 'req\\.params', sourceType: 'http_param' },
|
|
236
|
+
{ base: 'req\\.query', sourceType: 'http_param' },
|
|
237
|
+
{ base: 'req\\.body', sourceType: 'http_body' },
|
|
238
|
+
{ base: 'req\\.headers', sourceType: 'http_header' },
|
|
239
|
+
{ base: 'req\\.cookies', sourceType: 'http_cookie' },
|
|
240
|
+
{ base: 'req\\.url', sourceType: 'http_path' },
|
|
241
|
+
{ base: 'req\\.path', sourceType: 'http_path' },
|
|
242
|
+
{ base: 'req\\.originalUrl', sourceType: 'http_path' },
|
|
243
|
+
{ base: 'req\\.file', sourceType: 'file_input' },
|
|
244
|
+
{ base: 'req\\.files', sourceType: 'file_input' },
|
|
245
|
+
{ base: 'request\\.params', sourceType: 'http_param' },
|
|
246
|
+
{ base: 'request\\.query', sourceType: 'http_param' },
|
|
247
|
+
{ base: 'request\\.body', sourceType: 'http_body' },
|
|
248
|
+
{ base: 'request\\.headers', sourceType: 'http_header' },
|
|
249
|
+
{ base: 'process\\.env', sourceType: 'env_input' },
|
|
250
|
+
{ base: 'process\\.argv', sourceType: 'io_input' },
|
|
251
|
+
{ base: 'ctx\\.query', sourceType: 'http_param' },
|
|
252
|
+
{ base: 'ctx\\.params', sourceType: 'http_param' },
|
|
253
|
+
{ base: 'ctx\\.request', sourceType: 'http_body' },
|
|
254
|
+
];
|
|
255
|
+
for (const { base, sourceType } of basePatterns) {
|
|
256
|
+
exactPatterns.push({ pattern: new RegExp(`^${base}\\b`), sourceType });
|
|
257
|
+
containedPatterns.push({ pattern: new RegExp(`\\b${base}\\b`), sourceType });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// First check exact patterns (direct argument like req.params.id)
|
|
261
|
+
for (const { pattern, sourceType } of exactPatterns) {
|
|
262
|
+
if (pattern.test(argExpression)) {
|
|
263
|
+
return { isTainted: true, sourceType };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Then check contained patterns (binary expressions like 'str' + req.params.id)
|
|
267
|
+
for (const { pattern, sourceType } of containedPatterns) {
|
|
268
|
+
if (pattern.test(argExpression)) {
|
|
269
|
+
return { isTainted: true, sourceType };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return { isTainted: false, sourceType: null };
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Check if a call matches a sink pattern.
|
|
276
|
+
*/
|
|
277
|
+
function matchesSinkPattern(call, pattern) {
|
|
278
|
+
// Method name must match
|
|
279
|
+
// Handle fully qualified names (e.g., "java.io.FileInputStream" should match "FileInputStream")
|
|
280
|
+
const callMethodName = call.method_name;
|
|
281
|
+
const patternMethod = pattern.method;
|
|
282
|
+
// Direct match
|
|
283
|
+
let methodMatches = callMethodName === patternMethod;
|
|
284
|
+
// If not direct match, check if fully qualified name ends with pattern
|
|
285
|
+
if (!methodMatches && callMethodName.includes('.')) {
|
|
286
|
+
const simpleName = callMethodName.substring(callMethodName.lastIndexOf('.') + 1);
|
|
287
|
+
methodMatches = simpleName === patternMethod;
|
|
288
|
+
}
|
|
289
|
+
if (!methodMatches) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
// Check class if specified
|
|
293
|
+
if (pattern.class) {
|
|
294
|
+
if (pattern.class === 'constructor') {
|
|
295
|
+
// Constructor call - method name is the class name
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
// Check receiver - if pattern has class, receiver should match
|
|
299
|
+
if (call.receiver && !receiverMightBeClass(call.receiver, pattern.class)) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
// If no receiver but class is required, don't match
|
|
303
|
+
if (!call.receiver) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// If no class specified, match any receiver (or no receiver)
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Check if an annotation list contains a specific annotation.
|
|
312
|
+
*/
|
|
313
|
+
function matchesAnnotation(annotations, targetAnnotation) {
|
|
314
|
+
for (const ann of annotations) {
|
|
315
|
+
// Handle both "RequestParam" and "RequestParam(value=...)" formats
|
|
316
|
+
const annName = ann.split('(')[0].trim();
|
|
317
|
+
if (annName === targetAnnotation) {
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Check if a receiver variable might be an instance of a class.
|
|
325
|
+
* This is a heuristic - full type inference would be more accurate.
|
|
326
|
+
*/
|
|
327
|
+
function receiverMightBeClass(receiver, className) {
|
|
328
|
+
// Direct match
|
|
329
|
+
if (receiver === className) {
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
// Handle fully qualified paths like "org.owasp.benchmark.helpers.DatabaseHelper.JDBCtemplate"
|
|
333
|
+
// Check if the receiver ends with the class name (case insensitive)
|
|
334
|
+
const lowerReceiver = receiver.toLowerCase();
|
|
335
|
+
const lowerClass = className.toLowerCase();
|
|
336
|
+
if (lowerReceiver.endsWith(lowerClass) || lowerReceiver.endsWith('.' + lowerClass)) {
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
// Extract last part of dotted path (without method calls)
|
|
340
|
+
if (receiver.includes('.') && !receiver.endsWith(')')) {
|
|
341
|
+
const lastPart = receiver.substring(receiver.lastIndexOf('.') + 1);
|
|
342
|
+
if (lastPart.toLowerCase() === lowerClass) {
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
// Also check common naming patterns in the last part
|
|
346
|
+
if (lastPart.toLowerCase().includes(lowerClass)) {
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Handle chained calls like "response.getWriter()" - extract last method call
|
|
351
|
+
// and check if it returns the expected type
|
|
352
|
+
if (receiver.includes('.') && receiver.endsWith(')')) {
|
|
353
|
+
const methodCallMatch = receiver.match(/\.(\w+)\(\)$/);
|
|
354
|
+
if (methodCallMatch) {
|
|
355
|
+
const methodName = methodCallMatch[1];
|
|
356
|
+
const returnTypeMappings = {
|
|
357
|
+
'getWriter': ['PrintWriter'],
|
|
358
|
+
'getOutputStream': ['OutputStream', 'ServletOutputStream'],
|
|
359
|
+
'getReader': ['BufferedReader'],
|
|
360
|
+
'getInputStream': ['InputStream', 'ServletInputStream'],
|
|
361
|
+
'getConnection': ['Connection'],
|
|
362
|
+
'createStatement': ['Statement'],
|
|
363
|
+
'prepareStatement': ['PreparedStatement'],
|
|
364
|
+
'getRuntime': ['Runtime'],
|
|
365
|
+
};
|
|
366
|
+
const expectedTypes = returnTypeMappings[methodName];
|
|
367
|
+
if (Array.isArray(expectedTypes) && expectedTypes.includes(className)) {
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// e.g., "request" might be HttpServletRequest
|
|
373
|
+
if (lowerClass.includes(lowerReceiver)) {
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
// e.g., "stmt" might be Statement
|
|
377
|
+
if (lowerClass.startsWith(lowerReceiver.substring(0, 3))) {
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
// Common abbreviations
|
|
381
|
+
const commonMappings = {
|
|
382
|
+
// HTTP/Servlet
|
|
383
|
+
request: ['HttpServletRequest', 'ServletRequest'],
|
|
384
|
+
response: ['HttpServletResponse', 'ServletResponse'],
|
|
385
|
+
session: ['HttpSession'],
|
|
386
|
+
// Database
|
|
387
|
+
stmt: ['Statement', 'PreparedStatement'],
|
|
388
|
+
conn: ['Connection'],
|
|
389
|
+
em: ['EntityManager'],
|
|
390
|
+
ps: ['PreparedStatement'],
|
|
391
|
+
rs: ['ResultSet'],
|
|
392
|
+
template: ['JdbcTemplate'],
|
|
393
|
+
// I/O
|
|
394
|
+
writer: ['PrintWriter'],
|
|
395
|
+
out: ['PrintWriter', 'OutputStream'],
|
|
396
|
+
reader: ['BufferedReader'],
|
|
397
|
+
// Process/Runtime
|
|
398
|
+
runtime: ['Runtime'],
|
|
399
|
+
pb: ['ProcessBuilder'],
|
|
400
|
+
// Scripting
|
|
401
|
+
engine: ['ScriptEngine'],
|
|
402
|
+
// LDAP
|
|
403
|
+
ctx: ['Context', 'InitialContext', 'DirContext', 'InitialDirContext', 'LdapContext'],
|
|
404
|
+
context: ['Context', 'InitialContext', 'DirContext', 'InitialDirContext', 'LdapContext'],
|
|
405
|
+
dirCtx: ['DirContext', 'InitialDirContext'],
|
|
406
|
+
ldapCtx: ['LdapContext'],
|
|
407
|
+
idc: ['InitialDirContext'],
|
|
408
|
+
ic: ['InitialContext'],
|
|
409
|
+
dc: ['DirContext'],
|
|
410
|
+
lc: ['LdapContext'],
|
|
411
|
+
// XML/XPath
|
|
412
|
+
xpath: ['XPath'],
|
|
413
|
+
xp: ['XPath'],
|
|
414
|
+
doc: ['Document', 'DocumentBuilder'],
|
|
415
|
+
document: ['Document'],
|
|
416
|
+
builder: ['DocumentBuilder', 'SAXParserFactory'],
|
|
417
|
+
parser: ['SAXParser', 'XMLReader', 'DocumentBuilder'],
|
|
418
|
+
saxParser: ['SAXParser'],
|
|
419
|
+
xmlReader: ['XMLReader'],
|
|
420
|
+
transformer: ['Transformer', 'TransformerFactory'],
|
|
421
|
+
tf: ['TransformerFactory'],
|
|
422
|
+
unmarshaller: ['Unmarshaller'],
|
|
423
|
+
jaxb: ['Unmarshaller'],
|
|
424
|
+
// HTTP Clients (SSRF)
|
|
425
|
+
url: ['URL'],
|
|
426
|
+
uri: ['URI'],
|
|
427
|
+
client: ['HttpClient', 'WebClient'],
|
|
428
|
+
httpClient: ['HttpClient'],
|
|
429
|
+
webClient: ['WebClient'],
|
|
430
|
+
restTemplate: ['RestTemplate'],
|
|
431
|
+
rest: ['RestTemplate'],
|
|
432
|
+
// Deserialization
|
|
433
|
+
ois: ['ObjectInputStream'],
|
|
434
|
+
objectInput: ['ObjectInputStream'],
|
|
435
|
+
xstream: ['XStream'],
|
|
436
|
+
mapper: ['ObjectMapper'],
|
|
437
|
+
objectMapper: ['ObjectMapper'],
|
|
438
|
+
// Files
|
|
439
|
+
files: ['Files'],
|
|
440
|
+
// Mail/MIME parts (JavaMail)
|
|
441
|
+
part: ['Part', 'MimePart', 'BodyPart', 'MimeBodyPart'],
|
|
442
|
+
bodyPart: ['BodyPart', 'MimeBodyPart'],
|
|
443
|
+
mimePart: ['MimePart', 'MimeBodyPart'],
|
|
444
|
+
mimeBodyPart: ['MimeBodyPart'],
|
|
445
|
+
message: ['Message', 'MimeMessage'],
|
|
446
|
+
mimeMessage: ['MimeMessage'],
|
|
447
|
+
multipart: ['Multipart', 'MimeMultipart'],
|
|
448
|
+
mp: ['Multipart', 'MimeMultipart'],
|
|
449
|
+
// Zip/Archive
|
|
450
|
+
zipEntry: ['ZipEntry'],
|
|
451
|
+
entry: ['ZipEntry', 'TarArchiveEntry', 'JarEntry'],
|
|
452
|
+
jarEntry: ['JarEntry'],
|
|
453
|
+
// String builders/buffers (XSS via HTML construction)
|
|
454
|
+
sb: ['StringBuilder', 'StringBuffer'],
|
|
455
|
+
buffer: ['StringBuilder', 'StringBuffer'],
|
|
456
|
+
result: ['StringBuilder', 'StringBuffer'],
|
|
457
|
+
html: ['StringBuilder', 'StringBuffer'],
|
|
458
|
+
output: ['StringBuilder', 'StringBuffer'],
|
|
459
|
+
buf: ['StringBuilder', 'StringBuffer'],
|
|
460
|
+
m_result: ['StringBuilder', 'StringBuffer'],
|
|
461
|
+
stringBuffer: ['StringBuffer'],
|
|
462
|
+
stringBuilder: ['StringBuilder'],
|
|
463
|
+
// Maps/Collections (plugin parameters, config values)
|
|
464
|
+
params: ['Map', 'HashMap', 'LinkedHashMap', 'TreeMap'],
|
|
465
|
+
parameters: ['Map', 'HashMap'],
|
|
466
|
+
args: ['Map', 'HashMap'],
|
|
467
|
+
options: ['Map', 'HashMap'],
|
|
468
|
+
config: ['Map', 'HashMap', 'Properties'],
|
|
469
|
+
props: ['Properties', 'Map'],
|
|
470
|
+
map: ['Map', 'HashMap', 'LinkedHashMap', 'TreeMap'],
|
|
471
|
+
m_params: ['Map', 'HashMap'],
|
|
472
|
+
// JavaScript/Node.js/Express mappings
|
|
473
|
+
req: ['Request', 'HttpServletRequest'],
|
|
474
|
+
res: ['Response', 'HttpServletResponse'],
|
|
475
|
+
app: ['Express', 'Application'],
|
|
476
|
+
router: ['Router'],
|
|
477
|
+
fs: ['fs'],
|
|
478
|
+
path: ['path'],
|
|
479
|
+
http: ['http'],
|
|
480
|
+
https: ['https'],
|
|
481
|
+
child_process: ['child_process'],
|
|
482
|
+
crypto: ['crypto'],
|
|
483
|
+
exec: ['child_process'],
|
|
484
|
+
spawn: ['child_process'],
|
|
485
|
+
db: ['Connection', 'Pool', 'mysql'],
|
|
486
|
+
pool: ['Pool', 'Connection'],
|
|
487
|
+
mysql: ['mysql'],
|
|
488
|
+
knex: ['knex'],
|
|
489
|
+
prisma: ['prisma'],
|
|
490
|
+
axios: ['axios'],
|
|
491
|
+
fetch: ['fetch'],
|
|
492
|
+
};
|
|
493
|
+
const mappings = commonMappings[lowerReceiver];
|
|
494
|
+
if (mappings && Array.isArray(mappings) && mappings.includes(className)) {
|
|
495
|
+
return true;
|
|
496
|
+
}
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Format call location for human-readable output.
|
|
501
|
+
*/
|
|
502
|
+
function formatCallLocation(call) {
|
|
503
|
+
const parts = [];
|
|
504
|
+
if (call.receiver) {
|
|
505
|
+
parts.push(`${call.receiver}.${call.method_name}()`);
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
parts.push(`${call.method_name}()`);
|
|
509
|
+
}
|
|
510
|
+
if (call.in_method) {
|
|
511
|
+
parts.push(`in ${call.in_method}`);
|
|
512
|
+
}
|
|
513
|
+
return parts.join(' ');
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Calculate confidence score for a sink match.
|
|
517
|
+
*/
|
|
518
|
+
function calculateSinkConfidence(call, pattern) {
|
|
519
|
+
let confidence = 0.8; // Base confidence
|
|
520
|
+
// Higher confidence if we have a receiver that matches
|
|
521
|
+
if (pattern.class && call.receiver) {
|
|
522
|
+
if (receiverMightBeClass(call.receiver, pattern.class)) {
|
|
523
|
+
confidence += 0.1;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
// Higher confidence for critical severity patterns
|
|
527
|
+
if (pattern.severity === 'critical') {
|
|
528
|
+
confidence += 0.1;
|
|
529
|
+
}
|
|
530
|
+
return Math.min(confidence, 1.0);
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Check if a variable at a given position flows to a dangerous sink argument.
|
|
534
|
+
*/
|
|
535
|
+
export function isInDangerousPosition(argPosition, pattern) {
|
|
536
|
+
return pattern.arg_positions.includes(argPosition);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Find sanitizers in method calls and annotated parameters.
|
|
540
|
+
*/
|
|
541
|
+
function findSanitizers(calls, types, patterns) {
|
|
542
|
+
const sanitizers = [];
|
|
543
|
+
// Build a set of method names with @sanitizer annotation (from Javadoc comments)
|
|
544
|
+
const sanitizerMethods = new Set();
|
|
545
|
+
for (const type of types) {
|
|
546
|
+
for (const method of type.methods) {
|
|
547
|
+
if (method.annotations.includes('sanitizer')) {
|
|
548
|
+
sanitizerMethods.add(method.name);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
// Check method calls for sanitizer methods
|
|
553
|
+
for (const call of calls) {
|
|
554
|
+
// Check if this call is to a method with @sanitizer annotation
|
|
555
|
+
if (sanitizerMethods.has(call.method_name)) {
|
|
556
|
+
sanitizers.push({
|
|
557
|
+
type: 'javadoc_sanitizer',
|
|
558
|
+
method: formatSanitizerMethod(call),
|
|
559
|
+
line: call.location.line,
|
|
560
|
+
sanitizes: ['xss', 'sql_injection', 'path_traversal', 'command_injection', 'ssrf'], // Generic sanitizer removes all
|
|
561
|
+
});
|
|
562
|
+
continue; // Skip pattern matching - already added as sanitizer
|
|
563
|
+
}
|
|
564
|
+
for (const pattern of patterns) {
|
|
565
|
+
if (matchesSanitizerPattern(call, pattern)) {
|
|
566
|
+
sanitizers.push({
|
|
567
|
+
type: determineSanitizerType(pattern),
|
|
568
|
+
method: formatSanitizerMethod(call),
|
|
569
|
+
line: call.location.line,
|
|
570
|
+
sanitizes: pattern.removes,
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// Check annotated parameters for sanitizer annotations
|
|
576
|
+
for (const type of types) {
|
|
577
|
+
for (const method of type.methods) {
|
|
578
|
+
for (const param of method.parameters) {
|
|
579
|
+
for (const pattern of patterns) {
|
|
580
|
+
if (pattern.annotation && matchesAnnotation(param.annotations, pattern.annotation)) {
|
|
581
|
+
sanitizers.push({
|
|
582
|
+
type: 'annotation',
|
|
583
|
+
method: `@${pattern.annotation} ${param.name} in ${method.name}`,
|
|
584
|
+
line: method.start_line,
|
|
585
|
+
sanitizes: pattern.removes,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
return sanitizers;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Check if a call matches a sanitizer pattern.
|
|
596
|
+
*/
|
|
597
|
+
function matchesSanitizerPattern(call, pattern) {
|
|
598
|
+
// Method-based matching
|
|
599
|
+
if (pattern.method) {
|
|
600
|
+
if (call.method_name !== pattern.method) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
// If class is specified, check receiver
|
|
604
|
+
if (pattern.class) {
|
|
605
|
+
if (!call.receiver || !receiverMightBeClass(call.receiver, pattern.class)) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return true;
|
|
610
|
+
}
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Determine the type of sanitizer based on pattern.
|
|
615
|
+
*/
|
|
616
|
+
function determineSanitizerType(pattern) {
|
|
617
|
+
if (pattern.annotation) {
|
|
618
|
+
return 'annotation';
|
|
619
|
+
}
|
|
620
|
+
if (pattern.method) {
|
|
621
|
+
return 'method_call';
|
|
622
|
+
}
|
|
623
|
+
return 'unknown';
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Format sanitizer method for human-readable output.
|
|
627
|
+
*/
|
|
628
|
+
function formatSanitizerMethod(call) {
|
|
629
|
+
if (call.receiver) {
|
|
630
|
+
return `${call.receiver}.${call.method_name}()`;
|
|
631
|
+
}
|
|
632
|
+
return `${call.method_name}()`;
|
|
633
|
+
}
|
|
634
|
+
//# sourceMappingURL=taint-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taint-matcher.js","sourceRoot":"","sources":["../../src/analysis/taint-matcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAiB,EACjB,KAAiB,EACjB,SAAsB,gBAAgB,EAAE;IAExC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAEnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,KAAiB,EACjB,KAAiB,EACjB,QAAyB;IAEzB,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,qBAAqB;IACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,QAAQ,EAAE,kBAAkB,CAAC,IAAI,CAAC;oBAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;oBACxB,UAAU,EAAE,GAAG;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;wBAChD,IAAI,iBAAiB,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;4BAC7D,iEAAiE;4BACjE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC;4BAClD,OAAO,CAAC,IAAI,CAAC;gCACX,IAAI,EAAE,OAAO,CAAC,IAAI;gCAClB,QAAQ,EAAE,IAAI,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,EAAE;gCAClE,QAAQ,EAAE,OAAO,CAAC,QAAQ;gCAC1B,IAAI,EAAE,SAAS;gCACf,UAAU,EAAE,GAAG;6BAChB,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,wEAAwE;IACxE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,kEAAkE;YAClE,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,SAAS;YAEnD,kEAAkE;YAClE,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,uBAAuB,CAAC,CAAC;YAC/G,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEhD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtC,mDAAmD;gBACnD,IAAI,KAAK,CAAC,IAAI,IAAI,8BAA8B,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7D,iEAAiE;oBACjE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC;oBAClD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,uBAAuB;wBAC7B,QAAQ,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,EAAE;wBACzD,QAAQ,EAAE,QAAQ;wBAClB,IAAI,EAAE,SAAS;wBACf,UAAU,EAAE,GAAG,EAAE,qDAAqD;qBACvE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,yFAAyF;IACzF,qCAAqC;IACrC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAE5F,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gBACnB,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,UAAU,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBACnH,IAAI,UAAU,CAAC,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;oBAClD,iDAAiD;oBACjD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC;oBAC3G,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,OAAO,CAAC,IAAI,CAAC;4BACX,IAAI,EAAE,UAAU,CAAC,UAAU;4BAC3B,QAAQ,EAAE,GAAG,GAAG,CAAC,UAAU,OAAO,IAAI,CAAC,SAAS,IAAI,WAAW,EAAE;4BACjE,QAAQ,EAAE,MAAM;4BAChB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;4BACxB,UAAU,EAAE,GAAG;yBAChB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,SAAS,8BAA8B,CAAC,QAAgB;IACtD,wCAAwC;IACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE/C,kEAAkE;IAClE,sFAAsF;IACtF,uDAAuD;IACvD,MAAM,aAAa,GAAG;QACpB,kFAAkF;QAClF,oBAAoB,EAAE,qBAAqB;QAC3C,gBAAgB,EAAE,iBAAiB;QACnC,aAAa,EAAE,gBAAgB;QAC/B,mBAAmB;QACnB,OAAO,EAAE,UAAU,EAAE,cAAc;QACnC,YAAY,EAAE,kBAAkB;QAChC,wBAAwB;QACxB,aAAa,EAAE,mBAAmB;KACnC,CAAC;IAEF,IAAI,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2CAA2C;IAC3C,MAAM,cAAc,GAAG;QACrB,eAAe;QACf,QAAQ;QACR,eAAe;QACf,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc;QACzD,mBAAmB;QACnB,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO;QACpD,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS;QACrE,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO;QACnD,mBAAmB,EAAE,sBAAsB;QAC3C,yCAAyC;QACzC,UAAU;QACV,QAAQ,EAAE,UAAU;QACpB,YAAY;QACZ,UAAU,EAAE,UAAU;QACtB,aAAa;QACb,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa;QACnD,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW;QACnC,QAAQ,EAAE,QAAQ;KACnB,CAAC;IAEF,IAAI,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB;IACxB,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,qEAAqE;QACrE,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YACnF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAiB,EAAE,QAAuB;IAC3D,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;gBACtC,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,GAAG,EAAE,OAAO,CAAC,GAAG;oBAChB,QAAQ,EAAE,kBAAkB,CAAC,IAAI,CAAC;oBAClC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;oBACxB,UAAU,EAAE,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC;iBACnD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAc,EAAE,OAAsB;IAClE,wBAAwB;IACxB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wCAAwC;QACxC,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;YACrD,4DAA4D;YAC5D,4DAA4D;YAC5D,2BAA2B;YAC3B,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzE,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,cAAc,KAAK,IAAI,CAAC;IACzC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,2BAA2B,CAClC,aAAqB,EACrB,cAAgC;IAEhC,4EAA4E;IAC5E,MAAM,aAAa,GAAuD,EAAE,CAAC;IAC7E,MAAM,iBAAiB,GAAuD,EAAE,CAAC;IAEjF,IAAI,cAAc,EAAE,CAAC;QACnB,qCAAqC;QACrC,KAAK,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC;YAChC,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,gBAAgB,EAAE,CAAC;gBACpD,iDAAiD;gBACjD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC;gBACnE,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjE,mFAAmF;gBACnF,MAAM,cAAc,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC;gBACzE,iBAAiB,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG;YACnB,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,YAA0B,EAAE;YAChE,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,YAA0B,EAAE;YAC/D,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,WAAyB,EAAE;YAC7D,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,aAA2B,EAAE;YAClE,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,aAA2B,EAAE;YAClE,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAyB,EAAE;YAC5D,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,WAAyB,EAAE;YAC7D,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,WAAyB,EAAE;YACpE,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,YAA0B,EAAE;YAC9D,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,YAA0B,EAAE;YAC/D,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,YAA0B,EAAE;YACpE,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAA0B,EAAE;YACnE,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAyB,EAAE;YACjE,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,aAA2B,EAAE;YACtE,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,WAAyB,EAAE;YAChE,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAwB,EAAE;YAChE,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,YAA0B,EAAE;YAC/D,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,YAA0B,EAAE;YAChE,EAAE,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,WAAyB,EAAE;SACjE,CAAC;QAEF,KAAK,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,YAAY,EAAE,CAAC;YAChD,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YACvE,iBAAiB,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,KAAK,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,aAAa,EAAE,CAAC;QACpD,IAAI,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IAED,gFAAgF;IAChF,KAAK,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,iBAAiB,EAAE,CAAC;QACxD,IAAI,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,IAAc,EAAE,OAAoB;IAC9D,yBAAyB;IACzB,gGAAgG;IAChG,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC;IACxC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAErC,eAAe;IACf,IAAI,aAAa,GAAG,cAAc,KAAK,aAAa,CAAC;IAErD,uEAAuE;IACvE,IAAI,CAAC,aAAa,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjF,aAAa,GAAG,UAAU,KAAK,aAAa,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2BAA2B;IAC3B,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;YACpC,mDAAmD;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,+DAA+D;QAC/D,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,oDAAoD;QACpD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,WAAqB,EAAE,gBAAwB;IACxE,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,mEAAmE;QACnE,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,OAAO,KAAK,gBAAgB,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,QAAgB,EAAE,SAAiB;IAC/D,eAAe;IACf,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8FAA8F;IAC9F,oEAAoE;IACpE,MAAM,aAAa,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0DAA0D;IAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,UAAU,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,qDAAqD;QACrD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,4CAA4C;IAC5C,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACvD,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,kBAAkB,GAA6B;gBACnD,WAAW,EAAE,CAAC,aAAa,CAAC;gBAC5B,iBAAiB,EAAE,CAAC,cAAc,EAAE,qBAAqB,CAAC;gBAC1D,WAAW,EAAE,CAAC,gBAAgB,CAAC;gBAC/B,gBAAgB,EAAE,CAAC,aAAa,EAAE,oBAAoB,CAAC;gBACvD,eAAe,EAAE,CAAC,YAAY,CAAC;gBAC/B,iBAAiB,EAAE,CAAC,WAAW,CAAC;gBAChC,kBAAkB,EAAE,CAAC,mBAAmB,CAAC;gBACzC,YAAY,EAAE,CAAC,SAAS,CAAC;aAC1B,CAAC;YACF,MAAM,aAAa,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtE,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kCAAkC;IAClC,IAAI,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uBAAuB;IACvB,MAAM,cAAc,GAA6B;QAC/C,eAAe;QACf,OAAO,EAAE,CAAC,oBAAoB,EAAE,gBAAgB,CAAC;QACjD,QAAQ,EAAE,CAAC,qBAAqB,EAAE,iBAAiB,CAAC;QACpD,OAAO,EAAE,CAAC,aAAa,CAAC;QAExB,WAAW;QACX,IAAI,EAAE,CAAC,WAAW,EAAE,mBAAmB,CAAC;QACxC,IAAI,EAAE,CAAC,YAAY,CAAC;QACpB,EAAE,EAAE,CAAC,eAAe,CAAC;QACrB,EAAE,EAAE,CAAC,mBAAmB,CAAC;QACzB,EAAE,EAAE,CAAC,WAAW,CAAC;QACjB,QAAQ,EAAE,CAAC,cAAc,CAAC;QAE1B,MAAM;QACN,MAAM,EAAE,CAAC,aAAa,CAAC;QACvB,GAAG,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC;QACpC,MAAM,EAAE,CAAC,gBAAgB,CAAC;QAE1B,kBAAkB;QAClB,OAAO,EAAE,CAAC,SAAS,CAAC;QACpB,EAAE,EAAE,CAAC,gBAAgB,CAAC;QAEtB,YAAY;QACZ,MAAM,EAAE,CAAC,cAAc,CAAC;QAExB,OAAO;QACP,GAAG,EAAE,CAAC,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,CAAC;QACpF,OAAO,EAAE,CAAC,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,CAAC;QACxF,MAAM,EAAE,CAAC,YAAY,EAAE,mBAAmB,CAAC;QAC3C,OAAO,EAAE,CAAC,aAAa,CAAC;QACxB,GAAG,EAAE,CAAC,mBAAmB,CAAC;QAC1B,EAAE,EAAE,CAAC,gBAAgB,CAAC;QACtB,EAAE,EAAE,CAAC,YAAY,CAAC;QAClB,EAAE,EAAE,CAAC,aAAa,CAAC;QAEnB,YAAY;QACZ,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,EAAE,EAAE,CAAC,OAAO,CAAC;QACb,GAAG,EAAE,CAAC,UAAU,EAAE,iBAAiB,CAAC;QACpC,QAAQ,EAAE,CAAC,UAAU,CAAC;QACtB,OAAO,EAAE,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;QAChD,MAAM,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,iBAAiB,CAAC;QACrD,SAAS,EAAE,CAAC,WAAW,CAAC;QACxB,SAAS,EAAE,CAAC,WAAW,CAAC;QACxB,WAAW,EAAE,CAAC,aAAa,EAAE,oBAAoB,CAAC;QAClD,EAAE,EAAE,CAAC,oBAAoB,CAAC;QAC1B,YAAY,EAAE,CAAC,cAAc,CAAC;QAC9B,IAAI,EAAE,CAAC,cAAc,CAAC;QAEtB,sBAAsB;QACtB,GAAG,EAAE,CAAC,KAAK,CAAC;QACZ,GAAG,EAAE,CAAC,KAAK,CAAC;QACZ,MAAM,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC;QACnC,UAAU,EAAE,CAAC,YAAY,CAAC;QAC1B,SAAS,EAAE,CAAC,WAAW,CAAC;QACxB,YAAY,EAAE,CAAC,cAAc,CAAC;QAC9B,IAAI,EAAE,CAAC,cAAc,CAAC;QAEtB,kBAAkB;QAClB,GAAG,EAAE,CAAC,mBAAmB,CAAC;QAC1B,WAAW,EAAE,CAAC,mBAAmB,CAAC;QAClC,OAAO,EAAE,CAAC,SAAS,CAAC;QACpB,MAAM,EAAE,CAAC,cAAc,CAAC;QACxB,YAAY,EAAE,CAAC,cAAc,CAAC;QAE9B,QAAQ;QACR,KAAK,EAAE,CAAC,OAAO,CAAC;QAEhB,6BAA6B;QAC7B,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,CAAC;QACtD,QAAQ,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;QACtC,QAAQ,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;QACtC,YAAY,EAAE,CAAC,cAAc,CAAC;QAC9B,OAAO,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC;QACnC,WAAW,EAAE,CAAC,aAAa,CAAC;QAC5B,SAAS,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC;QACzC,EAAE,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC;QAElC,cAAc;QACd,QAAQ,EAAE,CAAC,UAAU,CAAC;QACtB,KAAK,EAAE,CAAC,UAAU,EAAE,iBAAiB,EAAE,UAAU,CAAC;QAClD,QAAQ,EAAE,CAAC,UAAU,CAAC;QAEtB,sDAAsD;QACtD,EAAE,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QACrC,MAAM,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QACzC,MAAM,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QACzC,IAAI,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QACvC,MAAM,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QACzC,GAAG,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QACtC,QAAQ,EAAE,CAAC,eAAe,EAAE,cAAc,CAAC;QAC3C,YAAY,EAAE,CAAC,cAAc,CAAC;QAC9B,aAAa,EAAE,CAAC,eAAe,CAAC;QAEhC,sDAAsD;QACtD,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,CAAC;QACtD,UAAU,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;QAC9B,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;QACxB,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;QAC3B,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC;QACxC,KAAK,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC;QAC5B,GAAG,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,CAAC;QACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;QAE5B,sCAAsC;QACtC,GAAG,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC;QACtC,GAAG,EAAE,CAAC,UAAU,EAAE,qBAAqB,CAAC;QACxC,GAAG,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC;QAC/B,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,EAAE,EAAE,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,MAAM,CAAC;QACd,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,aAAa,EAAE,CAAC,eAAe,CAAC;QAChC,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,IAAI,EAAE,CAAC,eAAe,CAAC;QACvB,KAAK,EAAE,CAAC,eAAe,CAAC;QACxB,EAAE,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC;QACnC,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;QAC5B,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,IAAI,EAAE,CAAC,MAAM,CAAC;QACd,MAAM,EAAE,CAAC,QAAQ,CAAC;QAClB,KAAK,EAAE,CAAC,OAAO,CAAC;QAChB,KAAK,EAAE,CAAC,OAAO,CAAC;KACjB,CAAC;IAEF,MAAM,QAAQ,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IAC/C,IAAI,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,IAAc;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,IAAc,EAAE,OAAoB;IACnE,IAAI,UAAU,GAAG,GAAG,CAAC,CAAC,kBAAkB;IAExC,uDAAuD;IACvD,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnC,IAAI,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,UAAU,IAAI,GAAG,CAAC;QACpB,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,IAAI,OAAO,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACpC,UAAU,IAAI,GAAG,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,OAAoB;IAEpB,OAAO,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,KAAiB,EACjB,KAAiB,EACjB,QAA4B;IAE5B,MAAM,UAAU,GAAqB,EAAE,CAAC;IAExC,iFAAiF;IACjF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7C,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,+DAA+D;QAC/D,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,mBAAmB;gBACzB,MAAM,EAAE,qBAAqB,CAAC,IAAI,CAAC;gBACnC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;gBACxB,SAAS,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,gCAAgC;aACrH,CAAC,CAAC;YACH,SAAS,CAAC,qDAAqD;QACjE,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC3C,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,sBAAsB,CAAC,OAAO,CAAC;oBACrC,MAAM,EAAE,qBAAqB,CAAC,IAAI,CAAC;oBACnC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;oBACxB,SAAS,EAAE,OAAO,CAAC,OAAO;iBAC3B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,IAAI,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;wBACnF,UAAU,CAAC,IAAI,CAAC;4BACd,IAAI,EAAE,YAAY;4BAClB,MAAM,EAAE,IAAI,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,EAAE;4BAChE,IAAI,EAAE,MAAM,CAAC,UAAU;4BACvB,SAAS,EAAE,OAAO,CAAC,OAAO;yBAC3B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,IAAc,EAAE,OAAyB;IACxE,wBAAwB;IACxB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wCAAwC;QACxC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1E,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,OAAyB;IACvD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC;IAClD,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC;AACjC,CAAC"}
|