@aglyn/plugins-outreach 1.0.0-beta.152 → 1.0.0-beta.154
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 +5 -1
- package/package.json +12 -12
- package/src/lib/components/enroll-dialog.js +142 -32
- package/src/lib/components/enroll-dialog.js.map +1 -1
- package/src/lib/components/enrollments-table.js +37 -8
- package/src/lib/components/enrollments-table.js.map +1 -1
- package/src/lib/components/mailbox-card.d.ts +1 -0
- package/src/lib/components/mailbox-card.js +25 -5
- package/src/lib/components/mailbox-card.js.map +1 -1
- package/src/lib/components/use-outreach-crm.d.ts +20 -1
- package/src/lib/components/use-outreach-crm.js +78 -4
- package/src/lib/components/use-outreach-crm.js.map +1 -1
- package/src/lib/declarations.console-server.js +14 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/engine/enrollment-state.d.ts +6 -1
- package/src/lib/engine/enrollment-state.js +3 -1
- package/src/lib/engine/enrollment-state.js.map +1 -1
- package/src/lib/enrollment/enroll-people.d.ts +52 -7
- package/src/lib/enrollment/enroll-people.js +109 -12
- package/src/lib/enrollment/enroll-people.js.map +1 -1
- package/src/lib/enrollment/gate-lookups.d.ts +12 -3
- package/src/lib/enrollment/gate-lookups.js +17 -14
- package/src/lib/enrollment/gate-lookups.js.map +1 -1
- package/src/lib/mailboxes/mailbox-api.d.ts +6 -0
- package/src/lib/mailboxes/mailbox-api.js.map +1 -1
- package/src/lib/mailboxes/mailbox-routes.js +11 -0
- package/src/lib/mailboxes/mailbox-routes.js.map +1 -1
- package/src/lib/model/outreach-api.d.ts +39 -8
- package/src/lib/model/outreach-api.js.map +1 -1
- package/src/lib/model/outreach.types.d.ts +28 -3
- package/src/lib/model/outreach.types.js +9 -0
- package/src/lib/model/outreach.types.js.map +1 -1
- package/src/lib/model/stored-records.js +7 -0
- package/src/lib/model/stored-records.js.map +1 -1
- package/src/lib/routes/enroll-routes.js +112 -39
- package/src/lib/routes/enroll-routes.js.map +1 -1
- package/src/lib/routes/preview-routes.js +18 -5
- package/src/lib/routes/preview-routes.js.map +1 -1
- package/src/lib/runtime/lead-records.d.ts +26 -0
- package/src/lib/runtime/lead-records.js +84 -0
- package/src/lib/runtime/lead-records.js.map +1 -0
- package/src/lib/runtime/send-job.js +30 -12
- package/src/lib/runtime/send-job.js.map +1 -1
- package/src/lib/runtime/sync-job.js +11 -3
- package/src/lib/runtime/sync-job.js.map +1 -1
- package/src/lib/runtime/timeline.d.ts +6 -4
- package/src/lib/runtime/timeline.js +3 -7
- package/src/lib/runtime/timeline.js.map +1 -1
- package/src/lib/storage/outreach-records.d.ts +21 -2
- package/src/lib/storage/outreach-records.js +31 -2
- package/src/lib/storage/outreach-records.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/runtime/timeline.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n PluginRecordTaskKind,\n PluginRecordWrite,\n} from '@aglyn/aglyn/plugin-manager/plugin-record-timeline'\nimport { OUTREACH_PLUGIN_ID } from '../constants/bundle-common'\nimport type { OutreachTaskKind } from '../model/outreach.types'\nimport type { OutreachRuntimeDeps } from './runtime-deps'\n\n/**\n * OUTREACH ON THE CONTACT'S TIMELINE (AGL-2981).\n *\n * Every email a sequence sends, every reply it reads, and every task it\n * asks of the rep goes onto the contact's record through the core's\n * record-timeline seam — whichever plugin keeps the workspace's records —\n * never by writing that plugin's documents. An email is filed once per\n * `Message-ID`, under the id the capture address would file a forwarded copy\n * by; a task once per the key given here.\n *\n * The timeline is bookkeeping beside the act: an email has already left\n * when it is filed, so a writer that refuses or fails is logged and the\n * send stands. A workspace with no record system files nothing.\n */\n\n/** The record system's word for a step's task kind. */\nexport const OUTREACH_TASK_KIND_TO_RECORD: Record<OutreachTaskKind, PluginRecordTaskKind> = {\n call: 'call',\n linkedin: 'todo',\n todo: 'todo',\n}\n\n/** Files one email on a contact; never throws. */\nexport async function fileOutreachEmail(\n deps: Pick<OutreachRuntimeDeps, 'timeline'>,\n input: {\n orgId: string\n hostId: string\n contactId:
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/runtime/timeline.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n PluginRecordLink,\n PluginRecordTaskKind,\n PluginRecordWrite,\n} from '@aglyn/aglyn/plugin-manager/plugin-record-timeline'\nimport { OUTREACH_PLUGIN_ID } from '../constants/bundle-common'\nimport type { OutreachTaskKind } from '../model/outreach.types'\nimport type { OutreachRuntimeDeps } from './runtime-deps'\n\n/**\n * OUTREACH ON THE CONTACT'S TIMELINE (AGL-2981).\n *\n * Every email a sequence sends, every reply it reads, and every task it\n * asks of the rep goes onto the contact's record through the core's\n * record-timeline seam — whichever plugin keeps the workspace's records —\n * never by writing that plugin's documents. An email is filed once per\n * `Message-ID`, under the id the capture address would file a forwarded copy\n * by; a task once per the key given here.\n *\n * The timeline is bookkeeping beside the act: an email has already left\n * when it is filed, so a writer that refuses or fails is logged and the\n * send stands. A workspace with no record system files nothing.\n */\n\n/** The record system's word for a step's task kind. */\nexport const OUTREACH_TASK_KIND_TO_RECORD: Record<OutreachTaskKind, PluginRecordTaskKind> = {\n call: 'call',\n linkedin: 'todo',\n todo: 'todo',\n}\n\n/** Files one email on a person's record — the contact, or the lead while they are one (AGL-3234); never throws. */\nexport async function fileOutreachEmail(\n deps: Pick<OutreachRuntimeDeps, 'timeline'>,\n input: {\n orgId: string\n hostId: string\n /** The record the entry lands on: `{ contactId }` or `{ leadId }`. */\n link: PluginRecordLink\n direction: 'outbound' | 'inbound'\n subject: string\n from: string\n to: string | null\n messageId: string\n inReplyTo?: string | null\n body: string\n atMs: number\n byUid: string\n byName?: string | null\n },\n): Promise<PluginRecordWrite | null> {\n const writer = deps.timeline()\n if (!writer) return null\n try {\n const written = await writer.logActivity({\n orgId: input.orgId,\n hostId: input.hostId,\n link: input.link,\n sourcePluginId: OUTREACH_PLUGIN_ID,\n kind: 'email',\n atMs: input.atMs,\n body: input.body,\n byUid: input.byUid,\n byName: input.byName ?? null,\n email: {\n direction: input.direction,\n subject: input.subject,\n from: input.from,\n to: input.to,\n messageId: input.messageId,\n inReplyTo: input.inReplyTo ?? null,\n },\n })\n if (written.ok === false) console.warn(`[outreach] the record system did not file an email: ${written.error}`)\n return written\n } catch (error) {\n console.error('[outreach] filing an email on the record failed', error)\n return null\n }\n}\n\n/**\n * Files one task on a contact. Answers the record system's answer, `null`\n * when the workspace keeps no records; a writer that THROWS is the caller's,\n * which a step waits out rather than completing without its task.\n */\nexport async function fileOutreachTask(\n deps: Pick<OutreachRuntimeDeps, 'timeline'>,\n input: {\n orgId: string\n hostId: string\n /** The record the task lands on: `{ contactId }` or `{ leadId }`. */\n link: PluginRecordLink\n dedupeKey: string\n title: string\n notes?: string | null\n kind: PluginRecordTaskKind\n dueAtMs: number\n assigneeUid: string\n },\n): Promise<PluginRecordWrite | null> {\n const writer = deps.timeline()\n if (!writer) return null\n return writer.createTask({\n orgId: input.orgId,\n hostId: input.hostId,\n link: input.link,\n sourcePluginId: OUTREACH_PLUGIN_ID,\n dedupeKey: input.dedupeKey,\n title: input.title,\n notes: input.notes ?? null,\n kind: input.kind,\n dueAtMs: input.dueAtMs,\n assigneeUid: input.assigneeUid,\n createdByUid: '',\n })\n}\n"],"names":["OUTREACH_PLUGIN_ID","OUTREACH_TASK_KIND_TO_RECORD","call","linkedin","todo","fileOutreachEmail","deps","input","writer","timeline","written","logActivity","orgId","hostId","link","sourcePluginId","kind","atMs","body","byUid","byName","email","direction","subject","from","to","messageId","inReplyTo","ok","console","warn","error","fileOutreachTask","createTask","dedupeKey","title","notes","dueAtMs","assigneeUid","createdByUid"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAOD,SAASA,kBAAkB,QAAQ,gCAA4B;AAI/D;;;;;;;;;;;;;CAaC,GAED,qDAAqD,GACrD,OAAO,MAAMC,+BAA+E;IAC1FC,MAAM;IACNC,UAAU;IACVC,MAAM;AACR,EAAC;AAED,iHAAiH,GACjH,OAAO,eAAeC,kBACpBC,IAA2C,EAC3CC,KAeC;IAED,MAAMC,SAASF,KAAKG,QAAQ;IAC5B,IAAI,CAACD,QAAQ,OAAO;IACpB,IAAI;YAUQD,eAOKA;QAhBf,MAAMG,UAAU,MAAMF,OAAOG,WAAW,CAAC;YACvCC,OAAOL,MAAMK,KAAK;YAClBC,QAAQN,MAAMM,MAAM;YACpBC,MAAMP,MAAMO,IAAI;YAChBC,gBAAgBf;YAChBgB,MAAM;YACNC,MAAMV,MAAMU,IAAI;YAChBC,MAAMX,MAAMW,IAAI;YAChBC,OAAOZ,MAAMY,KAAK;YAClBC,MAAM,GAAEb,gBAAAA,MAAMa,MAAM,YAAZb,gBAAgB;YACxBc,OAAO;gBACLC,WAAWf,MAAMe,SAAS;gBAC1BC,SAAShB,MAAMgB,OAAO;gBACtBC,MAAMjB,MAAMiB,IAAI;gBAChBC,IAAIlB,MAAMkB,EAAE;gBACZC,WAAWnB,MAAMmB,SAAS;gBAC1BC,SAAS,GAAEpB,mBAAAA,MAAMoB,SAAS,YAAfpB,mBAAmB;YAChC;QACF;QACA,IAAIG,QAAQkB,EAAE,KAAK,OAAOC,QAAQC,IAAI,CAAC,CAAC,oDAAoD,EAAEpB,QAAQqB,KAAK,EAAE;QAC7G,OAAOrB;IACT,EAAE,OAAOqB,OAAO;QACdF,QAAQE,KAAK,CAAC,mDAAmDA;QACjE,OAAO;IACT;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeC,iBACpB1B,IAA2C,EAC3CC,KAWC;QAWQA;IATT,MAAMC,SAASF,KAAKG,QAAQ;IAC5B,IAAI,CAACD,QAAQ,OAAO;IACpB,OAAOA,OAAOyB,UAAU,CAAC;QACvBrB,OAAOL,MAAMK,KAAK;QAClBC,QAAQN,MAAMM,MAAM;QACpBC,MAAMP,MAAMO,IAAI;QAChBC,gBAAgBf;QAChBkC,WAAW3B,MAAM2B,SAAS;QAC1BC,OAAO5B,MAAM4B,KAAK;QAClBC,KAAK,GAAE7B,eAAAA,MAAM6B,KAAK,YAAX7B,eAAe;QACtBS,MAAMT,MAAMS,IAAI;QAChBqB,SAAS9B,MAAM8B,OAAO;QACtBC,aAAa/B,MAAM+B,WAAW;QAC9BC,cAAc;IAChB;AACF"}
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
* document reads back into its model shape through `model/stored-records`,
|
|
21
21
|
* re-exported here for the routes.
|
|
22
22
|
*/
|
|
23
|
-
import {
|
|
23
|
+
import type { OutreachPersonRef } from '../model/outreach-api';
|
|
24
|
+
import { type OutreachEnrollment, type OutreachOrgCollection } from '../model/outreach.types';
|
|
24
25
|
export { readStoredOutreachEnrollment, readStoredOutreachMailbox, readStoredOutreachSequence, } from '../model/stored-records';
|
|
25
26
|
/** `orgs/{orgId}/<collection>` for one of Outreach's org-scoped collections. */
|
|
26
27
|
export declare function outreachOrgCollection(firestore: FirebaseFirestore.Firestore, orgId: string, collection: OutreachOrgCollection): FirebaseFirestore.CollectionReference;
|
|
@@ -29,5 +30,23 @@ export declare function outreachOrgCollection(firestore: FirebaseFirestore.Fires
|
|
|
29
30
|
* person is enrolled in a sequence once, ever: a second enroll finds the
|
|
30
31
|
* first document where a random id would have made a second, and a second
|
|
31
32
|
* run through the same emails is exactly what must not happen.
|
|
33
|
+
*
|
|
34
|
+
* `personId` is the contact's document id, or the lead's person key for an
|
|
35
|
+
* enrollment made on a lead (AGL-3234). A lead that converts keeps its
|
|
36
|
+
* enrollment under the key it was enrolled by; the enroll routes also
|
|
37
|
+
* refuse a second enrollment of the same ADDRESS in one sequence, which is
|
|
38
|
+
* what keeps the converted contact from being enrolled beside its lead.
|
|
39
|
+
*/
|
|
40
|
+
export declare function outreachEnrollmentId(sequenceId: string, personId: string): string;
|
|
41
|
+
/** The record an enrollment names (AGL-3234): the lead while it targets one, the contact otherwise. */
|
|
42
|
+
export declare function outreachEnrollmentPerson(enrollment: Pick<OutreachEnrollment, 'target' | 'contactId' | 'leadId'>): OutreachPersonRef;
|
|
43
|
+
/** The key the runtime files a person under: the id of whichever record they are. */
|
|
44
|
+
export declare function outreachPersonId(person: OutreachPersonRef): string;
|
|
45
|
+
/**
|
|
46
|
+
* The timeline link for what a sequence does to a person (AGL-3234): the
|
|
47
|
+
* lead's page while the enrollment targets a lead, the contact's after.
|
|
32
48
|
*/
|
|
33
|
-
export declare function
|
|
49
|
+
export declare function outreachEnrollmentLink(enrollment: Pick<OutreachEnrollment, 'target' | 'contactId' | 'leadId'>): {
|
|
50
|
+
contactId?: string;
|
|
51
|
+
leadId?: string;
|
|
52
|
+
};
|
|
@@ -28,8 +28,37 @@ export { readStoredOutreachEnrollment, readStoredOutreachMailbox, readStoredOutr
|
|
|
28
28
|
* person is enrolled in a sequence once, ever: a second enroll finds the
|
|
29
29
|
* first document where a random id would have made a second, and a second
|
|
30
30
|
* run through the same emails is exactly what must not happen.
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
*
|
|
32
|
+
* `personId` is the contact's document id, or the lead's person key for an
|
|
33
|
+
* enrollment made on a lead (AGL-3234). A lead that converts keeps its
|
|
34
|
+
* enrollment under the key it was enrolled by; the enroll routes also
|
|
35
|
+
* refuse a second enrollment of the same ADDRESS in one sequence, which is
|
|
36
|
+
* what keeps the converted contact from being enrolled beside its lead.
|
|
37
|
+
*/ export function outreachEnrollmentId(sequenceId, personId) {
|
|
38
|
+
return `${sequenceId}_${personId}`;
|
|
39
|
+
}
|
|
40
|
+
/** The record an enrollment names (AGL-3234): the lead while it targets one, the contact otherwise. */ export function outreachEnrollmentPerson(enrollment) {
|
|
41
|
+
return enrollment.target === 'lead' && enrollment.leadId ? {
|
|
42
|
+
kind: 'lead',
|
|
43
|
+
id: enrollment.leadId
|
|
44
|
+
} : {
|
|
45
|
+
kind: 'contact',
|
|
46
|
+
id: enrollment.contactId
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** The key the runtime files a person under: the id of whichever record they are. */ export function outreachPersonId(person) {
|
|
50
|
+
return person.id;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The timeline link for what a sequence does to a person (AGL-3234): the
|
|
54
|
+
* lead's page while the enrollment targets a lead, the contact's after.
|
|
55
|
+
*/ export function outreachEnrollmentLink(enrollment) {
|
|
56
|
+
const person = outreachEnrollmentPerson(enrollment);
|
|
57
|
+
return person.kind === 'lead' ? {
|
|
58
|
+
leadId: person.id
|
|
59
|
+
} : {
|
|
60
|
+
contactId: person.id
|
|
61
|
+
};
|
|
33
62
|
}
|
|
34
63
|
|
|
35
64
|
//# sourceMappingURL=outreach-records.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/storage/outreach-records.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Where the org-scoped Outreach documents live, as the server reaches them\n * (AGL-2980). Server only — the references are the Admin SDK's. Each\n * document reads back into its model shape through `model/stored-records`,\n * re-exported here for the routes.\n */\n\nimport { OUTREACH_COLLECTIONS
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/storage/outreach-records.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Where the org-scoped Outreach documents live, as the server reaches them\n * (AGL-2980). Server only — the references are the Admin SDK's. Each\n * document reads back into its model shape through `model/stored-records`,\n * re-exported here for the routes.\n */\n\nimport type { OutreachPersonRef } from '../model/outreach-api'\nimport {\n OUTREACH_COLLECTIONS,\n type OutreachEnrollment,\n type OutreachOrgCollection,\n} from '../model/outreach.types'\n\nexport {\n readStoredOutreachEnrollment,\n readStoredOutreachMailbox,\n readStoredOutreachSequence,\n} from '../model/stored-records'\n\n/** `orgs/{orgId}/<collection>` for one of Outreach's org-scoped collections. */\nexport function outreachOrgCollection(\n firestore: FirebaseFirestore.Firestore,\n orgId: string,\n collection: OutreachOrgCollection,\n): FirebaseFirestore.CollectionReference {\n return firestore.collection('orgs').doc(orgId).collection(OUTREACH_COLLECTIONS[collection])\n}\n\n/**\n * The id of one person's enrollment in one sequence. Deterministic, so a\n * person is enrolled in a sequence once, ever: a second enroll finds the\n * first document where a random id would have made a second, and a second\n * run through the same emails is exactly what must not happen.\n *\n * `personId` is the contact's document id, or the lead's person key for an\n * enrollment made on a lead (AGL-3234). A lead that converts keeps its\n * enrollment under the key it was enrolled by; the enroll routes also\n * refuse a second enrollment of the same ADDRESS in one sequence, which is\n * what keeps the converted contact from being enrolled beside its lead.\n */\nexport function outreachEnrollmentId(sequenceId: string, personId: string): string {\n return `${sequenceId}_${personId}`\n}\n\n/** The record an enrollment names (AGL-3234): the lead while it targets one, the contact otherwise. */\nexport function outreachEnrollmentPerson(\n enrollment: Pick<OutreachEnrollment, 'target' | 'contactId' | 'leadId'>,\n): OutreachPersonRef {\n return enrollment.target === 'lead' && enrollment.leadId\n ? { kind: 'lead', id: enrollment.leadId }\n : { kind: 'contact', id: enrollment.contactId }\n}\n\n/** The key the runtime files a person under: the id of whichever record they are. */\nexport function outreachPersonId(person: OutreachPersonRef): string {\n return person.id\n}\n\n/**\n * The timeline link for what a sequence does to a person (AGL-3234): the\n * lead's page while the enrollment targets a lead, the contact's after.\n */\nexport function outreachEnrollmentLink(\n enrollment: Pick<OutreachEnrollment, 'target' | 'contactId' | 'leadId'>,\n): { contactId?: string; leadId?: string } {\n const person = outreachEnrollmentPerson(enrollment)\n return person.kind === 'lead' ? { leadId: person.id } : { contactId: person.id }\n}\n"],"names":["OUTREACH_COLLECTIONS","readStoredOutreachEnrollment","readStoredOutreachMailbox","readStoredOutreachSequence","outreachOrgCollection","firestore","orgId","collection","doc","outreachEnrollmentId","sequenceId","personId","outreachEnrollmentPerson","enrollment","target","leadId","kind","id","contactId","outreachPersonId","person","outreachEnrollmentLink"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;CAKC,GAGD,SACEA,oBAAoB,QAGf,6BAAyB;AAEhC,SACEC,4BAA4B,EAC5BC,yBAAyB,EACzBC,0BAA0B,QACrB,6BAAyB;AAEhC,8EAA8E,GAC9E,OAAO,SAASC,sBACdC,SAAsC,EACtCC,KAAa,EACbC,UAAiC;IAEjC,OAAOF,UAAUE,UAAU,CAAC,QAAQC,GAAG,CAACF,OAAOC,UAAU,CAACP,oBAAoB,CAACO,WAAW;AAC5F;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASE,qBAAqBC,UAAkB,EAAEC,QAAgB;IACvE,OAAO,GAAGD,WAAW,CAAC,EAAEC,UAAU;AACpC;AAEA,qGAAqG,GACrG,OAAO,SAASC,yBACdC,UAAuE;IAEvE,OAAOA,WAAWC,MAAM,KAAK,UAAUD,WAAWE,MAAM,GACpD;QAAEC,MAAM;QAAQC,IAAIJ,WAAWE,MAAM;IAAC,IACtC;QAAEC,MAAM;QAAWC,IAAIJ,WAAWK,SAAS;IAAC;AAClD;AAEA,mFAAmF,GACnF,OAAO,SAASC,iBAAiBC,MAAyB;IACxD,OAAOA,OAAOH,EAAE;AAClB;AAEA;;;CAGC,GACD,OAAO,SAASI,uBACdR,UAAuE;IAEvE,MAAMO,SAASR,yBAAyBC;IACxC,OAAOO,OAAOJ,IAAI,KAAK,SAAS;QAAED,QAAQK,OAAOH,EAAE;IAAC,IAAI;QAAEC,WAAWE,OAAOH,EAAE;IAAC;AACjF"}
|