@kud/gh 0.13.0 → 0.14.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/inbox.d.ts +96 -7
- package/dist/inbox.d.ts.map +1 -1
- package/dist/inbox.js +180 -6
- package/dist/inbox.js.map +1 -1
- package/package.json +1 -1
package/dist/inbox.d.ts
CHANGED
|
@@ -127,18 +127,26 @@ export type InboxQueryOptions = {
|
|
|
127
127
|
* full first: 100 — ~11s 502, twice
|
|
128
128
|
* minimal first: 100 1 pt 2.1s 200
|
|
129
129
|
*
|
|
130
|
-
* The 502 is
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
130
|
+
* The 502 is a wall-clock refusal rather than a node-count one — cutting the
|
|
131
|
+
* review-thread window by 65% still 502s at ~11s — so `first: 50` is the
|
|
132
|
+
* ceiling with a foot over the line, and a full fragment cannot reach 99 at
|
|
133
|
+
* any window. A two-tier fetch can: the full shape at the default cap for the
|
|
134
|
+
* rows that get a verdict, then `{ shape: "minimal", limits: {
|
|
135
|
+
* reviewRequests: 100 } }` for the rest.
|
|
136
|
+
*
|
|
137
|
+
* This note used to name the SEARCH as what was timing out, and that was
|
|
138
|
+
* wrong in a way worth keeping visible: it made the fix look like "address
|
|
139
|
+
* the rows directly and the problem goes away". It does not. A `nodes(ids:)`
|
|
140
|
+
* lookup with the same selections dies at the same size and the same eleven
|
|
141
|
+
* seconds — see `HEALTH_BATCH_SIZE`, where it is measured. What the request
|
|
142
|
+
* came through was never the variable; how many nodes it had to expand was.
|
|
136
143
|
*
|
|
137
144
|
* A caller doing that owes the overflow rows an honest verdict. A minimal row
|
|
138
145
|
* carries no health, and health absent is not health `waiting` — see
|
|
139
146
|
* `computeHealth`'s note on why this set is all-or-nothing, and
|
|
140
147
|
* `@kud/gh-workflow`'s `whoseMove`, which answers `unknown` rather than
|
|
141
|
-
* guessing.
|
|
148
|
+
* guessing. `healthIdsFrom` / `buildHealthQueries` / `mergeHealth` are the
|
|
149
|
+
* third tier that pays that debt where the caller wants the verdicts.
|
|
142
150
|
*/
|
|
143
151
|
limits?: Partial<Record<InboxSource, number>>;
|
|
144
152
|
};
|
|
@@ -234,4 +242,85 @@ export type SourceCoverage = {
|
|
|
234
242
|
export declare const sourceCoverage: (data: any) => Partial<Record<InboxSource, SourceCoverage>>;
|
|
235
243
|
/** The sources whose rows are a sample rather than the set. */
|
|
236
244
|
export declare const truncatedSources: (data: any) => InboxSource[];
|
|
245
|
+
/**
|
|
246
|
+
* How many PR ids one health request may carry.
|
|
247
|
+
*
|
|
248
|
+
* The third tier's whole reason for existing, so it is a measurement rather than
|
|
249
|
+
* a taste. Measured 2026-09-09 on a live account with 102 matching review
|
|
250
|
+
* requests, asking for the real `PR_HEALTH` + `PR_CONVERSATION` selections by
|
|
251
|
+
* node id:
|
|
252
|
+
*
|
|
253
|
+
* nodes(ids:) 100 — ~11s 502, twice
|
|
254
|
+
* nodes(ids:) 50 28 pts 8.7s 200 (6,200 nodes)
|
|
255
|
+
* nodes(ids:) 25 14 pts 4.0s 200 (3,100 nodes)
|
|
256
|
+
* 4 × 25 in parallel 56 pts 6.0s wall 200 ×4
|
|
257
|
+
*
|
|
258
|
+
* WHICH CORRECTS THE NOTE ON `limits` ABOVE, and the correction is the useful
|
|
259
|
+
* half: the 502 at `first: 100` was read there as the SEARCH timing out at
|
|
260
|
+
* GitHub's proxy. It is not. A direct node lookup — no search index involved at
|
|
261
|
+
* all — fails identically, at the same size and the same eleven seconds. What
|
|
262
|
+
* dies is the resolver's wall clock expanding ~12,000 nodes of check rollups and
|
|
263
|
+
* review threads, whichever door the request came through. The search endpoint
|
|
264
|
+
* was innocent.
|
|
265
|
+
*
|
|
266
|
+
* So batching is the MECHANISM here, not an optimisation of it: a tier three
|
|
267
|
+
* that fired one 100-id request would reproduce the exact failure it exists to
|
|
268
|
+
* fix. Cost per PR is 0.56 points either way — GraphQL prices nodes, not
|
|
269
|
+
* requests — so splitting buys reliability at no extra budget, exactly as
|
|
270
|
+
* `INBOX_SOURCES_PER_QUERY` does one level up.
|
|
271
|
+
*/
|
|
272
|
+
export declare const HEALTH_BATCH_SIZE = 25;
|
|
273
|
+
/**
|
|
274
|
+
* PR node ids on this data that arrived WITHOUT the health selection.
|
|
275
|
+
*
|
|
276
|
+
* The filter is load-bearing rather than tidiness. A two-tier fetch merges the
|
|
277
|
+
* cheap overflow after the full rows precisely so a URL collision keeps the
|
|
278
|
+
* full one, which means a naive "every id here" would re-fetch the rows that
|
|
279
|
+
* already carry a verdict — on a 102-row account that is ~11 points bought to
|
|
280
|
+
* learn what tier one already answered.
|
|
281
|
+
*
|
|
282
|
+
* `sources` narrows it further, and a caller should use it: only the PR sources
|
|
283
|
+
* can be enriched at all, and the issue sources that truncate carry no health to
|
|
284
|
+
* begin with.
|
|
285
|
+
*/
|
|
286
|
+
export declare const healthIdsFrom: (data: any, sources?: readonly InboxSource[]) => string[];
|
|
287
|
+
/**
|
|
288
|
+
* One `nodes(ids:)` document carrying the health and conversation selections for
|
|
289
|
+
* PRs already identified elsewhere.
|
|
290
|
+
*
|
|
291
|
+
* BOTH fragments, and health alone would be a bug. `computeHealth`'s precedence
|
|
292
|
+
* reads `unresolvedThreads` out of `reviewThreads`, which lives in
|
|
293
|
+
* `PR_CONVERSATION` — so a health-only enrichment would report `waiting` on a PR
|
|
294
|
+
* with open threads, which is the silent wrong token this whole set is
|
|
295
|
+
* all-or-nothing to prevent, one layer down.
|
|
296
|
+
*
|
|
297
|
+
* It also costs almost nothing to include: `reviewThreads` is ~100 of the ~124
|
|
298
|
+
* nodes a PR drags, so the rest of the conversation rides along nearly free —
|
|
299
|
+
* and an enriched overflow row comes out FULLY equal to a tier-one row, with its
|
|
300
|
+
* last actor and activity age intact, rather than a second-class one carrying a
|
|
301
|
+
* token and no story behind it.
|
|
302
|
+
*/
|
|
303
|
+
export declare const buildHealthQuery: (ids: readonly string[]) => string;
|
|
304
|
+
/**
|
|
305
|
+
* The same, split into documents small enough to answer — to be issued in
|
|
306
|
+
* parallel and handed to `mergeHealth`.
|
|
307
|
+
*
|
|
308
|
+
* Prefer this to `buildHealthQuery` for anything but a handful of ids. See
|
|
309
|
+
* `HEALTH_BATCH_SIZE` for why the split is the mechanism.
|
|
310
|
+
*/
|
|
311
|
+
export declare const buildHealthQueries: (ids: readonly string[], batchSize?: number) => string[];
|
|
312
|
+
/**
|
|
313
|
+
* Merge tier-three health onto the rows that were fetched without it.
|
|
314
|
+
*
|
|
315
|
+
* By node id, and all-or-nothing per node — a batch that failed merges nothing,
|
|
316
|
+
* a node that merges nothing keeps no health keys, `healthOf` reads the absence
|
|
317
|
+
* and `whoseMove` answers `unknown`. The invariant holds by CONSTRUCTION rather
|
|
318
|
+
* than by a flag anyone has to remember to pass, which is the same reason
|
|
319
|
+
* `@kud/gh-workflow` tests presence instead of trusting its caller.
|
|
320
|
+
*
|
|
321
|
+
* Returns a new object; the input is not mutated, because a caller merging the
|
|
322
|
+
* enriched copy alongside the original relies on the original still being what
|
|
323
|
+
* it was.
|
|
324
|
+
*/
|
|
325
|
+
export declare const mergeHealth: (data: any, parts: readonly any[]) => any;
|
|
237
326
|
//# sourceMappingURL=inbox.d.ts.map
|
package/dist/inbox.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CASrD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAA;AAE3C,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,UAAU,GACV,YAAY,GACZ,gBAAgB,GAChB,SAAS,GACT,cAAc,CAAA;AAElB,oEAAoE;AACpE,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAS/C,CAAA;AAED,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAChC
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"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"}
|
package/dist/inbox.js
CHANGED
|
@@ -207,7 +207,7 @@ const SOURCES = {
|
|
|
207
207
|
myPRs: ({ scope, health, conversation }, first) => ` myPRs: search(query: "${scope}is:pr is:open author:@me", type: ISSUE, first: ${first}) {
|
|
208
208
|
issueCount
|
|
209
209
|
nodes { __typename ... on PullRequest {
|
|
210
|
-
number title createdAt url headRefName isDraft
|
|
210
|
+
id number title createdAt url headRefName isDraft
|
|
211
211
|
repository { nameWithOwner }
|
|
212
212
|
author { login }
|
|
213
213
|
${health}
|
|
@@ -217,7 +217,7 @@ const SOURCES = {
|
|
|
217
217
|
reviewRequests: ({ scope, health, conversation }, first) => ` reviewRequests: search(query: "${scope}is:pr is:open review-requested:@me", type: ISSUE, first: ${first}) {
|
|
218
218
|
issueCount
|
|
219
219
|
nodes { __typename ... on PullRequest {
|
|
220
|
-
number title createdAt url headRefName isDraft
|
|
220
|
+
id number title createdAt url headRefName isDraft
|
|
221
221
|
repository { nameWithOwner }
|
|
222
222
|
author { login }
|
|
223
223
|
${health}
|
|
@@ -227,7 +227,7 @@ const SOURCES = {
|
|
|
227
227
|
reviewed: ({ scope, health, conversation }, first) => ` reviewed: search(query: "${scope}is:pr is:open reviewed-by:@me -author:@me -review-requested:@me", type: ISSUE, first: ${first}) {
|
|
228
228
|
issueCount
|
|
229
229
|
nodes { __typename ... on PullRequest {
|
|
230
|
-
number title createdAt url headRefName isDraft
|
|
230
|
+
id number title createdAt url headRefName isDraft
|
|
231
231
|
repository { nameWithOwner }
|
|
232
232
|
author { login }
|
|
233
233
|
${health}
|
|
@@ -244,7 +244,7 @@ const SOURCES = {
|
|
|
244
244
|
${issueLabels}
|
|
245
245
|
}
|
|
246
246
|
... on PullRequest {
|
|
247
|
-
number title createdAt url headRefName isDraft repository { nameWithOwner } author { login }
|
|
247
|
+
id number title createdAt url headRefName isDraft repository { nameWithOwner } author { login }
|
|
248
248
|
${health}
|
|
249
249
|
${conversation}
|
|
250
250
|
}
|
|
@@ -301,7 +301,7 @@ const SOURCES = {
|
|
|
301
301
|
repoPRs: ({ scope, owned, health, conversation }, first) => ` repoPRs: search(query: "${scope}${owned}is:pr is:open -author:@me archived:false", type: ISSUE, first: ${first}) {
|
|
302
302
|
issueCount
|
|
303
303
|
nodes { __typename ... on PullRequest {
|
|
304
|
-
number title createdAt url headRefName isDraft
|
|
304
|
+
id number title createdAt url headRefName isDraft
|
|
305
305
|
repository { nameWithOwner }
|
|
306
306
|
author { login }
|
|
307
307
|
${health}
|
|
@@ -311,7 +311,7 @@ const SOURCES = {
|
|
|
311
311
|
recentlyDone: ({ scope, doneSince }, first) => ` recentlyDone: search(query: "${scope}is:pr author:@me -is:open closed:>=${doneSince}", type: ISSUE, first: ${first}) {
|
|
312
312
|
issueCount
|
|
313
313
|
nodes { __typename ... on PullRequest {
|
|
314
|
-
number title state isDraft createdAt mergedAt closedAt url
|
|
314
|
+
id number title state isDraft createdAt mergedAt closedAt url
|
|
315
315
|
repository { nameWithOwner }
|
|
316
316
|
}}
|
|
317
317
|
}`,
|
|
@@ -492,4 +492,178 @@ export const sourceCoverage = (data) => {
|
|
|
492
492
|
};
|
|
493
493
|
/** The sources whose rows are a sample rather than the set. */
|
|
494
494
|
export const truncatedSources = (data) => INBOX_SOURCES.filter((source) => sourceCoverage(data)[source]?.truncated);
|
|
495
|
+
/**
|
|
496
|
+
* How many PR ids one health request may carry.
|
|
497
|
+
*
|
|
498
|
+
* The third tier's whole reason for existing, so it is a measurement rather than
|
|
499
|
+
* a taste. Measured 2026-09-09 on a live account with 102 matching review
|
|
500
|
+
* requests, asking for the real `PR_HEALTH` + `PR_CONVERSATION` selections by
|
|
501
|
+
* node id:
|
|
502
|
+
*
|
|
503
|
+
* nodes(ids:) 100 — ~11s 502, twice
|
|
504
|
+
* nodes(ids:) 50 28 pts 8.7s 200 (6,200 nodes)
|
|
505
|
+
* nodes(ids:) 25 14 pts 4.0s 200 (3,100 nodes)
|
|
506
|
+
* 4 × 25 in parallel 56 pts 6.0s wall 200 ×4
|
|
507
|
+
*
|
|
508
|
+
* WHICH CORRECTS THE NOTE ON `limits` ABOVE, and the correction is the useful
|
|
509
|
+
* half: the 502 at `first: 100` was read there as the SEARCH timing out at
|
|
510
|
+
* GitHub's proxy. It is not. A direct node lookup — no search index involved at
|
|
511
|
+
* all — fails identically, at the same size and the same eleven seconds. What
|
|
512
|
+
* dies is the resolver's wall clock expanding ~12,000 nodes of check rollups and
|
|
513
|
+
* review threads, whichever door the request came through. The search endpoint
|
|
514
|
+
* was innocent.
|
|
515
|
+
*
|
|
516
|
+
* So batching is the MECHANISM here, not an optimisation of it: a tier three
|
|
517
|
+
* that fired one 100-id request would reproduce the exact failure it exists to
|
|
518
|
+
* fix. Cost per PR is 0.56 points either way — GraphQL prices nodes, not
|
|
519
|
+
* requests — so splitting buys reliability at no extra budget, exactly as
|
|
520
|
+
* `INBOX_SOURCES_PER_QUERY` does one level up.
|
|
521
|
+
*/
|
|
522
|
+
export const HEALTH_BATCH_SIZE = 25;
|
|
523
|
+
/*
|
|
524
|
+
* A node the health fragment was never asked for.
|
|
525
|
+
*
|
|
526
|
+
* Tested on `reviewDecision` alone, and that is sound rather than sloppy: the
|
|
527
|
+
* selection is dropped WHOLE (see `PR_HEALTH`), so one key's absence is the
|
|
528
|
+
* whole set's absence. `@kud/gh-workflow`'s `hasHealthSelection` tests all three
|
|
529
|
+
* with `||` for a different job — it guards against a caller who built the node
|
|
530
|
+
* by hand — and importing it here is not available anyway, since the flow runs
|
|
531
|
+
* this way and not back.
|
|
532
|
+
*/
|
|
533
|
+
const lacksHealth = (node) => Boolean(node) && !("reviewDecision" in node);
|
|
534
|
+
/*
|
|
535
|
+
* Rows whose verdict is already settled without the selection, and which
|
|
536
|
+
* therefore buy nothing by being enriched: `computeHealth` short-circuits on
|
|
537
|
+
* `state` and `isDraft` before it reads a single check.
|
|
538
|
+
*
|
|
539
|
+
* A COST filter, not a correctness one — merging health onto a merged PR changes
|
|
540
|
+
* no answer, it just spends 0.56 points to learn something already known.
|
|
541
|
+
*/
|
|
542
|
+
const settledWithoutHealth = (node) => node?.state === "MERGED" || node?.state === "CLOSED" || node?.isDraft === true;
|
|
543
|
+
/**
|
|
544
|
+
* PR node ids on this data that arrived WITHOUT the health selection.
|
|
545
|
+
*
|
|
546
|
+
* The filter is load-bearing rather than tidiness. A two-tier fetch merges the
|
|
547
|
+
* cheap overflow after the full rows precisely so a URL collision keeps the
|
|
548
|
+
* full one, which means a naive "every id here" would re-fetch the rows that
|
|
549
|
+
* already carry a verdict — on a 102-row account that is ~11 points bought to
|
|
550
|
+
* learn what tier one already answered.
|
|
551
|
+
*
|
|
552
|
+
* `sources` narrows it further, and a caller should use it: only the PR sources
|
|
553
|
+
* can be enriched at all, and the issue sources that truncate carry no health to
|
|
554
|
+
* begin with.
|
|
555
|
+
*/
|
|
556
|
+
export const healthIdsFrom = (data, sources) => {
|
|
557
|
+
const ids = [];
|
|
558
|
+
if (!data)
|
|
559
|
+
return ids;
|
|
560
|
+
for (const source of sources ?? INBOX_SOURCES)
|
|
561
|
+
for (const node of data[source]?.nodes ?? []) {
|
|
562
|
+
if (node?.__typename !== "PullRequest")
|
|
563
|
+
continue;
|
|
564
|
+
if (typeof node.id !== "string")
|
|
565
|
+
continue;
|
|
566
|
+
if (!lacksHealth(node) || settledWithoutHealth(node))
|
|
567
|
+
continue;
|
|
568
|
+
ids.push(node.id);
|
|
569
|
+
}
|
|
570
|
+
return [...new Set(ids)];
|
|
571
|
+
};
|
|
572
|
+
/**
|
|
573
|
+
* One `nodes(ids:)` document carrying the health and conversation selections for
|
|
574
|
+
* PRs already identified elsewhere.
|
|
575
|
+
*
|
|
576
|
+
* BOTH fragments, and health alone would be a bug. `computeHealth`'s precedence
|
|
577
|
+
* reads `unresolvedThreads` out of `reviewThreads`, which lives in
|
|
578
|
+
* `PR_CONVERSATION` — so a health-only enrichment would report `waiting` on a PR
|
|
579
|
+
* with open threads, which is the silent wrong token this whole set is
|
|
580
|
+
* all-or-nothing to prevent, one layer down.
|
|
581
|
+
*
|
|
582
|
+
* It also costs almost nothing to include: `reviewThreads` is ~100 of the ~124
|
|
583
|
+
* nodes a PR drags, so the rest of the conversation rides along nearly free —
|
|
584
|
+
* and an enriched overflow row comes out FULLY equal to a tier-one row, with its
|
|
585
|
+
* last actor and activity age intact, rather than a second-class one carrying a
|
|
586
|
+
* token and no story behind it.
|
|
587
|
+
*/
|
|
588
|
+
export const buildHealthQuery = (ids) => `
|
|
589
|
+
{
|
|
590
|
+
rateLimit { cost nodeCount remaining resetAt }
|
|
591
|
+
nodes(ids: [${ids.map((id) => JSON.stringify(id)).join(", ")}]) {
|
|
592
|
+
__typename
|
|
593
|
+
... on PullRequest {
|
|
594
|
+
id
|
|
595
|
+
${PR_HEALTH}
|
|
596
|
+
${PR_CONVERSATION}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
`;
|
|
601
|
+
/**
|
|
602
|
+
* The same, split into documents small enough to answer — to be issued in
|
|
603
|
+
* parallel and handed to `mergeHealth`.
|
|
604
|
+
*
|
|
605
|
+
* Prefer this to `buildHealthQuery` for anything but a handful of ids. See
|
|
606
|
+
* `HEALTH_BATCH_SIZE` for why the split is the mechanism.
|
|
607
|
+
*/
|
|
608
|
+
export const buildHealthQueries = (ids, batchSize = HEALTH_BATCH_SIZE) => {
|
|
609
|
+
const size = Math.max(1, Math.trunc(batchSize));
|
|
610
|
+
const queries = [];
|
|
611
|
+
for (let i = 0; i < ids.length; i += size)
|
|
612
|
+
queries.push(buildHealthQuery(ids.slice(i, i + size)));
|
|
613
|
+
return queries;
|
|
614
|
+
};
|
|
615
|
+
/*
|
|
616
|
+
* Every health key, and the rollup non-null.
|
|
617
|
+
*
|
|
618
|
+
* GraphQL can answer 200 with `errors` and null fields, and a node arriving with
|
|
619
|
+
* `reviewDecision` present but `statusCheckRollup: null` is the one shape that
|
|
620
|
+
* defeats the guard downstream: `hasHealthSelection` would read true on the
|
|
621
|
+
* first key while `computeHealth` saw zero checks and returned `waiting`. A
|
|
622
|
+
* confident wrong answer, through the only door left open.
|
|
623
|
+
*
|
|
624
|
+
* So the test is per NODE rather than per response. A partial answer should
|
|
625
|
+
* degrade to fewer verdicts, never to a wrong one.
|
|
626
|
+
*/
|
|
627
|
+
const carriesHealth = (node) => Boolean(node) &&
|
|
628
|
+
"reviewDecision" in node &&
|
|
629
|
+
"mergeable" in node &&
|
|
630
|
+
node.statusCheckRollup != null;
|
|
631
|
+
/**
|
|
632
|
+
* Merge tier-three health onto the rows that were fetched without it.
|
|
633
|
+
*
|
|
634
|
+
* By node id, and all-or-nothing per node — a batch that failed merges nothing,
|
|
635
|
+
* a node that merges nothing keeps no health keys, `healthOf` reads the absence
|
|
636
|
+
* and `whoseMove` answers `unknown`. The invariant holds by CONSTRUCTION rather
|
|
637
|
+
* than by a flag anyone has to remember to pass, which is the same reason
|
|
638
|
+
* `@kud/gh-workflow` tests presence instead of trusting its caller.
|
|
639
|
+
*
|
|
640
|
+
* Returns a new object; the input is not mutated, because a caller merging the
|
|
641
|
+
* enriched copy alongside the original relies on the original still being what
|
|
642
|
+
* it was.
|
|
643
|
+
*/
|
|
644
|
+
export const mergeHealth = (data, parts) => {
|
|
645
|
+
if (!data)
|
|
646
|
+
return data;
|
|
647
|
+
const byId = new Map();
|
|
648
|
+
for (const part of parts)
|
|
649
|
+
for (const node of part?.nodes ?? [])
|
|
650
|
+
if (typeof node?.id === "string" && carriesHealth(node))
|
|
651
|
+
byId.set(node.id, node);
|
|
652
|
+
if (byId.size === 0)
|
|
653
|
+
return data;
|
|
654
|
+
const out = { ...data };
|
|
655
|
+
for (const source of INBOX_SOURCES) {
|
|
656
|
+
const answered = data[source];
|
|
657
|
+
if (!answered?.nodes)
|
|
658
|
+
continue;
|
|
659
|
+
out[source] = {
|
|
660
|
+
...answered,
|
|
661
|
+
nodes: answered.nodes.map((node) => {
|
|
662
|
+
const found = typeof node?.id === "string" ? byId.get(node.id) : undefined;
|
|
663
|
+
return found ? { ...node, ...found } : node;
|
|
664
|
+
}),
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
return out;
|
|
668
|
+
};
|
|
495
669
|
//# sourceMappingURL=inbox.js.map
|
package/dist/inbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,YAAY;AACZ,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,uDAAuD;AAEvD;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,KAAK,EAAE,YAAY;IACnB,cAAc,EAAE,EAAE;IAClB,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,GAAG;IACf,cAAc,EAAE,GAAG;IACnB,OAAO,EAAE,EAAE;IACX,YAAY,EAAE,EAAE;CACjB,CAAA;AAeD,oEAAoE;AACpE,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,OAAO;IACP,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,YAAY;IACZ,gBAAgB;IAChB,SAAS;IACT,cAAc;CACf,CAAA;
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,YAAY;AACZ,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,uDAAuD;AAEvD;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,KAAK,EAAE,YAAY;IACnB,cAAc,EAAE,EAAE;IAClB,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,GAAG;IACf,cAAc,EAAE,GAAG;IACnB,OAAO,EAAE,EAAE;IACX,YAAY,EAAE,EAAE;CACjB,CAAA;AAeD,oEAAoE;AACpE,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,OAAO;IACP,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,YAAY;IACZ,gBAAgB;IAChB,SAAS;IACT,cAAc;CACf,CAAA;AAkED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,UAA6B,EAAE,EACF,EAAE;IAC/B,MAAM,MAAM,GAAG,EAAE,GAAG,aAAa,EAAE,CAAA;IACnC,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAA;QACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,mEAAmE;AACnE,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,yBAAyB;AACzB,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,2EAA2E;AAC3E,qBAAqB;AACrB,MAAM,SAAS,GAAG;;;;;YAKN,CAAA;AAEZ,6EAA6E;AAC7E,gFAAgF;AAChF,8EAA8E;AAC9E,2DAA2D;AAC3D,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,+DAA+D;AAC/D,EAAE;AACF,4EAA4E;AAC5E,wEAAwE;AACxE,gFAAgF;AAChF,uEAAuE;AACvE,gFAAgF;AAChF,8EAA8E;AAC9E,yEAAyE;AACzE,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,8EAA8E;AAC9E,sEAAsE;AACtE,iFAAiF;AACjF,yEAAyE;AACzE,MAAM,eAAe,GAAG;;;;;;;;8DAQsC,CAAA;AAE9D,MAAM,kBAAkB,GAAG;uFAC4D,CAAA;AAEvF,+EAA+E;AAC/E,qEAAqE;AACrE,MAAM,YAAY,GAAG;2CACsB,CAAA;AAE3C;;;;;GAKG;AACH,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAChC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAavE;;;;;GAKG;AACH,MAAM,OAAO,GAAkE;IAC7E,KAAK,EAAE,CACL,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAC/B,KAAK,EACL,EAAE,CAAC,2BAA2B,KAAK,kDAAkD,KAAK;;;;;;QAMtF,MAAM;QACN,YAAY;;IAEhB;IAEF,cAAc,EAAE,CACd,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAC/B,KAAK,EACL,EAAE,CAAC,oCAAoC,KAAK,4DAA4D,KAAK;;;;;;QAMzG,MAAM;QACN,YAAY;;IAEhB;IAEF,QAAQ,EAAE,CACR,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAC/B,KAAK,EACL,EAAE,CAAC,8BAA8B,KAAK,yFAAyF,KAAK;;;;;;QAMhI,MAAM;QACN,YAAY;;IAEhB;IAEF,QAAQ,EAAE,CACR,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,EAC/D,KAAK,EACL,EAAE,CAAC,8BAA8B,KAAK,8CAA8C,KAAK;;;;;;UAMnF,iBAAiB;UACjB,WAAW;;;;UAIX,MAAM;UACN,YAAY;;;IAGlB;IAEF,UAAU,EAAE,CACV,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,EAChD,KAAK,EACL,EAAE,CAAC,gCAAgC,KAAK,GAAG,KAAK,yDAAyD,KAAK;;;;;;QAM1G,iBAAiB;QACjB,WAAW;;IAEf;IAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,EAAE,CACd,EAAE,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,EACzC,KAAK,EACL,EAAE,CAAC,oCAAoC,KAAK,8EAA8E,KAAK;;;;;;QAM3H,iBAAiB;QACjB,WAAW;;IAEf;IAEF,OAAO,EAAE,CACP,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EACtC,KAAK,EACL,EAAE,CAAC,6BAA6B,KAAK,GAAG,KAAK,kEAAkE,KAAK;;;;;;QAMhH,MAAM;QACN,YAAY;;IAEhB;IAEF,YAAY,EAAE,CACZ,EAAE,KAAK,EAAE,SAAS,EAAE,EACpB,KAAK,EACL,EAAE,CAAC,kCAAkC,KAAK,sCAAsC,SAAS,0BAA0B,KAAK;;;;;;IAMxH;CACH,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,EACrB,IAAI,EACJ,cAAc,GAAG,EAAE,EACnB,KAAK,GAAG,MAAM,GACI,EAAc,EAAE;IAClC;yEACqE;IACrE,MAAM,IAAI,GAAG,KAAK,KAAK,MAAM,CAAA;IAC7B,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE;QAClC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW;QAC9B,SAAS,EAAE,QAAQ,CAAC,cAAc,CAAC;QACnC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;QAC7B,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE;QACzC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;QACjD,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;KACtC,CAAA;AACH,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,GAAG,CAAC,OAA0B,EAA0B,EAAE;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,aAAa,CAAA;IAChD,OAAO,OAAO,CAAC,IAAI;QACjB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,gBAAgB,CAAC;QACzD,CAAC,CAAC,OAAO,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,UAA6B,EAAE,EAAE,EAAE;IACjE,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACzC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAEjC;;;;;;;;;OASG;IACH,OAAO;;;;EAIP,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;CAEhF,CAAA;AACD,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,UAA4D,EAAE,EACpD,EAAE;IACZ,MAAM,EAAE,eAAe,GAAG,uBAAuB,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAA;IAC9E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAA;IAErD,MAAM,MAAM,GAAoB,EAAE,CAAA;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI;QAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAkB,CAAC,CAAA;IAE1D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,eAAe,CAAC,EAAE,GAAG,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CACrD,CAAA;AACH,CAAC,CAAA;AASD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAY,EAAO,EAAE;IAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAE3C,MAAM,MAAM,GAAqB,QAAQ;SACtC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;SAC7B,MAAM,CAAC,OAAO,CAAC,CAAA;IAElB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAC5B,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAChB,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAChE,SAAS,CACV,CAAA;IAED,OAAO;QACL,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC;QACjC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM;QACpD,GAAG,CAAC,QAAQ;YACV,CAAC,CAAC;gBACE,SAAS,EAAE;oBACT,GAAG,QAAQ;oBACX,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC3D,SAAS,EAAE,MAAM,CAAC,MAAM,CACtB,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EACxC,CAAC,CACF;iBACF;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAA;AACH,CAAC,CAAA;AAYD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,IAAS,EACqC,EAAE;IAChD,MAAM,GAAG,GAAiD,EAAE,CAAA;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAA;IAErB,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,IAAI,CAAC,QAAQ;YAAE,SAAQ;QACvB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAA;QACzC,MAAM,KAAK,GACT,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAA;QACvE,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,KAAK,EAAE,CAAA;IAC1D,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAS,EAAiB,EAAE,CAC3D,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC;;;;;;;;;GASG;AACH,MAAM,WAAW,GAAG,CAAC,IAAS,EAAW,EAAE,CACzC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAA;AAE9C;;;;;;;GAOG;AACH,MAAM,oBAAoB,GAAG,CAAC,IAAS,EAAW,EAAE,CAClD,IAAI,EAAE,KAAK,KAAK,QAAQ,IAAI,IAAI,EAAE,KAAK,KAAK,QAAQ,IAAI,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,IAAS,EACT,OAAgC,EACtB,EAAE;IACZ,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAA;IAErB,KAAK,MAAM,MAAM,IAAI,OAAO,IAAI,aAAa;QAC3C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,EAAE,UAAU,KAAK,aAAa;gBAAE,SAAQ;YAChD,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;gBAAE,SAAQ;YACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC;gBAAE,SAAQ;YAC9D,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACnB,CAAC;IAEH,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AAC1B,CAAC,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAsB,EAAE,EAAE,CAAC;;;gBAG5C,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;QAItD,SAAS;QACT,eAAe;;;;CAItB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,GAAsB,EACtB,YAAoB,iBAAiB,EAC3B,EAAE;IACZ,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IAC/C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI;QACvC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;IACxD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,aAAa,GAAG,CAAC,IAAS,EAAW,EAAE,CAC3C,OAAO,CAAC,IAAI,CAAC;IACb,gBAAgB,IAAI,IAAI;IACxB,WAAW,IAAI,IAAI;IACnB,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAA;AAEhC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAS,EAAE,KAAqB,EAAO,EAAE;IACnE,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IAEtB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAe,CAAA;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK;QACtB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE;YAClC,IAAI,OAAO,IAAI,EAAE,EAAE,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC;gBACrD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAE7B,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEhC,MAAM,GAAG,GAAQ,EAAE,GAAG,IAAI,EAAE,CAAA;IAC5B,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;QAC7B,IAAI,CAAC,QAAQ,EAAE,KAAK;YAAE,SAAQ;QAC9B,GAAG,CAAC,MAAM,CAAC,GAAG;YACZ,GAAG,QAAQ;YACX,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE;gBACtC,MAAM,KAAK,GACT,OAAO,IAAI,EAAE,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;gBAC9D,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;YAC7C,CAAC,CAAC;SACH,CAAA;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
|