@aglyn/plugins-outreach 1.0.0-beta.196 → 1.0.0-beta.197

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.
Files changed (53) hide show
  1. package/package.json +14 -14
  2. package/src/lib/components/enroll-dialog.js +60 -1
  3. package/src/lib/components/enroll-dialog.js.map +1 -1
  4. package/src/lib/components/mailbox-card.js +11 -2
  5. package/src/lib/components/mailbox-card.js.map +1 -1
  6. package/src/lib/components/sequence-detail.js +1 -0
  7. package/src/lib/components/sequence-detail.js.map +1 -1
  8. package/src/lib/components/sequence-editor.d.ts +2 -0
  9. package/src/lib/components/sequence-editor.js +26 -2
  10. package/src/lib/components/sequence-editor.js.map +1 -1
  11. package/src/lib/components/sequence-step-card.d.ts +7 -0
  12. package/src/lib/components/sequence-step-card.js +37 -14
  13. package/src/lib/components/sequence-step-card.js.map +1 -1
  14. package/src/lib/components/sequences-section.js +12 -3
  15. package/src/lib/components/sequences-section.js.map +1 -1
  16. package/src/lib/components/step-test-dialog.d.ts +31 -0
  17. package/src/lib/components/step-test-dialog.js +247 -0
  18. package/src/lib/components/step-test-dialog.js.map +1 -0
  19. package/src/lib/components/use-outreach-api.d.ts +8 -1
  20. package/src/lib/components/use-outreach-api.js +4 -0
  21. package/src/lib/components/use-outreach-api.js.map +1 -1
  22. package/src/lib/components/use-outreach-data.d.ts +6 -1
  23. package/src/lib/components/use-outreach-data.js +6 -3
  24. package/src/lib/components/use-outreach-data.js.map +1 -1
  25. package/src/lib/constants/api-routes.d.ts +7 -0
  26. package/src/lib/constants/api-routes.js +6 -0
  27. package/src/lib/constants/api-routes.js.map +1 -1
  28. package/src/lib/model/outreach-api.d.ts +21 -1
  29. package/src/lib/model/outreach-api.js.map +1 -1
  30. package/src/lib/model/outreach.types.d.ts +6 -0
  31. package/src/lib/model/outreach.types.js.map +1 -1
  32. package/src/lib/model/step-preview.d.ts +7 -1
  33. package/src/lib/model/step-preview.js +3 -2
  34. package/src/lib/model/step-preview.js.map +1 -1
  35. package/src/lib/routes/platform-deps.d.ts +2 -2
  36. package/src/lib/routes/platform-deps.js +2 -2
  37. package/src/lib/routes/platform-deps.js.map +1 -1
  38. package/src/lib/routes/preview-routes.d.ts +24 -0
  39. package/src/lib/routes/preview-routes.js +99 -95
  40. package/src/lib/routes/preview-routes.js.map +1 -1
  41. package/src/lib/routes/register-routes.d.ts +7 -0
  42. package/src/lib/routes/register-routes.js +24 -0
  43. package/src/lib/routes/register-routes.js.map +1 -1
  44. package/src/lib/routes/step-test-routes.d.ts +88 -0
  45. package/src/lib/routes/step-test-routes.js +275 -0
  46. package/src/lib/routes/step-test-routes.js.map +1 -0
  47. package/src/lib/runtime/click-events.js +10 -0
  48. package/src/lib/runtime/click-events.js.map +1 -1
  49. package/src/lib/runtime/click-link.d.ts +11 -0
  50. package/src/lib/runtime/click-link.js +9 -4
  51. package/src/lib/runtime/click-link.js.map +1 -1
  52. package/src/lib/runtime/click-route.js +3 -0
  53. package/src/lib/runtime/click-route.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/plugins-outreach",
3
- "version": "1.0.0-beta.196",
3
+ "version": "1.0.0-beta.197",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,19 +25,19 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/aglyn": "1.0.0-beta.196",
29
- "@aglyn/shared-data-mdi": "1.0.0-beta.196",
30
- "@aglyn/shared-ui-email-campaigns": "1.0.0-beta.196",
31
- "@aglyn/shared-ui-jsx": "1.0.0-beta.196",
32
- "@aglyn/shared-ui-next": "1.0.0-beta.196",
33
- "@aglyn/shared-ui-snackstack": "1.0.0-beta.196",
34
- "@aglyn/shared-util-email": "1.0.0-beta.196",
35
- "@aglyn/shared-util-http": "1.0.0-beta.196",
36
- "@aglyn/shared-util-timestamp": "1.0.0-beta.196",
37
- "@aglyn/shared-util-tools": "1.0.0-beta.196",
38
- "@aglyn/tenant-data-admin": "1.0.0-beta.196",
39
- "@aglyn/tenant-feature-instance": "1.0.0-beta.196",
40
- "@aglyn/tenant-runtime": "1.0.0-beta.196",
28
+ "@aglyn/aglyn": "1.0.0-beta.197",
29
+ "@aglyn/shared-data-mdi": "1.0.0-beta.197",
30
+ "@aglyn/shared-ui-email-campaigns": "1.0.0-beta.197",
31
+ "@aglyn/shared-ui-jsx": "1.0.0-beta.197",
32
+ "@aglyn/shared-ui-next": "1.0.0-beta.197",
33
+ "@aglyn/shared-ui-snackstack": "1.0.0-beta.197",
34
+ "@aglyn/shared-util-email": "1.0.0-beta.197",
35
+ "@aglyn/shared-util-http": "1.0.0-beta.197",
36
+ "@aglyn/shared-util-timestamp": "1.0.0-beta.197",
37
+ "@aglyn/shared-util-tools": "1.0.0-beta.197",
38
+ "@aglyn/tenant-data-admin": "1.0.0-beta.197",
39
+ "@aglyn/tenant-feature-instance": "1.0.0-beta.197",
40
+ "@aglyn/tenant-runtime": "1.0.0-beta.197",
41
41
  "@swc/helpers": "0.5.23"
42
42
  },
43
43
  "peerDependencies": {
@@ -82,6 +82,7 @@ const STATUS_COLORS = {
82
82
  const [problem, setProblem] = useState(null);
83
83
  const [supplied, setSupplied] = useState({});
84
84
  const [emailPreview, setEmailPreview] = useState({});
85
+ const [stepTests, setStepTests] = useState({});
85
86
  const views = useOutreachSavedViews(props.open ? orgId : null, props.uid);
86
87
  const search = useOutreachContactSearch({
87
88
  orgId: props.open && tab === 'search' ? orgId : null,
@@ -103,6 +104,7 @@ const STATUS_COLORS = {
103
104
  setProblem(null);
104
105
  setSupplied({});
105
106
  setEmailPreview({});
107
+ setStepTests({});
106
108
  };
107
109
  const close = ()=>{
108
110
  reset();
@@ -279,6 +281,47 @@ const STATUS_COLORS = {
279
281
  ]))
280
282
  });
281
283
  };
284
+ /**
285
+ * This person's first email, sent to the member as a test (AGL-3325):
286
+ * their record, the personal line as written so far and the curated copy
287
+ * they used (AGL-3324) fill it, and nothing is enrolled or stored for
288
+ * them.
289
+ */ const sendTest = async (person)=>{
290
+ setStepTests((previous)=>_extends({}, previous, {
291
+ [person.personId]: {
292
+ status: 'sending'
293
+ }
294
+ }));
295
+ try {
296
+ var _ref;
297
+ var _supplied_person_personId;
298
+ const overrides = usedOverrides(supplied[person.personId]);
299
+ const answer = await api.sendStepTest(_extends({
300
+ sequenceId: sequence.id
301
+ }, person.target === 'lead' && person.leadId ? {
302
+ leadId: person.leadId
303
+ } : {
304
+ contactId: person.contactId
305
+ }, {
306
+ personalLine: (_ref = (_supplied_person_personId = supplied[person.personId]) == null ? void 0 : _supplied_person_personId.personalLine.trim()) != null ? _ref : ''
307
+ }, overrides.length ? {
308
+ stepOverrides: overrides
309
+ } : {}));
310
+ setStepTests((previous)=>_extends({}, previous, {
311
+ [person.personId]: {
312
+ status: 'sent',
313
+ answer
314
+ }
315
+ }));
316
+ } catch (error) {
317
+ setStepTests((previous)=>_extends({}, previous, {
318
+ [person.personId]: {
319
+ status: 'failed',
320
+ message: error.message
321
+ }
322
+ }));
323
+ }
324
+ };
282
325
  const title = `Enroll people in ${sequence.name}`;
