@baijimu/cmodel 1.1.0 → 1.1.1
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/README.md +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +1 -186
- package/dist/types.d.ts +0 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/parser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AAIpB,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,CAAC;AAEhE,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,GACvB,cAAc,CAAC,CAAC,CAAC,CAsCnB"}
|
package/dist/parser.js
CHANGED
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
import { CONTRACT_VERSION, } from "./types.js";
|
|
2
2
|
const codePattern = /^(?:0|[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*)$/;
|
|
3
|
-
const reasonPattern = /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/;
|
|
4
|
-
const domainPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*(?:\.[a-z0-9]+(?:-[a-z0-9]+)*)+$/;
|
|
5
|
-
const servicePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
6
|
-
const operationPattern = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;
|
|
7
|
-
const categories = new Set([
|
|
8
|
-
"validation",
|
|
9
|
-
"auth",
|
|
10
|
-
"permission",
|
|
11
|
-
"not_found",
|
|
12
|
-
"conflict",
|
|
13
|
-
"rate_limit",
|
|
14
|
-
"upstream_timeout",
|
|
15
|
-
"upstream_rate_limit",
|
|
16
|
-
"upstream_unavailable",
|
|
17
|
-
"internal",
|
|
18
|
-
"cancelled",
|
|
19
|
-
]);
|
|
20
3
|
export class CModelContractError extends Error {
|
|
21
4
|
path;
|
|
22
5
|
constructor(path, message) {
|
|
@@ -27,13 +10,7 @@ export class CModelContractError extends Error {
|
|
|
27
10
|
}
|
|
28
11
|
export function parseCModelResponse(httpStatus, input, parseData) {
|
|
29
12
|
const envelope = envelopeAt(input, "$");
|
|
30
|
-
requiredKeys(envelope, "$", [
|
|
31
|
-
"contractVersion",
|
|
32
|
-
"errorCode",
|
|
33
|
-
"value",
|
|
34
|
-
"data",
|
|
35
|
-
"systemCurrentTime",
|
|
36
|
-
]);
|
|
13
|
+
requiredKeys(envelope, "$", ["contractVersion", "errorCode", "data"]);
|
|
37
14
|
const contractVersion = stringAt(envelope.contractVersion, "$.contractVersion", 1, 64);
|
|
38
15
|
if (contractVersion !== CONTRACT_VERSION) {
|
|
39
16
|
fail("$.contractVersion", `unsupported contract version ${contractVersion}`);
|
|
@@ -42,8 +19,6 @@ export function parseCModelResponse(httpStatus, input, parseData) {
|
|
|
42
19
|
if (!codePattern.test(errorCode)) {
|
|
43
20
|
fail("$.errorCode", "must be 0 or upper snake case");
|
|
44
21
|
}
|
|
45
|
-
const value = stringAt(envelope.value, "$.value", 0, 512);
|
|
46
|
-
const systemCurrentTime = safeIntegerAt(envelope.systemCurrentTime, "$.systemCurrentTime", 0);
|
|
47
22
|
const httpSuccess = httpStatus >= 200 && httpStatus < 300;
|
|
48
23
|
if (httpStatus === 204) {
|
|
49
24
|
fail("$httpStatus", "CModel responses cannot use 204 No Content");
|
|
@@ -52,16 +27,11 @@ export function parseCModelResponse(httpStatus, input, parseData) {
|
|
|
52
27
|
if (!httpSuccess) {
|
|
53
28
|
fail("$httpStatus", "non-2xx status cannot carry a success envelope");
|
|
54
29
|
}
|
|
55
|
-
if ("error" in envelope) {
|
|
56
|
-
fail("$.error", "success response cannot contain error");
|
|
57
|
-
}
|
|
58
30
|
const data = envelope.data === null ? null : parseData(envelope.data, "$.data");
|
|
59
31
|
return {
|
|
60
32
|
contractVersion: CONTRACT_VERSION,
|
|
61
33
|
errorCode: "0",
|
|
62
|
-
value,
|
|
63
34
|
data,
|
|
64
|
-
systemCurrentTime,
|
|
65
35
|
};
|
|
66
36
|
}
|
|
67
37
|
if (httpSuccess) {
|
|
@@ -70,152 +40,12 @@ export function parseCModelResponse(httpStatus, input, parseData) {
|
|
|
70
40
|
if (envelope.data !== null) {
|
|
71
41
|
fail("$.data", "failure response data must be null");
|
|
72
42
|
}
|
|
73
|
-
if (!("error" in envelope)) {
|
|
74
|
-
fail("$.error", "failure response must contain error");
|
|
75
|
-
}
|
|
76
|
-
const error = parseError(envelope.error, "$.error");
|
|
77
|
-
if (error.code !== errorCode) {
|
|
78
|
-
fail("$.error.code", "must equal errorCode");
|
|
79
|
-
}
|
|
80
|
-
if (error.userMessage !== value) {
|
|
81
|
-
fail("$.value", "must equal error.userMessage");
|
|
82
|
-
}
|
|
83
43
|
return {
|
|
84
44
|
contractVersion: CONTRACT_VERSION,
|
|
85
45
|
errorCode,
|
|
86
|
-
value,
|
|
87
46
|
data: null,
|
|
88
|
-
systemCurrentTime,
|
|
89
|
-
error,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
function parseError(input, path) {
|
|
93
|
-
const value = objectAt(input, path, [
|
|
94
|
-
"code",
|
|
95
|
-
"domain",
|
|
96
|
-
"reason",
|
|
97
|
-
"category",
|
|
98
|
-
"message",
|
|
99
|
-
"userMessage",
|
|
100
|
-
"retryable",
|
|
101
|
-
"source",
|
|
102
|
-
"trace",
|
|
103
|
-
"upstream",
|
|
104
|
-
"causes",
|
|
105
|
-
"violations",
|
|
106
|
-
]);
|
|
107
|
-
requiredKeys(value, path, [
|
|
108
|
-
"code",
|
|
109
|
-
"domain",
|
|
110
|
-
"reason",
|
|
111
|
-
"category",
|
|
112
|
-
"message",
|
|
113
|
-
"userMessage",
|
|
114
|
-
"retryable",
|
|
115
|
-
"source",
|
|
116
|
-
"trace",
|
|
117
|
-
]);
|
|
118
|
-
const code = stringAt(value.code, `${path}.code`, 1, 128);
|
|
119
|
-
if (code === "0" || !codePattern.test(code))
|
|
120
|
-
fail(`${path}.code`, "invalid failure code");
|
|
121
|
-
const domain = stringAt(value.domain, `${path}.domain`, 3, 128);
|
|
122
|
-
if (!domainPattern.test(domain))
|
|
123
|
-
fail(`${path}.domain`, "invalid domain");
|
|
124
|
-
const reason = stringAt(value.reason, `${path}.reason`, 1, 96);
|
|
125
|
-
if (!reasonPattern.test(reason))
|
|
126
|
-
fail(`${path}.reason`, "invalid reason");
|
|
127
|
-
const category = stringAt(value.category, `${path}.category`, 1, 64);
|
|
128
|
-
if (!categories.has(category))
|
|
129
|
-
fail(`${path}.category`, "unknown category");
|
|
130
|
-
const message = stringAt(value.message, `${path}.message`, 1, 1024);
|
|
131
|
-
const userMessage = stringAt(value.userMessage, `${path}.userMessage`, 1, 512);
|
|
132
|
-
if (typeof value.retryable !== "boolean")
|
|
133
|
-
fail(`${path}.retryable`, "must be boolean");
|
|
134
|
-
const source = parseSource(value.source, `${path}.source`);
|
|
135
|
-
const trace = parseTrace(value.trace, `${path}.trace`);
|
|
136
|
-
const upstream = value.upstream === undefined ? undefined : parseUpstream(value.upstream, `${path}.upstream`);
|
|
137
|
-
const causes = value.causes === undefined ? undefined : arrayAt(value.causes, `${path}.causes`, 1, 16).map((cause, index) => parseCause(cause, `${path}.causes[${index}]`));
|
|
138
|
-
const violations = value.violations === undefined ? undefined : arrayAt(value.violations, `${path}.violations`, 1, 100).map((violation, index) => parseViolation(violation, `${path}.violations[${index}]`));
|
|
139
|
-
return {
|
|
140
|
-
code,
|
|
141
|
-
domain,
|
|
142
|
-
reason,
|
|
143
|
-
category: category,
|
|
144
|
-
message,
|
|
145
|
-
userMessage,
|
|
146
|
-
retryable: value.retryable,
|
|
147
|
-
source,
|
|
148
|
-
trace,
|
|
149
|
-
...(upstream === undefined ? {} : { upstream }),
|
|
150
|
-
...(causes === undefined ? {} : { causes }),
|
|
151
|
-
...(violations === undefined ? {} : { violations }),
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
function parseSource(input, path) {
|
|
155
|
-
const value = objectAt(input, path, ["service", "operation"]);
|
|
156
|
-
requiredKeys(value, path, ["service"]);
|
|
157
|
-
const service = stringAt(value.service, `${path}.service`, 1, 96);
|
|
158
|
-
if (!servicePattern.test(service))
|
|
159
|
-
fail(`${path}.service`, "must use lower-kebab-case");
|
|
160
|
-
const operation = value.operation === undefined ? undefined : stringAt(value.operation, `${path}.operation`, 1, 160);
|
|
161
|
-
if (operation !== undefined && !operationPattern.test(operation))
|
|
162
|
-
fail(`${path}.operation`, "contains unsupported characters");
|
|
163
|
-
return { service, ...(operation === undefined ? {} : { operation }) };
|
|
164
|
-
}
|
|
165
|
-
function parseTrace(input, path) {
|
|
166
|
-
const value = objectAt(input, path, ["requestId", "traceId"]);
|
|
167
|
-
requiredKeys(value, path, ["requestId"]);
|
|
168
|
-
const requestId = stringAt(value.requestId, `${path}.requestId`, 1, 256);
|
|
169
|
-
const traceId = value.traceId === undefined ? undefined : stringAt(value.traceId, `${path}.traceId`, 1, 256);
|
|
170
|
-
return { requestId, ...(traceId === undefined ? {} : { traceId }) };
|
|
171
|
-
}
|
|
172
|
-
function parseUpstream(input, path) {
|
|
173
|
-
const value = objectAt(input, path, ["service", "status", "code", "retryAfterMillis"]);
|
|
174
|
-
requiredKeys(value, path, ["service"]);
|
|
175
|
-
const service = stringAt(value.service, `${path}.service`, 1, 96);
|
|
176
|
-
const status = value.status === undefined ? undefined : integerAt(value.status, `${path}.status`, 100, 599);
|
|
177
|
-
const code = value.code === undefined ? undefined : stringAt(value.code, `${path}.code`, 1, 256);
|
|
178
|
-
const retryAfterMillis = value.retryAfterMillis === undefined ? undefined : safeIntegerAt(value.retryAfterMillis, `${path}.retryAfterMillis`, 0);
|
|
179
|
-
return {
|
|
180
|
-
service,
|
|
181
|
-
...(status === undefined ? {} : { status }),
|
|
182
|
-
...(code === undefined ? {} : { code }),
|
|
183
|
-
...(retryAfterMillis === undefined ? {} : { retryAfterMillis }),
|
|
184
47
|
};
|
|
185
48
|
}
|
|
186
|
-
function parseCause(input, path) {
|
|
187
|
-
const value = objectAt(input, path, ["code", "domain", "reason", "source"]);
|
|
188
|
-
requiredKeys(value, path, ["code", "domain", "reason", "source"]);
|
|
189
|
-
const code = stringAt(value.code, `${path}.code`, 1, 128);
|
|
190
|
-
const domain = stringAt(value.domain, `${path}.domain`, 3, 128);
|
|
191
|
-
const reason = stringAt(value.reason, `${path}.reason`, 1, 96);
|
|
192
|
-
if (code === "0" || !codePattern.test(code))
|
|
193
|
-
fail(`${path}.code`, "invalid cause code");
|
|
194
|
-
if (!domainPattern.test(domain))
|
|
195
|
-
fail(`${path}.domain`, "invalid domain");
|
|
196
|
-
if (!reasonPattern.test(reason))
|
|
197
|
-
fail(`${path}.reason`, "invalid reason");
|
|
198
|
-
return { code, domain, reason, source: parseSource(value.source, `${path}.source`) };
|
|
199
|
-
}
|
|
200
|
-
function parseViolation(input, path) {
|
|
201
|
-
const value = objectAt(input, path, ["path", "reason", "message"]);
|
|
202
|
-
requiredKeys(value, path, ["path", "reason", "message"]);
|
|
203
|
-
const violationPath = stringAt(value.path, `${path}.path`, 1, 256);
|
|
204
|
-
const reason = stringAt(value.reason, `${path}.reason`, 1, 96);
|
|
205
|
-
if (!reasonPattern.test(reason))
|
|
206
|
-
fail(`${path}.reason`, "invalid reason");
|
|
207
|
-
return { path: violationPath, reason, message: stringAt(value.message, `${path}.message`, 1, 512) };
|
|
208
|
-
}
|
|
209
|
-
function objectAt(input, path, allowedKeys) {
|
|
210
|
-
if (typeof input !== "object" || input === null || Array.isArray(input))
|
|
211
|
-
fail(path, "must be an object");
|
|
212
|
-
const value = input;
|
|
213
|
-
const allowed = new Set(allowedKeys);
|
|
214
|
-
for (const key of Object.keys(value))
|
|
215
|
-
if (!allowed.has(key))
|
|
216
|
-
fail(`${path}.${key}`, "unknown field");
|
|
217
|
-
return value;
|
|
218
|
-
}
|
|
219
49
|
function envelopeAt(input, path) {
|
|
220
50
|
if (typeof input !== "object" || input === null || Array.isArray(input))
|
|
221
51
|
fail(path, "must be an object");
|
|
@@ -234,21 +64,6 @@ function stringAt(input, path, minimum, maximum) {
|
|
|
234
64
|
fail(path, `length must be between ${minimum} and ${maximum}`);
|
|
235
65
|
return input;
|
|
236
66
|
}
|
|
237
|
-
function integerAt(input, path, minimum, maximum) {
|
|
238
|
-
if (!Number.isInteger(input) || typeof input !== "number" || input < minimum || input > maximum)
|
|
239
|
-
fail(path, `must be an integer between ${minimum} and ${maximum}`);
|
|
240
|
-
return input;
|
|
241
|
-
}
|
|
242
|
-
function safeIntegerAt(input, path, minimum) {
|
|
243
|
-
if (typeof input !== "number" || !Number.isSafeInteger(input) || input < minimum)
|
|
244
|
-
fail(path, `must be a safe integer greater than or equal to ${minimum}`);
|
|
245
|
-
return input;
|
|
246
|
-
}
|
|
247
|
-
function arrayAt(input, path, minimum, maximum) {
|
|
248
|
-
if (!Array.isArray(input) || input.length < minimum || input.length > maximum)
|
|
249
|
-
fail(path, `must contain between ${minimum} and ${maximum} items`);
|
|
250
|
-
return input;
|
|
251
|
-
}
|
|
252
67
|
function fail(path, message) {
|
|
253
68
|
throw new CModelContractError(path, message);
|
|
254
69
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -42,17 +42,12 @@ export interface CModelError {
|
|
|
42
42
|
export interface CModelSuccess<T> {
|
|
43
43
|
readonly contractVersion: typeof CONTRACT_VERSION;
|
|
44
44
|
readonly errorCode: "0";
|
|
45
|
-
readonly value: string;
|
|
46
45
|
readonly data: T | null;
|
|
47
|
-
readonly systemCurrentTime: number;
|
|
48
46
|
}
|
|
49
47
|
export interface CModelFailure {
|
|
50
48
|
readonly contractVersion: typeof CONTRACT_VERSION;
|
|
51
49
|
readonly errorCode: string;
|
|
52
|
-
readonly value: string;
|
|
53
50
|
readonly data: null;
|
|
54
|
-
readonly systemCurrentTime: number;
|
|
55
|
-
readonly error: CModelError;
|
|
56
51
|
}
|
|
57
52
|
export type CModelResponse<T> = CModelSuccess<T> | CModelFailure;
|
|
58
53
|
export declare function isCModelSuccess<T>(response: CModelResponse<T>): response is CModelSuccess<T>;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,WAAW,GACX,UAAU,GACV,YAAY,GACZ,kBAAkB,GAClB,qBAAqB,GACrB,sBAAsB,GACtB,UAAU,GACV,WAAW,CAAC;AAEhB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,OAAO,gBAAgB,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC;IACxB,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD,MAAM,MAAM,aAAa,GACrB,YAAY,GACZ,MAAM,GACN,YAAY,GACZ,WAAW,GACX,UAAU,GACV,YAAY,GACZ,kBAAkB,GAClB,qBAAqB,GACrB,sBAAsB,GACtB,UAAU,GACV,WAAW,CAAC;AAEhB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,OAAO,gBAAgB,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,gBAAgB,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC;AAEjE,wBAAgB,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,aAAa,CAAC,CAAC,CAAC,CAE5F"}
|