mcp-usage-control-cloudflare 1.0.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/dist/schema.js ADDED
@@ -0,0 +1,265 @@
1
+ export const CLOUDFLARE_USAGE_SCHEMA_VERSION = 3;
2
+ const SCHEMA_TABLE = 'usage_control_schema';
3
+ const BUDGETS_TABLE = 'budgets';
4
+ const RESERVATIONS_TABLE = 'reservations';
5
+ const RESERVATION_GROWTH_TABLE = 'reservation_growth';
6
+ const RESERVATION_VECTORS_TABLE = 'reservation_vectors';
7
+ const ACTIVE_EXPIRY_INDEX = 'reservations_active_expiry';
8
+ const TOMBSTONE_EXPIRY_INDEX = 'reservations_tombstone_expiry';
9
+ const BUDGET_COLUMNS = [
10
+ { name: 'id', type: 'TEXT', notNull: false, primaryKey: 1 },
11
+ { name: 'used', type: 'INTEGER', notNull: true, primaryKey: 0 },
12
+ ];
13
+ const RESERVATION_COLUMNS = [
14
+ { name: 'id', type: 'TEXT', notNull: false, primaryKey: 1 },
15
+ { name: 'state', type: 'TEXT', notNull: true, primaryKey: 0 },
16
+ { name: 'reserved_units', type: 'INTEGER', notNull: true, primaryKey: 0 },
17
+ { name: 'expires_at', type: 'INTEGER', notNull: true, primaryKey: 0 },
18
+ { name: 'actual_units', type: 'INTEGER', notNull: false, primaryKey: 0 },
19
+ { name: 'outcome_hash', type: 'TEXT', notNull: false, primaryKey: 0 },
20
+ { name: 'terminal_reason', type: 'TEXT', notNull: false, primaryKey: 0 },
21
+ { name: 'tombstone_expires_at', type: 'INTEGER', notNull: false, primaryKey: 0 },
22
+ { name: 'budget_ids_json', type: 'TEXT', notNull: true, primaryKey: 0 },
23
+ ];
24
+ const RESERVATION_GROWTH_COLUMNS = [
25
+ { name: 'reservation_id', type: 'TEXT', notNull: false, primaryKey: 1 },
26
+ { name: 'growth_cursor', type: 'TEXT', notNull: true, primaryKey: 0 },
27
+ { name: 'last_growth_json', type: 'TEXT', notNull: false, primaryKey: 0 },
28
+ ];
29
+ const RESERVATION_VECTOR_COLUMNS = [
30
+ { name: 'reservation_id', type: 'TEXT', notNull: false, primaryKey: 1 },
31
+ { name: 'dimensions_json', type: 'TEXT', notNull: true, primaryKey: 0 },
32
+ { name: 'actual_dimensions_json', type: 'TEXT', notNull: false, primaryKey: 0 },
33
+ { name: 'last_vector_growth_json', type: 'TEXT', notNull: false, primaryKey: 0 },
34
+ ];
35
+ /**
36
+ * Initializes or validates the Cloudflare SQLite schema as one synchronous
37
+ * transaction. The first versioned release adopts the exact pre-versioning
38
+ * schema as v1 without rewriting accounting rows.
39
+ */
40
+ export function initializeCloudflareUsageSchema(storage) {
41
+ storage.transactionSync(() => {
42
+ createSchemaTable(storage);
43
+ const version = readSchemaVersion(storage);
44
+ if (version === undefined) {
45
+ adoptOrCreateV1(storage);
46
+ migrateV1ToV2(storage);
47
+ migrateV2ToV3(storage);
48
+ storage.sql.exec(`INSERT INTO ${SCHEMA_TABLE} (id, version) VALUES (1, ?)`, CLOUDFLARE_USAGE_SCHEMA_VERSION);
49
+ validateV3(storage);
50
+ return;
51
+ }
52
+ if (version > CLOUDFLARE_USAGE_SCHEMA_VERSION) {
53
+ throw new Error(`Unsupported Cloudflare usage schema version ${version}; ` +
54
+ `runtime supports up to ${CLOUDFLARE_USAGE_SCHEMA_VERSION}`);
55
+ }
56
+ if (version === 1) {
57
+ validateV1(storage, { allowMissingIndexes: false });
58
+ migrateV1ToV2(storage);
59
+ migrateV2ToV3(storage);
60
+ storage.sql.exec(`UPDATE ${SCHEMA_TABLE} SET version = ? WHERE id = 1`, 3);
61
+ validateV3(storage);
62
+ return;
63
+ }
64
+ if (version === 2) {
65
+ validateV2(storage);
66
+ migrateV2ToV3(storage);
67
+ storage.sql.exec(`UPDATE ${SCHEMA_TABLE} SET version = ? WHERE id = 1`, 3);
68
+ validateV3(storage);
69
+ return;
70
+ }
71
+ validateV3(storage);
72
+ });
73
+ }
74
+ export function readCloudflareUsageSchemaVersion(storage) {
75
+ return readSchemaVersion(storage);
76
+ }
77
+ function createSchemaTable(storage) {
78
+ storage.sql.exec(`
79
+ CREATE TABLE IF NOT EXISTS ${SCHEMA_TABLE} (
80
+ id INTEGER PRIMARY KEY CHECK (id = 1),
81
+ version INTEGER NOT NULL CHECK (version >= 1)
82
+ );
83
+ `);
84
+ }
85
+ function readSchemaVersion(storage) {
86
+ const rows = storage.sql
87
+ .exec(`SELECT id, version FROM ${SCHEMA_TABLE}`)
88
+ .toArray();
89
+ if (rows.length === 0)
90
+ return undefined;
91
+ if (rows.length !== 1)
92
+ throw new Error('Invalid Cloudflare usage schema metadata');
93
+ const row = rows[0];
94
+ if (!row || integer(row.id, 'schema id') !== 1) {
95
+ throw new Error('Invalid Cloudflare usage schema metadata');
96
+ }
97
+ const version = integer(row.version, 'schema version');
98
+ if (version < 1)
99
+ throw new Error('Invalid Cloudflare usage schema version');
100
+ return version;
101
+ }
102
+ function adoptOrCreateV1(storage) {
103
+ const objects = applicationTables(storage);
104
+ const hasBudgets = objects.has(BUDGETS_TABLE);
105
+ const hasReservations = objects.has(RESERVATIONS_TABLE);
106
+ if (!hasBudgets && !hasReservations) {
107
+ createV1Tables(storage);
108
+ createV1Indexes(storage);
109
+ validateV1(storage, { allowMissingIndexes: false });
110
+ return;
111
+ }
112
+ if (!hasBudgets || !hasReservations) {
113
+ throw new Error('Incompatible unversioned Cloudflare usage schema: expected both budgets and reservations tables');
114
+ }
115
+ // This is the exact schema shipped before explicit versioning. Validate it
116
+ // before adding the v1 marker so unknown/partial layouts never get adopted.
117
+ validateV1(storage, { allowMissingIndexes: true });
118
+ createV1Indexes(storage);
119
+ validateV1(storage, { allowMissingIndexes: false });
120
+ }
121
+ function createV1Tables(storage) {
122
+ storage.sql.exec(`
123
+ CREATE TABLE ${BUDGETS_TABLE} (
124
+ id TEXT PRIMARY KEY,
125
+ used INTEGER NOT NULL CHECK (used >= 0)
126
+ );
127
+ `);
128
+ storage.sql.exec(`
129
+ CREATE TABLE ${RESERVATIONS_TABLE} (
130
+ id TEXT PRIMARY KEY,
131
+ state TEXT NOT NULL CHECK (state IN ('pending', 'liable', 'settled')),
132
+ reserved_units INTEGER NOT NULL CHECK (reserved_units >= 0),
133
+ expires_at INTEGER NOT NULL,
134
+ actual_units INTEGER,
135
+ outcome_hash TEXT,
136
+ terminal_reason TEXT,
137
+ tombstone_expires_at INTEGER,
138
+ budget_ids_json TEXT NOT NULL
139
+ );
140
+ `);
141
+ }
142
+ function createV1Indexes(storage) {
143
+ storage.sql.exec(`CREATE INDEX IF NOT EXISTS ${ACTIVE_EXPIRY_INDEX}
144
+ ON ${RESERVATIONS_TABLE}(state, expires_at)`);
145
+ storage.sql.exec(`CREATE INDEX IF NOT EXISTS ${TOMBSTONE_EXPIRY_INDEX}
146
+ ON ${RESERVATIONS_TABLE}(state, tombstone_expires_at)`);
147
+ }
148
+ function migrateV1ToV2(storage) {
149
+ storage.sql.exec(`
150
+ CREATE TABLE IF NOT EXISTS ${RESERVATION_GROWTH_TABLE} (
151
+ reservation_id TEXT PRIMARY KEY,
152
+ growth_cursor TEXT NOT NULL,
153
+ last_growth_json TEXT
154
+ );
155
+ `);
156
+ }
157
+ function validateV2(storage) {
158
+ validateV1(storage, { allowMissingIndexes: false });
159
+ const objects = applicationTables(storage);
160
+ if (!objects.has(RESERVATION_GROWTH_TABLE)) {
161
+ throw new Error('Cloudflare usage schema v2 is missing reservation_growth');
162
+ }
163
+ validateColumns(storage, RESERVATION_GROWTH_TABLE, RESERVATION_GROWTH_COLUMNS);
164
+ }
165
+ function migrateV2ToV3(storage) {
166
+ storage.sql.exec(`
167
+ CREATE TABLE IF NOT EXISTS ${RESERVATION_VECTORS_TABLE} (
168
+ reservation_id TEXT PRIMARY KEY,
169
+ dimensions_json TEXT NOT NULL,
170
+ actual_dimensions_json TEXT,
171
+ last_vector_growth_json TEXT
172
+ );
173
+ `);
174
+ }
175
+ function validateV3(storage) {
176
+ validateV2(storage);
177
+ const objects = applicationTables(storage);
178
+ if (!objects.has(RESERVATION_VECTORS_TABLE)) {
179
+ throw new Error('Cloudflare usage schema v3 is missing reservation_vectors');
180
+ }
181
+ validateColumns(storage, RESERVATION_VECTORS_TABLE, RESERVATION_VECTOR_COLUMNS);
182
+ }
183
+ function validateV1(storage, options) {
184
+ const objects = applicationTables(storage);
185
+ if (!objects.has(BUDGETS_TABLE) || !objects.has(RESERVATIONS_TABLE)) {
186
+ throw new Error('Cloudflare usage schema v1 is missing required tables');
187
+ }
188
+ validateColumns(storage, BUDGETS_TABLE, BUDGET_COLUMNS);
189
+ validateColumns(storage, RESERVATIONS_TABLE, RESERVATION_COLUMNS);
190
+ const budgetsSql = objectSql(objects, BUDGETS_TABLE);
191
+ requireSqlFragment(budgetsSql, 'check(used>=0)', BUDGETS_TABLE);
192
+ const reservationsSql = objectSql(objects, RESERVATIONS_TABLE);
193
+ requireSqlFragment(reservationsSql, "check(statein('pending','liable','settled'))", RESERVATIONS_TABLE);
194
+ requireSqlFragment(reservationsSql, 'check(reserved_units>=0)', RESERVATIONS_TABLE);
195
+ validateIndex(storage, ACTIVE_EXPIRY_INDEX, 'onreservations(state,expires_at)', options.allowMissingIndexes);
196
+ validateIndex(storage, TOMBSTONE_EXPIRY_INDEX, 'onreservations(state,tombstone_expires_at)', options.allowMissingIndexes);
197
+ }
198
+ function applicationTables(storage) {
199
+ const rows = storage.sql
200
+ .exec(`SELECT name, type, sql FROM sqlite_master
201
+ WHERE type = 'table' AND name IN (?, ?, ?, ?)`, BUDGETS_TABLE, RESERVATIONS_TABLE, RESERVATION_GROWTH_TABLE, RESERVATION_VECTORS_TABLE)
202
+ .toArray();
203
+ return new Map(rows.map(row => [String(row.name), row]));
204
+ }
205
+ function validateColumns(storage, tableName, expected) {
206
+ const rows = storage.sql
207
+ .exec(`PRAGMA table_info(${tableName})`)
208
+ .toArray();
209
+ if (rows.length !== expected.length) {
210
+ throw new Error(`Incompatible Cloudflare usage schema for ${tableName}: column count differs`);
211
+ }
212
+ for (let index = 0; index < expected.length; index += 1) {
213
+ const row = rows[index];
214
+ const column = expected[index];
215
+ if (!row || !column)
216
+ throw new Error(`Invalid schema metadata for ${tableName}`);
217
+ const name = String(row.name);
218
+ const type = String(row.type).toUpperCase();
219
+ const notNull = integer(row.notnull, `${tableName}.${name}.notnull`) === 1;
220
+ const primaryKey = integer(row.pk, `${tableName}.${name}.pk`);
221
+ if (name !== column.name ||
222
+ type !== column.type ||
223
+ notNull !== column.notNull ||
224
+ primaryKey !== column.primaryKey) {
225
+ throw new Error(`Incompatible Cloudflare usage schema for ${tableName}.${column.name}`);
226
+ }
227
+ }
228
+ }
229
+ function validateIndex(storage, name, requiredSqlFragment, allowMissing) {
230
+ const rows = storage.sql
231
+ .exec(`SELECT name, type, sql FROM sqlite_master WHERE type = 'index' AND name = ?`, name)
232
+ .toArray();
233
+ if (rows.length === 0) {
234
+ if (allowMissing)
235
+ return;
236
+ throw new Error(`Cloudflare usage schema v1 is missing index ${name}`);
237
+ }
238
+ if (rows.length !== 1)
239
+ throw new Error(`Invalid Cloudflare usage index metadata: ${name}`);
240
+ const sql = rows[0]?.sql;
241
+ if (typeof sql !== 'string' || !compactSql(sql).includes(requiredSqlFragment)) {
242
+ throw new Error(`Incompatible Cloudflare usage index ${name}`);
243
+ }
244
+ }
245
+ function objectSql(objects, name) {
246
+ const sql = objects.get(name)?.sql;
247
+ if (typeof sql !== 'string')
248
+ throw new Error(`Missing SQL definition for ${name}`);
249
+ return compactSql(sql);
250
+ }
251
+ function requireSqlFragment(sql, fragment, objectName) {
252
+ if (!sql.includes(fragment)) {
253
+ throw new Error(`Incompatible Cloudflare usage schema constraint for ${objectName}`);
254
+ }
255
+ }
256
+ function compactSql(sql) {
257
+ return sql.toLowerCase().replace(/\s+/g, '');
258
+ }
259
+ function integer(value, name) {
260
+ if (typeof value !== 'number' || !Number.isSafeInteger(value)) {
261
+ throw new Error(`Invalid ${name}`);
262
+ }
263
+ return value;
264
+ }
265
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { DurableObjectState } from 'cloudflare:workers';
2
+ import { type CloudflarePruneBudgetsCommand, type CloudflarePruneBudgetsReply } from './maintenance-protocol.js';
3
+ import { type CloudflareLookupCommand, type CloudflareLookupReply } from './reconciliation-protocol.js';
4
+ import { UsageControlDurableObject as BaseUsageControlDurableObject } from './worker.js';
5
+ /**
6
+ * Public Durable Object entry point with explicit SQLite schema validation.
7
+ * Schema initialization runs before the legacy v1 constructor so incompatible
8
+ * or newer databases fail closed before any compatibility DDL can run.
9
+ */
10
+ export declare class UsageControlDurableObject extends BaseUsageControlDurableObject {
11
+ constructor(ctx: DurableObjectState, env: unknown);
12
+ /** Read-only lookup for explicit lost-reserve-ACK reconciliation. */
13
+ lookup(command: CloudflareLookupCommand): Promise<CloudflareLookupReply>;
14
+ /** Explicit bounded historical budget maintenance; never infers window age. */
15
+ pruneBudgets(command: CloudflarePruneBudgetsCommand): Promise<CloudflarePruneBudgetsReply>;
16
+ }
17
+ //# sourceMappingURL=versioned-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versioned-worker.d.ts","sourceRoot":"","sources":["../src/versioned-worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EACjC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,yBAAyB,IAAI,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAEzF;;;;GAIG;AACH,qBAAa,yBAA0B,SAAQ,6BAA6B;gBAC9D,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,OAAO;IAKjD,qEAAqE;IAC/D,MAAM,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI9E,+EAA+E;IACzE,YAAY,CAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,2BAA2B,CAAC;CAGxC"}
@@ -0,0 +1,24 @@
1
+ import { pruneCloudflareBudgets, } from './maintenance-protocol.js';
2
+ import { lookupCloudflareReservation, } from './reconciliation-protocol.js';
3
+ import { initializeCloudflareUsageSchema } from './schema.js';
4
+ import { UsageControlDurableObject as BaseUsageControlDurableObject } from './worker.js';
5
+ /**
6
+ * Public Durable Object entry point with explicit SQLite schema validation.
7
+ * Schema initialization runs before the legacy v1 constructor so incompatible
8
+ * or newer databases fail closed before any compatibility DDL can run.
9
+ */
10
+ export class UsageControlDurableObject extends BaseUsageControlDurableObject {
11
+ constructor(ctx, env) {
12
+ initializeCloudflareUsageSchema(ctx.storage);
13
+ super(ctx, env);
14
+ }
15
+ /** Read-only lookup for explicit lost-reserve-ACK reconciliation. */
16
+ async lookup(command) {
17
+ return lookupCloudflareReservation(this.ctx.storage, command);
18
+ }
19
+ /** Explicit bounded historical budget maintenance; never infers window age. */
20
+ async pruneBudgets(command) {
21
+ return pruneCloudflareBudgets(this.ctx.storage, command);
22
+ }
23
+ }
24
+ //# sourceMappingURL=versioned-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"versioned-worker.js","sourceRoot":"","sources":["../src/versioned-worker.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,GAGvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,2BAA2B,GAG5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,yBAAyB,IAAI,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAEzF;;;;GAIG;AACH,MAAM,OAAO,yBAA0B,SAAQ,6BAA6B;IAC1E,YAAY,GAAuB,EAAE,GAAY;QAC/C,+BAA+B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,MAAM,CAAC,OAAgC;QAC3C,OAAO,2BAA2B,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,YAAY,CAChB,OAAsC;QAEtC,OAAO,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ import { DurableObject, type DurableObjectState } from 'cloudflare:workers';
2
+ import type { CloudflareGrowCommand, CloudflareGrowReply, CloudflareMarkLiableCommand, CloudflareRenewCommand, CloudflareReserveCommand, CloudflareReserveReply, CloudflareSettlementReply, CloudflareSettleCommand, CloudflareVectorGrowCommand, CloudflareVectorGrowReply, CloudflareVectorReserveCommand, CloudflareVectorReserveReply, CloudflareVectorSettleCommand, CloudflareVectorSettlementReply, CloudflareStoreEnvelope } from './index.js';
3
+ /**
4
+ * SQLite-backed Durable Object implementing one atomic usage-control domain.
5
+ * Export this class from a Worker and declare it with storage = "sqlite".
6
+ */
7
+ export declare class UsageControlDurableObject extends DurableObject<unknown> {
8
+ constructor(ctx: DurableObjectState, env: unknown);
9
+ reserve(command: CloudflareReserveCommand): Promise<CloudflareStoreEnvelope<CloudflareReserveReply>>;
10
+ reserveVector(command: CloudflareVectorReserveCommand): Promise<CloudflareStoreEnvelope<CloudflareVectorReserveReply>>;
11
+ grow(command: CloudflareGrowCommand): Promise<CloudflareStoreEnvelope<CloudflareGrowReply>>;
12
+ growVector(command: CloudflareVectorGrowCommand): Promise<CloudflareStoreEnvelope<CloudflareVectorGrowReply>>;
13
+ markLiable(command: CloudflareMarkLiableCommand): Promise<CloudflareStoreEnvelope<{
14
+ expiresAt: number;
15
+ }>>;
16
+ renew(command: CloudflareRenewCommand): Promise<CloudflareStoreEnvelope<{
17
+ expiresAt: number;
18
+ }>>;
19
+ settle(command: CloudflareSettleCommand): Promise<CloudflareStoreEnvelope<CloudflareSettlementReply>>;
20
+ settleVector(command: CloudflareVectorSettleCommand): Promise<CloudflareStoreEnvelope<CloudflareVectorSettlementReply>>;
21
+ private ensureSchema;
22
+ private readVectorRow;
23
+ private recoverExpiredBatch;
24
+ private recoverSpecific;
25
+ private recoverRow;
26
+ }
27
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAEV,qBAAqB,EACrB,mBAAmB,EACnB,2BAA2B,EAG3B,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EAEvB,2BAA2B,EAC3B,yBAAyB,EACzB,8BAA8B,EAC9B,4BAA4B,EAC5B,6BAA6B,EAC7B,+BAA+B,EAC/B,uBAAuB,EAExB,MAAM,YAAY,CAAC;AA0EpB;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,aAAa,CAAC,OAAO,CAAC;gBACvD,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,OAAO;IAK3C,OAAO,CACX,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,sBAAsB,CAAC,CAAC;IA2FrD,aAAa,CACjB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,uBAAuB,CAAC,4BAA4B,CAAC,CAAC;IA4G3D,IAAI,CACR,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;IA4HlD,UAAU,CACd,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,uBAAuB,CAAC,yBAAyB,CAAC,CAAC;IA6JxD,UAAU,CACd,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,uBAAuB,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAkCpD,KAAK,CACT,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,uBAAuB,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAiCpD,MAAM,CACV,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,uBAAuB,CAAC,yBAAyB,CAAC,CAAC;IAuFxD,YAAY,CAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,+BAA+B,CAAC,CAAC;IA6FpE,OAAO,CAAC,YAAY;IA6CpB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,mBAAmB;IA4F3B,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,UAAU;CAoGnB"}