common-tg-service 1.2.27 → 1.2.29
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.
|
@@ -22,13 +22,14 @@ const ALLOWED_ORIGINS = [
|
|
|
22
22
|
const IGNORE_PATHS = [
|
|
23
23
|
'/',
|
|
24
24
|
'/favicon.ico',
|
|
25
|
+
'/userdata',
|
|
25
26
|
/^\/favicon\//i,
|
|
26
27
|
/^\/blockuserall\//i,
|
|
27
28
|
/^\/sendtoall\//i,
|
|
28
|
-
/^\/sendtochannel(
|
|
29
|
+
/^\/sendtochannel(?:$|\/)/i,
|
|
29
30
|
'/apim',
|
|
30
31
|
'/health',
|
|
31
|
-
/^\/public(
|
|
32
|
+
/^\/public(?:$|\/)/i,
|
|
32
33
|
];
|
|
33
34
|
let AuthGuard = AuthGuard_1 = class AuthGuard {
|
|
34
35
|
constructor() {
|
|
@@ -39,8 +40,7 @@ let AuthGuard = AuthGuard_1 = class AuthGuard {
|
|
|
39
40
|
const path = request.path;
|
|
40
41
|
const url = request.url;
|
|
41
42
|
const originalUrl = request.originalUrl;
|
|
42
|
-
const apiKey = request.headers['x-api-key']?.toString() ||
|
|
43
|
-
request.query['apiKey']?.toString();
|
|
43
|
+
const apiKey = request.headers['x-api-key']?.toString() || request.query['apiKey']?.toString();
|
|
44
44
|
const clientIp = this.extractRealClientIP(request);
|
|
45
45
|
const origin = this.extractRealOrigin(request);
|
|
46
46
|
if (this.isIgnoredPath(path, url, originalUrl)) {
|
|
@@ -48,150 +48,121 @@ let AuthGuard = AuthGuard_1 = class AuthGuard {
|
|
|
48
48
|
}
|
|
49
49
|
this.logger.debug(`Request Received: ${originalUrl}`);
|
|
50
50
|
let passedReason = null;
|
|
51
|
-
if (apiKey && apiKey.toLowerCase() ===
|
|
51
|
+
if (apiKey && apiKey.toLowerCase() === 'santoor') {
|
|
52
52
|
passedReason = 'API key valid';
|
|
53
53
|
}
|
|
54
|
-
else {
|
|
55
|
-
this.logger.debug(`❌ API Key mismatch`);
|
|
56
|
-
}
|
|
57
|
-
if (!passedReason && ALLOWED_IPS.includes(clientIp)) {
|
|
54
|
+
else if (ALLOWED_IPS.includes(clientIp)) {
|
|
58
55
|
passedReason = 'IP allowed';
|
|
59
56
|
}
|
|
60
|
-
else if (
|
|
61
|
-
this.logger.debug(`❌ IP not allowed`);
|
|
62
|
-
}
|
|
63
|
-
if (!passedReason && origin && this.isOriginAllowed(origin)) {
|
|
57
|
+
else if (origin && this.isOriginAllowed(origin)) {
|
|
64
58
|
passedReason = 'Origin allowed';
|
|
65
59
|
}
|
|
66
|
-
else if (!passedReason) {
|
|
67
|
-
this.logger.debug(`❌ Origin not allowed`);
|
|
68
|
-
}
|
|
69
60
|
if (passedReason) {
|
|
70
61
|
return true;
|
|
71
62
|
}
|
|
72
63
|
this.logger.warn(`❌ Access denied — no condition satisfied`);
|
|
73
|
-
|
|
64
|
+
this.notifyUnauthorized(clientIp, origin, originalUrl);
|
|
74
65
|
throw new common_1.UnauthorizedException('Access denied: No valid API key, IP, or Origin');
|
|
75
66
|
}
|
|
76
|
-
isIgnoredPath(
|
|
77
|
-
const
|
|
78
|
-
for (const urlToTest of urlsToTest) {
|
|
67
|
+
isIgnoredPath(...urls) {
|
|
68
|
+
for (const urlToTest of urls.filter(Boolean)) {
|
|
79
69
|
for (const ignore of IGNORE_PATHS) {
|
|
80
70
|
if (typeof ignore === 'string') {
|
|
81
71
|
if (ignore.toLowerCase() === urlToTest.toLowerCase()) {
|
|
82
72
|
return true;
|
|
83
73
|
}
|
|
84
74
|
}
|
|
85
|
-
else {
|
|
86
|
-
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
75
|
+
else if (ignore.test(urlToTest)) {
|
|
76
|
+
return true;
|
|
89
77
|
}
|
|
90
78
|
}
|
|
91
79
|
}
|
|
92
80
|
return false;
|
|
93
81
|
}
|
|
94
82
|
isOriginAllowed(origin) {
|
|
95
|
-
|
|
83
|
+
try {
|
|
84
|
+
const { protocol, host } = new URL(origin.toLowerCase().trim());
|
|
85
|
+
const normalized = `${protocol}//${host}`;
|
|
86
|
+
return ALLOWED_ORIGINS.includes(normalized);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
96
89
|
return false;
|
|
97
|
-
|
|
98
|
-
return ALLOWED_ORIGINS.includes(normalizedOrigin);
|
|
90
|
+
}
|
|
99
91
|
}
|
|
100
92
|
getHeaderValue(request, headerName) {
|
|
101
93
|
return request.headers[headerName.toLowerCase()];
|
|
102
94
|
}
|
|
103
95
|
extractRealClientIP(request) {
|
|
104
96
|
const cfConnectingIP = this.getHeaderValue(request, 'cf-connecting-ip');
|
|
105
|
-
if (cfConnectingIP)
|
|
97
|
+
if (cfConnectingIP)
|
|
106
98
|
return cfConnectingIP;
|
|
107
|
-
}
|
|
108
99
|
const xRealIP = this.getHeaderValue(request, 'x-real-ip');
|
|
109
|
-
if (xRealIP)
|
|
100
|
+
if (xRealIP)
|
|
110
101
|
return xRealIP;
|
|
111
|
-
}
|
|
112
102
|
const xForwardedFor = this.getHeaderValue(request, 'x-forwarded-for');
|
|
113
|
-
if (xForwardedFor)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return cleanIP;
|
|
121
|
-
}
|
|
122
|
-
const connectionIP = request.connection?.remoteAddress;
|
|
123
|
-
if (connectionIP) {
|
|
124
|
-
const cleanIP = connectionIP.replace('::ffff:', '');
|
|
125
|
-
return cleanIP;
|
|
126
|
-
}
|
|
127
|
-
this.logger.warn(`Unable to extract client IP, using fallback`);
|
|
103
|
+
if (xForwardedFor)
|
|
104
|
+
return xForwardedFor.split(',')[0].trim();
|
|
105
|
+
if (request.ip)
|
|
106
|
+
return request.ip.replace('::ffff:', '');
|
|
107
|
+
if (request.connection?.remoteAddress)
|
|
108
|
+
return request.connection.remoteAddress.replace('::ffff:', '');
|
|
109
|
+
this.logger.warn(`Unable to extract client IP`);
|
|
128
110
|
return 'unknown';
|
|
129
111
|
}
|
|
130
112
|
extractRealOrigin(request) {
|
|
131
113
|
const origin = this.getHeaderValue(request, 'origin');
|
|
132
|
-
if (origin)
|
|
114
|
+
if (origin)
|
|
133
115
|
return origin;
|
|
134
|
-
}
|
|
135
116
|
const xOriginalHost = this.getHeaderValue(request, 'x-original-host');
|
|
136
|
-
if (xOriginalHost)
|
|
137
|
-
|
|
138
|
-
const constructedOrigin = `${protocol}://${xOriginalHost}`;
|
|
139
|
-
return constructedOrigin;
|
|
140
|
-
}
|
|
117
|
+
if (xOriginalHost)
|
|
118
|
+
return `${this.extractProtocol(request)}://${xOriginalHost}`;
|
|
141
119
|
const xForwardedHost = this.getHeaderValue(request, 'x-forwarded-host');
|
|
142
|
-
if (xForwardedHost)
|
|
143
|
-
|
|
144
|
-
const constructedOrigin = `${protocol}://${xForwardedHost}`;
|
|
145
|
-
return constructedOrigin;
|
|
146
|
-
}
|
|
120
|
+
if (xForwardedHost)
|
|
121
|
+
return `${this.extractProtocol(request)}://${xForwardedHost}`;
|
|
147
122
|
const host = this.getHeaderValue(request, 'host');
|
|
148
|
-
if (host)
|
|
149
|
-
|
|
150
|
-
const constructedOrigin = `${protocol}://${host}`;
|
|
151
|
-
return constructedOrigin;
|
|
152
|
-
}
|
|
123
|
+
if (host)
|
|
124
|
+
return `${this.extractProtocol(request)}://${host}`;
|
|
153
125
|
const referer = this.getHeaderValue(request, 'referer');
|
|
154
126
|
if (referer) {
|
|
155
127
|
try {
|
|
156
128
|
const refererUrl = new URL(referer);
|
|
157
|
-
|
|
158
|
-
return refererOrigin;
|
|
129
|
+
return `${refererUrl.protocol}//${refererUrl.host}`;
|
|
159
130
|
}
|
|
160
|
-
catch
|
|
161
|
-
this.logger.debug(`
|
|
131
|
+
catch {
|
|
132
|
+
this.logger.debug(`Invalid referer: ${referer}`);
|
|
162
133
|
}
|
|
163
134
|
}
|
|
164
|
-
this.logger.debug(`Unable to extract origin from any header`);
|
|
165
135
|
return undefined;
|
|
166
136
|
}
|
|
167
137
|
extractProtocol(request) {
|
|
168
138
|
const xForwardedProto = this.getHeaderValue(request, 'x-forwarded-proto');
|
|
169
|
-
if (xForwardedProto)
|
|
139
|
+
if (xForwardedProto)
|
|
170
140
|
return xForwardedProto.toLowerCase();
|
|
171
|
-
}
|
|
172
141
|
const cfVisitor = this.getHeaderValue(request, 'cf-visitor');
|
|
173
142
|
if (cfVisitor) {
|
|
174
143
|
try {
|
|
175
144
|
const visitor = JSON.parse(cfVisitor);
|
|
176
|
-
if (visitor.scheme)
|
|
145
|
+
if (visitor.scheme)
|
|
177
146
|
return visitor.scheme.toLowerCase();
|
|
178
|
-
}
|
|
179
147
|
}
|
|
180
|
-
catch
|
|
181
|
-
this.logger.debug(`Failed to parse CF-Visitor
|
|
148
|
+
catch {
|
|
149
|
+
this.logger.debug(`Failed to parse CF-Visitor`);
|
|
182
150
|
}
|
|
183
151
|
}
|
|
184
|
-
if (request.secure)
|
|
152
|
+
if (request.secure)
|
|
185
153
|
return 'https';
|
|
186
|
-
}
|
|
187
154
|
const xForwardedSsl = this.getHeaderValue(request, 'x-forwarded-ssl');
|
|
188
|
-
if (xForwardedSsl
|
|
155
|
+
if (xForwardedSsl?.toLowerCase() === 'on')
|
|
189
156
|
return 'https';
|
|
157
|
+
return process.env.NODE_ENV === 'production' ? 'https' : 'http';
|
|
158
|
+
}
|
|
159
|
+
notifyUnauthorized(clientIp, origin, originalUrl) {
|
|
160
|
+
try {
|
|
161
|
+
(0, utils_1.fetchWithTimeout)(`${(0, logbots_1.notifbot)()}&text=${encodeURIComponent(`${process.env.clientId || process.env.serviceName} Failed :: Unauthorized access attempt from ${clientIp || 'unknown IP'} with origin ${origin || 'unknown origin'} for ${originalUrl}`)}`);
|
|
190
162
|
}
|
|
191
|
-
|
|
192
|
-
|
|
163
|
+
catch (err) {
|
|
164
|
+
this.logger.error(`Notifbot failed: ${err.message}`);
|
|
193
165
|
}
|
|
194
|
-
return 'http';
|
|
195
166
|
}
|
|
196
167
|
};
|
|
197
168
|
exports.AuthGuard = AuthGuard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../src/guards/auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA0G;AAE1G,oCAA4C;AAC5C,8CAA4C;AAE5C,MAAM,WAAW,GAAG,CAAC,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../src/guards/auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA0G;AAE1G,oCAA4C;AAC5C,8CAA4C;AAE5C,MAAM,WAAW,GAAG,CAAC,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC;AAExG,MAAM,eAAe,GAAG;IACpB,uBAAuB;IACvB,6BAA6B;IAC7B,6BAA6B;IAC7B,8BAA8B;IAC9B,gCAAgC;CACnC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AAEtC,MAAM,YAAY,GAAwB;IACtC,GAAG;IACH,cAAc;IACd,WAAW;IACX,eAAe;IACf,oBAAoB;IACpB,iBAAiB;IACjB,2BAA2B;IAC3B,OAAO;IACP,SAAS;IACT,oBAAoB;CACvB,CAAC;AAGK,IAAM,SAAS,iBAAf,MAAM,SAAS;IAAf;QACc,WAAM,GAAG,IAAI,eAAM,CAAC,WAAS,CAAC,IAAI,CAAC,CAAC;IAgJzD,CAAC;IA9IG,WAAW,CAAC,OAAyB;QACjC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAE7D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACxB,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAExC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;QAC/F,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;QAItD,IAAI,YAAY,GAAkB,IAAI,CAAC;QAGvC,IAAI,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,SAAS,EAAE,CAAC;YAC/C,YAAY,GAAG,eAAe,CAAC;QACnC,CAAC;aAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,YAAY,GAAG,YAAY,CAAC;QAChC,CAAC;aAAM,IAAI,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,YAAY,GAAG,gBAAgB,CAAC;QACpC,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YAEf,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QAC7D,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACvD,MAAM,IAAI,8BAAqB,CAAC,gDAAgD,CAAC,CAAC;IACtF,CAAC;IAEO,aAAa,CAAC,GAAG,IAAc;QACnC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3C,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;gBAChC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;wBACnD,OAAO,IAAI,CAAC;oBAChB,CAAC;gBACL,CAAC;qBAAM,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;oBAChC,OAAO,IAAI,CAAC;gBAChB,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,eAAe,CAAC,MAAc;QAClC,IAAI,CAAC;YACD,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,UAAU,GAAG,GAAG,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,OAAgB,EAAE,UAAkB;QACvD,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAW,CAAC;IAC/D,CAAC;IAEO,mBAAmB,CAAC,OAAgB;QACxC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACxE,IAAI,cAAc;YAAE,OAAO,cAAc,CAAC;QAE1C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC1D,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC;QAE5B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QACtE,IAAI,aAAa;YAAE,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE7D,IAAI,OAAO,CAAC,EAAE;YAAE,OAAO,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,UAAU,EAAE,aAAa;YAAE,OAAO,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEtG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAChD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,iBAAiB,CAAC,OAAgB;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QACtE,IAAI,aAAa;YAAE,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,aAAa,EAAE,CAAC;QAEhF,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;QACxE,IAAI,cAAc;YAAE,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,cAAc,EAAE,CAAC;QAElF,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAClD,IAAI,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QAE9D,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACxD,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC;gBACD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;gBACpC,OAAO,GAAG,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACL,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YACrD,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,eAAe,CAAC,OAAgB;QACpC,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;QAC1E,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC,WAAW,EAAE,CAAC;QAE1D,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC7D,IAAI,SAAS,EAAE,CAAC;YACZ,IAAI,CAAC;gBACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAI,OAAO,CAAC,MAAM;oBAAE,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACL,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YACpD,CAAC;QACL,CAAC;QAED,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QACtE,IAAI,aAAa,EAAE,WAAW,EAAE,KAAK,IAAI;YAAE,OAAO,OAAO,CAAC;QAE1D,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IACpE,CAAC;IAEO,kBAAkB,CAAC,QAAgB,EAAE,MAA0B,EAAE,WAAmB;QACxF,IAAI,CAAC;YACD,IAAA,wBAAgB,EAAC,GAAG,IAAA,kBAAQ,GAAE,SAAS,kBAAkB,CACrD,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,+CAA+C,QAAQ,IAAI,YAAY,gBAAgB,MAAM,IAAI,gBAAgB,QAAQ,WAAW,EAAE,CAC3L,EAAE,CAAC,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACL,CAAC;CACJ,CAAA;AAjJY,8BAAS;oBAAT,SAAS;IADrB,IAAA,mBAAU,GAAE;GACA,SAAS,CAiJrB"}
|