@openlimiter/core 0.2.0 → 0.4.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/cache.d.ts +64 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +132 -9
- package/dist/cache.js.map +1 -1
- package/dist/collection.d.ts +151 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +218 -0
- package/dist/collection.js.map +1 -0
- package/dist/connection-state.d.ts +178 -0
- package/dist/connection-state.d.ts.map +1 -0
- package/dist/connection-state.js +304 -0
- package/dist/connection-state.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/merge.d.ts +1 -0
- package/dist/merge.d.ts.map +1 -1
- package/dist/merge.js +12 -4
- package/dist/merge.js.map +1 -1
- package/dist/normalizer.d.ts.map +1 -1
- package/dist/normalizer.js +50 -2
- package/dist/normalizer.js.map +1 -1
- package/dist/schedule.d.ts +75 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +131 -0
- package/dist/schedule.js.map +1 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +54 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/schedule.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When a connection may next ask its provider a question.
|
|
3
|
+
*
|
|
4
|
+
* Background collection is the difference between a quota monitor and a file
|
|
5
|
+
* viewer, and a collector that retries a failing provider on a fixed interval
|
|
6
|
+
* is how a monitor gets an account rate limited. The whole policy lives here as
|
|
7
|
+
* arithmetic over injected values: the caller supplies the clock and the random
|
|
8
|
+
* source, so a schedule is exactly reproducible in a test and identical on all
|
|
9
|
+
* three operating systems.
|
|
10
|
+
*/
|
|
11
|
+
/** Longest our own backoff will ever grow to on its own. */
|
|
12
|
+
export const REFRESH_BACKOFF_CEILING_SECONDS = 3_600;
|
|
13
|
+
/**
|
|
14
|
+
* Longest a provider may push us out with Retry-After.
|
|
15
|
+
*
|
|
16
|
+
* The header is honoured because the provider knows its own limits better than
|
|
17
|
+
* we do, but a header is still input from outside, and a day is already far
|
|
18
|
+
* past the point where a person would reconnect by hand.
|
|
19
|
+
*/
|
|
20
|
+
export const REFRESH_RETRY_AFTER_CEILING_SECONDS = 86_400;
|
|
21
|
+
/** How far either side of the computed delay the jitter may move it. */
|
|
22
|
+
export const REFRESH_JITTER_RATIO = 0.2;
|
|
23
|
+
/** The reader supplied sentinel for a connection that only refreshes by hand. */
|
|
24
|
+
export const SCHEDULE_EXEMPT_BASE_SECONDS = 0;
|
|
25
|
+
/** Missing wire cadence fails closed to the most conservative live default. */
|
|
26
|
+
export const REFRESH_FALLBACK_BASE_SECONDS = 300;
|
|
27
|
+
/** A stable scheduled instant for a connection exempt from background reads. */
|
|
28
|
+
export const SCHEDULE_EXEMPT_INSTANT = "9999-12-31T23:59:59.999Z";
|
|
29
|
+
function usableRandom(random) {
|
|
30
|
+
let value;
|
|
31
|
+
try {
|
|
32
|
+
value = random();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return 0.5;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
38
|
+
return 0.5;
|
|
39
|
+
return Math.min(Math.max(value, 0), 1);
|
|
40
|
+
}
|
|
41
|
+
function usableBase(baseSeconds) {
|
|
42
|
+
if (!Number.isFinite(baseSeconds) || baseSeconds < 0) {
|
|
43
|
+
return REFRESH_FALLBACK_BASE_SECONDS;
|
|
44
|
+
}
|
|
45
|
+
if (baseSeconds === SCHEDULE_EXEMPT_BASE_SECONDS) {
|
|
46
|
+
return Number.POSITIVE_INFINITY;
|
|
47
|
+
}
|
|
48
|
+
return Math.min(baseSeconds, REFRESH_BACKOFF_CEILING_SECONDS);
|
|
49
|
+
}
|
|
50
|
+
function usableAttempt(attempt) {
|
|
51
|
+
if (!Number.isFinite(attempt) || attempt <= 0)
|
|
52
|
+
return 0;
|
|
53
|
+
/*
|
|
54
|
+
* The exponent is clamped before it is used rather than after. Two to the
|
|
55
|
+
* power of a large attempt count overflows to Infinity long before the
|
|
56
|
+
* ceiling below could catch it, and Infinity times a jitter factor is not a
|
|
57
|
+
* date.
|
|
58
|
+
*/
|
|
59
|
+
return Math.min(Math.floor(attempt), 32);
|
|
60
|
+
}
|
|
61
|
+
function usableRetryAfter(value) {
|
|
62
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0)
|
|
63
|
+
return null;
|
|
64
|
+
return Math.min(value, REFRESH_RETRY_AFTER_CEILING_SECONDS);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The delay before the next attempt, in seconds.
|
|
68
|
+
*
|
|
69
|
+
* Doubling per consecutive failure, capped at an hour, then jittered by up to
|
|
70
|
+
* a fifth either way so a hundred installations that all failed at the same
|
|
71
|
+
* moment do not all come back at the same moment.
|
|
72
|
+
*
|
|
73
|
+
* The order matters and is the whole subtlety here. Jitter is applied to OUR
|
|
74
|
+
* backoff and to nothing else, and the provider's Retry-After is then taken as
|
|
75
|
+
* a floor underneath the jittered result. Jittering a Retry-After instead would
|
|
76
|
+
* subtract up to a fifth from an instruction the provider gave us: a header
|
|
77
|
+
* asking for a day back would come back as nineteen hours and knock on the door
|
|
78
|
+
* almost five hours early, which is precisely the behaviour that gets an account
|
|
79
|
+
* limited harder. Jitter exists to spread our own retries, so it may only ever
|
|
80
|
+
* move our own number. A Retry-After shorter than our backoff changes nothing,
|
|
81
|
+
* because a provider cannot talk us out of backing off.
|
|
82
|
+
*/
|
|
83
|
+
export function refreshDelaySeconds(input) {
|
|
84
|
+
const base = usableBase(input.baseSeconds);
|
|
85
|
+
if (base === Number.POSITIVE_INFINITY)
|
|
86
|
+
return base;
|
|
87
|
+
const attempt = usableAttempt(input.attempt);
|
|
88
|
+
const backoff = Math.min(base * Math.pow(2, attempt), REFRESH_BACKOFF_CEILING_SECONDS);
|
|
89
|
+
const jitter = 1 + (usableRandom(input.random) * 2 - 1) * REFRESH_JITTER_RATIO;
|
|
90
|
+
const jittered = backoff * jitter;
|
|
91
|
+
const retryAfter = usableRetryAfter(input.retryAfterSeconds);
|
|
92
|
+
return retryAfter === null ? jittered : Math.max(jittered, retryAfter);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The instant of the next attempt, or null when the supplied clock is not a
|
|
96
|
+
* readable instant. Nothing is guessed from a clock we cannot read.
|
|
97
|
+
*/
|
|
98
|
+
export function nextRefreshAt(now, input) {
|
|
99
|
+
const current = Date.parse(now);
|
|
100
|
+
if (!Number.isFinite(current))
|
|
101
|
+
return null;
|
|
102
|
+
if (input.baseSeconds === SCHEDULE_EXEMPT_BASE_SECONDS) {
|
|
103
|
+
return SCHEDULE_EXEMPT_INSTANT;
|
|
104
|
+
}
|
|
105
|
+
const milliseconds = current + Math.round(refreshDelaySeconds(input) * 1_000);
|
|
106
|
+
if (!Number.isFinite(milliseconds))
|
|
107
|
+
return null;
|
|
108
|
+
const next = new Date(milliseconds);
|
|
109
|
+
return Number.isFinite(next.getTime()) ? next.toISOString() : null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Whether a scheduled instant has arrived.
|
|
113
|
+
*
|
|
114
|
+
* A schedule we cannot read counts as due. The alternative is a connection that
|
|
115
|
+
* never refreshes again because one unreadable value got written once, and the
|
|
116
|
+
* first successful attempt replaces it with a readable one. A clock we cannot
|
|
117
|
+
* read is the opposite case and counts as not due, because with no present
|
|
118
|
+
* moment there is nothing to compare against.
|
|
119
|
+
*/
|
|
120
|
+
export function isDue(nextAt, now) {
|
|
121
|
+
const current = Date.parse(now);
|
|
122
|
+
if (!Number.isFinite(current))
|
|
123
|
+
return false;
|
|
124
|
+
if (nextAt === null)
|
|
125
|
+
return true;
|
|
126
|
+
const scheduled = Date.parse(nextAt);
|
|
127
|
+
if (!Number.isFinite(scheduled))
|
|
128
|
+
return true;
|
|
129
|
+
return current >= scheduled;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -31,6 +31,47 @@ export interface SnapshotAmounts {
|
|
|
31
31
|
limitAmount: number;
|
|
32
32
|
currency: SnapshotCurrency;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* How an observation reached us, stated in our own vocabulary.
|
|
36
|
+
*
|
|
37
|
+
* A provider tells us what its meter reads. It never tells us how we read it,
|
|
38
|
+
* so this field is written by OpenLimiter and only ever holds one of the values
|
|
39
|
+
* below. A human surface can then say "this came from your local Claude Code"
|
|
40
|
+
* or "this came from an official API" without a provider being able to write
|
|
41
|
+
* that sentence for us.
|
|
42
|
+
*/
|
|
43
|
+
export declare const SNAPSHOT_SOURCE_KINDS: readonly ["statusline_payload", "explicit_ingest", "manual_document", "remote_api", "unknown"];
|
|
44
|
+
export type SnapshotSourceKind = (typeof SNAPSHOT_SOURCE_KINDS)[number];
|
|
45
|
+
/**
|
|
46
|
+
* Which reader carried the observation. Closed for the same reason as above.
|
|
47
|
+
*
|
|
48
|
+
* The first three name a concrete path this product actually has, because a
|
|
49
|
+
* source chip saying "your Claude Code statusline" and one saying "you imported
|
|
50
|
+
* this" are the difference between a live reading and a paste, and a generic
|
|
51
|
+
* reader kind cannot tell a person which they are looking at. The rest are the
|
|
52
|
+
* reader kinds the connection architecture defines, kept for paths that exist
|
|
53
|
+
* on paper before they exist in code.
|
|
54
|
+
*/
|
|
55
|
+
export declare const SNAPSHOT_OBSERVED_VIA: readonly ["claude_code_statusline", "ingest_command", "manual_json", "local_event", "local_file", "local_command", "remote_http", "user_entry", "unknown"];
|
|
56
|
+
export type SnapshotObservedVia = (typeof SNAPSHOT_OBSERVED_VIA)[number];
|
|
57
|
+
export interface SnapshotProvenance {
|
|
58
|
+
sourceKind: SnapshotSourceKind;
|
|
59
|
+
observedVia: SnapshotObservedVia;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* What a reading's provenance becomes when the stated provenance cannot be
|
|
63
|
+
* believed. The reading itself still stands: how a number arrived is a separate
|
|
64
|
+
* question from whether the number is in range.
|
|
65
|
+
*/
|
|
66
|
+
export declare const UNKNOWN_PROVENANCE: SnapshotProvenance;
|
|
67
|
+
/**
|
|
68
|
+
* Shape of an account identifier, when a source names one.
|
|
69
|
+
*
|
|
70
|
+
* Lowercase, digits and hyphens, never a space, so it can be joined into a cache
|
|
71
|
+
* identity with a space separator and never collide. It is an opaque local alias
|
|
72
|
+
* and is not required to be an account name any provider would recognise.
|
|
73
|
+
*/
|
|
74
|
+
export declare const ACCOUNT_ID_PATTERN: RegExp;
|
|
34
75
|
export interface ConnectorLabels {
|
|
35
76
|
credentialOrigin: "official-local-tool" | "user-key" | "browser-session" | "user-entered";
|
|
36
77
|
dataInterfaceStatus: "native-statusline-payload" | "documented-api" | "internal-endpoint" | "authenticated-scrape" | "manual";
|
|
@@ -53,6 +94,16 @@ export interface Snapshot {
|
|
|
53
94
|
usedAmount?: number;
|
|
54
95
|
limitAmount?: number;
|
|
55
96
|
currency?: SnapshotCurrency;
|
|
97
|
+
/**
|
|
98
|
+
* Which account this reading belongs to, when a source names one.
|
|
99
|
+
*
|
|
100
|
+
* Absent means one unnamed account, which is every reading written before
|
|
101
|
+
* multiple accounts existed. Absent is not the same as an account called
|
|
102
|
+
* "default": a row without this field keeps the identity it always had.
|
|
103
|
+
*/
|
|
104
|
+
accountId?: string;
|
|
105
|
+
/** How the reading arrived. Absent means it was never recorded. */
|
|
106
|
+
provenance?: SnapshotProvenance;
|
|
56
107
|
}
|
|
57
108
|
export interface RawMeter {
|
|
58
109
|
provider: unknown;
|
|
@@ -69,6 +120,8 @@ export interface RawMeter {
|
|
|
69
120
|
usedAmount?: unknown;
|
|
70
121
|
limitAmount?: unknown;
|
|
71
122
|
currency?: unknown;
|
|
123
|
+
accountId?: unknown;
|
|
124
|
+
provenance?: unknown;
|
|
72
125
|
}
|
|
73
126
|
export interface ConnectorReadContext {
|
|
74
127
|
payload?: unknown;
|
|
@@ -82,10 +135,23 @@ export type ConnectorResult = {
|
|
|
82
135
|
ok: false;
|
|
83
136
|
reason: "unknown" | "unavailable" | "not_configured";
|
|
84
137
|
};
|
|
138
|
+
/**
|
|
139
|
+
* What a connector's payload IS, before its parser sees it.
|
|
140
|
+
*
|
|
141
|
+
* Almost every provider answers JSON. OpenCode answers a logged in HTML page,
|
|
142
|
+
* because it publishes no usage interface at all. That difference cannot live
|
|
143
|
+
* only in the reader that happens to know about it: the desktop pipeline, the
|
|
144
|
+
* ingest command and the web engine all hand payloads to parsers, and any one
|
|
145
|
+
* of them that assumes JSON silently breaks the text reader. So the connector
|
|
146
|
+
* declares it, and every payload boundary asks.
|
|
147
|
+
*/
|
|
148
|
+
export type ConnectorEncoding = "json" | "text";
|
|
85
149
|
export interface ConnectorContract {
|
|
86
150
|
readonly id: Lowercase<ProviderCode>;
|
|
87
151
|
readonly displayName: string;
|
|
88
152
|
readonly labels: ConnectorLabels;
|
|
153
|
+
/** Whether this connector's parser wants parsed JSON or the raw text. */
|
|
154
|
+
readonly encoding: ConnectorEncoding;
|
|
89
155
|
detect(environment: Readonly<Record<string, string | undefined>>): boolean;
|
|
90
156
|
read(context: ConnectorReadContext): Promise<ConnectorResult>;
|
|
91
157
|
}
|
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,cAAc,iFAOjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AACzE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC;AACjE,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,oBAAoB,GACpB,cAAc,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAErC,6EAA6E;AAC7E,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EACZ,qBAAqB,GACrB,UAAU,GACV,iBAAiB,GACjB,cAAc,CAAC;IACnB,mBAAmB,EACf,2BAA2B,GAC3B,gBAAgB,GAChB,mBAAmB,GACnB,sBAAsB,GACtB,QAAQ,CAAC;IACb,cAAc,EAAE,KAAK,GAAG,MAAM,CAAC;IAC/B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,CAAC;IACxB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -8,4 +8,58 @@ export const PROVIDER_CODES = [
|
|
|
8
8
|
];
|
|
9
9
|
/** Largest money amount a reading may carry. Above this it is not a plan. */
|
|
10
10
|
export const MAX_SNAPSHOT_AMOUNT = 1_000_000;
|
|
11
|
+
/**
|
|
12
|
+
* How an observation reached us, stated in our own vocabulary.
|
|
13
|
+
*
|
|
14
|
+
* A provider tells us what its meter reads. It never tells us how we read it,
|
|
15
|
+
* so this field is written by OpenLimiter and only ever holds one of the values
|
|
16
|
+
* below. A human surface can then say "this came from your local Claude Code"
|
|
17
|
+
* or "this came from an official API" without a provider being able to write
|
|
18
|
+
* that sentence for us.
|
|
19
|
+
*/
|
|
20
|
+
export const SNAPSHOT_SOURCE_KINDS = [
|
|
21
|
+
"statusline_payload",
|
|
22
|
+
"explicit_ingest",
|
|
23
|
+
"manual_document",
|
|
24
|
+
"remote_api",
|
|
25
|
+
"unknown"
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Which reader carried the observation. Closed for the same reason as above.
|
|
29
|
+
*
|
|
30
|
+
* The first three name a concrete path this product actually has, because a
|
|
31
|
+
* source chip saying "your Claude Code statusline" and one saying "you imported
|
|
32
|
+
* this" are the difference between a live reading and a paste, and a generic
|
|
33
|
+
* reader kind cannot tell a person which they are looking at. The rest are the
|
|
34
|
+
* reader kinds the connection architecture defines, kept for paths that exist
|
|
35
|
+
* on paper before they exist in code.
|
|
36
|
+
*/
|
|
37
|
+
export const SNAPSHOT_OBSERVED_VIA = [
|
|
38
|
+
"claude_code_statusline",
|
|
39
|
+
"ingest_command",
|
|
40
|
+
"manual_json",
|
|
41
|
+
"local_event",
|
|
42
|
+
"local_file",
|
|
43
|
+
"local_command",
|
|
44
|
+
"remote_http",
|
|
45
|
+
"user_entry",
|
|
46
|
+
"unknown"
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* What a reading's provenance becomes when the stated provenance cannot be
|
|
50
|
+
* believed. The reading itself still stands: how a number arrived is a separate
|
|
51
|
+
* question from whether the number is in range.
|
|
52
|
+
*/
|
|
53
|
+
export const UNKNOWN_PROVENANCE = {
|
|
54
|
+
sourceKind: "unknown",
|
|
55
|
+
observedVia: "unknown"
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Shape of an account identifier, when a source names one.
|
|
59
|
+
*
|
|
60
|
+
* Lowercase, digits and hyphens, never a space, so it can be joined into a cache
|
|
61
|
+
* identity with a space separator and never collide. It is an opaque local alias
|
|
62
|
+
* and is not required to be an account name any provider would recognise.
|
|
63
|
+
*/
|
|
64
|
+
export const ACCOUNT_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/u;
|
|
11
65
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,aAAa;IACb,UAAU;IACV,QAAQ;CACA,CAAC;AA2BX,6EAA6E;AAC7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,aAAa;IACb,UAAU;IACV,QAAQ;CACA,CAAC;AA2BX,6EAA6E;AAC7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAgB7C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,oBAAoB;IACpB,iBAAiB;IACjB,iBAAiB;IACjB,YAAY;IACZ,SAAS;CACD,CAAC;AAIX;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,wBAAwB;IACxB,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,YAAY;IACZ,eAAe;IACf,aAAa;IACb,YAAY;IACZ,SAAS;CACD,CAAC;AASX;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAuB;IACpD,UAAU,EAAE,SAAS;IACrB,WAAW,EAAE,SAAS;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,4BAA4B,CAAC"}
|