@dasasian/firebase-structured-logger 0.8.0 → 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/README.md +234 -35
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/logger.d.ts +22 -2
- package/dist/client/logger.d.ts.map +1 -1
- package/dist/client/logger.js +135 -21
- package/dist/client/logger.js.map +1 -1
- package/dist/client/rateLimiter.d.ts +106 -11
- package/dist/client/rateLimiter.d.ts.map +1 -1
- package/dist/client/rateLimiter.js +334 -21
- package/dist/client/rateLimiter.js.map +1 -1
- package/dist/functions/httpHandler.d.ts +1 -1
- package/dist/functions/httpHandler.js +1 -1
- package/dist/functions/index.d.ts +1 -1
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/logHandler.d.ts +10 -5
- package/dist/functions/logHandler.d.ts.map +1 -1
- package/dist/functions/logHandler.js +17 -5
- package/dist/functions/logHandler.js.map +1 -1
- package/dist/functions/logger.d.ts.map +1 -1
- package/dist/functions/logger.js +232 -10
- package/dist/functions/logger.js.map +1 -1
- package/dist/functions/sourceMapCache.js +1 -1
- package/dist/functions/sourceMapCache.js.map +1 -1
- package/dist/shared/deprecate.d.ts +4 -0
- package/dist/shared/deprecate.d.ts.map +1 -0
- package/dist/shared/deprecate.js +30 -0
- package/dist/shared/deprecate.js.map +1 -0
- package/dist/shared/nodeModules.d.ts +39 -0
- package/dist/shared/nodeModules.d.ts.map +1 -0
- package/dist/shared/nodeModules.js +120 -0
- package/dist/shared/nodeModules.js.map +1 -0
- package/dist/shared/types.d.ts +7 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/versionRange.d.ts +17 -0
- package/dist/shared/versionRange.d.ts.map +1 -0
- package/dist/shared/versionRange.js +48 -0
- package/dist/shared/versionRange.js.map +1 -0
- package/dist/tools/doctor.d.ts +54 -0
- package/dist/tools/doctor.d.ts.map +1 -0
- package/dist/tools/doctor.js +381 -0
- package/dist/tools/doctor.js.map +1 -0
- package/dist/tools/index.js +34 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/uploadSourceMaps.d.ts +7 -0
- package/dist/tools/uploadSourceMaps.d.ts.map +1 -1
- package/dist/tools/uploadSourceMaps.js.map +1 -1
- package/package.json +11 -11
- package/skills/query-logs/SKILL.md +49 -0
|
@@ -2,28 +2,104 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.configureRateLimiter = configureRateLimiter;
|
|
4
4
|
exports.signatureFor = signatureFor;
|
|
5
|
+
exports.describeSignature = describeSignature;
|
|
5
6
|
exports.allow = allow;
|
|
7
|
+
exports.flushDueSummaries = flushDueSummaries;
|
|
8
|
+
exports.peekPendingSummaries = peekPendingSummaries;
|
|
9
|
+
exports.acknowledgeSummary = acknowledgeSummary;
|
|
6
10
|
exports.resetRateLimiter = resetRateLimiter;
|
|
7
|
-
const
|
|
11
|
+
const severity_1 = require("../shared/severity");
|
|
12
|
+
const deprecate_1 = require("../shared/deprecate");
|
|
13
|
+
const DEFAULT_BURST_LIMIT = 50;
|
|
14
|
+
const DEFAULT_RECHARGE_SECONDS_PER_LOG = 60;
|
|
15
|
+
const DEFAULT_RESERVED_FOR_ERRORS = 10;
|
|
8
16
|
const DEFAULT_DUPLICATE_LIMIT = 3;
|
|
9
17
|
const DEFAULT_STORAGE_KEY = 'fsl_ratelimit';
|
|
18
|
+
const DEFAULT_SUMMARY_INTERVAL_MINUTES = 60;
|
|
19
|
+
const DEFAULT_SUMMARY_MAX_AGE_DAYS = 7;
|
|
20
|
+
const DEFAULT_MAX_PENDING_SUMMARIES = 50;
|
|
21
|
+
// Fixed, not configurable — the seven knobs in RateLimitConfig are the whole
|
|
22
|
+
// documented surface (README, "Volume controls"). A second storage key for the
|
|
23
|
+
// summary queue would be an eighth nobody asked for.
|
|
24
|
+
const SUMMARY_STORAGE_KEY = 'fsl_pending_summaries';
|
|
25
|
+
/**
|
|
26
|
+
* The flood this feature exists to survive is exactly "many distinct
|
|
27
|
+
* messages" — a URL, an id, anything with a variable in the string — so
|
|
28
|
+
* `state.signatures` cannot be left to grow one entry per message forever:
|
|
29
|
+
* that eventually fills sessionStorage (a quota error, then the state is
|
|
30
|
+
* silently lost) and makes every `allow()` parse an ever-larger map. Not a
|
|
31
|
+
* config knob: nobody tunes this per app, it is a safety valve.
|
|
32
|
+
*/
|
|
33
|
+
const MAX_SIGNATURES = 200;
|
|
10
34
|
// Session-scoped by design: one browser session, one budget. Deliberately not
|
|
11
35
|
// per-Logger — see the module-scoped state rule in CLAUDE.md.
|
|
12
36
|
let config = {
|
|
13
|
-
|
|
37
|
+
burstLimit: DEFAULT_BURST_LIMIT,
|
|
38
|
+
rechargeSecondsPerLog: DEFAULT_RECHARGE_SECONDS_PER_LOG,
|
|
39
|
+
reservedForErrors: DEFAULT_RESERVED_FOR_ERRORS,
|
|
14
40
|
duplicateLimit: DEFAULT_DUPLICATE_LIMIT,
|
|
15
41
|
storageKey: DEFAULT_STORAGE_KEY,
|
|
42
|
+
summaryIntervalMinutes: DEFAULT_SUMMARY_INTERVAL_MINUTES,
|
|
43
|
+
summaryMaxAgeDays: DEFAULT_SUMMARY_MAX_AGE_DAYS,
|
|
44
|
+
maxPendingSummaries: DEFAULT_MAX_PENDING_SUMMARIES,
|
|
16
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* `reservedForErrors` above half of `burstLimit` would leave warnings no room
|
|
48
|
+
* to spend at all, so it is capped there — whether it arrived directly or was
|
|
49
|
+
* converted from the deprecated `errorReserve`. Warned once per process, like
|
|
50
|
+
* the renames themselves.
|
|
51
|
+
*/
|
|
52
|
+
let warnedReservedForErrorsCapped = false;
|
|
53
|
+
function capReservedForErrors(value, burstLimit) {
|
|
54
|
+
const half = burstLimit / 2;
|
|
55
|
+
if (value <= half)
|
|
56
|
+
return value;
|
|
57
|
+
if (!warnedReservedForErrorsCapped) {
|
|
58
|
+
warnedReservedForErrorsCapped = true;
|
|
59
|
+
console.warn('[fsl] "reservedForErrors" above half of "burstLimit" is capped at half, so warnings always have room.');
|
|
60
|
+
}
|
|
61
|
+
return half;
|
|
62
|
+
}
|
|
17
63
|
function configureRateLimiter(options) {
|
|
18
|
-
|
|
64
|
+
const { sessionLimit, refillPerMinute, errorReserve, burstLimit, rechargeSecondsPerLog, reservedForErrors, ...rest } = options;
|
|
65
|
+
if (sessionLimit !== undefined)
|
|
66
|
+
(0, deprecate_1.warnDeprecated)('sessionLimit', 'burstLimit');
|
|
67
|
+
const resolvedBurstLimit = burstLimit ?? sessionLimit;
|
|
68
|
+
if (refillPerMinute !== undefined)
|
|
69
|
+
(0, deprecate_1.warnDeprecated)('refillPerMinute', 'rechargeSecondsPerLog');
|
|
70
|
+
const resolvedRecharge = rechargeSecondsPerLog ?? (refillPerMinute !== undefined ? 60 / refillPerMinute : undefined);
|
|
71
|
+
// Needed to convert `errorReserve` (a share) and to cap either name — both
|
|
72
|
+
// read the burst limit this same call is possibly also changing.
|
|
73
|
+
const effectiveBurstLimit = resolvedBurstLimit ?? config.burstLimit;
|
|
74
|
+
if (errorReserve !== undefined)
|
|
75
|
+
(0, deprecate_1.warnDeprecated)('errorReserve', 'reservedForErrors');
|
|
76
|
+
const rawReservedForErrors = reservedForErrors ?? (errorReserve !== undefined ? Math.round(errorReserve * effectiveBurstLimit) : undefined);
|
|
77
|
+
const resolvedReservedForErrors = rawReservedForErrors !== undefined ? capReservedForErrors(rawReservedForErrors, effectiveBurstLimit) : undefined;
|
|
78
|
+
config = {
|
|
79
|
+
...config,
|
|
80
|
+
...rest,
|
|
81
|
+
...(resolvedBurstLimit !== undefined ? { burstLimit: resolvedBurstLimit } : {}),
|
|
82
|
+
...(resolvedRecharge !== undefined ? { rechargeSecondsPerLog: resolvedRecharge } : {}),
|
|
83
|
+
...(resolvedReservedForErrors !== undefined ? { reservedForErrors: resolvedReservedForErrors } : {}),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// This tab's identity for `sentLate`. Regenerated by `resetRateLimiter`, which
|
|
87
|
+
// is how tests simulate a new visit — a real reload gets a new one for free,
|
|
88
|
+
// since the module (and this `let`) is re-evaluated from scratch.
|
|
89
|
+
let bootId = generateId();
|
|
90
|
+
function generateId() {
|
|
91
|
+
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
92
|
+
}
|
|
93
|
+
function defaultState() {
|
|
94
|
+
return { available: config.burstLimit, lastRefillAt: Date.now(), signatures: {} };
|
|
19
95
|
}
|
|
20
96
|
function readState() {
|
|
21
97
|
try {
|
|
22
98
|
const stored = sessionStorage.getItem(config.storageKey);
|
|
23
|
-
return stored ? JSON.parse(stored) :
|
|
99
|
+
return stored ? JSON.parse(stored) : defaultState();
|
|
24
100
|
}
|
|
25
101
|
catch {
|
|
26
|
-
return
|
|
102
|
+
return defaultState();
|
|
27
103
|
}
|
|
28
104
|
}
|
|
29
105
|
function writeState(state) {
|
|
@@ -34,6 +110,39 @@ function writeState(state) {
|
|
|
34
110
|
// sessionStorage full or unavailable — rate limiting degrades, logging continues
|
|
35
111
|
}
|
|
36
112
|
}
|
|
113
|
+
function readSummaryQueue() {
|
|
114
|
+
try {
|
|
115
|
+
const stored = localStorage.getItem(SUMMARY_STORAGE_KEY);
|
|
116
|
+
return stored ? JSON.parse(stored) : [];
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function writeSummaryQueue(queue) {
|
|
123
|
+
try {
|
|
124
|
+
localStorage.setItem(SUMMARY_STORAGE_KEY, JSON.stringify(queue));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// localStorage full or unavailable — summaries degrade, logging continues
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function isExpired(summary, now) {
|
|
131
|
+
return now - summary.createdAt >= config.summaryMaxAgeDays * 24 * 60 * 60 * 1000;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Refill the budget for the time elapsed since it was last touched, capped at
|
|
135
|
+
* `burstLimit`. Mutates `state` in place; the caller decides whether the
|
|
136
|
+
* result is worth persisting.
|
|
137
|
+
*/
|
|
138
|
+
function refill(state, now) {
|
|
139
|
+
const elapsedMinutes = (now - state.lastRefillAt) / 60_000;
|
|
140
|
+
if (elapsedMinutes <= 0)
|
|
141
|
+
return;
|
|
142
|
+
const perMinute = 60 / config.rechargeSecondsPerLog;
|
|
143
|
+
state.available = Math.min(config.burstLimit, state.available + elapsedMinutes * perMinute);
|
|
144
|
+
state.lastRefillAt = now;
|
|
145
|
+
}
|
|
37
146
|
/**
|
|
38
147
|
* Build the key used to recognise a repeat of the same problem. Two occurrences
|
|
39
148
|
* count as duplicates only if the message and the screen both match, so the same
|
|
@@ -45,8 +154,51 @@ function writeState(state) {
|
|
|
45
154
|
* without the staleness of a span someone has to remember to clear.
|
|
46
155
|
*/
|
|
47
156
|
function signatureFor(error, screen) {
|
|
48
|
-
|
|
49
|
-
|
|
157
|
+
// A JSON list, not a joined string: a summary rebuilds the name, message and
|
|
158
|
+
// screen from this key (parseSignatureKey), and a message containing `:` or
|
|
159
|
+
// `|` — "upload failed: timeout" — must not split into the wrong fields.
|
|
160
|
+
const errorType = error instanceof Error ? error.name : null;
|
|
161
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
162
|
+
return JSON.stringify([errorType, message, screen ?? '']);
|
|
163
|
+
}
|
|
164
|
+
/** A signature as a person reads it, for the console: `TypeError: cannot read 'id' | checkout`. */
|
|
165
|
+
function describeSignature(signature) {
|
|
166
|
+
const { errorType, message, screen } = parseSignature(signature);
|
|
167
|
+
return `${errorType ? `${errorType}: ` : ''}${message}${screen ? ` | ${screen}` : ''}`;
|
|
168
|
+
}
|
|
169
|
+
function parseSignature(signature) {
|
|
170
|
+
try {
|
|
171
|
+
const [errorType, message, screen] = JSON.parse(signature);
|
|
172
|
+
return { errorType: errorType ?? undefined, message, screen: screen || undefined };
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Not one of ours — keep it whole rather than guess at its parts.
|
|
176
|
+
return { message: signature };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* A signature is further scoped to the release and the user before it is
|
|
181
|
+
* counted — two releases, or two people on one machine, must never share one
|
|
182
|
+
* running count. See README, "Repeats are counted, not dropped".
|
|
183
|
+
*/
|
|
184
|
+
function compoundKey(signature, labels) {
|
|
185
|
+
return JSON.stringify([signature, labels?.releaseId ?? '', labels?.userId ?? '']);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* The inverse of `compoundKey` + `signatureFor`: recover the name, message,
|
|
189
|
+
* screen, releaseId and userId a summary needs from the key that already
|
|
190
|
+
* holds them, rather than storing a second copy per signature — see
|
|
191
|
+
* `SignatureState`'s doc for why that copy has to go. Both are JSON lists, so
|
|
192
|
+
* the fields come back exactly, whatever characters a message contains.
|
|
193
|
+
*/
|
|
194
|
+
function parseSignatureKey(key) {
|
|
195
|
+
try {
|
|
196
|
+
const [signature, releaseId, userId] = JSON.parse(key);
|
|
197
|
+
return { ...parseSignature(signature), releaseId: releaseId || undefined, userId: userId || undefined };
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return { message: key };
|
|
201
|
+
}
|
|
50
202
|
}
|
|
51
203
|
/**
|
|
52
204
|
* Decide whether one log may be sent, and consume its budget if so.
|
|
@@ -58,24 +210,187 @@ function signatureFor(error, screen) {
|
|
|
58
210
|
* cannot be checked without consuming.
|
|
59
211
|
*
|
|
60
212
|
* Pass a `signature` to opt this log into duplicate suppression. Any severity
|
|
61
|
-
* may do so; it is not reserved for errors.
|
|
213
|
+
* may do so; it is not reserved for errors. Once `duplicateLimit` full copies
|
|
214
|
+
* have gone out, further occurrences are neither sent nor refused outright —
|
|
215
|
+
* they are counted here, toward the next repeat summary, and cost no budget.
|
|
216
|
+
*/
|
|
217
|
+
/**
|
|
218
|
+
* Keep `state.signatures` at or under `MAX_SIGNATURES`. Evicts the oldest
|
|
219
|
+
* (by `lastTouched`) signatures that have no pending repeat count first;
|
|
220
|
+
* a signature with an unsent `repeatCount` is never dropped, even if that
|
|
221
|
+
* leaves the map over the cap — losing a count already promised to a summary
|
|
222
|
+
* is worse than a temporarily oversized map.
|
|
62
223
|
*/
|
|
63
|
-
function
|
|
224
|
+
function pruneSignatures(state) {
|
|
225
|
+
const keys = Object.keys(state.signatures);
|
|
226
|
+
let overflow = keys.length - MAX_SIGNATURES;
|
|
227
|
+
if (overflow <= 0)
|
|
228
|
+
return;
|
|
229
|
+
const evictable = keys
|
|
230
|
+
.filter((k) => state.signatures[k].repeatCount === undefined)
|
|
231
|
+
.sort((a, b) => state.signatures[a].lastTouched - state.signatures[b].lastTouched);
|
|
232
|
+
for (const k of evictable) {
|
|
233
|
+
if (overflow <= 0)
|
|
234
|
+
break;
|
|
235
|
+
delete state.signatures[k];
|
|
236
|
+
overflow--;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function allow(options) {
|
|
240
|
+
const now = Date.now();
|
|
64
241
|
const state = readState();
|
|
65
|
-
|
|
242
|
+
refill(state, now);
|
|
243
|
+
let key;
|
|
244
|
+
let sig;
|
|
245
|
+
if (options.signature !== undefined) {
|
|
246
|
+
key = compoundKey(options.signature, options.labels);
|
|
247
|
+
sig = state.signatures[key] ?? { count: 0, repeatKey: generateId(), lastTouched: now };
|
|
248
|
+
sig.lastTouched = now;
|
|
249
|
+
}
|
|
250
|
+
if (sig && key && sig.count >= config.duplicateLimit) {
|
|
251
|
+
sig.repeatCount = (sig.repeatCount ?? 0) + 1;
|
|
252
|
+
if (sig.firstSeen === undefined)
|
|
253
|
+
sig.firstSeen = now;
|
|
254
|
+
sig.lastSeen = now;
|
|
255
|
+
state.signatures[key] = sig;
|
|
256
|
+
pruneSignatures(state);
|
|
257
|
+
writeState(state);
|
|
258
|
+
return { allowed: false, reason: 'duplicate', signature: options.signature };
|
|
259
|
+
}
|
|
260
|
+
// Capped here, where it is used, not only where it was configured: the
|
|
261
|
+
// default reservedForErrors (10) with a small burstLimit, or a later call
|
|
262
|
+
// that lowers burstLimit alone, would otherwise reserve the whole burst and
|
|
263
|
+
// refuse every warning. capReservedForErrors warns only for a value someone
|
|
264
|
+
// actually passed.
|
|
265
|
+
const reserveThreshold = Math.min(config.reservedForErrors, config.burstLimit / 2);
|
|
266
|
+
if (state.available < 1) {
|
|
267
|
+
writeState(state);
|
|
66
268
|
return { allowed: false, reason: 'session-limit' };
|
|
67
269
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
270
|
+
// "ERROR and above" as a rank, not the literal string 'ERROR' — so the check
|
|
271
|
+
// stays right if a more severe level is ever added to SEVERITY_ORDER.
|
|
272
|
+
// Would spending one dip into the reserve? Asked that way, not as
|
|
273
|
+
// "available <= reserve": the count refills continuously and is almost never
|
|
274
|
+
// whole, so at 1.02 with a reserve of 1 the old check let a warning through
|
|
275
|
+
// and it spent the reserve. Found as a CI-only flake — on a fast machine the
|
|
276
|
+
// calls share one millisecond and the count stays exactly 1.
|
|
277
|
+
if (state.available - 1 < reserveThreshold && severity_1.SEVERITY_ORDER[options.severity] > severity_1.SEVERITY_ORDER.ERROR) {
|
|
278
|
+
writeState(state);
|
|
279
|
+
return { allowed: false, reason: 'reserve' };
|
|
280
|
+
}
|
|
281
|
+
state.available -= 1;
|
|
282
|
+
if (sig && key) {
|
|
283
|
+
sig.count += 1;
|
|
284
|
+
state.signatures[key] = sig;
|
|
285
|
+
pruneSignatures(state);
|
|
74
286
|
}
|
|
75
|
-
state.logCount++;
|
|
76
287
|
writeState(state);
|
|
77
|
-
return { allowed: true };
|
|
288
|
+
return { allowed: true, repeatKey: sig?.repeatKey };
|
|
78
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Move any signature's accumulated repeats into the pending-summary queue —
|
|
292
|
+
* every one whose window (`summaryIntervalMinutes`) has elapsed, or every one
|
|
293
|
+
* with anything to send when `force` is true (the tab going hidden).
|
|
294
|
+
*
|
|
295
|
+
* Only the counting resets; `count` (full copies already sent) is untouched,
|
|
296
|
+
* so a signature stays in "counting" mode across summary windows rather than
|
|
297
|
+
* sending three more full copies before the next summary.
|
|
298
|
+
*/
|
|
299
|
+
function flushDueSummaries(force = false) {
|
|
300
|
+
const now = Date.now();
|
|
301
|
+
const state = readState();
|
|
302
|
+
refill(state, now);
|
|
303
|
+
const intervalMs = config.summaryIntervalMinutes * 60_000;
|
|
304
|
+
let changed = false;
|
|
305
|
+
for (const key of Object.keys(state.signatures)) {
|
|
306
|
+
const sig = state.signatures[key];
|
|
307
|
+
if (!sig.repeatCount || sig.firstSeen === undefined || sig.lastSeen === undefined)
|
|
308
|
+
continue;
|
|
309
|
+
if (!force && now - sig.firstSeen < intervalMs)
|
|
310
|
+
continue;
|
|
311
|
+
const { errorType, message, screen, releaseId, userId } = parseSignatureKey(key);
|
|
312
|
+
const maxAgeMs = config.summaryMaxAgeDays * 24 * 60 * 60 * 1000;
|
|
313
|
+
const queue = readSummaryQueue().filter((s) => now - s.createdAt < maxAgeMs);
|
|
314
|
+
queue.push({
|
|
315
|
+
id: generateId(),
|
|
316
|
+
message,
|
|
317
|
+
errorType,
|
|
318
|
+
screen,
|
|
319
|
+
releaseId,
|
|
320
|
+
userId,
|
|
321
|
+
repeatOf: sig.repeatKey,
|
|
322
|
+
repeatCount: sig.repeatCount,
|
|
323
|
+
firstSeen: new Date(sig.firstSeen).toISOString(),
|
|
324
|
+
lastSeen: new Date(sig.lastSeen).toISOString(),
|
|
325
|
+
createdAt: now,
|
|
326
|
+
bootId,
|
|
327
|
+
});
|
|
328
|
+
// Keep the newest when the queue is over its cap.
|
|
329
|
+
const trimmed = queue.length > config.maxPendingSummaries
|
|
330
|
+
? queue.slice(queue.length - config.maxPendingSummaries)
|
|
331
|
+
: queue;
|
|
332
|
+
writeSummaryQueue(trimmed);
|
|
333
|
+
sig.repeatCount = undefined;
|
|
334
|
+
sig.firstSeen = undefined;
|
|
335
|
+
sig.lastSeen = undefined;
|
|
336
|
+
changed = true;
|
|
337
|
+
}
|
|
338
|
+
if (changed)
|
|
339
|
+
writeState(state);
|
|
340
|
+
}
|
|
341
|
+
function toSentSummary(s) {
|
|
342
|
+
return {
|
|
343
|
+
id: s.id,
|
|
344
|
+
message: s.message,
|
|
345
|
+
errorType: s.errorType,
|
|
346
|
+
screen: s.screen,
|
|
347
|
+
releaseId: s.releaseId,
|
|
348
|
+
userId: s.userId,
|
|
349
|
+
repeatOf: s.repeatOf,
|
|
350
|
+
repeatCount: s.repeatCount,
|
|
351
|
+
firstSeen: s.firstSeen,
|
|
352
|
+
lastSeen: s.lastSeen,
|
|
353
|
+
sentLate: s.bootId !== bootId,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Look at every pending summary not past `summaryMaxAgeDays`, WITHOUT
|
|
358
|
+
* removing it from the queue. A summary may only leave the queue once its
|
|
359
|
+
* send has actually succeeded — see `acknowledgeSummary` — so a failed send
|
|
360
|
+
* (offline, or the tab tearing down right after the `visibilitychange` that
|
|
361
|
+
* triggered this) leaves it queued for the next flush or the next visit to
|
|
362
|
+
* retry, instead of losing it. `sentLate` is true for anything queued by an
|
|
363
|
+
* earlier page load (a different `bootId`): the case the README's "next
|
|
364
|
+
* visit sends them" describes.
|
|
365
|
+
*
|
|
366
|
+
* Expired entries ARE removed here — there is no send to wait on for those.
|
|
367
|
+
*/
|
|
368
|
+
function peekPendingSummaries() {
|
|
369
|
+
const now = Date.now();
|
|
370
|
+
const queue = readSummaryQueue();
|
|
371
|
+
const fresh = queue.filter((s) => !isExpired(s, now));
|
|
372
|
+
if (fresh.length !== queue.length)
|
|
373
|
+
writeSummaryQueue(fresh);
|
|
374
|
+
return fresh.map(toSentSummary);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Remove one summary from the queue by id, once its send has resolved. A
|
|
378
|
+
* retry that calls this again for an id already gone is a no-op — it never
|
|
379
|
+
* re-adds anything, so it cannot create a second entry.
|
|
380
|
+
*/
|
|
381
|
+
function acknowledgeSummary(id) {
|
|
382
|
+
const queue = readSummaryQueue();
|
|
383
|
+
const next = queue.filter((s) => s.id !== id);
|
|
384
|
+
if (next.length !== queue.length)
|
|
385
|
+
writeSummaryQueue(next);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Test-only reset. There is no `beforeunload` wiring any more — the budget
|
|
389
|
+
* lives in `sessionStorage` on purpose, so a reload keeps it — but tests still
|
|
390
|
+
* need a way to start a clean session, and to simulate a genuinely new visit
|
|
391
|
+
* (a new tab gets a new `bootId` for free, since the module reloads with it;
|
|
392
|
+
* a test in the same process cannot, so this rotates it explicitly).
|
|
393
|
+
*/
|
|
79
394
|
function resetRateLimiter() {
|
|
80
395
|
try {
|
|
81
396
|
sessionStorage.removeItem(config.storageKey);
|
|
@@ -83,8 +398,6 @@ function resetRateLimiter() {
|
|
|
83
398
|
catch {
|
|
84
399
|
// Silently fail
|
|
85
400
|
}
|
|
86
|
-
|
|
87
|
-
if (typeof window !== 'undefined') {
|
|
88
|
-
window.addEventListener('beforeunload', resetRateLimiter);
|
|
401
|
+
bootId = generateId();
|
|
89
402
|
}
|
|
90
403
|
//# sourceMappingURL=rateLimiter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../src/client/rateLimiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -72,7 +72,7 @@ export interface HttpLogHandlerConfig extends ClientLogHandlerConfig {
|
|
|
72
72
|
*
|
|
73
73
|
* const app = express()
|
|
74
74
|
* app.use(express.json({ limit: '10mb' })) // attachments ride in the body
|
|
75
|
-
* app.post('/log', createHttpLogHandler({
|
|
75
|
+
* app.post('/log', createHttpLogHandler({ bucket, authorize }))
|
|
76
76
|
*
|
|
77
77
|
* On the client, point `logFunction` at it:
|
|
78
78
|
*
|
|
@@ -40,7 +40,7 @@ function send(res, status, body) {
|
|
|
40
40
|
*
|
|
41
41
|
* const app = express()
|
|
42
42
|
* app.use(express.json({ limit: '10mb' })) // attachments ride in the body
|
|
43
|
-
* app.post('/log', createHttpLogHandler({
|
|
43
|
+
* app.post('/log', createHttpLogHandler({ bucket, authorize }))
|
|
44
44
|
*
|
|
45
45
|
* On the client, point `logFunction` at it:
|
|
46
46
|
*
|
|
@@ -5,7 +5,7 @@ export { withLogging, getLogger } from './requestLogger';
|
|
|
5
5
|
export { configureAttachments } from './sourceMapCache';
|
|
6
6
|
export { createClientLogHandler, createClientLogFunction, ClientLogError } from './logHandler';
|
|
7
7
|
export { createHttpLogHandler } from './httpHandler';
|
|
8
|
-
export type { ClientLogHandlerConfig, ClientLogRequest } from './logHandler';
|
|
8
|
+
export type { ClientLogHandlerConfig, ClientLogRequest, LogRequest } from './logHandler';
|
|
9
9
|
export type { HttpLogHandlerConfig, HttpLogRequest, HttpLogResponse } from './httpHandler';
|
|
10
10
|
export type { LogSeverity, LogPayload, BaseLabels } from '../shared/types';
|
|
11
11
|
export declare const logError: (...args: Parameters<LogWriter["error"]>) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpD,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/functions/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpD,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACxF,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC1F,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE1E,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAG,IAAkC,CAAA;AACrG,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAG,IAAoC,CAAA;AACxG,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAG,IAAiC,CAAA;AAClG,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAG,IAAkC,CAAA"}
|
|
@@ -12,6 +12,8 @@ export interface ClientLogHandlerConfig {
|
|
|
12
12
|
* handler. Override either half independently with `sourceMaps` below or
|
|
13
13
|
* `configureAttachments()`.
|
|
14
14
|
*/
|
|
15
|
+
bucket?: string;
|
|
16
|
+
/** @deprecated Use `bucket`. */
|
|
15
17
|
bucketName?: string;
|
|
16
18
|
cors?: boolean | string | string[];
|
|
17
19
|
maxInstances?: number;
|
|
@@ -20,7 +22,8 @@ export interface ClientLogHandlerConfig {
|
|
|
20
22
|
*
|
|
21
23
|
* Genuinely per-handler: both values travel explicitly to `getSourceMap`, so
|
|
22
24
|
* two handlers configured differently cannot resolve to whichever was
|
|
23
|
-
* constructed last. `bucket` overrides `
|
|
25
|
+
* constructed last. `sourceMaps.bucket` overrides the top-level `bucket` for
|
|
26
|
+
* map lookups only.
|
|
24
27
|
*
|
|
25
28
|
* `prefix` must match `fsl upload-sourcemaps --prefix`. They are the two ends
|
|
26
29
|
* of one contract (#35) and nothing checks them against each other — when they
|
|
@@ -54,23 +57,25 @@ export declare class ClientLogError extends Error {
|
|
|
54
57
|
* not `.auth`, not `.rawRequest`. Saying so is what lets an Express adapter, or
|
|
55
58
|
* anything else, call this without constructing a callable request (#34).
|
|
56
59
|
*/
|
|
57
|
-
export interface
|
|
60
|
+
export interface LogRequest {
|
|
58
61
|
data: LogPayload;
|
|
59
62
|
}
|
|
63
|
+
/** @deprecated Use `LogRequest`. */
|
|
64
|
+
export type ClientLogRequest = LogRequest;
|
|
60
65
|
/**
|
|
61
66
|
* Create an onCall handler that receives LogPayload from the client,
|
|
62
67
|
* symbolicates stack traces, and writes structured entries to Cloud Logging.
|
|
63
68
|
*
|
|
64
69
|
* @example
|
|
65
|
-
* export const logFrontendEvent = onCall(createClientLogHandler({
|
|
70
|
+
* export const logFrontendEvent = onCall(createClientLogHandler({ bucket: 'my-bucket' }))
|
|
66
71
|
*/
|
|
67
|
-
export declare function createClientLogHandler(config: ClientLogHandlerConfig): (request:
|
|
72
|
+
export declare function createClientLogHandler(config: ClientLogHandlerConfig): (request: LogRequest) => Promise<void>;
|
|
68
73
|
/**
|
|
69
74
|
* Convenience factory that wraps createClientLogHandler in onCall.
|
|
70
75
|
* Use when you want a ready-to-export Cloud Function.
|
|
71
76
|
*
|
|
72
77
|
* @example
|
|
73
|
-
* export const logFrontendEvent = createClientLogFunction({
|
|
78
|
+
* export const logFrontendEvent = createClientLogFunction({ bucket: 'my-bucket' })
|
|
74
79
|
*/
|
|
75
80
|
export declare function createClientLogFunction(config: ClientLogHandlerConfig & {
|
|
76
81
|
cors?: boolean | string | string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logHandler.d.ts","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,aAAa,MAAM,6BAA6B,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"logHandler.d.ts","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,aAAa,MAAM,6BAA6B,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAA;AAwB/D,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAClD;AAaD;;;;;;;;GAQG;AACH,qBAAa,cAAe,SAAQ,KAAK;IAErC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,GAAG,UAAU;gBAArC,IAAI,EAAE,kBAAkB,GAAG,UAAU,EAC9C,OAAO,EAAE,MAAM;CAKlB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,oCAAoC;AACpC,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAA;AA6DzC;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,IAIrD,SAAS,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC,CAsClD;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,sBAAsB,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,sEAiB/F"}
|
|
@@ -4,6 +4,7 @@ exports.ClientLogError = void 0;
|
|
|
4
4
|
exports.createClientLogHandler = createClientLogHandler;
|
|
5
5
|
exports.createClientLogFunction = createClientLogFunction;
|
|
6
6
|
const severity_1 = require("../shared/severity");
|
|
7
|
+
const deprecate_1 = require("../shared/deprecate");
|
|
7
8
|
const logger_1 = require("./logger");
|
|
8
9
|
const sourceMapCache_1 = require("./sourceMapCache");
|
|
9
10
|
const symbolicate_1 = require("./symbolicate");
|
|
@@ -19,6 +20,15 @@ const symbolicate_1 = require("./symbolicate");
|
|
|
19
20
|
function loadFirebaseHttps() {
|
|
20
21
|
return require('firebase-functions/v2/https');
|
|
21
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* `bucket`, falling back to the deprecated `bucketName` with a warning. The new
|
|
25
|
+
* name wins when both are given, and the warning still fires — see #44.
|
|
26
|
+
*/
|
|
27
|
+
function resolveBucket(config) {
|
|
28
|
+
if (config.bucketName !== undefined)
|
|
29
|
+
(0, deprecate_1.warnDeprecated)('bucketName', 'bucket');
|
|
30
|
+
return config.bucket ?? config.bucketName;
|
|
31
|
+
}
|
|
22
32
|
const VALID_SEVERITIES = new Set(severity_1.SEVERITIES);
|
|
23
33
|
/**
|
|
24
34
|
* What the bare handler throws.
|
|
@@ -91,11 +101,12 @@ async function symbolicateError(releaseId, error, bucketName, prefix) {
|
|
|
91
101
|
* symbolicates stack traces, and writes structured entries to Cloud Logging.
|
|
92
102
|
*
|
|
93
103
|
* @example
|
|
94
|
-
* export const logFrontendEvent = onCall(createClientLogHandler({
|
|
104
|
+
* export const logFrontendEvent = onCall(createClientLogHandler({ bucket: 'my-bucket' }))
|
|
95
105
|
*/
|
|
96
106
|
function createClientLogHandler(config) {
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
const bucket = resolveBucket(config);
|
|
108
|
+
if (bucket)
|
|
109
|
+
(0, sourceMapCache_1.configureSourceMapBucket)(bucket);
|
|
99
110
|
return async (request) => {
|
|
100
111
|
const { message, severity, labels, jsonPayload } = request.data;
|
|
101
112
|
if (!message || !severity) {
|
|
@@ -109,7 +120,7 @@ function createClientLogHandler(config) {
|
|
|
109
120
|
let processedError = jsonPayload?.error;
|
|
110
121
|
if (processedError?.stack && !isEmulator) {
|
|
111
122
|
const releaseId = labels?.releaseId ?? 'unknown';
|
|
112
|
-
processedError = await symbolicateError(releaseId, processedError, config.sourceMaps?.bucket ??
|
|
123
|
+
processedError = await symbolicateError(releaseId, processedError, config.sourceMaps?.bucket ?? bucket, config.sourceMaps?.prefix);
|
|
113
124
|
}
|
|
114
125
|
(0, logger_1.writeLog)({
|
|
115
126
|
message,
|
|
@@ -117,6 +128,7 @@ function createClientLogHandler(config) {
|
|
|
117
128
|
labels: (0, logger_1.cleanLabels)(labels),
|
|
118
129
|
jsonPayload: { ...jsonPayload, error: processedError },
|
|
119
130
|
attachments: request.data.attachments,
|
|
131
|
+
timestamp: request.data.timestamp,
|
|
120
132
|
});
|
|
121
133
|
}
|
|
122
134
|
catch (err) {
|
|
@@ -130,7 +142,7 @@ function createClientLogHandler(config) {
|
|
|
130
142
|
* Use when you want a ready-to-export Cloud Function.
|
|
131
143
|
*
|
|
132
144
|
* @example
|
|
133
|
-
* export const logFrontendEvent = createClientLogFunction({
|
|
145
|
+
* export const logFrontendEvent = createClientLogFunction({ bucket: 'my-bucket' })
|
|
134
146
|
*/
|
|
135
147
|
function createClientLogFunction(config) {
|
|
136
148
|
const handler = createClientLogHandler(config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logHandler.js","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logHandler.js","sourceRoot":"","sources":["../../src/functions/logHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/functions/logger.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/functions/logger.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAmB,MAAM,iBAAiB,CAAC;AAQhF,KAAK,WAAW,GAAG,OAAO,aAAa,CAAC;AA+CxC;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAKrE;AAkKD,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAKD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAQ9D;AAoFD;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,UAAU,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE,IAAI,CAoON;AAaD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;eAuBrC,OAAO,WACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC5C,IAAI;oBAWI,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAC5C,IAAI;uBAEI,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAC5C,IAAI;qBAEI,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,YACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,gBACnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAC5C,IAAI;EAEV;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAG3D,YAAY,EAAE,WAAW,EAAE,CAAC"}
|