283
326
  return /*#__PURE__*/ _jsxs(Dialog, {
284
327
  open: props.open,
@@ -544,6 +587,8 @@ const STATUS_COLORS = {
544
587
  onSupply: (next)=>supply(person.personId, next),
545
588
  emailPreview: emailPreview[person.personId],
546
589
  onPreviewEmail: ()=>void previewEmail(person),
590
+ stepTest: stepTests[person.personId],
591
+ onSendTest: ()=>void sendTest(person),
547
592
  onCurate: ()=>void curate(person),
548
593
  onWriteThemselves: ()=>writeThemselves(person),
549
594
  disabled: stage.kind === 'enrolling'
@@ -620,7 +665,7 @@ function summary(answer) {
620
665
  }
621
666
  function PersonRow(props) {
622
667
  var _ref, _ref1, _ref2, _ref3;
623
- var _props_emailPreview, _props_emailPreview1, _props_emailPreview2;
668
+ var _props_stepTest, _props_stepTest1, _props_stepTest2, _props_stepTest3, _props_emailPreview, _props_emailPreview1, _props_emailPreview2;
624
669
  const { person, supplied, disabled } = props;
625
670
  const name = person.name || person.email || person.personId;
626
671
  const line = (_ref = supplied == null ? void 0 : supplied.personalLine) != null ? _ref : '';
@@ -773,6 +818,12 @@ function PersonRow(props) {
773
818
  disabled: disabled,
774
819
  children: "Preview the first email"
775
820
  }),
821
+ /*#__PURE__*/ _jsx(Button, {
822
+ size: "small",
823
+ onClick: props.onSendTest,
824
+ disabled: disabled || ((_props_stepTest = props.stepTest) == null ? void 0 : _props_stepTest.status) === 'sending',
825
+ children: ((_props_stepTest1 = props.stepTest) == null ? void 0 : _props_stepTest1.status) === 'sending' ? 'Sending…' : 'Send me this as a test'
826
+ }),
776
827
  /*#__PURE__*/ _jsx(Button, {
777
828
  size: "small",
778
829
  onClick: props.onCurate,
@@ -781,6 +832,14 @@ function PersonRow(props) {
781
832
  })
782
833
  ]
783
834
  }),
835
+ ((_props_stepTest2 = props.stepTest) == null ? void 0 : _props_stepTest2.status) === 'failed' ? /*#__PURE__*/ _jsx(Alert, {
836
+ severity: "error",
837
+ children: props.stepTest.message
838
+ }) : null,
839
+ ((_props_stepTest3 = props.stepTest) == null ? void 0 : _props_stepTest3.status) === 'sent' ? /*#__PURE__*/ _jsx(Alert, {
840
+ severity: "success",
841
+ children: `Sent to ${props.stepTest.answer.sentTo} as “${props.stepTest.answer.subject}”. ${name} was not enrolled.`
842
+ }) : null,
784
843
  curation.status === 'drafting' ? /*#__PURE__*/ _jsx(OutreachLoading, {
785
844
  label: "Drafting their emails…"
786
845
  }) : null,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/enroll-dialog.tsx"],"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'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n type ChipProps,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n List,\n ListItem,\n ListItemButton,\n ListItemIcon,\n ListItemText,\n MenuItem,\n Paper,\n Stack,\n Tab,\n Tabs,\n TextField,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport { useMemo, useState } from 'react'\nimport {\n OUTREACH_ENROLL_BATCH_MAX,\n type OutreachEnrollOutcome,\n type OutreachEnrollPreviewPerson,\n type OutreachEnrollPreviewResponse,\n type OutreachEnrollPreviewStatus,\n type OutreachEnrollSource,\n type OutreachPreviewResponse,\n} from '../model/outreach-api'\nimport {\n OUTREACH_ATTESTATION_LABELS,\n OUTREACH_PERSONAL_LINE_MAX,\n type OutreachAttestationKind,\n type OutreachSequence,\n type OutreachSequenceStep,\n} from '../model/outreach.types'\nimport { outreachEmailStepLabel } from './curate-step-dialog'\nimport {\n OutreachCuratedStepEditor,\n outreachDraftState,\n outreachDraftToOverride,\n outreachMemberDraftStates,\n type OutreachCuratedDraftState,\n} from './curated-step-editor'\nimport { OutreachLoading, OutreachLoadProblem } from './outreach-ui'\nimport type { OutreachApi } from './use-outreach-api'\nimport {\n type OutreachContactOption,\n useOutreachContactSearch,\n useOutreachLeadSearch,\n useOutreachSavedViews,\n} from './use-outreach-crm'\n\nexport interface OutreachEnrollDialogProps {\n open: boolean\n onClose(): void\n orgId: string\n sequence: OutreachSequence\n /** The consent group of the sequence's site: whose names a search shows. */\n contactGroupId: string\n uid: string | null\n api: OutreachApi\n}\n\nconst STATUS_LABELS: Record<OutreachEnrollPreviewStatus, string> = {\n eligible: 'Eligible',\n needs_confirmation: 'Needs you',\n blocked: 'Blocked',\n}\n\nconst STATUS_COLORS: Record<OutreachEnrollPreviewStatus, ChipProps['color']> = {\n eligible: 'success',\n needs_confirmation: 'warning',\n blocked: 'default',\n}\n\n/** Where one person's curated drafts stand (AGL-3324). */\ntype Curation =\n | { status: 'idle' }\n | { status: 'drafting' }\n | { status: 'failed'; message: string }\n | { status: 'ready' }\n\n/** What the rep has supplied for one person. */\ninterface Supplied {\n include: boolean\n personalLine: string\n attestations: OutreachAttestationKind[]\n /** The email steps drafted for this person, by step index; absent until they curate. */\n drafts?: Record<number, OutreachCuratedDraftState>\n curation?: Curation\n}\n\n/** The drafts the rep used, as the enroll and the preview carry them. */\nfunction usedOverrides(supplied: Supplied | undefined) {\n return Object.values(supplied?.drafts ?? {})\n .map(outreachDraftToOverride)\n .filter((override): override is NonNullable<typeof override> => override !== null)\n}\n\n/** Whether a drafted step is still waiting on the rep to use it or keep the template. */\nfunction hasOpenDrafts(supplied: Supplied | undefined): boolean {\n return Object.values(supplied?.drafts ?? {}).some((draft) => draft.decision === 'pending')\n}\n\ntype Stage =\n | { kind: 'source' }\n | { kind: 'previewing' }\n | { kind: 'preview'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'enrolling'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'done'; results: OutreachEnrollOutcome[]; enrolled: number }\n\n/** Whether a person may be sent to Confirm as the rep has left them. */\nexport function outreachPersonReady(\n person: OutreachEnrollPreviewPerson,\n supplied: Supplied | undefined,\n): boolean {\n if (person.status === 'blocked' || !supplied?.include) return false\n const line = supplied.personalLine.trim()\n if (line.length > OUTREACH_PERSONAL_LINE_MAX) return false\n // A draft the rep has read but neither used nor kept holds them back\n // (AGL-3324): nothing is enrolled with a decision still open.\n if (hasOpenDrafts(supplied)) return false\n if (person.status === 'eligible') return true\n if (person.requires.personalLine && !line) return false\n return person.requires.attestations.every((kind) =>\n supplied.attestations.includes(kind),\n )\n}\n\n/**\n * Enroll people in a sequence (AGL-2980).\n *\n * The rep picks a saved Contacts view or searches for people, and sees each\n * marked as the gates see them: eligible, blocked with the reason, or\n * waiting on them — for a cold contact, a personal line and the three\n * attestations only they can make, stored on the enrollment with who ticked\n * them and when. Enroll sends only the people who are ready, and the server\n * checks every gate again as it enrolls them.\n */\nexport function OutreachEnrollDialog(props: OutreachEnrollDialogProps) {\n const { orgId, sequence, api } = props\n const theme = useTheme()\n const narrow = useMediaQuery(theme.breakpoints.down('sm'))\n const [tab, setTab] = useState<'view' | 'search' | 'leads'>('view')\n const [viewId, setViewId] = useState('')\n const [text, setText] = useState('')\n const [picked, setPicked] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n // The leads picked from the sequence's site (AGL-3234), kept apart from\n // the contacts: the two are different records and the source names which.\n const [leadText, setLeadText] = useState('')\n const [pickedLeads, setPickedLeads] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n const [stage, setStage] = useState<Stage>({ kind: 'source' })\n const [problem, setProblem] = useState<string | null>(null)\n const [supplied, setSupplied] = useState<Record<string, Supplied>>({})\n const [emailPreview, setEmailPreview] = useState<\n Record<\n string,\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n >\n >({})\n\n const views = useOutreachSavedViews(props.open ? orgId : null, props.uid)\n const search = useOutreachContactSearch({\n orgId: props.open && tab === 'search' ? orgId : null,\n hostId: sequence.hostId,\n contactGroupId: props.contactGroupId,\n text,\n })\n const leadSearch = useOutreachLeadSearch({\n // The lead silo is the org's (AGL-3275); the site still narrows it.\n orgId,\n hostId: sequence.hostId,\n text: leadText,\n enabled: props.open && tab === 'leads',\n })\n\n const reset = () => {\n setStage({ kind: 'source' })\n setProblem(null)\n setSupplied({})\n setEmailPreview({})\n }\n const close = () => {\n reset()\n setPicked(new Map())\n setPickedLeads(new Map())\n setText('')\n setLeadText('')\n setViewId('')\n props.onClose()\n }\n\n const preview = async (source: OutreachEnrollSource) => {\n setProblem(null)\n setStage({ kind: 'previewing' })\n try {\n const answer = await api.previewEnrollment(sequence.id, source)\n setSupplied(\n Object.fromEntries(\n answer.people.map((person) => [\n person.personId,\n {\n include: person.status !== 'blocked',\n personalLine: '',\n attestations: [],\n },\n ]),\n ),\n )\n setStage({ kind: 'preview', answer })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'source' })\n }\n }\n\n const answer =\n stage.kind === 'preview' || stage.kind === 'enrolling' ? stage.answer : null\n const ready = useMemo(\n () =>\n answer\n ? answer.people.filter((person) =>\n outreachPersonReady(person, supplied[person.personId]),\n )\n : [],\n [answer, supplied],\n )\n const waiting = answer\n ? answer.people.filter(\n (person) =>\n person.status !== 'blocked' &&\n supplied[person.personId]?.include &&\n !outreachPersonReady(person, supplied[person.personId]),\n ).length\n : 0\n\n const enroll = async () => {\n if (!answer || !ready.length) return\n setProblem(null)\n setStage({ kind: 'enrolling', answer })\n try {\n const result = await api.enroll(\n sequence.id,\n ready.map((person) => ({\n // A contact by id, or a lead by its key (AGL-3234).\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n attestations: supplied[person.personId]?.attestations ?? [],\n // The steps they curated and confirmed (AGL-3324); nothing else.\n ...(usedOverrides(supplied[person.personId]).length\n ? { stepOverrides: usedOverrides(supplied[person.personId]) }\n : {}),\n })),\n )\n setStage({\n kind: 'done',\n results: result.results,\n enrolled: result.enrolled,\n })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'preview', answer })\n }\n }\n\n const supply = (personId: string, next: Partial<Supplied>) =>\n setSupplied((previous) => ({\n ...previous,\n [personId]: { ...previous[personId], ...next } as Supplied,\n }))\n\n const previewEmail = async (person: OutreachEnrollPreviewPerson) => {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'loading' },\n }))\n try {\n const overrides = usedOverrides(supplied[person.personId])\n const result = await api.previewEmail({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n // The preview shows the curated version (AGL-3324).\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n })\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'ready', answer: result },\n }))\n } catch (error) {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: {\n status: 'failed',\n message: (error as Error).message,\n },\n }))\n }\n }\n\n /**\n * Curate for this person (AGL-3324): every email step drafted from their\n * record, the sequence's steps and the personal line as written so far,\n * shown under them for the rep to edit and confirm. Nothing is stored\n * until Enroll carries the drafts they used.\n */\n const curate = async (person: OutreachEnrollPreviewPerson) => {\n supply(person.personId, { curation: { status: 'drafting' } })\n try {\n const answer = await api.curateDrafts({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n })\n const audit = { prompt: answer.prompt, model: answer.model }\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n answer.drafts.map((draft) => [draft.stepIndex, outreachDraftState(draft, sequence.steps, 'ai', audit)]),\n ),\n })\n } catch (error) {\n supply(person.personId, { curation: { status: 'failed', message: (error as Error).message } })\n }\n }\n\n /** The rep's own words for every email step, when the AI cannot draft. */\n const writeThemselves = (person: OutreachEnrollPreviewPerson) => {\n const stepIndexes = sequence.steps\n .map((step, index) => (step.kind === 'email' ? index : -1))\n .filter((index) => index >= 0)\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n outreachMemberDraftStates(sequence.steps, stepIndexes).map((draft) => [draft.stepIndex, draft]),\n ),\n })\n }\n\n const title = `Enroll people in ${sequence.name}`\n\n return (\n <Dialog\n open={props.open}\n onClose={close}\n fullWidth\n maxWidth=\"md\"\n fullScreen={narrow}\n aria-label={title}\n >\n <DialogTitle>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <span>{title}</span>\n <HelpTip {...pluginDocsHelp('sequences', { anchor: '#enroll' })} />\n </Stack>\n </DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2}>\n {problem ? <Alert severity=\"error\">{problem}</Alert> : null}\n\n {stage.kind === 'source' ? (\n <>\n <Tabs\n value={tab}\n onChange={(_event, next) => setTab(next)}\n aria-label=\"Where the people come from\"\n >\n <Tab value=\"view\" label=\"Saved view\" />\n <Tab value=\"search\" label=\"Search\" />\n <Tab value=\"leads\" label=\"Leads\" />\n </Tabs>\n {tab === 'view' ? (\n views.status === 'loading' ? (\n <OutreachLoading label=\"Loading saved views…\" />\n ) : views.status === 'error' || views.status === 'refused' ? (\n <OutreachLoadProblem\n status={views.status}\n what=\"saved views\"\n message={\n views.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : null\n }\n />\n ) : views.data.length ? (\n <TextField\n select\n label=\"Saved Contacts view\"\n value={viewId}\n onChange={(event) => setViewId(event.target.value)}\n helperText={`Enrolls up to ${OUTREACH_ENROLL_BATCH_MAX} of the people the view shows at this sequence’s site — a Contacts view, or a Leads view of the site’s leads.`}\n fullWidth\n >\n {views.data.map((view) => (\n <MenuItem key={view.id} value={view.id}>\n {view.section === 'leads' ? `${view.name} (Leads)` : view.name}\n </MenuItem>\n ))}\n </TextField>\n ) : (\n <Alert severity=\"info\">\n You have no saved Contacts views to enroll from. Save one in\n the CRM, or search instead.\n </Alert>\n )\n ) : tab === 'leads' ? (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search leads\"\n placeholder=\"A name, or an email address\"\n value={leadText}\n onChange={(event) => setLeadText(event.target.value)}\n helperText=\"The open leads at this sequence’s site. A lead is enrolled as it is, and follows itself to the contact it becomes.\"\n fullWidth\n autoFocus\n />\n {leadSearch.status === 'loading' ? (\n <OutreachLoading label=\"Reading leads…\" />\n ) : null}\n {leadSearch.status === 'error' || leadSearch.status === 'refused' ? (\n <OutreachLoadProblem\n status={leadSearch.status}\n what=\"leads\"\n message={\n leadSearch.status === 'refused'\n ? 'Enrolling reads your CRM’s leads, and your role does not include Manage data.'\n : 'The leads could not be read. Try again.'\n }\n />\n ) : null}\n {leadSearch.status === 'ready' && !leadSearch.idle && !leadSearch.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No open leads at this sequence’s site match.\n </Typography>\n ) : null}\n {leadSearch.data.length ? (\n <List dense aria-label=\"Lead results\">\n {leadSearch.data.map((lead) => {\n const checked = pickedLeads.has(lead.id)\n return (\n <ListItem key={lead.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(lead.id)\n else if (next.size < OUTREACH_ENROLL_BATCH_MAX) next.set(lead.id, lead)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox edge=\"start\" checked={checked} tabIndex={-1} disableRipple />\n </ListItemIcon>\n <ListItemText\n primary={lead.name || lead.email || lead.id}\n secondary={lead.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {pickedLeads.size ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked leads\"\n >\n {[...pickedLeads.values()].map((lead) => (\n <Chip\n key={lead.id}\n size=\"small\"\n label={lead.name || lead.email || lead.id}\n onDelete={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n next.delete(lead.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n ) : (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search contacts\"\n placeholder=\"A name, or an email address\"\n value={text}\n onChange={(event) => setText(event.target.value)}\n fullWidth\n autoFocus\n />\n {search.status === 'loading' ? (\n <OutreachLoading label=\"Searching…\" />\n ) : null}\n {search.status === 'error' || search.status === 'refused' ? (\n <OutreachLoadProblem\n status={search.status}\n what=\"contacts\"\n message={\n search.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : 'The search failed. Try again.'\n }\n />\n ) : null}\n {search.status === 'ready' &&\n !search.idle &&\n !search.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No contacts at this sequence’s site match.\n </Typography>\n ) : null}\n {search.data.length ? (\n <List dense aria-label=\"Search results\">\n {search.data.map((contact) => {\n const checked = picked.has(contact.id)\n return (\n <ListItem key={contact.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(contact.id)\n else if (\n next.size < OUTREACH_ENROLL_BATCH_MAX\n )\n next.set(contact.id, contact)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox\n edge=\"start\"\n checked={checked}\n tabIndex={-1}\n disableRipple\n />\n </ListItemIcon>\n <ListItemText\n primary={\n contact.name || contact.email || contact.id\n }\n secondary={contact.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {picked.size ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked\"\n >\n {[...picked.values()].map((contact) => (\n <Chip\n key={contact.id}\n size=\"small\"\n label={contact.name || contact.email || contact.id}\n onDelete={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n next.delete(contact.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n )}\n </>\n ) : null}\n\n {stage.kind === 'previewing' ? (\n <OutreachLoading label=\"Checking each person…\" />\n ) : null}\n\n {answer ? (\n <Stack spacing={1.5}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {summary(answer)}\n </Typography>\n {answer.truncated ? (\n <Alert severity=\"info\">\n {`This shows the first ${answer.people.length} of ${answer.total}. Enroll these, then preview again for the rest.`}\n </Alert>\n ) : null}\n <Stack\n spacing={1}\n component=\"ul\"\n sx={{ listStyle: 'none', p: 0, m: 0 }}\n aria-label=\"People\"\n >\n {answer.people.map((person) => (\n <PersonRow\n key={person.personId}\n person={person}\n steps={sequence.steps}\n supplied={supplied[person.personId]}\n onSupply={(next) => supply(person.personId, next)}\n emailPreview={emailPreview[person.personId]}\n onPreviewEmail={() => void previewEmail(person)}\n onCurate={() => void curate(person)}\n onWriteThemselves={() => writeThemselves(person)}\n disabled={stage.kind === 'enrolling'}\n />\n ))}\n </Stack>\n {waiting ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${waiting} ${waiting === 1 ? 'person still needs' : 'people still need'} a personal line or a confirmation, or a decision on a draft, and won't be enrolled until they have one.`}\n </Typography>\n ) : null}\n </Stack>\n ) : null}\n\n {stage.kind === 'done' ? (\n <DoneSummary results={stage.results} enrolled={stage.enrolled} />\n ) : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n {stage.kind === 'done' ? (\n <Button variant=\"contained\" onClick={close}>\n Done\n </Button>\n ) : (\n <>\n <Button onClick={close}>Cancel</Button>\n {stage.kind === 'preview' || stage.kind === 'enrolling' ? (\n <>\n <Button onClick={reset} disabled={stage.kind === 'enrolling'}>\n Back\n </Button>\n <Button\n variant=\"contained\"\n disabled={!ready.length || stage.kind === 'enrolling'}\n onClick={() => void enroll()}\n >\n {stage.kind === 'enrolling'\n ? 'Enrolling…'\n : `Enroll ${ready.length} ${ready.length === 1 ? 'person' : 'people'}`}\n </Button>\n </>\n ) : (\n <Button\n variant=\"contained\"\n disabled={\n stage.kind === 'previewing' ||\n (tab === 'view' ? !viewId : tab === 'leads' ? !pickedLeads.size : !picked.size)\n }\n onClick={() =>\n void preview(\n tab === 'view'\n ? { kind: 'view', viewId }\n : tab === 'leads'\n ? { kind: 'leads', leadIds: [...pickedLeads.keys()] }\n : { kind: 'contacts', contactIds: [...picked.keys()] },\n )\n }\n >\n Check people\n </Button>\n )}\n </>\n )}\n </DialogActions>\n </Dialog>\n )\n}\nOutreachEnrollDialog.displayName = 'OutreachEnrollDialog'\n\nfunction summary(answer: OutreachEnrollPreviewResponse): string {\n const count = (status: OutreachEnrollPreviewStatus) =>\n answer.people.filter((person) => person.status === status).length\n return `${count('eligible')} eligible · ${count('needs_confirmation')} need you · ${count('blocked')} blocked`\n}\n\nfunction PersonRow(props: {\n person: OutreachEnrollPreviewPerson\n steps: readonly OutreachSequenceStep[]\n supplied: Supplied | undefined\n onSupply(next: Partial<Supplied>): void\n emailPreview:\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n | undefined\n onPreviewEmail(): void\n onCurate(): void\n onWriteThemselves(): void\n disabled: boolean\n}) {\n const { person, supplied, disabled } = props\n const name = person.name || person.email || person.personId\n const line = supplied?.personalLine ?? ''\n const tooLong = line.trim().length > OUTREACH_PERSONAL_LINE_MAX\n const curation = supplied?.curation ?? { status: 'idle' }\n const drafts = Object.values(supplied?.drafts ?? {}).sort((a, b) => a.stepIndex - b.stepIndex)\n const usedCount = drafts.filter((draft) => draft.decision === 'use').length\n return (\n <Paper component=\"li\" variant=\"outlined\" sx={{ p: 1.5 }} aria-label={name}>\n <Stack spacing={1}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { sm: 'center' } }}\n >\n <Stack sx={{ flexGrow: 1, minWidth: 0 }}>\n <Typography variant=\"body2\">{name}</Typography>\n {person.email && person.email !== name ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {person.email}\n </Typography>\n ) : null}\n </Stack>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n {person.target === 'lead' ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Lead\" />\n ) : null}\n {person.cold ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Cold\" />\n ) : null}\n <Chip\n size=\"small\"\n label={STATUS_LABELS[person.status]}\n color={STATUS_COLORS[person.status]}\n />\n </Stack>\n </Stack>\n {person.status === 'blocked' ? (\n <Stack component=\"ul\" spacing={0.5} sx={{ m: 0, pl: 2.5 }}>\n {person.blocks.map((block) => (\n <Typography\n key={block.code}\n component=\"li\"\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ) : (\n <Stack spacing={1}>\n <FormControlLabel\n control={\n <Checkbox\n checked={supplied?.include ?? true}\n onChange={(event) =>\n props.onSupply({ include: event.target.checked })\n }\n disabled={disabled}\n />\n }\n label=\"Enroll this person\"\n />\n {supplied?.include === false ? null : (\n <>\n <TextField\n label={\n person.requires.personalLine\n ? 'Personal line'\n : 'Personal line (optional)'\n }\n placeholder=\"One sentence on why you're writing to this person now.\"\n value={line}\n onChange={(event) =>\n props.onSupply({ personalLine: event.target.value })\n }\n disabled={disabled}\n required={person.requires.personalLine}\n error={tooLong}\n helperText={\n tooLong\n ? `Keep it to one sentence, under ${OUTREACH_PERSONAL_LINE_MAX} characters.`\n : 'Goes where the emails say {{enrollment.personalLine}}.'\n }\n fullWidth\n size=\"small\"\n />\n {person.requires.attestations.length ? (\n <FormGroup aria-label={`What you confirm about ${name}`}>\n {person.requires.attestations.map((kind) => (\n <FormControlLabel\n key={kind}\n control={\n <Checkbox\n checked={\n supplied?.attestations.includes(kind) ?? false\n }\n onChange={(event) =>\n props.onSupply({\n attestations: event.target.checked\n ? [...(supplied?.attestations ?? []), kind]\n : (supplied?.attestations ?? []).filter(\n (entry) => entry !== kind,\n ),\n })\n }\n disabled={disabled}\n />\n }\n label={OUTREACH_ATTESTATION_LABELS[kind]}\n />\n ))}\n </FormGroup>\n ) : null}\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n <Button\n size=\"small\"\n onClick={props.onPreviewEmail}\n disabled={disabled}\n >\n Preview the first email\n </Button>\n <Button\n size=\"small\"\n onClick={props.onCurate}\n disabled={disabled || curation.status === 'drafting'}\n >\n {drafts.length ? 'Curate again' : 'Curate for this person'}\n </Button>\n </Stack>\n {curation.status === 'drafting' ? (\n <OutreachLoading label=\"Drafting their emails…\" />\n ) : null}\n {curation.status === 'failed' ? (\n <Stack spacing={1}>\n <Alert severity=\"warning\">{curation.message}</Alert>\n <Stack direction=\"row\">\n <Button size=\"small\" onClick={props.onWriteThemselves} disabled={disabled}>\n Write them yourself\n </Button>\n </Stack>\n </Stack>\n ) : null}\n {drafts.length ? (\n <Stack spacing={1} aria-label={`Curated emails for ${name}`}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {usedCount\n ? `${usedCount} of ${drafts.length} ${drafts.length === 1 ? 'email' : 'emails'} curated for ${name}. Nothing is sent that you haven't confirmed.`\n : `Their emails, rewritten for them. Read each one, edit it, and use it or keep the template.`}\n </Typography>\n {drafts.map((draft) => (\n <OutreachCuratedStepEditor\n key={draft.stepIndex}\n draft={draft}\n label={outreachEmailStepLabel(props.steps, draft.stepIndex)}\n onChange={(next) =>\n props.onSupply({ drafts: { ...(supplied?.drafts ?? {}), [next.stepIndex]: next } })\n }\n disabled={disabled}\n />\n ))}\n </Stack>\n ) : null}\n {props.emailPreview?.status === 'loading' ? (\n <OutreachLoading label=\"Writing the email…\" />\n ) : null}\n {props.emailPreview?.status === 'failed' ? (\n <Alert severity=\"error\">{props.emailPreview.message}</Alert>\n ) : null}\n {props.emailPreview?.status === 'ready' ? (\n props.emailPreview.answer.error ? (\n <Alert severity=\"info\">\n {props.emailPreview.answer.error.message}\n </Alert>\n ) : (\n <Paper\n variant=\"outlined\"\n sx={{ p: 1.5 }}\n aria-label={`First email to ${name}`}\n >\n <Typography variant=\"body2\">{`Subject: ${props.emailPreview.answer.subject}`}</Typography>\n <Typography\n variant=\"body2\"\n sx={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n mt: 1,\n }}\n >\n {props.emailPreview.answer.text}\n </Typography>\n </Paper>\n )\n ) : null}\n </>\n )}\n </Stack>\n )}\n </Stack>\n </Paper>\n )\n}\n\nfunction DoneSummary(props: {\n results: OutreachEnrollOutcome[]\n enrolled: number\n}) {\n const refused = props.results.filter(\n (\n result,\n ): result is Extract<OutreachEnrollOutcome, { outcome: 'blocked' }> =>\n result.outcome === 'blocked',\n )\n return (\n <Stack spacing={1.5}>\n <Alert severity={props.enrolled ? 'success' : 'info'}>\n {props.enrolled\n ? `Enrolled ${props.enrolled} ${props.enrolled === 1 ? 'person' : 'people'}. Their first step goes out in the mailbox's sending hours.`\n : 'Nobody was enrolled.'}\n </Alert>\n {refused.length ? (\n <Stack spacing={1}>\n <Typography variant=\"subtitle2\">\n Not enrolled, checked again just now:\n </Typography>\n {refused.map((result) => (\n <Stack key={result.personId} spacing={0.25}>\n <Typography variant=\"body2\">\n {result.email ?? result.personId}\n </Typography>\n {result.blocks.map((block) => (\n <Typography\n key={block.code}\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ))}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n\nexport default OutreachEnrollDialog\n"],"names":["pluginDocsHelp","HelpTip","Alert","Button","Checkbox","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","List","ListItem","ListItemButton","ListItemIcon","ListItemText","MenuItem","Paper","Stack","Tab","Tabs","TextField","Typography","useMediaQuery","useTheme","useMemo","useState","OUTREACH_ENROLL_BATCH_MAX","OUTREACH_ATTESTATION_LABELS","OUTREACH_PERSONAL_LINE_MAX","outreachEmailStepLabel","OutreachCuratedStepEditor","outreachDraftState","outreachDraftToOverride","outreachMemberDraftStates","OutreachLoading","OutreachLoadProblem","useOutreachContactSearch","useOutreachLeadSearch","useOutreachSavedViews","STATUS_LABELS","eligible","needs_confirmation","blocked","STATUS_COLORS","usedOverrides","supplied","Object","values","drafts","map","filter","override","hasOpenDrafts","some","draft","decision","outreachPersonReady","person","status","include","line","personalLine","trim","length","requires","attestations","every","kind","includes","OutreachEnrollDialog","props","orgId","sequence","api","theme","narrow","breakpoints","down","tab","setTab","viewId","setViewId","text","setText","picked","setPicked","Map","leadText","setLeadText","pickedLeads","setPickedLeads","stage","setStage","problem","setProblem","setSupplied","emailPreview","setEmailPreview","views","open","uid","search","hostId","contactGroupId","leadSearch","enabled","reset","close","onClose","preview","source","answer","previewEnrollment","id","fromEntries","people","personId","error","message","ready","waiting","enroll","result","target","leadId","contactId","stepOverrides","results","enrolled","supply","next","previous","previewEmail","overrides","sequenceId","curate","curation","curateDrafts","audit","prompt","model","stepIndex","steps","writeThemselves","stepIndexes","step","index","title","name","fullWidth","maxWidth","fullScreen","aria-label","direction","spacing","sx","alignItems","span","anchor","dividers","severity","value","onChange","_event","label","what","data","select","event","helperText","view","section","placeholder","autoFocus","idle","variant","color","dense","lead","checked","has","disablePadding","onClick","delete","size","set","edge","tabIndex","disableRipple","primary","email","secondary","flexWrap","rowGap","onDelete","contact","summary","truncated","total","component","listStyle","p","m","PersonRow","onSupply","onPreviewEmail","onCurate","onWriteThemselves","disabled","DoneSummary","leadIds","keys","contactIds","displayName","count","tooLong","sort","a","b","usedCount","xs","sm","flexGrow","minWidth","cold","pl","blocks","block","reason","code","control","required","entry","subject","whiteSpace","wordBreak","mt","refused","outcome"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,SAASA,cAAc,QAAQ,eAAc;AAC7C,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SACEC,KAAK,EACLC,MAAM,EACNC,QAAQ,EACRC,IAAI,EAEJC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,WAAW,EACXC,gBAAgB,EAChBC,SAAS,EACTC,IAAI,EACJC,QAAQ,EACRC,cAAc,EACdC,YAAY,EACZC,YAAY,EACZC,QAAQ,EACRC,KAAK,EACLC,KAAK,EACLC,GAAG,EACHC,IAAI,EACJC,SAAS,EACTC,UAAU,EACVC,aAAa,EACbC,QAAQ,QACH,gBAAe;AACtB,SAASC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AACzC,SACEC,yBAAyB,QAOpB,2BAAuB;AAC9B,SACEC,2BAA2B,EAC3BC,0BAA0B,QAIrB,6BAAyB;AAChC,SAASC,sBAAsB,QAAQ,0BAAsB;AAC7D,SACEC,yBAAyB,EACzBC,kBAAkB,EAClBC,uBAAuB,EACvBC,yBAAyB,QAEpB,2BAAuB;AAC9B,SAASC,eAAe,EAAEC,mBAAmB,QAAQ,mBAAe;AAEpE,SAEEC,wBAAwB,EACxBC,qBAAqB,EACrBC,qBAAqB,QAChB,wBAAoB;AAa3B,MAAMC,gBAA6D;IACjEC,UAAU;IACVC,oBAAoB;IACpBC,SAAS;AACX;AAEA,MAAMC,gBAAyE;IAC7EH,UAAU;IACVC,oBAAoB;IACpBC,SAAS;AACX;AAmBA,uEAAuE,GACvE,SAASE,cAAcC,QAA8B;;IACnD,OAAOC,OAAOC,MAAM,SAACF,4BAAAA,SAAUG,MAAM,mBAAI,CAAC,GACvCC,GAAG,CAACjB,yBACJkB,MAAM,CAAC,CAACC,WAAuDA,aAAa;AACjF;AAEA,uFAAuF,GACvF,SAASC,cAAcP,QAA8B;;IACnD,OAAOC,OAAOC,MAAM,SAACF,4BAAAA,SAAUG,MAAM,mBAAI,CAAC,GAAGK,IAAI,CAAC,CAACC,QAAUA,MAAMC,QAAQ,KAAK;AAClF;AASA,sEAAsE,GACtE,OAAO,SAASC,oBACdC,MAAmC,EACnCZ,QAA8B;IAE9B,IAAIY,OAAOC,MAAM,KAAK,aAAa,EAACb,4BAAAA,SAAUc,OAAO,GAAE,OAAO;IAC9D,MAAMC,OAAOf,SAASgB,YAAY,CAACC,IAAI;IACvC,IAAIF,KAAKG,MAAM,GAAGnC,4BAA4B,OAAO;IACrD,qEAAqE;IACrE,8DAA8D;IAC9D,IAAIwB,cAAcP,WAAW,OAAO;IACpC,IAAIY,OAAOC,MAAM,KAAK,YAAY,OAAO;IACzC,IAAID,OAAOO,QAAQ,CAACH,YAAY,IAAI,CAACD,MAAM,OAAO;IAClD,OAAOH,OAAOO,QAAQ,CAACC,YAAY,CAACC,KAAK,CAAC,CAACC,OACzCtB,SAASoB,YAAY,CAACG,QAAQ,CAACD;AAEnC;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASE,qBAAqBC,KAAgC;IACnE,MAAM,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,GAAG,EAAE,GAAGH;IACjC,MAAMI,QAAQnD;IACd,MAAMoD,SAASrD,cAAcoD,MAAME,WAAW,CAACC,IAAI,CAAC;IACpD,MAAM,CAACC,KAAKC,OAAO,GAAGtD,SAAsC;IAC5D,MAAM,CAACuD,QAAQC,UAAU,GAAGxD,SAAS;IACrC,MAAM,CAACyD,MAAMC,QAAQ,GAAG1D,SAAS;IACjC,MAAM,CAAC2D,QAAQC,UAAU,GAAG5D,SAC1B,IAAI6D;IAEN,wEAAwE;IACxE,0EAA0E;IAC1E,MAAM,CAACC,UAAUC,YAAY,GAAG/D,SAAS;IACzC,MAAM,CAACgE,aAAaC,eAAe,GAAGjE,SACpC,IAAI6D;IAEN,MAAM,CAACK,OAAOC,SAAS,GAAGnE,SAAgB;QAAE0C,MAAM;IAAS;IAC3D,MAAM,CAAC0B,SAASC,WAAW,GAAGrE,SAAwB;IACtD,MAAM,CAACoB,UAAUkD,YAAY,GAAGtE,SAAmC,CAAC;IACpE,MAAM,CAACuE,cAAcC,gBAAgB,GAAGxE,SAOtC,CAAC;IAEH,MAAMyE,QAAQ5D,sBAAsBgC,MAAM6B,IAAI,GAAG5B,QAAQ,MAAMD,MAAM8B,GAAG;IACxE,MAAMC,SAASjE,yBAAyB;QACtCmC,OAAOD,MAAM6B,IAAI,IAAIrB,QAAQ,WAAWP,QAAQ;QAChD+B,QAAQ9B,SAAS8B,MAAM;QACvBC,gBAAgBjC,MAAMiC,cAAc;QACpCrB;IACF;IACA,MAAMsB,aAAanE,sBAAsB;QACvC,oEAAoE;QACpEkC;QACA+B,QAAQ9B,SAAS8B,MAAM;QACvBpB,MAAMK;QACNkB,SAASnC,MAAM6B,IAAI,IAAIrB,QAAQ;IACjC;IAEA,MAAM4B,QAAQ;QACZd,SAAS;YAAEzB,MAAM;QAAS;QAC1B2B,WAAW;QACXC,YAAY,CAAC;QACbE,gBAAgB,CAAC;IACnB;IACA,MAAMU,QAAQ;QACZD;QACArB,UAAU,IAAIC;QACdI,eAAe,IAAIJ;QACnBH,QAAQ;QACRK,YAAY;QACZP,UAAU;QACVX,MAAMsC,OAAO;IACf;IAEA,MAAMC,UAAU,OAAOC;QACrBhB,WAAW;QACXF,SAAS;YAAEzB,MAAM;QAAa;QAC9B,IAAI;YACF,MAAM4C,SAAS,MAAMtC,IAAIuC,iBAAiB,CAACxC,SAASyC,EAAE,EAAEH;YACxDf,YACEjD,OAAOoE,WAAW,CAChBH,OAAOI,MAAM,CAAClE,GAAG,CAAC,CAACQ,SAAW;oBAC5BA,OAAO2D,QAAQ;oBACf;wBACEzD,SAASF,OAAOC,MAAM,KAAK;wBAC3BG,cAAc;wBACdI,cAAc,EAAE;oBAClB;iBACD;YAGL2B,SAAS;gBAAEzB,MAAM;gBAAW4C;YAAO;QACrC,EAAE,OAAOM,OAAO;YACdvB,WAAW,AAACuB,MAAgBC,OAAO;YACnC1B,SAAS;gBAAEzB,MAAM;YAAS;QAC5B;IACF;IAEA,MAAM4C,SACJpB,MAAMxB,IAAI,KAAK,aAAawB,MAAMxB,IAAI,KAAK,cAAcwB,MAAMoB,MAAM,GAAG;IAC1E,MAAMQ,QAAQ/F,QACZ,IACEuF,SACIA,OAAOI,MAAM,CAACjE,MAAM,CAAC,CAACO,SACpBD,oBAAoBC,QAAQZ,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,KAEvD,EAAE,EACR;QAACL;QAAQlE;KAAS;IAEpB,MAAM2E,UAAUT,SACZA,OAAOI,MAAM,CAACjE,MAAM,CAClB,CAACO;YAECZ;eADAY,OAAOC,MAAM,KAAK,eAClBb,4BAAAA,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,qBAAzBvE,0BAA2Bc,OAAO,KAClC,CAACH,oBAAoBC,QAAQZ,QAAQ,CAACY,OAAO2D,QAAQ,CAAC;OACxDrD,MAAM,GACR;IAEJ,MAAM0D,SAAS;QACb,IAAI,CAACV,UAAU,CAACQ,MAAMxD,MAAM,EAAE;QAC9B+B,WAAW;QACXF,SAAS;YAAEzB,MAAM;YAAa4C;QAAO;QACrC,IAAI;YACF,MAAMW,SAAS,MAAMjD,IAAIgD,MAAM,CAC7BjD,SAASyC,EAAE,EACXM,MAAMtE,GAAG,CAAC,CAACQ;;oBAKKZ,2BACAA;uBANO,aAEjBY,OAAOkE,MAAM,KAAK,UAAUlE,OAAOmE,MAAM,GACzC;oBAAEA,QAAQnE,OAAOmE,MAAM;gBAAC,IACxB;oBAAEC,WAAWpE,OAAOoE,SAAS;gBAAC;oBAClChE,YAAY,WAAEhB,4BAAAA,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,qBAAzBvE,0BAA2BgB,YAAY,CAACC,IAAI,qBAAM;oBAChEG,YAAY,YAAEpB,6BAAAA,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,qBAAzBvE,2BAA2BoB,YAAY,oBAAI,EAAE;mBAEvDrB,cAAcC,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,EAAErD,MAAM,GAC/C;oBAAE+D,eAAelF,cAAcC,QAAQ,CAACY,OAAO2D,QAAQ,CAAC;gBAAE,IAC1D,CAAC;;YAGTxB,SAAS;gBACPzB,MAAM;gBACN4D,SAASL,OAAOK,OAAO;gBACvBC,UAAUN,OAAOM,QAAQ;YAC3B;QACF,EAAE,OAAOX,OAAO;YACdvB,WAAW,AAACuB,MAAgBC,OAAO;YACnC1B,SAAS;gBAAEzB,MAAM;gBAAW4C;YAAO;QACrC;IACF;IAEA,MAAMkB,SAAS,CAACb,UAAkBc,OAChCnC,YAAY,CAACoC,WAAc,aACtBA;gBACH,CAACf,SAAS,EAAE,aAAKe,QAAQ,CAACf,SAAS,EAAKc;;IAG5C,MAAME,eAAe,OAAO3E;QAC1BwC,gBAAgB,CAACkC,WAAc,aAC1BA;gBACH,CAAC1E,OAAO2D,QAAQ,CAAC,EAAE;oBAAE1D,QAAQ;gBAAU;;QAEzC,IAAI;;gBAOcb;YANhB,MAAMwF,YAAYzF,cAAcC,QAAQ,CAACY,OAAO2D,QAAQ,CAAC;YACzD,MAAMM,SAAS,MAAMjD,IAAI2D,YAAY,CAAC;gBACpCE,YAAY9D,SAASyC,EAAE;eACnBxD,OAAOkE,MAAM,KAAK,UAAUlE,OAAOmE,MAAM,GACzC;gBAAEA,QAAQnE,OAAOmE,MAAM;YAAC,IACxB;gBAAEC,WAAWpE,OAAOoE,SAAS;YAAC;gBAClChE,YAAY,WAAEhB,4BAAAA,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,qBAAzBvE,0BAA2BgB,YAAY,CAACC,IAAI,qBAAM;eAE5DuE,UAAUtE,MAAM,GAAG;gBAAE+D,eAAeO;YAAU,IAAI,CAAC;YAEzDpC,gBAAgB,CAACkC,WAAc,aAC1BA;oBACH,CAAC1E,OAAO2D,QAAQ,CAAC,EAAE;wBAAE1D,QAAQ;wBAASqD,QAAQW;oBAAO;;QAEzD,EAAE,OAAOL,OAAO;YACdpB,gBAAgB,CAACkC,WAAc,aAC1BA;oBACH,CAAC1E,OAAO2D,QAAQ,CAAC,EAAE;wBACjB1D,QAAQ;wBACR4D,SAAS,AAACD,MAAgBC,OAAO;oBACnC;;QAEJ;IACF;IAEA;;;;;GAKC,GACD,MAAMiB,SAAS,OAAO9E;QACpBwE,OAAOxE,OAAO2D,QAAQ,EAAE;YAAEoB,UAAU;gBAAE9E,QAAQ;YAAW;QAAE;QAC3D,IAAI;;gBAMcb;YALhB,MAAMkE,SAAS,MAAMtC,IAAIgE,YAAY,CAAC;gBACpCH,YAAY9D,SAASyC,EAAE;eACnBxD,OAAOkE,MAAM,KAAK,UAAUlE,OAAOmE,MAAM,GACzC;gBAAEA,QAAQnE,OAAOmE,MAAM;YAAC,IACxB;gBAAEC,WAAWpE,OAAOoE,SAAS;YAAC;gBAClChE,YAAY,WAAEhB,4BAAAA,QAAQ,CAACY,OAAO2D,QAAQ,CAAC,qBAAzBvE,0BAA2BgB,YAAY,CAACC,IAAI,qBAAM;;YAElE,MAAM4E,QAAQ;gBAAEC,QAAQ5B,OAAO4B,MAAM;gBAAEC,OAAO7B,OAAO6B,KAAK;YAAC;YAC3DX,OAAOxE,OAAO2D,QAAQ,EAAE;gBACtBoB,UAAU;oBAAE9E,QAAQ;gBAAQ;gBAC5BV,QAAQF,OAAOoE,WAAW,CACxBH,OAAO/D,MAAM,CAACC,GAAG,CAAC,CAACK,QAAU;wBAACA,MAAMuF,SAAS;wBAAE9G,mBAAmBuB,OAAOkB,SAASsE,KAAK,EAAE,MAAMJ;qBAAO;YAE1G;QACF,EAAE,OAAOrB,OAAO;YACdY,OAAOxE,OAAO2D,QAAQ,EAAE;gBAAEoB,UAAU;oBAAE9E,QAAQ;oBAAU4D,SAAS,AAACD,MAAgBC,OAAO;gBAAC;YAAE;QAC9F;IACF;IAEA,wEAAwE,GACxE,MAAMyB,kBAAkB,CAACtF;QACvB,MAAMuF,cAAcxE,SAASsE,KAAK,CAC/B7F,GAAG,CAAC,CAACgG,MAAMC,QAAWD,KAAK9E,IAAI,KAAK,UAAU+E,QAAQ,CAAC,GACvDhG,MAAM,CAAC,CAACgG,QAAUA,SAAS;QAC9BjB,OAAOxE,OAAO2D,QAAQ,EAAE;YACtBoB,UAAU;gBAAE9E,QAAQ;YAAQ;YAC5BV,QAAQF,OAAOoE,WAAW,CACxBjF,0BAA0BuC,SAASsE,KAAK,EAAEE,aAAa/F,GAAG,CAAC,CAACK,QAAU;oBAACA,MAAMuF,SAAS;oBAAEvF;iBAAM;QAElG;IACF;IAEA,MAAM6F,QAAQ,CAAC,iBAAiB,EAAE3E,SAAS4E,IAAI,EAAE;IAEjD,qBACE,MAAChJ;QACC+F,MAAM7B,MAAM6B,IAAI;QAChBS,SAASD;QACT0C,SAAS;QACTC,UAAS;QACTC,YAAY5E;QACZ6E,cAAYL;;0BAEZ,KAAC5I;0BACC,cAAA,MAACU;oBAAMwI,WAAU;oBAAMC,SAAS;oBAAKC,IAAI;wBAAEC,YAAY;oBAAS;;sCAC9D,KAACC;sCAAMV;;sCACP,KAACpJ,sBAAYD,eAAe,aAAa;4BAAEgK,QAAQ;wBAAU;;;;0BAGjE,KAACxJ;gBAAcyJ,QAAQ;0BACrB,cAAA,MAAC9I;oBAAMyI,SAAS;;wBACb7D,wBAAU,KAAC7F;4BAAMgK,UAAS;sCAASnE;6BAAmB;wBAEtDF,MAAMxB,IAAI,KAAK,yBACd;;8CACE,MAAChD;oCACC8I,OAAOnF;oCACPoF,UAAU,CAACC,QAAQjC,OAASnD,OAAOmD;oCACnCsB,cAAW;;sDAEX,KAACtI;4CAAI+I,OAAM;4CAAOG,OAAM;;sDACxB,KAAClJ;4CAAI+I,OAAM;4CAASG,OAAM;;sDAC1B,KAAClJ;4CAAI+I,OAAM;4CAAQG,OAAM;;;;gCAE1BtF,QAAQ,SACPoB,MAAMxC,MAAM,KAAK,0BACf,KAACxB;oCAAgBkI,OAAM;qCACrBlE,MAAMxC,MAAM,KAAK,WAAWwC,MAAMxC,MAAM,KAAK,0BAC/C,KAACvB;oCACCuB,QAAQwC,MAAMxC,MAAM;oCACpB2G,MAAK;oCACL/C,SACEpB,MAAMxC,MAAM,KAAK,YACb,qFACA;qCAGNwC,MAAMoE,IAAI,CAACvG,MAAM,iBACnB,KAAC3C;oCACCmJ,MAAM;oCACNH,OAAM;oCACNH,OAAOjF;oCACPkF,UAAU,CAACM,QAAUvF,UAAUuF,MAAM7C,MAAM,CAACsC,KAAK;oCACjDQ,YAAY,CAAC,cAAc,EAAE/I,0BAA0B,6GAA6G,CAAC;oCACrK2H,SAAS;8CAERnD,MAAMoE,IAAI,CAACrH,GAAG,CAAC,CAACyH,qBACf,KAAC3J;4CAAuBkJ,OAAOS,KAAKzD,EAAE;sDACnCyD,KAAKC,OAAO,KAAK,UAAU,GAAGD,KAAKtB,IAAI,CAAC,QAAQ,CAAC,GAAGsB,KAAKtB,IAAI;2CADjDsB,KAAKzD,EAAE;mDAM1B,KAACjH;oCAAMgK,UAAS;8CAAO;qCAKvBlF,QAAQ,wBACV,MAAC7D;oCAAMyI,SAAS;;sDACd,KAACtI;4CACCgJ,OAAM;4CACNQ,aAAY;4CACZX,OAAO1E;4CACP2E,UAAU,CAACM,QAAUhF,YAAYgF,MAAM7C,MAAM,CAACsC,KAAK;4CACnDQ,YAAW;4CACXpB,SAAS;4CACTwB,SAAS;;wCAEVrE,WAAW9C,MAAM,KAAK,0BACrB,KAACxB;4CAAgBkI,OAAM;6CACrB;wCACH5D,WAAW9C,MAAM,KAAK,WAAW8C,WAAW9C,MAAM,KAAK,0BACtD,KAACvB;4CACCuB,QAAQ8C,WAAW9C,MAAM;4CACzB2G,MAAK;4CACL/C,SACEd,WAAW9C,MAAM,KAAK,YAClB,kFACA;6CAGN;wCACH8C,WAAW9C,MAAM,KAAK,WAAW,CAAC8C,WAAWsE,IAAI,IAAI,CAACtE,WAAW8D,IAAI,CAACvG,MAAM,iBAC3E,KAAC1C;4CAAW0J,SAAQ;4CAAQC,OAAM;sDAAiB;6CAGjD;wCACHxE,WAAW8D,IAAI,CAACvG,MAAM,iBACrB,KAACrD;4CAAKuK,KAAK;4CAACzB,cAAW;sDACpBhD,WAAW8D,IAAI,CAACrH,GAAG,CAAC,CAACiI;gDACpB,MAAMC,UAAU1F,YAAY2F,GAAG,CAACF,KAAKjE,EAAE;gDACvC,qBACE,KAACtG;oDAAuB0K,cAAc;8DACpC,cAAA,MAACzK;wDACC0K,SAAS,IACP5F,eAAe,CAACyC;gEACd,MAAMD,OAAO,IAAI5C,IAAI6C;gEACrB,IAAIgD,SAASjD,KAAKqD,MAAM,CAACL,KAAKjE,EAAE;qEAC3B,IAAIiB,KAAKsD,IAAI,GAAG9J,2BAA2BwG,KAAKuD,GAAG,CAACP,KAAKjE,EAAE,EAAEiE;gEAClE,OAAOhD;4DACT;;0EAGF,KAACrH;0EACC,cAAA,KAACX;oEAASwL,MAAK;oEAAQP,SAASA;oEAASQ,UAAU,CAAC;oEAAGC,aAAa;;;0EAEtE,KAAC9K;gEACC+K,SAASX,KAAK9B,IAAI,IAAI8B,KAAKY,KAAK,IAAIZ,KAAKjE,EAAE;gEAC3C8E,WAAWb,KAAKY,KAAK;;;;mDAhBZZ,KAAKjE,EAAE;4CAqB1B;6CAEA;wCACHxB,YAAY+F,IAAI,iBACf,KAACvK;4CACCwI,WAAU;4CACVC,SAAS;4CACTC,IAAI;gDAAEqC,UAAU;gDAAQC,QAAQ;4CAAE;4CAClCzC,cAAW;sDAEV;mDAAI/D,YAAY1C,MAAM;6CAAG,CAACE,GAAG,CAAC,CAACiI,qBAC9B,KAAC/K;oDAECqL,MAAK;oDACLpB,OAAOc,KAAK9B,IAAI,IAAI8B,KAAKY,KAAK,IAAIZ,KAAKjE,EAAE;oDACzCiF,UAAU,IACRxG,eAAe,CAACyC;4DACd,MAAMD,OAAO,IAAI5C,IAAI6C;4DACrBD,KAAKqD,MAAM,CAACL,KAAKjE,EAAE;4DACnB,OAAOiB;wDACT;mDARGgD,KAAKjE,EAAE;6CAahB;;mDAGN,MAAChG;oCAAMyI,SAAS;;sDACd,KAACtI;4CACCgJ,OAAM;4CACNQ,aAAY;4CACZX,OAAO/E;4CACPgF,UAAU,CAACM,QAAUrF,QAAQqF,MAAM7C,MAAM,CAACsC,KAAK;4CAC/CZ,SAAS;4CACTwB,SAAS;;wCAEVxE,OAAO3C,MAAM,KAAK,0BACjB,KAACxB;4CAAgBkI,OAAM;6CACrB;wCACH/D,OAAO3C,MAAM,KAAK,WAAW2C,OAAO3C,MAAM,KAAK,0BAC9C,KAACvB;4CACCuB,QAAQ2C,OAAO3C,MAAM;4CACrB2G,MAAK;4CACL/C,SACEjB,OAAO3C,MAAM,KAAK,YACd,qFACA;6CAGN;wCACH2C,OAAO3C,MAAM,KAAK,WACnB,CAAC2C,OAAOyE,IAAI,IACZ,CAACzE,OAAOiE,IAAI,CAACvG,MAAM,iBACjB,KAAC1C;4CAAW0J,SAAQ;4CAAQC,OAAM;sDAAiB;6CAGjD;wCACH3E,OAAOiE,IAAI,CAACvG,MAAM,iBACjB,KAACrD;4CAAKuK,KAAK;4CAACzB,cAAW;sDACpBnD,OAAOiE,IAAI,CAACrH,GAAG,CAAC,CAACkJ;gDAChB,MAAMhB,UAAU/F,OAAOgG,GAAG,CAACe,QAAQlF,EAAE;gDACrC,qBACE,KAACtG;oDAA0B0K,cAAc;8DACvC,cAAA,MAACzK;wDACC0K,SAAS,IACPjG,UAAU,CAAC8C;gEACT,MAAMD,OAAO,IAAI5C,IAAI6C;gEACrB,IAAIgD,SAASjD,KAAKqD,MAAM,CAACY,QAAQlF,EAAE;qEAC9B,IACHiB,KAAKsD,IAAI,GAAG9J,2BAEZwG,KAAKuD,GAAG,CAACU,QAAQlF,EAAE,EAAEkF;gEACvB,OAAOjE;4DACT;;0EAGF,KAACrH;0EACC,cAAA,KAACX;oEACCwL,MAAK;oEACLP,SAASA;oEACTQ,UAAU,CAAC;oEACXC,aAAa;;;0EAGjB,KAAC9K;gEACC+K,SACEM,QAAQ/C,IAAI,IAAI+C,QAAQL,KAAK,IAAIK,QAAQlF,EAAE;gEAE7C8E,WAAWI,QAAQL,KAAK;;;;mDA1BfK,QAAQlF,EAAE;4CA+B7B;6CAEA;wCACH7B,OAAOoG,IAAI,iBACV,KAACvK;4CACCwI,WAAU;4CACVC,SAAS;4CACTC,IAAI;gDAAEqC,UAAU;gDAAQC,QAAQ;4CAAE;4CAClCzC,cAAW;sDAEV;mDAAIpE,OAAOrC,MAAM;6CAAG,CAACE,GAAG,CAAC,CAACkJ,wBACzB,KAAChM;oDAECqL,MAAK;oDACLpB,OAAO+B,QAAQ/C,IAAI,IAAI+C,QAAQL,KAAK,IAAIK,QAAQlF,EAAE;oDAClDiF,UAAU,IACR7G,UAAU,CAAC8C;4DACT,MAAMD,OAAO,IAAI5C,IAAI6C;4DACrBD,KAAKqD,MAAM,CAACY,QAAQlF,EAAE;4DACtB,OAAOiB;wDACT;mDARGiE,QAAQlF,EAAE;6CAanB;;;;6BAIR;wBAEHtB,MAAMxB,IAAI,KAAK,6BACd,KAACjC;4BAAgBkI,OAAM;6BACrB;wBAEHrD,uBACC,MAAC9F;4BAAMyI,SAAS;;8CACd,KAACrI;oCAAW0J,SAAQ;oCAAQC,OAAM;8CAC/BoB,QAAQrF;;gCAEVA,OAAOsF,SAAS,iBACf,KAACrM;oCAAMgK,UAAS;8CACb,CAAC,qBAAqB,EAAEjD,OAAOI,MAAM,CAACpD,MAAM,CAAC,IAAI,EAAEgD,OAAOuF,KAAK,CAAC,gDAAgD,CAAC;qCAElH;8CACJ,KAACrL;oCACCyI,SAAS;oCACT6C,WAAU;oCACV5C,IAAI;wCAAE6C,WAAW;wCAAQC,GAAG;wCAAGC,GAAG;oCAAE;oCACpClD,cAAW;8CAEVzC,OAAOI,MAAM,CAAClE,GAAG,CAAC,CAACQ,uBAClB,KAACkJ;4CAEClJ,QAAQA;4CACRqF,OAAOtE,SAASsE,KAAK;4CACrBjG,UAAUA,QAAQ,CAACY,OAAO2D,QAAQ,CAAC;4CACnCwF,UAAU,CAAC1E,OAASD,OAAOxE,OAAO2D,QAAQ,EAAEc;4CAC5ClC,cAAcA,YAAY,CAACvC,OAAO2D,QAAQ,CAAC;4CAC3CyF,gBAAgB,IAAM,KAAKzE,aAAa3E;4CACxCqJ,UAAU,IAAM,KAAKvE,OAAO9E;4CAC5BsJ,mBAAmB,IAAMhE,gBAAgBtF;4CACzCuJ,UAAUrH,MAAMxB,IAAI,KAAK;2CATpBV,OAAO2D,QAAQ;;gCAazBI,wBACC,KAACnG;oCAAW0J,SAAQ;oCAAQC,OAAM;8CAC/B,GAAGxD,QAAQ,CAAC,EAAEA,YAAY,IAAI,uBAAuB,oBAAoB,wGAAwG,CAAC;qCAEnL;;6BAEJ;wBAEH7B,MAAMxB,IAAI,KAAK,uBACd,KAAC8I;4BAAYlF,SAASpC,MAAMoC,OAAO;4BAAEC,UAAUrC,MAAMqC,QAAQ;6BAC3D;;;;0BAGR,KAAC3H;0BACEsF,MAAMxB,IAAI,KAAK,uBACd,KAAClE;oBAAO8K,SAAQ;oBAAYO,SAAS3E;8BAAO;mCAI5C;;sCACE,KAAC1G;4BAAOqL,SAAS3E;sCAAO;;wBACvBhB,MAAMxB,IAAI,KAAK,aAAawB,MAAMxB,IAAI,KAAK,4BAC1C;;8CACE,KAAClE;oCAAOqL,SAAS5E;oCAAOsG,UAAUrH,MAAMxB,IAAI,KAAK;8CAAa;;8CAG9D,KAAClE;oCACC8K,SAAQ;oCACRiC,UAAU,CAACzF,MAAMxD,MAAM,IAAI4B,MAAMxB,IAAI,KAAK;oCAC1CmH,SAAS,IAAM,KAAK7D;8CAEnB9B,MAAMxB,IAAI,KAAK,cACZ,eACA,CAAC,OAAO,EAAEoD,MAAMxD,MAAM,CAAC,CAAC,EAAEwD,MAAMxD,MAAM,KAAK,IAAI,WAAW,UAAU;;;2CAI5E,KAAC9D;4BACC8K,SAAQ;4BACRiC,UACErH,MAAMxB,IAAI,KAAK,gBACdW,CAAAA,QAAQ,SAAS,CAACE,SAASF,QAAQ,UAAU,CAACW,YAAY+F,IAAI,GAAG,CAACpG,OAAOoG,IAAI,AAAD;4BAE/EF,SAAS,IACP,KAAKzE,QACH/B,QAAQ,SACJ;oCAAEX,MAAM;oCAAQa;gCAAO,IACvBF,QAAQ,UACN;oCAAEX,MAAM;oCAAS+I,SAAS;2CAAIzH,YAAY0H,IAAI;qCAAG;gCAAC,IAClD;oCAAEhJ,MAAM;oCAAYiJ,YAAY;2CAAIhI,OAAO+H,IAAI;qCAAG;gCAAC;sCAG9D;;;;;;;AASf;AACA9I,qBAAqBgJ,WAAW,GAAG;AAEnC,SAASjB,QAAQrF,MAAqC;IACpD,MAAMuG,QAAQ,CAAC5J,SACbqD,OAAOI,MAAM,CAACjE,MAAM,CAAC,CAACO,SAAWA,OAAOC,MAAM,KAAKA,QAAQK,MAAM;IACnE,OAAO,GAAGuJ,MAAM,YAAY,YAAY,EAAEA,MAAM,sBAAsB,YAAY,EAAEA,MAAM,WAAW,QAAQ,CAAC;AAChH;AAEA,SAASX,UAAUrI,KAclB;;QAqKgBA,qBAGAA,sBAGAA;IA1Kf,MAAM,EAAEb,MAAM,EAAEZ,QAAQ,EAAEmK,QAAQ,EAAE,GAAG1I;IACvC,MAAM8E,OAAO3F,OAAO2F,IAAI,IAAI3F,OAAOqI,KAAK,IAAIrI,OAAO2D,QAAQ;IAC3D,MAAMxD,eAAOf,4BAAAA,SAAUgB,YAAY,mBAAI;IACvC,MAAM0J,UAAU3J,KAAKE,IAAI,GAAGC,MAAM,GAAGnC;IACrC,MAAM4G,oBAAW3F,4BAAAA,SAAU2F,QAAQ,oBAAI;QAAE9E,QAAQ;IAAO;IACxD,MAAMV,SAASF,OAAOC,MAAM,UAACF,4BAAAA,SAAUG,MAAM,oBAAI,CAAC,GAAGwK,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAE5E,SAAS,GAAG6E,EAAE7E,SAAS;IAC7F,MAAM8E,YAAY3K,OAAOE,MAAM,CAAC,CAACI,QAAUA,MAAMC,QAAQ,KAAK,OAAOQ,MAAM;IAC3E,qBACE,KAAC/C;QAAMuL,WAAU;QAAKxB,SAAQ;QAAWpB,IAAI;YAAE8C,GAAG;QAAI;QAAGjD,cAAYJ;kBACnE,cAAA,MAACnI;YAAMyI,SAAS;;8BACd,MAACzI;oBACCwI,WAAW;wBAAEmE,IAAI;wBAAUC,IAAI;oBAAM;oBACrCnE,SAAS;oBACTC,IAAI;wBAAEC,YAAY;4BAAEiE,IAAI;wBAAS;oBAAE;;sCAEnC,MAAC5M;4BAAM0I,IAAI;gCAAEmE,UAAU;gCAAGC,UAAU;4BAAE;;8CACpC,KAAC1M;oCAAW0J,SAAQ;8CAAS3B;;gCAC5B3F,OAAOqI,KAAK,IAAIrI,OAAOqI,KAAK,KAAK1C,qBAChC,KAAC/H;oCAAW0J,SAAQ;oCAAUC,OAAM;8CACjCvH,OAAOqI,KAAK;qCAEb;;;sCAEN,MAAC7K;4BAAMwI,WAAU;4BAAMC,SAAS;4BAAGC,IAAI;gCAAEC,YAAY;4BAAS;;gCAC3DnG,OAAOkE,MAAM,KAAK,uBACjB,KAACxH;oCAAKqL,MAAK;oCAAQT,SAAQ;oCAAWX,OAAM;qCAC1C;gCACH3G,OAAOuK,IAAI,iBACV,KAAC7N;oCAAKqL,MAAK;oCAAQT,SAAQ;oCAAWX,OAAM;qCAC1C;8CACJ,KAACjK;oCACCqL,MAAK;oCACLpB,OAAO7H,aAAa,CAACkB,OAAOC,MAAM,CAAC;oCACnCsH,OAAOrI,aAAa,CAACc,OAAOC,MAAM,CAAC;;;;;;gBAIxCD,OAAOC,MAAM,KAAK,0BACjB,KAACzC;oBAAMsL,WAAU;oBAAK7C,SAAS;oBAAKC,IAAI;wBAAE+C,GAAG;wBAAGuB,IAAI;oBAAI;8BACrDxK,OAAOyK,MAAM,CAACjL,GAAG,CAAC,CAACkL,sBAClB,KAAC9M;4BAECkL,WAAU;4BACVxB,SAAQ;4BACRC,OAAM;sCAELmD,MAAMC,MAAM;2BALRD,MAAME,IAAI;mCAUrB,MAACpN;oBAAMyI,SAAS;;sCACd,KAAClJ;4BACC8N,uBACE,KAACpO;gCACCiL,OAAO,WAAEtI,4BAAAA,SAAUc,OAAO,oBAAI;gCAC9BuG,UAAU,CAACM,QACTlG,MAAMsI,QAAQ,CAAC;wCAAEjJ,SAAS6G,MAAM7C,MAAM,CAACwD,OAAO;oCAAC;gCAEjD6B,UAAUA;;4BAGd5C,OAAM;;wBAEPvH,CAAAA,4BAAAA,SAAUc,OAAO,MAAK,QAAQ,qBAC7B;;8CACE,KAACvC;oCACCgJ,OACE3G,OAAOO,QAAQ,CAACH,YAAY,GACxB,kBACA;oCAEN+G,aAAY;oCACZX,OAAOrG;oCACPsG,UAAU,CAACM,QACTlG,MAAMsI,QAAQ,CAAC;4CAAE/I,cAAc2G,MAAM7C,MAAM,CAACsC,KAAK;wCAAC;oCAEpD+C,UAAUA;oCACVuB,UAAU9K,OAAOO,QAAQ,CAACH,YAAY;oCACtCwD,OAAOkG;oCACP9C,YACE8C,UACI,CAAC,+BAA+B,EAAE3L,2BAA2B,YAAY,CAAC,GAC1E;oCAENyH,SAAS;oCACTmC,MAAK;;gCAEN/H,OAAOO,QAAQ,CAACC,YAAY,CAACF,MAAM,iBAClC,KAACtD;oCAAU+I,cAAY,CAAC,uBAAuB,EAAEJ,MAAM;8CACpD3F,OAAOO,QAAQ,CAACC,YAAY,CAAChB,GAAG,CAAC,CAACkB;;6DACjC,KAAC3D;4CAEC8N,uBACE,KAACpO;gDACCiL,OAAO,UACLtI,4BAAAA,SAAUoB,YAAY,CAACG,QAAQ,CAACD,wBAAS;gDAE3C+F,UAAU,CAACM;;2DACTlG,MAAMsI,QAAQ,CAAC;wDACb3I,cAAcuG,MAAM7C,MAAM,CAACwD,OAAO,GAC9B;uEAAKtI,4BAAAA,SAAUoB,YAAY,mBAAI,EAAE;4DAAGE;yDAAK,GACzC,UAACtB,4BAAAA,SAAUoB,YAAY,oBAAI,EAAE,EAAEf,MAAM,CACnC,CAACsL,QAAUA,UAAUrK;oDAE7B;;gDAEF6I,UAAUA;;4CAGd5C,OAAOzI,2BAA2B,CAACwC,KAAK;2CAlBnCA;;qCAsBT;8CACJ,MAAClD;oCAAMwI,WAAU;oCAAMC,SAAS;oCAAGC,IAAI;wCAAEqC,UAAU;wCAAQC,QAAQ;oCAAE;;sDACnE,KAAChM;4CACCuL,MAAK;4CACLF,SAAShH,MAAMuI,cAAc;4CAC7BG,UAAUA;sDACX;;sDAGD,KAAC/M;4CACCuL,MAAK;4CACLF,SAAShH,MAAMwI,QAAQ;4CACvBE,UAAUA,YAAYxE,SAAS9E,MAAM,KAAK;sDAEzCV,OAAOe,MAAM,GAAG,iBAAiB;;;;gCAGrCyE,SAAS9E,MAAM,KAAK,2BACnB,KAACxB;oCAAgBkI,OAAM;qCACrB;gCACH5B,SAAS9E,MAAM,KAAK,yBACnB,MAACzC;oCAAMyI,SAAS;;sDACd,KAAC1J;4CAAMgK,UAAS;sDAAWxB,SAASlB,OAAO;;sDAC3C,KAACrG;4CAAMwI,WAAU;sDACf,cAAA,KAACxJ;gDAAOuL,MAAK;gDAAQF,SAAShH,MAAMyI,iBAAiB;gDAAEC,UAAUA;0DAAU;;;;qCAK7E;gCACHhK,OAAOe,MAAM,iBACZ,MAAC9C;oCAAMyI,SAAS;oCAAGF,cAAY,CAAC,mBAAmB,EAAEJ,MAAM;;sDACzD,KAAC/H;4CAAW0J,SAAQ;4CAAUC,OAAM;sDACjC2C,YACG,GAAGA,UAAU,IAAI,EAAE3K,OAAOe,MAAM,CAAC,CAAC,EAAEf,OAAOe,MAAM,KAAK,IAAI,UAAU,SAAS,aAAa,EAAEqF,KAAK,6CAA6C,CAAC,GAC/I,CAAC,0FAA0F,CAAC;;wCAEjGpG,OAAOC,GAAG,CAAC,CAACK,sBACX,KAACxB;gDAECwB,OAAOA;gDACP8G,OAAOvI,uBAAuByC,MAAMwE,KAAK,EAAExF,MAAMuF,SAAS;gDAC1DqB,UAAU,CAAChC;;2DACT5D,MAAMsI,QAAQ,CAAC;wDAAE5J,QAAQ,qBAAMH,4BAAAA,SAAUG,MAAM,mBAAI,CAAC;4DAAI,CAACkF,KAAKW,SAAS,CAAC,EAAEX;;oDAAO;;gDAEnF8E,UAAUA;+CANL1J,MAAMuF,SAAS;;qCAUxB;gCACHvE,EAAAA,sBAAAA,MAAM0B,YAAY,qBAAlB1B,oBAAoBZ,MAAM,MAAK,0BAC9B,KAACxB;oCAAgBkI,OAAM;qCACrB;gCACH9F,EAAAA,uBAAAA,MAAM0B,YAAY,qBAAlB1B,qBAAoBZ,MAAM,MAAK,yBAC9B,KAAC1D;oCAAMgK,UAAS;8CAAS1F,MAAM0B,YAAY,CAACsB,OAAO;qCACjD;gCACHhD,EAAAA,uBAAAA,MAAM0B,YAAY,qBAAlB1B,qBAAoBZ,MAAM,MAAK,UAC9BY,MAAM0B,YAAY,CAACe,MAAM,CAACM,KAAK,iBAC7B,KAACrH;oCAAMgK,UAAS;8CACb1F,MAAM0B,YAAY,CAACe,MAAM,CAACM,KAAK,CAACC,OAAO;mDAG1C,MAACtG;oCACC+J,SAAQ;oCACRpB,IAAI;wCAAE8C,GAAG;oCAAI;oCACbjD,cAAY,CAAC,eAAe,EAAEJ,MAAM;;sDAEpC,KAAC/H;4CAAW0J,SAAQ;sDAAS,CAAC,SAAS,EAAEzG,MAAM0B,YAAY,CAACe,MAAM,CAAC0H,OAAO,EAAE;;sDAC5E,KAACpN;4CACC0J,SAAQ;4CACRpB,IAAI;gDACF+E,YAAY;gDACZC,WAAW;gDACXC,IAAI;4CACN;sDAECtK,MAAM0B,YAAY,CAACe,MAAM,CAAC7B,IAAI;;;qCAInC;;;;;;;;AAQpB;AAEA,SAAS+H,YAAY3I,KAGpB;IACC,MAAMuK,UAAUvK,MAAMyD,OAAO,CAAC7E,MAAM,CAClC,CACEwE,SAEAA,OAAOoH,OAAO,KAAK;IAEvB,qBACE,MAAC7N;QAAMyI,SAAS;;0BACd,KAAC1J;gBAAMgK,UAAU1F,MAAM0D,QAAQ,GAAG,YAAY;0BAC3C1D,MAAM0D,QAAQ,GACX,CAAC,SAAS,EAAE1D,MAAM0D,QAAQ,CAAC,CAAC,EAAE1D,MAAM0D,QAAQ,KAAK,IAAI,WAAW,SAAS,2DAA2D,CAAC,GACrI;;YAEL6G,QAAQ9K,MAAM,iBACb,MAAC9C;gBAAMyI,SAAS;;kCACd,KAACrI;wBAAW0J,SAAQ;kCAAY;;oBAG/B8D,QAAQ5L,GAAG,CAAC,CAACyE;4BAGPA;6CAFL,MAACzG;4BAA4ByI,SAAS;;8CACpC,KAACrI;oCAAW0J,SAAQ;+CACjBrD,gBAAAA,OAAOoE,KAAK,YAAZpE,gBAAgBA,OAAON,QAAQ;;gCAEjCM,OAAOwG,MAAM,CAACjL,GAAG,CAAC,CAACkL,sBAClB,KAAC9M;wCAEC0J,SAAQ;wCACRC,OAAM;kDAELmD,MAAMC,MAAM;uCAJRD,MAAME,IAAI;;2BANT3G,OAAON,QAAQ;;;iBAgB7B;;;AAGV;AAEA,eAAe/C,qBAAoB"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/components/enroll-dialog.tsx"],"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'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n type ChipProps,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n List,\n ListItem,\n ListItemButton,\n ListItemIcon,\n ListItemText,\n MenuItem,\n Paper,\n Stack,\n Tab,\n Tabs,\n TextField,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport { useMemo, useState } from 'react'\nimport {\n OUTREACH_ENROLL_BATCH_MAX,\n type OutreachEnrollOutcome,\n type OutreachEnrollPreviewPerson,\n type OutreachEnrollPreviewResponse,\n type OutreachEnrollPreviewStatus,\n type OutreachEnrollSource,\n type OutreachPreviewResponse,\n type OutreachStepTestResponse,\n} from '../model/outreach-api'\nimport {\n OUTREACH_ATTESTATION_LABELS,\n OUTREACH_PERSONAL_LINE_MAX,\n type OutreachAttestationKind,\n type OutreachSequence,\n type OutreachSequenceStep,\n} from '../model/outreach.types'\nimport { outreachEmailStepLabel } from './curate-step-dialog'\nimport {\n OutreachCuratedStepEditor,\n outreachDraftState,\n outreachDraftToOverride,\n outreachMemberDraftStates,\n type OutreachCuratedDraftState,\n} from './curated-step-editor'\nimport { OutreachLoading, OutreachLoadProblem } from './outreach-ui'\nimport type { OutreachApi } from './use-outreach-api'\nimport {\n type OutreachContactOption,\n useOutreachContactSearch,\n useOutreachLeadSearch,\n useOutreachSavedViews,\n} from './use-outreach-crm'\n\nexport interface OutreachEnrollDialogProps {\n open: boolean\n onClose(): void\n orgId: string\n sequence: OutreachSequence\n /** The consent group of the sequence's site: whose names a search shows. */\n contactGroupId: string\n uid: string | null\n api: OutreachApi\n}\n\nconst STATUS_LABELS: Record<OutreachEnrollPreviewStatus, string> = {\n eligible: 'Eligible',\n needs_confirmation: 'Needs you',\n blocked: 'Blocked',\n}\n\nconst STATUS_COLORS: Record<OutreachEnrollPreviewStatus, ChipProps['color']> = {\n eligible: 'success',\n needs_confirmation: 'warning',\n blocked: 'default',\n}\n\n/** Where one person's curated drafts stand (AGL-3324). */\ntype Curation =\n | { status: 'idle' }\n | { status: 'drafting' }\n | { status: 'failed'; message: string }\n | { status: 'ready' }\n\n/** What the rep has supplied for one person. */\ninterface Supplied {\n include: boolean\n personalLine: string\n attestations: OutreachAttestationKind[]\n /** The email steps drafted for this person, by step index; absent until they curate. */\n drafts?: Record<number, OutreachCuratedDraftState>\n curation?: Curation\n}\n\n/** The drafts the rep used, as the enroll and the preview carry them. */\nfunction usedOverrides(supplied: Supplied | undefined) {\n return Object.values(supplied?.drafts ?? {})\n .map(outreachDraftToOverride)\n .filter((override): override is NonNullable<typeof override> => override !== null)\n}\n\n/** Whether a drafted step is still waiting on the rep to use it or keep the template. */\nfunction hasOpenDrafts(supplied: Supplied | undefined): boolean {\n return Object.values(supplied?.drafts ?? {}).some((draft) => draft.decision === 'pending')\n}\n\n/** Where one person's test send stands (AGL-3325). */\ntype StepTest =\n | { status: 'sending' }\n | { status: 'sent'; answer: OutreachStepTestResponse }\n | { status: 'failed'; message: string }\n\ntype Stage =\n | { kind: 'source' }\n | { kind: 'previewing' }\n | { kind: 'preview'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'enrolling'; answer: OutreachEnrollPreviewResponse }\n | { kind: 'done'; results: OutreachEnrollOutcome[]; enrolled: number }\n\n/** Whether a person may be sent to Confirm as the rep has left them. */\nexport function outreachPersonReady(\n person: OutreachEnrollPreviewPerson,\n supplied: Supplied | undefined,\n): boolean {\n if (person.status === 'blocked' || !supplied?.include) return false\n const line = supplied.personalLine.trim()\n if (line.length > OUTREACH_PERSONAL_LINE_MAX) return false\n // A draft the rep has read but neither used nor kept holds them back\n // (AGL-3324): nothing is enrolled with a decision still open.\n if (hasOpenDrafts(supplied)) return false\n if (person.status === 'eligible') return true\n if (person.requires.personalLine && !line) return false\n return person.requires.attestations.every((kind) =>\n supplied.attestations.includes(kind),\n )\n}\n\n/**\n * Enroll people in a sequence (AGL-2980).\n *\n * The rep picks a saved Contacts view or searches for people, and sees each\n * marked as the gates see them: eligible, blocked with the reason, or\n * waiting on them — for a cold contact, a personal line and the three\n * attestations only they can make, stored on the enrollment with who ticked\n * them and when. Enroll sends only the people who are ready, and the server\n * checks every gate again as it enrolls them.\n */\nexport function OutreachEnrollDialog(props: OutreachEnrollDialogProps) {\n const { orgId, sequence, api } = props\n const theme = useTheme()\n const narrow = useMediaQuery(theme.breakpoints.down('sm'))\n const [tab, setTab] = useState<'view' | 'search' | 'leads'>('view')\n const [viewId, setViewId] = useState('')\n const [text, setText] = useState('')\n const [picked, setPicked] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n // The leads picked from the sequence's site (AGL-3234), kept apart from\n // the contacts: the two are different records and the source names which.\n const [leadText, setLeadText] = useState('')\n const [pickedLeads, setPickedLeads] = useState<Map<string, OutreachContactOption>>(\n new Map(),\n )\n const [stage, setStage] = useState<Stage>({ kind: 'source' })\n const [problem, setProblem] = useState<string | null>(null)\n const [supplied, setSupplied] = useState<Record<string, Supplied>>({})\n const [emailPreview, setEmailPreview] = useState<\n Record<\n string,\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n >\n >({})\n const [stepTests, setStepTests] = useState<Record<string, StepTest>>({})\n\n const views = useOutreachSavedViews(props.open ? orgId : null, props.uid)\n const search = useOutreachContactSearch({\n orgId: props.open && tab === 'search' ? orgId : null,\n hostId: sequence.hostId,\n contactGroupId: props.contactGroupId,\n text,\n })\n const leadSearch = useOutreachLeadSearch({\n // The lead silo is the org's (AGL-3275); the site still narrows it.\n orgId,\n hostId: sequence.hostId,\n text: leadText,\n enabled: props.open && tab === 'leads',\n })\n\n const reset = () => {\n setStage({ kind: 'source' })\n setProblem(null)\n setSupplied({})\n setEmailPreview({})\n setStepTests({})\n }\n const close = () => {\n reset()\n setPicked(new Map())\n setPickedLeads(new Map())\n setText('')\n setLeadText('')\n setViewId('')\n props.onClose()\n }\n\n const preview = async (source: OutreachEnrollSource) => {\n setProblem(null)\n setStage({ kind: 'previewing' })\n try {\n const answer = await api.previewEnrollment(sequence.id, source)\n setSupplied(\n Object.fromEntries(\n answer.people.map((person) => [\n person.personId,\n {\n include: person.status !== 'blocked',\n personalLine: '',\n attestations: [],\n },\n ]),\n ),\n )\n setStage({ kind: 'preview', answer })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'source' })\n }\n }\n\n const answer =\n stage.kind === 'preview' || stage.kind === 'enrolling' ? stage.answer : null\n const ready = useMemo(\n () =>\n answer\n ? answer.people.filter((person) =>\n outreachPersonReady(person, supplied[person.personId]),\n )\n : [],\n [answer, supplied],\n )\n const waiting = answer\n ? answer.people.filter(\n (person) =>\n person.status !== 'blocked' &&\n supplied[person.personId]?.include &&\n !outreachPersonReady(person, supplied[person.personId]),\n ).length\n : 0\n\n const enroll = async () => {\n if (!answer || !ready.length) return\n setProblem(null)\n setStage({ kind: 'enrolling', answer })\n try {\n const result = await api.enroll(\n sequence.id,\n ready.map((person) => ({\n // A contact by id, or a lead by its key (AGL-3234).\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n attestations: supplied[person.personId]?.attestations ?? [],\n // The steps they curated and confirmed (AGL-3324); nothing else.\n ...(usedOverrides(supplied[person.personId]).length\n ? { stepOverrides: usedOverrides(supplied[person.personId]) }\n : {}),\n })),\n )\n setStage({\n kind: 'done',\n results: result.results,\n enrolled: result.enrolled,\n })\n } catch (error) {\n setProblem((error as Error).message)\n setStage({ kind: 'preview', answer })\n }\n }\n\n const supply = (personId: string, next: Partial<Supplied>) =>\n setSupplied((previous) => ({\n ...previous,\n [personId]: { ...previous[personId], ...next } as Supplied,\n }))\n\n const previewEmail = async (person: OutreachEnrollPreviewPerson) => {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'loading' },\n }))\n try {\n const overrides = usedOverrides(supplied[person.personId])\n const result = await api.previewEmail({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n // The preview shows the curated version (AGL-3324).\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n })\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: { status: 'ready', answer: result },\n }))\n } catch (error) {\n setEmailPreview((previous) => ({\n ...previous,\n [person.personId]: {\n status: 'failed',\n message: (error as Error).message,\n },\n }))\n }\n }\n\n /**\n * Curate for this person (AGL-3324): every email step drafted from their\n * record, the sequence's steps and the personal line as written so far,\n * shown under them for the rep to edit and confirm. Nothing is stored\n * until Enroll carries the drafts they used.\n */\n const curate = async (person: OutreachEnrollPreviewPerson) => {\n supply(person.personId, { curation: { status: 'drafting' } })\n try {\n const answer = await api.curateDrafts({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n })\n const audit = { prompt: answer.prompt, model: answer.model }\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n answer.drafts.map((draft) => [draft.stepIndex, outreachDraftState(draft, sequence.steps, 'ai', audit)]),\n ),\n })\n } catch (error) {\n supply(person.personId, { curation: { status: 'failed', message: (error as Error).message } })\n }\n }\n\n /** The rep's own words for every email step, when the AI cannot draft. */\n const writeThemselves = (person: OutreachEnrollPreviewPerson) => {\n const stepIndexes = sequence.steps\n .map((step, index) => (step.kind === 'email' ? index : -1))\n .filter((index) => index >= 0)\n supply(person.personId, {\n curation: { status: 'ready' },\n drafts: Object.fromEntries(\n outreachMemberDraftStates(sequence.steps, stepIndexes).map((draft) => [draft.stepIndex, draft]),\n ),\n })\n }\n\n /**\n * This person's first email, sent to the member as a test (AGL-3325):\n * their record, the personal line as written so far and the curated copy\n * they used (AGL-3324) fill it, and nothing is enrolled or stored for\n * them.\n */\n const sendTest = async (person: OutreachEnrollPreviewPerson) => {\n setStepTests((previous) => ({ ...previous, [person.personId]: { status: 'sending' } }))\n try {\n const overrides = usedOverrides(supplied[person.personId])\n const answer = await api.sendStepTest({\n sequenceId: sequence.id,\n ...(person.target === 'lead' && person.leadId\n ? { leadId: person.leadId }\n : { contactId: person.contactId }),\n personalLine: supplied[person.personId]?.personalLine.trim() ?? '',\n ...(overrides.length ? { stepOverrides: overrides } : {}),\n })\n setStepTests((previous) => ({ ...previous, [person.personId]: { status: 'sent', answer } }))\n } catch (error) {\n setStepTests((previous) => ({\n ...previous,\n [person.personId]: { status: 'failed', message: (error as Error).message },\n }))\n }\n }\n\n const title = `Enroll people in ${sequence.name}`\n\n return (\n <Dialog\n open={props.open}\n onClose={close}\n fullWidth\n maxWidth=\"md\"\n fullScreen={narrow}\n aria-label={title}\n >\n <DialogTitle>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <span>{title}</span>\n <HelpTip {...pluginDocsHelp('sequences', { anchor: '#enroll' })} />\n </Stack>\n </DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2}>\n {problem ? <Alert severity=\"error\">{problem}</Alert> : null}\n\n {stage.kind === 'source' ? (\n <>\n <Tabs\n value={tab}\n onChange={(_event, next) => setTab(next)}\n aria-label=\"Where the people come from\"\n >\n <Tab value=\"view\" label=\"Saved view\" />\n <Tab value=\"search\" label=\"Search\" />\n <Tab value=\"leads\" label=\"Leads\" />\n </Tabs>\n {tab === 'view' ? (\n views.status === 'loading' ? (\n <OutreachLoading label=\"Loading saved views…\" />\n ) : views.status === 'error' || views.status === 'refused' ? (\n <OutreachLoadProblem\n status={views.status}\n what=\"saved views\"\n message={\n views.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : null\n }\n />\n ) : views.data.length ? (\n <TextField\n select\n label=\"Saved Contacts view\"\n value={viewId}\n onChange={(event) => setViewId(event.target.value)}\n helperText={`Enrolls up to ${OUTREACH_ENROLL_BATCH_MAX} of the people the view shows at this sequence’s site — a Contacts view, or a Leads view of the site’s leads.`}\n fullWidth\n >\n {views.data.map((view) => (\n <MenuItem key={view.id} value={view.id}>\n {view.section === 'leads' ? `${view.name} (Leads)` : view.name}\n </MenuItem>\n ))}\n </TextField>\n ) : (\n <Alert severity=\"info\">\n You have no saved Contacts views to enroll from. Save one in\n the CRM, or search instead.\n </Alert>\n )\n ) : tab === 'leads' ? (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search leads\"\n placeholder=\"A name, or an email address\"\n value={leadText}\n onChange={(event) => setLeadText(event.target.value)}\n helperText=\"The open leads at this sequence’s site. A lead is enrolled as it is, and follows itself to the contact it becomes.\"\n fullWidth\n autoFocus\n />\n {leadSearch.status === 'loading' ? (\n <OutreachLoading label=\"Reading leads…\" />\n ) : null}\n {leadSearch.status === 'error' || leadSearch.status === 'refused' ? (\n <OutreachLoadProblem\n status={leadSearch.status}\n what=\"leads\"\n message={\n leadSearch.status === 'refused'\n ? 'Enrolling reads your CRM’s leads, and your role does not include Manage data.'\n : 'The leads could not be read. Try again.'\n }\n />\n ) : null}\n {leadSearch.status === 'ready' && !leadSearch.idle && !leadSearch.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No open leads at this sequence’s site match.\n </Typography>\n ) : null}\n {leadSearch.data.length ? (\n <List dense aria-label=\"Lead results\">\n {leadSearch.data.map((lead) => {\n const checked = pickedLeads.has(lead.id)\n return (\n <ListItem key={lead.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(lead.id)\n else if (next.size < OUTREACH_ENROLL_BATCH_MAX) next.set(lead.id, lead)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox edge=\"start\" checked={checked} tabIndex={-1} disableRipple />\n </ListItemIcon>\n <ListItemText\n primary={lead.name || lead.email || lead.id}\n secondary={lead.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {pickedLeads.size ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked leads\"\n >\n {[...pickedLeads.values()].map((lead) => (\n <Chip\n key={lead.id}\n size=\"small\"\n label={lead.name || lead.email || lead.id}\n onDelete={() =>\n setPickedLeads((previous) => {\n const next = new Map(previous)\n next.delete(lead.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n ) : (\n <Stack spacing={1.5}>\n <TextField\n label=\"Search contacts\"\n placeholder=\"A name, or an email address\"\n value={text}\n onChange={(event) => setText(event.target.value)}\n fullWidth\n autoFocus\n />\n {search.status === 'loading' ? (\n <OutreachLoading label=\"Searching…\" />\n ) : null}\n {search.status === 'error' || search.status === 'refused' ? (\n <OutreachLoadProblem\n status={search.status}\n what=\"contacts\"\n message={\n search.status === 'refused'\n ? 'Enrolling reads your CRM’s contacts, and your role does not include Manage data.'\n : 'The search failed. Try again.'\n }\n />\n ) : null}\n {search.status === 'ready' &&\n !search.idle &&\n !search.data.length ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n No contacts at this sequence’s site match.\n </Typography>\n ) : null}\n {search.data.length ? (\n <List dense aria-label=\"Search results\">\n {search.data.map((contact) => {\n const checked = picked.has(contact.id)\n return (\n <ListItem key={contact.id} disablePadding>\n <ListItemButton\n onClick={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n if (checked) next.delete(contact.id)\n else if (\n next.size < OUTREACH_ENROLL_BATCH_MAX\n )\n next.set(contact.id, contact)\n return next\n })\n }\n >\n <ListItemIcon>\n <Checkbox\n edge=\"start\"\n checked={checked}\n tabIndex={-1}\n disableRipple\n />\n </ListItemIcon>\n <ListItemText\n primary={\n contact.name || contact.email || contact.id\n }\n secondary={contact.email}\n />\n </ListItemButton>\n </ListItem>\n )\n })}\n </List>\n ) : null}\n {picked.size ? (\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n aria-label=\"Picked\"\n >\n {[...picked.values()].map((contact) => (\n <Chip\n key={contact.id}\n size=\"small\"\n label={contact.name || contact.email || contact.id}\n onDelete={() =>\n setPicked((previous) => {\n const next = new Map(previous)\n next.delete(contact.id)\n return next\n })\n }\n />\n ))}\n </Stack>\n ) : null}\n </Stack>\n )}\n </>\n ) : null}\n\n {stage.kind === 'previewing' ? (\n <OutreachLoading label=\"Checking each person…\" />\n ) : null}\n\n {answer ? (\n <Stack spacing={1.5}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {summary(answer)}\n </Typography>\n {answer.truncated ? (\n <Alert severity=\"info\">\n {`This shows the first ${answer.people.length} of ${answer.total}. Enroll these, then preview again for the rest.`}\n </Alert>\n ) : null}\n <Stack\n spacing={1}\n component=\"ul\"\n sx={{ listStyle: 'none', p: 0, m: 0 }}\n aria-label=\"People\"\n >\n {answer.people.map((person) => (\n <PersonRow\n key={person.personId}\n person={person}\n steps={sequence.steps}\n supplied={supplied[person.personId]}\n onSupply={(next) => supply(person.personId, next)}\n emailPreview={emailPreview[person.personId]}\n onPreviewEmail={() => void previewEmail(person)}\n stepTest={stepTests[person.personId]}\n onSendTest={() => void sendTest(person)}\n onCurate={() => void curate(person)}\n onWriteThemselves={() => writeThemselves(person)}\n disabled={stage.kind === 'enrolling'}\n />\n ))}\n </Stack>\n {waiting ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`${waiting} ${waiting === 1 ? 'person still needs' : 'people still need'} a personal line or a confirmation, or a decision on a draft, and won't be enrolled until they have one.`}\n </Typography>\n ) : null}\n </Stack>\n ) : null}\n\n {stage.kind === 'done' ? (\n <DoneSummary results={stage.results} enrolled={stage.enrolled} />\n ) : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n {stage.kind === 'done' ? (\n <Button variant=\"contained\" onClick={close}>\n Done\n </Button>\n ) : (\n <>\n <Button onClick={close}>Cancel</Button>\n {stage.kind === 'preview' || stage.kind === 'enrolling' ? (\n <>\n <Button onClick={reset} disabled={stage.kind === 'enrolling'}>\n Back\n </Button>\n <Button\n variant=\"contained\"\n disabled={!ready.length || stage.kind === 'enrolling'}\n onClick={() => void enroll()}\n >\n {stage.kind === 'enrolling'\n ? 'Enrolling…'\n : `Enroll ${ready.length} ${ready.length === 1 ? 'person' : 'people'}`}\n </Button>\n </>\n ) : (\n <Button\n variant=\"contained\"\n disabled={\n stage.kind === 'previewing' ||\n (tab === 'view' ? !viewId : tab === 'leads' ? !pickedLeads.size : !picked.size)\n }\n onClick={() =>\n void preview(\n tab === 'view'\n ? { kind: 'view', viewId }\n : tab === 'leads'\n ? { kind: 'leads', leadIds: [...pickedLeads.keys()] }\n : { kind: 'contacts', contactIds: [...picked.keys()] },\n )\n }\n >\n Check people\n </Button>\n )}\n </>\n )}\n </DialogActions>\n </Dialog>\n )\n}\nOutreachEnrollDialog.displayName = 'OutreachEnrollDialog'\n\nfunction summary(answer: OutreachEnrollPreviewResponse): string {\n const count = (status: OutreachEnrollPreviewStatus) =>\n answer.people.filter((person) => person.status === status).length\n return `${count('eligible')} eligible · ${count('needs_confirmation')} need you · ${count('blocked')} blocked`\n}\n\nfunction PersonRow(props: {\n person: OutreachEnrollPreviewPerson\n steps: readonly OutreachSequenceStep[]\n supplied: Supplied | undefined\n onSupply(next: Partial<Supplied>): void\n emailPreview:\n | { status: 'loading' }\n | { status: 'ready'; answer: OutreachPreviewResponse }\n | { status: 'failed'; message: string }\n | undefined\n onPreviewEmail(): void\n stepTest: StepTest | undefined\n onSendTest(): void\n onCurate(): void\n onWriteThemselves(): void\n disabled: boolean\n}) {\n const { person, supplied, disabled } = props\n const name = person.name || person.email || person.personId\n const line = supplied?.personalLine ?? ''\n const tooLong = line.trim().length > OUTREACH_PERSONAL_LINE_MAX\n const curation = supplied?.curation ?? { status: 'idle' }\n const drafts = Object.values(supplied?.drafts ?? {}).sort((a, b) => a.stepIndex - b.stepIndex)\n const usedCount = drafts.filter((draft) => draft.decision === 'use').length\n return (\n <Paper component=\"li\" variant=\"outlined\" sx={{ p: 1.5 }} aria-label={name}>\n <Stack spacing={1}>\n <Stack\n direction={{ xs: 'column', sm: 'row' }}\n spacing={1}\n sx={{ alignItems: { sm: 'center' } }}\n >\n <Stack sx={{ flexGrow: 1, minWidth: 0 }}>\n <Typography variant=\"body2\">{name}</Typography>\n {person.email && person.email !== name ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {person.email}\n </Typography>\n ) : null}\n </Stack>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n {person.target === 'lead' ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Lead\" />\n ) : null}\n {person.cold ? (\n <Chip size=\"small\" variant=\"outlined\" label=\"Cold\" />\n ) : null}\n <Chip\n size=\"small\"\n label={STATUS_LABELS[person.status]}\n color={STATUS_COLORS[person.status]}\n />\n </Stack>\n </Stack>\n {person.status === 'blocked' ? (\n <Stack component=\"ul\" spacing={0.5} sx={{ m: 0, pl: 2.5 }}>\n {person.blocks.map((block) => (\n <Typography\n key={block.code}\n component=\"li\"\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ) : (\n <Stack spacing={1}>\n <FormControlLabel\n control={\n <Checkbox\n checked={supplied?.include ?? true}\n onChange={(event) =>\n props.onSupply({ include: event.target.checked })\n }\n disabled={disabled}\n />\n }\n label=\"Enroll this person\"\n />\n {supplied?.include === false ? null : (\n <>\n <TextField\n label={\n person.requires.personalLine\n ? 'Personal line'\n : 'Personal line (optional)'\n }\n placeholder=\"One sentence on why you're writing to this person now.\"\n value={line}\n onChange={(event) =>\n props.onSupply({ personalLine: event.target.value })\n }\n disabled={disabled}\n required={person.requires.personalLine}\n error={tooLong}\n helperText={\n tooLong\n ? `Keep it to one sentence, under ${OUTREACH_PERSONAL_LINE_MAX} characters.`\n : 'Goes where the emails say {{enrollment.personalLine}}.'\n }\n fullWidth\n size=\"small\"\n />\n {person.requires.attestations.length ? (\n <FormGroup aria-label={`What you confirm about ${name}`}>\n {person.requires.attestations.map((kind) => (\n <FormControlLabel\n key={kind}\n control={\n <Checkbox\n checked={\n supplied?.attestations.includes(kind) ?? false\n }\n onChange={(event) =>\n props.onSupply({\n attestations: event.target.checked\n ? [...(supplied?.attestations ?? []), kind]\n : (supplied?.attestations ?? []).filter(\n (entry) => entry !== kind,\n ),\n })\n }\n disabled={disabled}\n />\n }\n label={OUTREACH_ATTESTATION_LABELS[kind]}\n />\n ))}\n </FormGroup>\n ) : null}\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap', rowGap: 1 }}>\n <Button\n size=\"small\"\n onClick={props.onPreviewEmail}\n disabled={disabled}\n >\n Preview the first email\n </Button>\n <Button\n size=\"small\"\n onClick={props.onSendTest}\n disabled={disabled || props.stepTest?.status === 'sending'}\n >\n {props.stepTest?.status === 'sending' ? 'Sending…' : 'Send me this as a test'}\n </Button>\n <Button\n size=\"small\"\n onClick={props.onCurate}\n disabled={disabled || curation.status === 'drafting'}\n >\n {drafts.length ? 'Curate again' : 'Curate for this person'}\n </Button>\n </Stack>\n {props.stepTest?.status === 'failed' ? (\n <Alert severity=\"error\">{props.stepTest.message}</Alert>\n ) : null}\n {props.stepTest?.status === 'sent' ? (\n <Alert severity=\"success\">\n {`Sent to ${props.stepTest.answer.sentTo} as “${props.stepTest.answer.subject}”. ${name} was not enrolled.`}\n </Alert>\n ) : null}\n {curation.status === 'drafting' ? (\n <OutreachLoading label=\"Drafting their emails…\" />\n ) : null}\n {curation.status === 'failed' ? (\n <Stack spacing={1}>\n <Alert severity=\"warning\">{curation.message}</Alert>\n <Stack direction=\"row\">\n <Button size=\"small\" onClick={props.onWriteThemselves} disabled={disabled}>\n Write them yourself\n </Button>\n </Stack>\n </Stack>\n ) : null}\n {drafts.length ? (\n <Stack spacing={1} aria-label={`Curated emails for ${name}`}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {usedCount\n ? `${usedCount} of ${drafts.length} ${drafts.length === 1 ? 'email' : 'emails'} curated for ${name}. Nothing is sent that you haven't confirmed.`\n : `Their emails, rewritten for them. Read each one, edit it, and use it or keep the template.`}\n </Typography>\n {drafts.map((draft) => (\n <OutreachCuratedStepEditor\n key={draft.stepIndex}\n draft={draft}\n label={outreachEmailStepLabel(props.steps, draft.stepIndex)}\n onChange={(next) =>\n props.onSupply({ drafts: { ...(supplied?.drafts ?? {}), [next.stepIndex]: next } })\n }\n disabled={disabled}\n />\n ))}\n </Stack>\n ) : null}\n {props.emailPreview?.status === 'loading' ? (\n <OutreachLoading label=\"Writing the email…\" />\n ) : null}\n {props.emailPreview?.status === 'failed' ? (\n <Alert severity=\"error\">{props.emailPreview.message}</Alert>\n ) : null}\n {props.emailPreview?.status === 'ready' ? (\n props.emailPreview.answer.error ? (\n <Alert severity=\"info\">\n {props.emailPreview.answer.error.message}\n </Alert>\n ) : (\n <Paper\n variant=\"outlined\"\n sx={{ p: 1.5 }}\n aria-label={`First email to ${name}`}\n >\n <Typography variant=\"body2\">{`Subject: ${props.emailPreview.answer.subject}`}</Typography>\n <Typography\n variant=\"body2\"\n sx={{\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n mt: 1,\n }}\n >\n {props.emailPreview.answer.text}\n </Typography>\n </Paper>\n )\n ) : null}\n </>\n )}\n </Stack>\n )}\n </Stack>\n </Paper>\n )\n}\n\nfunction DoneSummary(props: {\n results: OutreachEnrollOutcome[]\n enrolled: number\n}) {\n const refused = props.results.filter(\n (\n result,\n ): result is Extract<OutreachEnrollOutcome, { outcome: 'blocked' }> =>\n result.outcome === 'blocked',\n )\n return (\n <Stack spacing={1.5}>\n <Alert severity={props.enrolled ? 'success' : 'info'}>\n {props.enrolled\n ? `Enrolled ${props.enrolled} ${props.enrolled === 1 ? 'person' : 'people'}. Their first step goes out in the mailbox's sending hours.`\n : 'Nobody was enrolled.'}\n </Alert>\n {refused.length ? (\n <Stack spacing={1}>\n <Typography variant=\"subtitle2\">\n Not enrolled, checked again just now:\n </Typography>\n {refused.map((result) => (\n <Stack key={result.personId} spacing={0.25}>\n <Typography variant=\"body2\">\n {result.email ?? result.personId}\n </Typography>\n {result.blocks.map((block) => (\n <Typography\n key={block.code}\n variant=\"body2\"\n color=\"text.secondary\"\n >\n {block.reason}\n </Typography>\n ))}\n </Stack>\n ))}\n </Stack>\n ) : null}\n </Stack>\n )\n}\n\nexport default OutreachEnrollDialog\n"],"names":["pluginDocsHelp","HelpTip","Alert","Button","Checkbox","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","List","ListItem","ListItemButton","ListItemIcon","ListItemText","MenuItem","Paper","Stack","Tab","Tabs","TextField","Typography","useMediaQuery","useTheme","useMemo","useState","OUTREACH_ENROLL_BATCH_MAX","OUTREACH_ATTESTATION_LABELS","OUTREACH_PERSONAL_LINE_MAX","outreachEmailStepLabel","OutreachCuratedStepEditor","outreachDraftState","outreachDraftToOverride","outreachMemberDraftStates","OutreachLoading","OutreachLoadProblem","useOutreachContactSearch","useOutreachLeadSearch","useOutreachSavedViews","STATUS_LABELS","eligible","needs_confirmation","blocked","STATUS_COLORS","usedOverrides","supplied","Object","values","drafts","map","filter","override","hasOpenDrafts","some","draft","decision","outreachPersonReady","person","status","include","line","personalLine","trim","length","requires","attestations","every","kind","includes","OutreachEnrollDialog","props","orgId","sequence","api","theme","narrow","breakpoints","down","tab","setTab","viewId","setViewId","text","setText","picked","setPicked","Map","leadText","setLeadText","pickedLeads","setPickedLeads","stage","setStage","problem","setProblem","setSupplied","emailPreview","setEmailPreview","stepTests","setStepTests","views","open","uid","search","hostId","contactGroupId","leadSearch","enabled","reset","close","onClose","preview","source","answer","previewEnrollment","id","fromEntries","people","personId","error","message","ready","waiting","enroll","result","target","leadId","contactId","stepOverrides","results","enrolled","supply","next","previous","previewEmail","overrides","sequenceId","curate","curation","curateDrafts","audit","prompt","model","stepIndex","steps","writeThemselves","stepIndexes","step","index","sendTest","sendStepTest","title","name","fullWidth","maxWidth","fullScreen","aria-label","direction","spacing","sx","alignItems","span","anchor","dividers","severity","value","onChange","_event","label","what","data","select","event","helperText","view","section","placeholder","autoFocus","idle","variant","color","dense","lead","checked","has","disablePadding","onClick","delete","size","set","edge","tabIndex","disableRipple","primary","email","secondary","flexWrap","rowGap","onDelete","contact","summary","truncated","total","component","listStyle","p","m","PersonRow","onSupply","onPreviewEmail","stepTest","onSendTest","onCurate","onWriteThemselves","disabled","DoneSummary","leadIds","keys","contactIds","displayName","count","tooLong","sort","a","b","usedCount","xs","sm","flexGrow","minWidth","cold","pl","blocks","block","reason","code","control","required","entry","sentTo","subject","whiteSpace","wordBreak","mt","refused","outcome"],"mappings":"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"}
@@ -21,7 +21,7 @@ import { CardDisplay, useConfirmationContext } from "@aglyn/shared-ui-jsx";
21
21
  import { useSnackbar } from "@aglyn/shared-ui-snackstack";
22
22
  import { Alert, Autocomplete, Box, Button, Chip, FormControlLabel, FormHelperText, MenuItem, Stack, Switch, TextField, ToggleButton, ToggleButtonGroup, Typography } from "@mui/material";
23
23
  import { useEffect, useMemo, useRef, useState } from "react";
24
- import { formatMinuteOfDay, isValidTimezone, OUTREACH_DEFAULT_WINDOW, OUTREACH_MAILBOX_STATUS_LABELS, OUTREACH_MAX_DAILY_CAP, OUTREACH_RAMP_STEPS, OUTREACH_WEEKDAY_LABELS, outreachEffectiveDailyCap, summarizeMailboxHealth, validateDailyCap, validateDisplayName, validateSendWindow } from "../mailboxes/mailbox-settings.js";
24
+ import { formatMinuteOfDay, isValidTimezone, OUTREACH_DEFAULT_WINDOW, OUTREACH_MAILBOX_STATUS_LABELS, OUTREACH_MAX_DAILY_CAP, OUTREACH_RAMP_STEPS, OUTREACH_WEEKDAY_LABELS, outreachEffectiveDailyCap, outreachLocalDay, summarizeMailboxHealth, validateDailyCap, validateDisplayName, validateSendWindow } from "../mailboxes/mailbox-settings.js";
25
25
  /**
26
26
  * What the card says about a mailbox that paused ITSELF (AGL-2981): the
27
27
  * engine's own sentence, when it paused, and — after a complaint — the day
@@ -108,7 +108,7 @@ const draftOf = (mailbox)=>{
108
108
  * because both act in that member's own Google account.
109
109
  */ export function MailboxCard(props) {
110
110
  var _mailbox_rampStartedAtMs, _OUTREACH_MAILBOX_STATUS_LABELS_mailbox_status, _STATUS_COLOR_mailbox_status;
111
- var _mailbox_sendAsOptions;
111
+ var _mailbox_health_daily_outreachLocalDay, _mailbox_health_daily, _mailbox_health, _mailbox_sendAsOptions;
112
112
  const { mailbox, isMine, canManage, api, onReconnect, reconnecting = false, nowMs = Date.now() } = props;
113
113
  const { enqueueSnackbar } = useSnackbar();
114
114
  const { confirm } = useConfirmationContext();
@@ -138,6 +138,9 @@ const draftOf = (mailbox)=>{
138
138
  stored
139
139
  ]);
140
140
  const health = summarizeMailboxHealth(mailbox.health, mailbox.timezone, nowMs);
141
+ // Tests of a sequence step sent today (AGL-3325): counted beside the
142
+ // sends, never among them, so the cap and the seven-day sum stay honest.
143
+ const testsToday = Math.max(0, Number((_mailbox_health = mailbox.health) == null ? void 0 : (_mailbox_health_daily = _mailbox_health.daily) == null ? void 0 : (_mailbox_health_daily_outreachLocalDay = _mailbox_health_daily[outreachLocalDay(nowMs, mailbox.timezone)]) == null ? void 0 : _mailbox_health_daily_outreachLocalDay.tests) || 0);
141
144
  const needsReconnect = mailbox.status === 'reconnect_required' || mailbox.status === 'disconnected';
142
145
  const capCheck = validateDailyCap(draft.dailyCap === '' ? Number.NaN : Number(draft.dailyCap));
143
146
  const windowCheck = validateSendWindow(draft.window);
@@ -331,6 +334,12 @@ const draftOf = (mailbox)=>{
331
334
  })
332
335
  ]
333
336
  }, label))
337
+ }),
338
+ /*#__PURE__*/ _jsx(Typography, {
339
+ variant: "caption",
340
+ color: "text.secondary",
341
+ "aria-label": "Tests today",
342
+ children: `Tests today: ${testsToday}`
334
343
  })
335
344
  ]
336
345
  }),