@aglyn/plugins-ai 1.0.0-beta.296 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -17
- package/src/lib/components/ai-job-links.d.ts +2 -1
- package/src/lib/components/ai-job-links.js +8 -2
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/assist-edit-canvas.d.ts +12 -6
- package/src/lib/components/assist-edit-canvas.js +86 -36
- package/src/lib/components/assist-edit-canvas.js.map +1 -1
- package/src/lib/components/assist-edit-card.component.js +9 -8
- package/src/lib/components/assist-edit-card.component.js.map +1 -1
- package/src/lib/components/assist-page-change-card.component.d.ts +1 -1
- package/src/lib/components/assist-page-change-card.component.js +2 -2
- package/src/lib/components/assist-page-change-card.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +19 -8
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/jobs/ai-job-edit-step.d.ts +20 -0
- package/src/lib/jobs/ai-job-edit-step.js +39 -3
- package/src/lib/jobs/ai-job-edit-step.js.map +1 -1
- package/src/lib/model/ai-edit-job.js +1 -1
- package/src/lib/model/ai-edit-job.js.map +1 -1
- package/src/lib/model/ai-job-notice.js +3 -1
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/assist-edit.d.ts +8 -7
- package/src/lib/model/assist-edit.js +4 -4
- package/src/lib/model/assist-edit.js.map +1 -1
- package/src/lib/model/assist-page-change.d.ts +14 -0
- package/src/lib/model/assist-page-change.js +21 -0
- package/src/lib/model/assist-page-change.js.map +1 -1
- package/src/lib/server/assist-chat.js +5 -1
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit.d.ts +12 -7
- package/src/lib/server/assist-edit.js +43 -22
- package/src/lib/server/assist-edit.js.map +1 -1
- package/src/lib/server/assist-page-change.js +1 -1
- package/src/lib/server/assist-page-change.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/assist-panel.component.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 {\n canvas,\n checkEntitlement,\n isBetaStaged,\n lockdownRefusalText,\n parseLockdownRefusal,\n planLabelGrantingFeature,\n type AglynOrgBilling,\n} from '@aglyn/aglyn'\nimport {\n editorSessionsRevision,\n openEditorSession,\n subscribeEditorSessions,\n} from '@aglyn/aglyn/plugin-manager/editor-sessions'\nimport { trackEvent } from '@aglyn/aglyn/app-utils/analytics-events'\nimport { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport {\n mdiChevronDown,\n mdiCreation,\n mdiChevronUp,\n mdiClose,\n mdiOpenInNew,\n mdiSend,\n mdiThumbDownOutline,\n mdiThumbUpOutline,\n} from '@aglyn/shared-data-mdi'\nimport { AppLink, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { BetaChip } from '@aglyn/shared-ui-jsx/components/beta-chip.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Alert,\n Badge,\n Box,\n Button,\n Chip,\n CircularProgress,\n Collapse,\n Drawer,\n Fab,\n IconButton,\n Link,\n Paper,\n Stack,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { usePathname, useRouter } from 'next/navigation'\nimport {\n Fragment,\n memo,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n assistEditDocumentOf,\n isAssistEditProposal,\n type AssistEditAppliedReport,\n type AssistEditProposal,\n} from '../model/assist-edit'\nimport { applyAssistEdit, describeAssistEditCanvas } from './assist-edit-canvas'\nimport { AssistEditCard } from './assist-edit-card.component'\nimport { AssistBuildCard } from './assist-build-card.component'\nimport { isAssistBuildProposal, type AssistBuildProposal } from '../model/assist-build'\nimport {\n assistBuildDraftLinks,\n isAssistFollowUpDue,\n isLiveAssistFollowUp,\n type AssistBuildDraft,\n type AssistBuildDraftLink,\n type AssistPendingFollowUp,\n} from '../model/assist-follow-up'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport { cancelAiJobRequest, startAssistBuildRequest, startAssistPageChangeRequest } from './ai-job-requests'\nimport {\n assistPageChangeDraftVersion,\n isAssistPageChangeProposal,\n type AssistPageChangeProposal,\n} from '../model/assist-page-change'\nimport { AssistPageChangeCard } from './assist-page-change-card.component'\nimport { aiInsightSurfaceForPath } from '../model/ai-insight'\nimport { AssistJobsDrawer } from './assist-jobs-drawer.component'\nimport {\n AI_JOB_LINK_PARAM,\n openAiJobs,\n useAiJobsInFlight,\n useAiJobsOpenRequest,\n type AiJobsOpenRequest,\n} from './ai-jobs-store'\nimport { aiJobPhase, aiJobsActivity, aiJobsLauncherLabel } from '../model/ai-job-activity'\nimport { AI_SITE_BUILD_HREF } from '../model/ai-job-notice'\nimport { AiModelSelector } from './ai-model-selector.component'\nimport { AiUsageStrip } from './ai-usage-strip.component'\nimport { useAiModelChoice } from './use-ai-model-choice'\nimport { followAiJobsForUsageMeter, refreshAiUsageMeterFree } from './ai-usage-meter-refresh'\nimport { readAiUsageMeter, usePublishAiUsageMeter } from './use-ai-usage-meter'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\n\n/**\n * Aglyn Assist (AGL-1860, phase 1 — answer + guide): the floating chat\n * helper mounted on every authenticated console page. Docs-grounded answers\n * with deep links for everyone the release flag admits; Pro+ (`aiAssist`)\n * adds page-context awareness. The panel never answers the entitlement\n * question from a loading default — capability messaging waits for\n * `useCurrentOrg().ready` (the checkQuota(undefined)=Free lesson).\n *\n * ## It also never runs against an org the URL did not name (AGL-1934)\n *\n * `useCurrentOrg()` deliberately keeps a fallback — org-less pages still need\n * an org to ACT on — so on the workspace picker it answers with a real org\n * and a truthy plan: a remembered selection, or simply the user's first. This\n * panel used to gate on nothing but `orgId` being present, which that\n * fallback always satisfies. The result was the whole component running for a\n * workspace nobody opened: the entitlement decided by its plan, the upgrade\n * nudge pitched on its behalf, the session thread filed under its id, and —\n * the reason this ranked High rather than cosmetic — every question POSTed\n * with its `orgId`, so the message was METERED to it. Billing data attributed\n * to the wrong customer.\n *\n * The gate is AGL-1130's `useUrlNamesOrg()`, the same predicate AGL-1916\n * applied to `QuotaWarningsBanner` on the same page, plus the positive\n * contradiction check that goes with it. It is expressed once, as\n * `scopedOrgId`, so that no send path can reach `orgId` around it — and the\n * server refuses an unscoped request independently (`assistScopeRefusal` in\n * `app/api/assist/chat/route.ts`), because a metering boundary the client\n * alone decides is not a boundary.\n */\n\ninterface AssistDocLink {\n title: string\n url: string\n}\n\n/**\n * A level-2 proposal, exactly as the server resolved it (AGL-1988).\n *\n * Every field here is inert. There is no method, no endpoint and no body,\n * because the server type has none: the assistant proposes, the user\n * confirms, and confirming NAVIGATES. The destination form's own submit\n * button stays the only thing that writes.\n */\ninterface AssistProposal {\n id: string\n label: string\n outcome: string\n href: string\n values: Array<{ name: string; value: string }>\n prefill: boolean\n /** The draft an open-draft proposal names (AGL-3616), as the server held it. */\n draft?: AssistBuildDraft\n /**\n * The request a confirmed open-draft proposal asks again once the draft's\n * canvas is open; `href` is then that draft's own Besigner, from the\n * panel's own record of its build.\n */\n followUp?: string\n}\n\ninterface AssistMessage {\n role: 'user' | 'assistant'\n text: string\n exchangeId?: string | null\n feedback?: 'up' | 'down'\n docs?: AssistDocLink[]\n proposal?: AssistProposal | null\n /** Set once the user acts on or waves away the card, so it does not linger. */\n proposalResolved?: boolean\n /**\n * A level-3 edit proposal, exactly as the server validated it (AGL-2906):\n * operations for the open canvas, applied only when the author presses\n * Apply, and never by a request.\n */\n edit?: AssistEditProposal | null\n /** What became of the edit card: applied, waved away, or refused with a reason. */\n editOutcome?:\n | { kind: 'applied' }\n | { kind: 'dismissed' }\n | { kind: 'failed'; message: string }\n /**\n * A build proposed from this turn (AGL-3616): the panel starts its one\n * `build` job when the turn ends, and the card shows that job's plan to\n * confirm, then where it stands.\n */\n build?: AssistBuildProposal | null\n /** The job the build started, as last seen. */\n buildJob?: AiJobSummary | null\n /** Why the build could not be planned or confirmed. */\n buildNotice?: string | null\n /**\n * A later turn's plan replaced this one before it was confirmed (AGL-4116):\n * its job was canceled, and the card gives way to one line.\n */\n buildReplaced?: boolean\n /**\n * A change to a page the site already has (AGL-4116): the panel starts its\n * `edit` job when the turn ends, and the card links the draft it makes.\n */\n pageChange?: AssistPageChangeProposal | null\n /** The edit job the change started, as last seen. */\n pageChangeJob?: AiJobSummary | null\n /** Why the change could not be started. */\n pageChangeNotice?: string | null\n}\n\n/** The key a follow-up waiting for its canvas is kept under, per org (AGL-3616). */\nconst followUpKey = (orgId: string) => `aglyn-assist-follow-up:${orgId}`\n\nfunction loadFollowUp(orgId: string | undefined): AssistPendingFollowUp | null {\n if (!orgId || typeof sessionStorage === 'undefined') return null\n try {\n const parsed: unknown = JSON.parse(sessionStorage.getItem(followUpKey(orgId)) ?? 'null')\n if (isLiveAssistFollowUp(parsed, Date.now())) return parsed\n // One past its time is never asked: forget it.\n if (parsed !== null) sessionStorage.removeItem(followUpKey(orgId))\n return null\n } catch {\n return null\n }\n}\n\nfunction saveFollowUp(orgId: string | undefined, followUp: AssistPendingFollowUp | null) {\n if (!orgId || typeof sessionStorage === 'undefined') return\n try {\n if (followUp) sessionStorage.setItem(followUpKey(orgId), JSON.stringify(followUp))\n else sessionStorage.removeItem(followUpKey(orgId))\n } catch {\n // Storage that refuses only loses the re-ask; the draft still opens.\n }\n}\n\n/**\n * The drafts this thread's builds made that open in the Besigner, newest\n * build first (AGL-3616): what a follow-up such as \"make the about page\n * shorter\" may open.\n */\nexport function assistThreadDraftLinks(\n messages: ReadonlyArray<{ buildJob?: AiJobSummary | null }>,\n orgSlug: string,\n): AssistBuildDraftLink[] {\n const jobs = messages.flatMap((message) => (message.buildJob ? [message.buildJob] : [])).reverse()\n return assistBuildDraftLinks(jobs, orgSlug)\n}\n\n/**\n * The builds in a thread whose plan is still waiting on the person\n * (AGL-4116): queued, being planned, or planned and not yet confirmed. A new\n * plan in the same thread replaces them, so a conversation that keeps\n * changing a plan holds one plan, not one per message.\n */\nexport function assistUnconfirmedBuilds(\n messages: ReadonlyArray<Pick<AssistMessage, 'build' | 'buildJob' | 'buildReplaced'>>,\n): Array<{ index: number; jobId: string }> {\n return messages.flatMap((message, index) => {\n const job = message.build && !message.buildReplaced ? message.buildJob : null\n if (!job) return []\n const phase = aiJobPhase(job)\n return phase === 'queued' || phase === 'planning' || phase === 'plan-ready' ? [{ index, jobId: job.id }] : []\n })\n}\n\n/** What a plan a later one replaced says in its card's place (AGL-4116). */\nexport const ASSIST_BUILD_REPLACED_COPY = 'Replaced by the updated plan below. Nothing from this one was built.'\n\n/** What a stored build that never got its job says, rather than planning forever. */\nconst BUILD_NOT_STARTED = 'This build was not started. Ask again to plan it.'\n\n/** What a stored page change that never got its job says (AGL-4116). */\nconst PAGE_CHANGE_NOT_STARTED = 'This change was not started. Ask again to make it.'\n\ninterface AssistQuotaInfo {\n period: 'day' | 'month'\n used: number\n limit: number\n remaining: number\n}\n\nconst HISTORY_TURNS_SENT = 12\n\n/**\n * The thread a question belongs to: one per site, and one for the\n * workspace's own pages (AGL-4116). A workspace-wide thread carried one\n * site's request into a build on another site, because the history that\n * rides each question is the thread's last turns.\n */\nexport function assistThreadKey(orgId: string, hostId: string | null | undefined): string {\n return hostId ? `aglyn-assist:${orgId}:${hostId}` : `aglyn-assist:${orgId}`\n}\n\nconst NO_MESSAGES: AssistMessage[] = []\n\n/**\n * The AI jobs page of the site a console page is on (AGL-4116), or `null`\n * off a site: `/{orgSlug}/hosts/{site}/ai-jobs`, the site named as the\n * address names it.\n */\nexport function assistSiteAiJobsHref(\n pathname: string | null | undefined,\n orgSlug: string | null | undefined,\n hostId: string | null | undefined,\n): string | null {\n if (!pathname || !orgSlug || !hostId) return null\n const parts = pathname.split('/').filter(Boolean)\n const site = parts[0] === orgSlug && parts[1] === 'hosts' ? parts[2] : undefined\n return site ? `/${orgSlug}/hosts/${site}${AI_SITE_BUILD_HREF}` : null\n}\n\nfunction loadThread(key: string): AssistMessage[] {\n if (typeof sessionStorage === 'undefined') return []\n try {\n const raw = sessionStorage.getItem(key)\n const parsed = raw ? (JSON.parse(raw) as AssistMessage[]) : []\n if (!Array.isArray(parsed)) return []\n // A build whose job was still being created when the page went away is\n // not started again from a stored thread (AGL-3616): it says so instead.\n // A page change likewise (AGL-4116).\n return parsed.map((message) =>\n message.build && !message.buildJob && !message.buildNotice\n ? { ...message, buildNotice: BUILD_NOT_STARTED }\n : message.pageChange && !message.pageChangeJob && !message.pageChangeNotice\n ? { ...message, pageChangeNotice: PAGE_CHANGE_NOT_STARTED }\n : message,\n )\n } catch {\n return []\n }\n}\n\nfunction saveThread(key: string, messages: AssistMessage[]) {\n if (typeof sessionStorage === 'undefined') return\n try {\n sessionStorage.setItem(key, JSON.stringify(messages))\n } catch {\n // Quota/full storage never breaks chat.\n }\n}\n\n/**\n * Minimal renderer for assistant text: markdown links and bare URLs become\n * links (internal root-relative paths ride AppLink, external open in a new\n * tab); everything else renders as plain text with line breaks. Phase 1 on\n * purpose — no full markdown surface inside the panel.\n */\nexport function renderAssistText(text: string): JSX.Element {\n const parts: Array<string | { label: string; href: string }> = []\n const pattern = /\\[([^\\]]+)\\]\\((\\/[^)\\s]*|https?:\\/\\/[^)\\s]+)\\)|https?:\\/\\/[^\\s)]+/g\n let cursor = 0\n for (const match of text.matchAll(pattern)) {\n const index = match.index ?? 0\n if (index > cursor) parts.push(text.slice(cursor, index))\n if (match[1] && match[2]) parts.push({ label: match[1], href: match[2] })\n else parts.push({ label: match[0], href: match[0] })\n cursor = index + match[0].length\n }\n if (cursor < text.length) parts.push(text.slice(cursor))\n return (\n <>\n {parts.map((part, i) => {\n if (typeof part === 'string') {\n return <Fragment key={i}>{part}</Fragment>\n }\n if (part.href.startsWith('/')) {\n return (\n <AppLink key={i} componentVariant=\"naked\" href={part.href}>\n {part.label}\n </AppLink>\n )\n }\n return (\n <Link key={i} href={part.href} target=\"_blank\" rel=\"noreferrer\">\n {part.label}\n </Link>\n )\n })}\n </>\n )\n}\n\n/**\n * Split an answer into its plain layer and its technical tail (AGL-1988).\n *\n * Aglyn's users run from first-time business owners to working developers,\n * and they get the same message. Two modes would be the obvious build and\n * the wrong one — it asks a beginner to label themselves before they have a\n * question, and asks a developer to opt in to being taken seriously. So the\n * model writes one answer with a technical paragraph at the end, and the\n * panel collapses it: the beginner never has to read past the plain steps,\n * the developer never has to ask for the route or the field name.\n *\n * Degrades to \"no tail\" when the marker is absent, which is the common case\n * and not a failure — plenty of answers have nothing technical to add.\n */\nexport function splitAssistDisclosure(text: string): {\n plain: string\n technical: string\n} {\n const match = text.match(/(?:^|\\n)[ \\t]*Under the hood:[ \\t]*/)\n if (!match || match.index === undefined) return { plain: text, technical: '' }\n const plain = text.slice(0, match.index).trimEnd()\n const technical = text.slice(match.index + match[0].length).trim()\n // An answer that is ONLY a technical tail is still the answer. Collapsing\n // the whole thing would show the user an empty bubble with a toggle.\n if (!plain || !technical) return { plain: text, technical: '' }\n return { plain, technical }\n}\n\n/** The collapsed developer layer. */\nfunction UnderTheHood({ technical }: { technical: string }) {\n const [open, setOpen] = useState(false)\n return (\n <Box sx={{ mt: 0.5 }}>\n <Link\n component=\"button\"\n type=\"button\"\n variant=\"caption\"\n underline=\"hover\"\n onClick={() => setOpen((prior) => !prior)}\n sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.25 }}\n >\n Under the hood\n <MdiIcon\n path={open ? mdiChevronUp.path : mdiChevronDown.path}\n sx={{ fontSize: 14 }}\n />\n </Link>\n <Collapse in={open} unmountOnExit>\n <Typography\n variant=\"caption\"\n component=\"div\"\n color=\"text.secondary\"\n sx={{ mt: 0.5, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}\n >\n {renderAssistText(technical)}\n </Typography>\n </Collapse>\n </Box>\n )\n}\n\n/**\n * The source links under an answer (AGL-2486).\n *\n * `docs` is server-resolved retrieval output and has ridden every `done`\n * event since Assist shipped, but NOTHING rendered it: it set the `grounded`\n * analytics flag and stopped there. So every answer carried its citations to\n * a reader who never saw them, and on the MODEL path that array is the only\n * citation there is — the completion is prose, and nothing obliges it to name\n * the page it was grounded in.\n *\n * ## Why this FILTERS rather than rendering the array straight\n *\n * The DEFLECTED path is the opposite case. `composeDocsAnswer` deliberately\n * puts the citation in the answer TEXT as `[label](url)`, because a link is\n * the one markup this panel speaks (`renderAssistText`) — that is a recorded\n * decision, not an oversight, and its own docstring names this array as the\n * tempting-but-wrong home for the citation *because* nothing renders it.\n * Rendering the array underneath would therefore print every heading a second\n * time on exactly the answers that already cite well. Anything whose url is\n * already linked in the text is dropped, which leaves a deflected answer\n * reading precisely as it does today and gives the model answer the sources\n * it has never shown.\n *\n * ## Why the array is not simply suppressed server-side instead\n *\n * That was the other candidate and it is a trap: `docs.length > 0` is what\n * sets the `grounded` analytics flag, so a docs-QUOTING answer would report\n * itself ungrounded. The most grounded turn the product serves would be\n * counted as a documentation gap, which is precisely backwards for the signal\n * `assist-signal-mining` exists to read.\n */\nexport function AssistSources({\n text,\n docs,\n}: {\n text: string\n docs?: readonly AssistDocLink[]\n}) {\n const unseen: AssistDocLink[] = []\n const shown = new Set<string>()\n for (const doc of docs ?? []) {\n // Already a link in the prose, or already listed here. Both are the same\n // failure to the reader: the same page offered twice.\n if (!doc?.url || text.includes(doc.url) || shown.has(doc.url)) continue\n shown.add(doc.url)\n unseen.push(doc)\n }\n if (!unseen.length) return null\n return (\n <Box sx={{ mt: 0.75 }}>\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n {unseen.length === 1 ? 'Source' : 'Sources'}\n </Typography>\n <Stack spacing={0.25} sx={{ mt: 0.25 }}>\n {unseen.map((doc) => (\n <Typography key={doc.url} variant=\"caption\" component=\"div\">\n {doc.url.startsWith('/') ? (\n <AppLink componentVariant=\"naked\" href={doc.url}>\n {doc.title}\n </AppLink>\n ) : (\n <Link href={doc.url} target=\"_blank\" rel=\"noreferrer\">\n {doc.title}\n </Link>\n )}\n </Typography>\n ))}\n </Stack>\n </Box>\n )\n}\n\n/**\n * The confirm card — the whole of \"automate current view\", and the whole of\n * its boundary.\n *\n * The assistant proposes; this card is the human confirmation; confirming\n * navigates. There is deliberately no submit path anywhere in this\n * component, and no network call: a chat assistant that writes without\n * consent is a far worse launch story than one that only advises, and the\n * cheapest way to be sure it cannot is for the code that could do it not to\n * exist. `assist-panel-proposal.spec.tsx` greps this file for exactly that.\n *\n * The copy is held to the same standard. While `prefill` is false — no\n * console page reads `assist_*` params yet — the card says it will open the\n * page and lists the values to use. It does not say it filled anything in,\n * because a form that comes up empty after that promise is worse than no\n * card at all.\n */\nfunction ProposalCard({\n proposal,\n onConfirm,\n onDismiss,\n brand,\n}: {\n proposal: AssistProposal\n onConfirm: () => void\n onDismiss: () => void\n brand: string\n}) {\n return (\n <Paper\n variant=\"outlined\"\n sx={{ mt: 1, p: 1.5, borderRadius: 2, bgcolor: 'background.paper' }}\n >\n <Typography variant=\"subtitle2\">{proposal.label}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n Opens {proposal.outcome}.\n </Typography>\n {proposal.followUp && (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\" sx={{ mt: 1 }}>\n {`${brand} Assist asks “${proposal.followUp}” again there. Nothing changes until you apply the edit it proposes.`}\n </Typography>\n )}\n {proposal.values.length > 0 && (\n <Box sx={{ mt: 1 }}>\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n {proposal.prefill ? 'Filled in for you:' : 'Values to use:'}\n </Typography>\n <Stack component=\"ul\" sx={{ m: 0, pl: 2.5 }}>\n {proposal.values.map(({ name, value }) => (\n <Typography key={name} component=\"li\" variant=\"caption\">\n {name}: <strong>{value}</strong>\n </Typography>\n ))}\n </Stack>\n </Box>\n )}\n {!proposal.followUp && (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n component=\"div\"\n sx={{ mt: 1 }}\n >\n {`${brand} Assist only opens the page. Nothing is saved until you `}\n {'fill the form in and submit it yourself.'}\n </Typography>\n )}\n <Stack direction=\"row\" spacing={1} sx={{ mt: 1.5 }}>\n <AppLink\n componentVariant=\"button\"\n href={proposal.href}\n variant=\"contained\"\n size=\"small\"\n onClick={onConfirm}\n startIcon={<MdiIcon path={mdiOpenInNew.path} />}\n >\n Take me there\n </AppLink>\n <Button size=\"small\" color=\"inherit\" onClick={onDismiss}>\n No thanks\n </Button>\n </Stack>\n </Paper>\n )\n}\n\n/**\n * The chat box and its Send button (AGL-3616).\n *\n * What is typed lives in the text field itself, not in state: a keystroke\n * commits nothing but the moment the box goes from empty to not, which is\n * the one thing the Send button draws. It used to be the panel's state, so\n * every keystroke committed the whole panel — the thread, the AI jobs list,\n * the usage strip — and React 19 counts each commit that leaves an update\n * pending as a nested one. On a busy page the browser delivers queued\n * keystrokes back to back, the 51st `setState` threw \"Maximum update depth\n * exceeded\" (#185), and the keystrokes it carried were lost. Memoized, so\n * nothing the panel redraws for redraws the box either.\n *\n * Focused when the panel opens, so the first keystroke lands in it.\n */\nconst AssistComposer = memo(function AssistComposer({\n busy,\n loaded,\n allowed,\n onSend,\n}: {\n busy: boolean\n /** The reader's AI permissions have answered. */\n loaded: boolean\n /** The reader may ask the assistant. */\n allowed: boolean\n onSend: (question: string) => unknown\n}) {\n const inputRef = useRef<HTMLTextAreaElement>(null)\n const [hasText, setHasText] = useState(false)\n const disabled = busy || !loaded || !allowed\n const noteText = (value: string) => {\n const next = value.trim().length > 0\n if (next !== hasText) setHasText(next)\n }\n const submit = () => {\n const node = inputRef.current\n const question = node?.value.trim() ?? ''\n if (!node || !question || disabled) return\n node.value = ''\n setHasText(false)\n void onSend(question)\n }\n return (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'flex-end' }}>\n <TextField\n fullWidth\n multiline\n maxRows={4}\n size=\"small\"\n placeholder=\"How do I…\"\n autoFocus\n inputRef={inputRef}\n disabled={disabled}\n onChange={(event) => noteText(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n submit()\n }\n }}\n />\n <Tooltip\n title={\n busy\n ? 'Waiting for an answer…'\n : !loaded\n ? 'Checking your permissions…'\n : !allowed\n ? 'Your role does not include the assistant'\n : 'Send message'\n }\n >\n <span>\n <IconButton\n color=\"primary\"\n aria-label=\"Send message\"\n disabled={disabled || !hasText}\n onClick={submit}\n >\n {busy ? (\n <CircularProgress size={20} />\n ) : (\n // 20px to match the CircularProgress it swaps with on the\n // line above — at the inherited 14px the button visibly grew\n // its contents while busy.\n <MdiIcon path={mdiSend.path} sx={{ fontSize: 20 }} />\n )}\n </IconButton>\n </span>\n </Tooltip>\n </Stack>\n )\n})\n\n/** The reader's AI verdict, on their own membership axis (AGL-2927). */\nexport interface AssistAiPermissions {\n /** True only once every read the answer depends on has answered. */\n loaded: boolean\n /** May the reader ask the assistant, rewrite copy, generate a section? */\n use: boolean\n /** May the reader run an AI generation job or an AI edit? */\n generate: boolean\n}\n\n/**\n * What the shell hands the assistant dock (AGL-2940): its own answers to\n * the questions only the shell can answer. The panel reads no console hook.\n */\nexport interface AssistDockProps {\n orgId?: string\n org?: Partial<AglynOrgBilling> | null\n orgReady: boolean\n /**\n * The org this panel may speak for, act as, and be METERED against — or\n * `undefined` where the page named none (AGL-1130, AGL-1934). Every use\n * of the org below goes through this rather than `orgId`, so a send path\n * cannot be added later that quietly reaches around the gate; the thread\n * key, the two POST bodies and the render gate all read the same value.\n */\n scopedOrgId?: string\n /** Path slug for building `/[orgSlug]/…` links (AGL-621). */\n orgSlug: string\n /** The site in view, or null off a host route. */\n hostId: string | null\n /** The product's name as this org reads it (AGL-2319). */\n productName: string\n /** The `release_assist` verdict, staff bypass applied. */\n assistVisible: boolean\n /** True when only the staff bypass makes the assistant visible. */\n assistStaffPreview: boolean\n /** The `release_ai_generative` verdict, staff bypass applied. */\n generativeVisible: boolean\n isStaff: boolean\n aiPermissions: AssistAiPermissions\n}\n\nexport function AssistPanelComponent(props: AssistDockProps) {\n const {\n org,\n orgId,\n orgReady,\n scopedOrgId,\n orgSlug,\n hostId,\n productName,\n assistVisible,\n assistStaffPreview,\n generativeVisible,\n isStaff,\n aiPermissions: ai,\n } = props\n const verdict = { visible: assistVisible, staffPreview: assistStaffPreview }\n const branding = { productName }\n const billingSlug = orgSlug\n const pathname = usePathname()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n\n const [open, setOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n // Every thread this panel has opened, by its key (AGL-4116): the one on\n // screen is this site's, and an answer still streaming lands in the thread\n // it was asked in, even after the page moved to another site.\n const threadKey = scopedOrgId ? assistThreadKey(scopedOrgId, hostId) : null\n const [threads, setThreads] = useState<Readonly<Record<string, AssistMessage[]>>>({})\n const messages = (threadKey && threads[threadKey]) || NO_MESSAGES\n const updateThread = useCallback(\n (key: string | null, update: (prior: AssistMessage[]) => AssistMessage[]) => {\n if (!key) return\n setThreads((prior) => ({ ...prior, [key]: update(prior[key] ?? loadThread(key)) }))\n },\n [],\n )\n const setMessages = useCallback(\n (update: (prior: AssistMessage[]) => AssistMessage[]) => updateThread(threadKey, update),\n [threadKey, updateThread],\n )\n const [quota, setQuota] = useState<AssistQuotaInfo | null>(null)\n const scrollRef = useRef<HTMLDivElement>(null)\n // The model switch and the usage strip (AGL-2942): the pick rides the\n // chat request, and each answer's `meter` moves every strip for the org.\n const modelChoice = useAiModelChoice({\n orgId: scopedOrgId,\n hostId,\n surface: 'assist',\n kind: 'assist.chat',\n })\n const publishMeter = usePublishAiUsageMeter(scopedOrgId)\n // The open editor, re-read whenever one opens, closes or reports a change —\n // so a card raised on a live version offers Apply once its new version is\n // the one open.\n const editorRevision = useSyncExternalStore(\n subscribeEditorSessions,\n editorSessionsRevision,\n editorSessionsRevision,\n )\n const editorSession = openEditorSession()\n\n // A thread per site, session-persisted; moving to another site or org\n // swaps threads (AGL-4116). Keyed on the SCOPED org (AGL-1934): gating only\n // the render would still load — and, on the next keystroke, save — a\n // thread under the fallback org's key on every mount of a page that named\n // no workspace.\n useEffect(() => {\n if (!threadKey) return\n setThreads((prior) => (threadKey in prior ? prior : { ...prior, [threadKey]: loadThread(threadKey) }))\n }, [threadKey])\n useEffect(() => {\n setQuota(null)\n }, [scopedOrgId])\n\n // Each thread is written back when it changes, the one on screen or one an\n // answer is still streaming into.\n const savedThreads = useRef<Record<string, AssistMessage[]>>({})\n useEffect(() => {\n for (const [key, list] of Object.entries(threads)) {\n if (savedThreads.current[key] === list) continue\n savedThreads.current[key] = list\n saveThread(key, list)\n }\n }, [threads])\n\n useEffect(() => {\n const node = scrollRef.current\n if (node) node.scrollTop = node.scrollHeight\n }, [messages])\n\n const entitled = orgReady && checkEntitlement(org as never, 'aiAssist')\n // Whether a question asked from a besigner document carries its canvas\n // (AGL-2906). A hint, not a grant: the server decides the edit rung again\n // from its own reads, and drops the outline below it.\n const editRungHint =\n generativeVisible &&\n ai.loaded &&\n ai.generate &&\n orgReady &&\n checkEntitlement(org as never, 'aiGenerative')\n\n // ── AI jobs, findable from anywhere (AGL-3593) ─────────────────────────\n //\n // The workspace's unsettled jobs, from the one list the top-bar indicator\n // reads — read only where the reader could run a job at all: the flag, the\n // plan's `aiGenerative` and their own `ai.generate`, as the drawer's gate.\n const jobsVisible = Boolean(scopedOrgId) && editRungHint\n const inFlight = useAiJobsInFlight(user, scopedOrgId, jobsVisible)\n // The same read tells the usage strip what a Free workspace has left, so\n // jobs that spend between chat messages move it (AGL-3722).\n useEffect(() => followAiJobsForUsageMeter(), [])\n const jobsActivity = aiJobsActivity(inFlight)\n // On a site, its jobs are read on its AI jobs page (AGL-4116): the list in\n // the chat was too cramped to read, and opening it scrolled the chat to\n // its top.\n const siteJobsHref = assistSiteAiJobsHref(pathname, orgSlug, hostId)\n const router = useRouter()\n // Any surface asking to open AI jobs — an \"Open AI jobs\" button, the\n // indicator, a notification's link — goes to the site's AI jobs page, on\n // the job it names. Off a site, it opens the panel on its drawer, and the\n // request is handed to the drawer until the panel closes, so opening the\n // panel again later does not re-highlight a job asked for before.\n const openRequest = useAiJobsOpenRequest()\n const [jobsFocus, setJobsFocus] = useState<AiJobsOpenRequest | null>(null)\n // The request outlives the panel: it is module state, and a page in\n // another layout mounts a fresh panel. Only a request made after this\n // panel mounted opens it — one already answered never reopens it.\n const answeredSeq = useRef(openRequest.seq)\n useEffect(() => {\n if (openRequest.seq <= answeredSeq.current) return\n answeredSeq.current = openRequest.seq\n if (siteJobsHref) {\n setOpen(false)\n router.push(openRequest.jobId ? `${siteJobsHref}/${encodeURIComponent(openRequest.jobId)}` : siteJobsHref)\n return\n }\n setJobsFocus(openRequest)\n setOpen(true)\n // A new `seq` is a new request; the object is read as it stands.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [openRequest.seq])\n useEffect(() => {\n if (!open) setJobsFocus(null)\n }, [open])\n // A notification's link names the job as `?aiJob={id}` on a console page:\n // arriving on it opens AI jobs on that job, once per address.\n useEffect(() => {\n if (!jobsVisible) return\n const jobId = new URLSearchParams(globalThis.location?.search ?? '').get(AI_JOB_LINK_PARAM)\n if (jobId) openAiJobs({ jobId })\n }, [jobsVisible, pathname])\n\n const send = useCallback(async (asked: string) => {\n const question = asked.trim()\n if (!question || busy || !scopedOrgId || !ai.use) return\n setBusy(true)\n // The drafts this thread's builds made (AGL-3616): the chat sees refs and\n // labels; the addresses stay here, for the card a follow-up raises.\n const draftLinks = hostId ? assistThreadDraftLinks(messages, orgSlug) : []\n // Only this site's turns ride the question (AGL-4116), and the answer\n // lands in the thread it was asked in.\n const history = messages\n .slice(-HISTORY_TURNS_SENT)\n .map(({ role, text }) => ({ role, text }))\n const askedIn = threadKey\n updateThread(askedIn, (prior) => [\n ...prior,\n { role: 'user', text: question },\n { role: 'assistant', text: '' },\n ])\n const patchAnswer = (patch: (message: AssistMessage) => AssistMessage) => {\n updateThread(askedIn, (prior) => {\n const next = [...prior]\n const last = next[next.length - 1]\n if (last?.role === 'assistant') next[next.length - 1] = patch(last)\n return next\n })\n }\n // A notice must not be swallowed by a partial answer: a refusal or a\n // max_tokens cut arrives AFTER text has streamed, and substituting only\n // when the bubble is empty would leave the user staring at half an\n // answer with nothing saying why it stopped.\n const failAnswer = (notice: string) => {\n patchAnswer((message) => ({\n ...message,\n text: message.text ? `${message.text}\\n\\n${notice}` : notice,\n }))\n }\n /** The build this turn proposed, started once its stream ends (AGL-3616). */\n let proposedBuild: AssistBuildProposal | null = null\n /** The page change this turn asked for, started once its stream ends (AGL-4116). */\n let proposedChange: AssistPageChangeProposal | null = null\n try {\n // The canvas outline rides along from the besigner document the open\n // editor holds — ids, component ids and short values, never the stored\n // document — and only while that editor is on the version the route\n // names, so the outline and the selection are the ones on screen.\n const editDocument = editRungHint ? assistEditDocumentOf(pathname ?? '') : null\n const session = editDocument ? openEditorSession() : undefined\n const canvasOutline =\n editDocument &&\n session &&\n session.documentKind === editDocument.kind &&\n session.documentId === editDocument.documentId &&\n session.versionId === editDocument.versionId\n ? describeAssistEditCanvas(canvas, session.selectedNodeId?.() ?? null)\n : null\n const response = await authorizedFetch(user, '/api/assist/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n orgId: scopedOrgId,\n question,\n history,\n // Page context rides along; the server drops it for free orgs\n // (level 2 is Pro+). Sending it is not a grant — the capability\n // decision is server-side.\n context: { route: pathname ?? '', hostId: hostId ?? '', orgSlug },\n // A pick, when the reader made one; the server decides again.\n ...(modelChoice.model ? { model: modelChoice.model } : {}),\n ...(canvasOutline ? { canvas: canvasOutline } : {}),\n // The draft open here is marked, with its canvas riding beside it,\n // so the answer edits it rather than offering to open it again\n // (AGL-3833).\n ...(draftLinks.length\n ? {\n drafts: draftLinks.map(({ ref, label, noun, href }) => ({\n ref,\n label,\n noun,\n ...(canvasOutline && href === pathname ? { open: true } : {}),\n })),\n }\n : {}),\n }),\n })\n if (!response.ok || !response.body) {\n const payload = await response.json().catch(() => null)\n const locked = parseLockdownRefusal(response.status, payload)\n if (locked) {\n failAnswer(lockdownRefusalText(locked))\n } else if (response.status === 501) {\n // 501 means the narrow thing it says: no model is available AND\n // the documentation had nothing to offer for this question either\n // — the server hands back the closest pages whenever it has any\n // (AGL-2486), so reaching here means it had none.\n //\n // Written for the person who is actually reading it. \"Not\n // configured on this deployment\" names a deployment the reader does\n // not administer and a configuration they cannot see, and landing\n // mid-thread after a working answer it reads as a breakage. What a\n // user needs here is what happened, what to try, and who can fix it\n // — in that order, in words that assume no idea what an API key\n // is. The\n // operator's half (the env var) stays in the API error body, where\n // an operator looks and a customer does not.\n failAnswer(\n `I could not find anything in the documentation about that, and I cannot work it through with you myself yet — ` +\n `${branding.productName} Assist has not been fully switched on here. ` +\n `Try asking in different words, or ask whoever set up this workspace to finish enabling the assistant.`,\n )\n } else if (\n (response.status === 429 || response.status === 402) &&\n payload?.reason === 'quota'\n ) {\n // 402 is the org's own hard cap (AGL-2653): the band would sell\n // past itself and this workspace switched the sale off. The\n // sentence names the switch, and the credit standing beside it is\n // as real as a 429's, so it lands on the same line.\n if (payload.quota) setQuota(payload.quota as AssistQuotaInfo)\n publishMeter(payload?.meter)\n failAnswer(String(payload?.error ?? 'Message limit reached.'))\n } else {\n failAnswer(String(payload?.error ?? 'The assistant request failed — try again.'))\n }\n return\n }\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue\n let event: Record<string, unknown>\n try {\n event = JSON.parse(line.slice('data: '.length))\n } catch {\n continue\n }\n if (event.type === 'delta' && typeof event.text === 'string') {\n const text = event.text as string\n patchAnswer((message) => ({ ...message, text: message.text + text }))\n } else if (event.type === 'done') {\n const docs = (event.docs as AssistDocLink[] | undefined) ?? []\n // Server-resolved and inert: an id from the closed set attached\n // to the view the question was asked from, plus a destination\n // this client did not choose. Null on every turn that proposed\n // nothing, which is most of them.\n const resolved = (event.proposal as AssistProposal | null) ?? null\n // An open-draft proposal goes to that draft's own Besigner, from\n // this panel's record of its build, and asks the request again\n // there; one naming a draft this panel does not hold is dropped.\n // Never the draft already open here (AGL-3833).\n const draftLink = resolved?.draft\n ? draftLinks.find((link) => link.ref === resolved.draft?.ref && link.href !== pathname)\n : null\n const proposal: AssistProposal | null =\n resolved?.draft\n ? draftLink\n ? { ...resolved, href: draftLink.href, followUp: question }\n : null\n : resolved\n // The edit proposal (AGL-2906), shape-checked before it can reach\n // a card whose Apply drives the canvas.\n const edit = isAssistEditProposal(event.edit) ? event.edit : null\n // The build proposal (AGL-3616), shape-checked before it can start a job.\n const build = isAssistBuildProposal(event.build) ? event.build : null\n proposedBuild = build\n // The page change (AGL-4116), shape-checked before it can start a job.\n const pageChange = isAssistPageChangeProposal(event.pageChange) ? event.pageChange : null\n proposedChange = pageChange\n patchAnswer((message) => ({\n ...message,\n exchangeId: (event.exchangeId as string | null) ?? null,\n docs,\n proposal,\n edit,\n ...(build ? { build, buildJob: null, buildNotice: null } : {}),\n ...(pageChange ? { pageChange, pageChangeJob: null, pageChangeNotice: null } : {}),\n }))\n if (event.quota) setQuota(event.quota as AssistQuotaInfo)\n publishMeter(event.meter)\n trackEvent('assistant_message_sent', {\n tier: entitled ? 'entitled' : 'free',\n grounded: docs.length > 0,\n })\n if (proposal) {\n trackEvent('assistant_proposal_shown', { action: proposal.id })\n }\n if (edit) {\n trackEvent('assistant_proposal_shown', { action: edit.id })\n }\n if (build) {\n trackEvent('assistant_proposal_shown', { action: build.id })\n }\n if (pageChange) {\n trackEvent('assistant_proposal_shown', { action: pageChange.id })\n }\n } else if (event.type === 'error') {\n failAnswer(String(event.error ?? 'The assistant stream failed.'))\n }\n }\n }\n // One request, one build (AGL-3616): the job is created here, once,\n // through the job door, and plans inline; its card shows the plan.\n if (proposedBuild) {\n // One plan per conversation (AGL-4116): a plan this thread proposed\n // and the person has not confirmed is replaced by the new one, which\n // the chat wrote from the whole request as it now stands. Its job is\n // canceled, so it never builds and never warns another door.\n for (const replaced of assistUnconfirmedBuilds(messages)) {\n updateThread(askedIn, (prior) =>\n prior.map((entry, i) => (i === replaced.index ? { ...entry, buildReplaced: true } : entry)),\n )\n void cancelAiJobRequest(user, scopedOrgId, replaced.jobId).then(({ job }) => {\n if (!job) return\n updateThread(askedIn, (prior) =>\n prior.map((entry, i) => (i === replaced.index ? { ...entry, buildJob: job } : entry)),\n )\n })\n }\n const decision = await startAssistBuildRequest(user, scopedOrgId, proposedBuild)\n // The plan the door ran inline has just spent (AGL-3722), so the strip\n // moves with it, to the figure the plan card quotes. Left to the jobs\n // list's next read it said what was left BEFORE the plan, under a card\n // that had it right: \"117 free AI credits left\" over \"You have 71\n // left\", 2026-10-10. The card's figure is read after the plan's spend\n // is counted once, so the strip takes it as it is.\n publishMeter(decision.meter)\n const uid = user?.uid\n if (uid && scopedOrgId) {\n refreshAiUsageMeterFree(uid, scopedOrgId, decision.job?.review?.freeCredits, readAiUsageMeter(uid, scopedOrgId))\n }\n patchAnswer((message) => ({ ...message, buildJob: decision.job, buildNotice: decision.error }))\n }\n // A change to a page (AGL-4116): its edit job starts here, once, with\n // no plan to confirm. A follow-up to a page this conversation already\n // changed starts from the draft that change made.\n if (proposedChange) {\n const decision = await startAssistPageChangeRequest(\n user,\n scopedOrgId,\n proposedChange,\n assistPageChangeDraftVersion(messages, proposedChange.pageId),\n )\n publishMeter(decision.meter)\n patchAnswer((message) => ({ ...message, pageChangeJob: decision.job, pageChangeNotice: decision.error }))\n }\n } catch (error) {\n console.error(error)\n failAnswer('The assistant request failed — check your connection and try again.')\n } finally {\n setBusy(false)\n }\n }, [\n ai.use,\n busy,\n editRungHint,\n entitled,\n hostId,\n messages,\n modelChoice.model,\n publishMeter,\n scopedOrgId,\n orgSlug,\n pathname,\n threadKey,\n updateThread,\n user,\n ])\n\n // A follow-up waiting for its draft's canvas (AGL-3616): kept per org, so a\n // panel the Besigner's layout mounts afresh still asks it.\n const [followUp, setFollowUp] = useState<AssistPendingFollowUp | null>(null)\n useEffect(() => {\n setFollowUp(loadFollowUp(scopedOrgId))\n }, [scopedOrgId])\n const followUpVersion = editorSession?.versionId ?? null\n useEffect(() => {\n if (!followUp) return\n if (!isLiveAssistFollowUp(followUp, Date.now())) {\n setFollowUp(null)\n saveFollowUp(scopedOrgId, null)\n return\n }\n // Asked once the draft's own canvas is open AND loaded, so the edit rung\n // reads it (AGL-3833). The editor reports its version as it mounts, before\n // the document reaches the canvas; it reports again once it has.\n if (busy || !ai.use) return\n const stand = {\n path: pathname ?? '',\n versionId: followUpVersion,\n canvasLoaded: Boolean(canvas.getNode(CANVAS_ROOT_ELEMENT_ID)),\n }\n if (!isAssistFollowUpDue(followUp, stand)) return\n setFollowUp(null)\n saveFollowUp(scopedOrgId, null)\n setOpen(true)\n void send(followUp.question)\n // The revision is how a canvas that finished loading reaches this effect.\n }, [ai.use, busy, followUp, followUpVersion, editorRevision, pathname, scopedOrgId, send])\n\n /** Keep a confirmed open-draft proposal's request for the draft's canvas. */\n const holdFollowUp = useCallback(\n (proposal: AssistProposal) => {\n if (!proposal.followUp) return\n const pending = { path: proposal.href, question: proposal.followUp, at: Date.now() }\n setFollowUp(pending)\n saveFollowUp(scopedOrgId, pending)\n },\n [scopedOrgId],\n )\n\n /**\n * Retire a card once it has been acted on or waved away. Local state only\n * — there is nothing to tell the server, because the proposal was never\n * anything the server was waiting on.\n */\n const resolveProposal = useCallback((index: number) => {\n setMessages((prior) =>\n prior.map((entry, i) =>\n i === index ? { ...entry, proposalResolved: true } : entry,\n ),\n )\n }, [setMessages])\n\n /**\n * Land a confirmed edit on the open editor (AGL-2906): through the canvas's\n * own mutators, as one undo step, unsaved. The only request that follows is\n * the activity record, and it carries counts, never content.\n */\n const applyEdit = useCallback(\n (index: number) => {\n const message = messages[index]\n const proposal = message?.edit\n if (!proposal || !scopedOrgId) return\n const session = openEditorSession()\n const result = applyAssistEdit(canvas, proposal, session)\n if (result.ok === false) {\n setMessages((prior) =>\n prior.map(\n (entry, i): AssistMessage =>\n i === index\n ? { ...entry, editOutcome: { kind: 'failed', message: result.message } }\n : entry,\n ),\n )\n return\n }\n setMessages((prior) =>\n prior.map(\n (entry, i): AssistMessage =>\n i === index ? { ...entry, editOutcome: { kind: 'applied' } } : entry,\n ),\n )\n trackEvent('assistant_proposal_confirmed', { action: proposal.id })\n enqueueSnackbar('Applied as unsaved changes — undo takes them back', {\n variant: 'success',\n persist: false,\n })\n if (!message.exchangeId || !session) return\n const report: AssistEditAppliedReport = {\n orgId: scopedOrgId,\n hostId: proposal.target.hostId,\n exchangeId: message.exchangeId,\n documentKind: proposal.target.kind,\n documentId: proposal.target.documentId,\n versionId: session.versionId,\n opCounts: result.opCounts,\n }\n // Fire and forget: the edit is already on the canvas, and a record that\n // fails to land must not read as an edit that failed.\n void authorizedFetch(user, '/api/assist/edit-applied', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(report),\n }).catch(() => undefined)\n },\n [enqueueSnackbar, messages, scopedOrgId, setMessages, user],\n )\n\n /** Keep what a build card learned about its job on its own message (AGL-3616). */\n const patchBuild = useCallback(\n (index: number, patch: Pick<AssistMessage, 'buildJob'> | Pick<AssistMessage, 'buildNotice'>) => {\n setMessages((prior) => prior.map((entry, i) => (i === index ? { ...entry, ...patch } : entry)))\n },\n [setMessages],\n )\n\n /** Keep what a page change card learned about its job on its own message (AGL-4116). */\n const patchPageChange = useCallback(\n (index: number, patch: Pick<AssistMessage, 'pageChangeJob' | 'pageChangeNotice'>) => {\n setMessages((prior) => prior.map((entry, i) => (i === index ? { ...entry, ...patch } : entry)))\n },\n [setMessages],\n )\n\n /** Start a page change again after it failed: a new edit job, from the same draft. */\n const [retryingChange, setRetryingChange] = useState<number | null>(null)\n const retryPageChange = useCallback(\n async (index: number) => {\n const proposal = messages[index]?.pageChange\n if (!proposal || !scopedOrgId) return\n setRetryingChange(index)\n patchPageChange(index, { pageChangeJob: null, pageChangeNotice: null })\n const decision = await startAssistPageChangeRequest(\n user,\n scopedOrgId,\n proposal,\n assistPageChangeDraftVersion(messages.slice(0, index), proposal.pageId),\n )\n publishMeter(decision.meter)\n patchPageChange(index, { pageChangeJob: decision.job, pageChangeNotice: decision.error })\n setRetryingChange(null)\n },\n [messages, patchPageChange, publishMeter, scopedOrgId, user],\n )\n\n /** Wave an edit card away. Nothing to tell the server: nothing happened. */\n const dismissEdit = useCallback((index: number) => {\n setMessages((prior) =>\n prior.map(\n (entry, i): AssistMessage =>\n i === index ? { ...entry, editOutcome: { kind: 'dismissed' } } : entry,\n ),\n )\n }, [setMessages])\n\n const sendFeedback = useCallback(\n async (index: number, feedback: 'up' | 'down') => {\n const message = messages[index]\n if (!message?.exchangeId || !scopedOrgId) return\n setMessages((prior) =>\n prior.map((entry, i) => (i === index ? { ...entry, feedback } : entry)),\n )\n trackEvent('assistant_feedback', { feedback })\n try {\n await authorizedFetch(user, '/api/assist/feedback', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n orgId: scopedOrgId,\n exchangeId: message.exchangeId,\n feedback,\n }),\n })\n } catch {\n enqueueSnackbar('Feedback could not be recorded', {\n variant: 'warning',\n persist: false,\n })\n }\n },\n [enqueueSnackbar, messages, scopedOrgId, setMessages, user],\n )\n\n // A released-off feature does not exist (staff preview excepted) — and\n // without an org IN SCOPE there is nothing to meter or record against\n // (AGL-1934). `scopedOrgId`, never `orgId`: the fallback org is always\n // present, which is exactly why gating on it announced and billed the\n // assistant on the workspace picker. Every hook above has already run, so\n // this early return costs no hook-order hazard.\n if (!verdict.visible || !scopedOrgId) return null\n\n return (\n <>\n {!open && (\n <Tooltip title={`${branding.productName} Assist`} placement=\"left\">\n <Fab\n color=\"primary\"\n size=\"medium\"\n // Says what waits inside as well as what it opens (AGL-3593).\n aria-label={aiJobsLauncherLabel(branding.productName, jobsActivity)}\n onClick={() => setOpen(true)}\n sx={{\n position: 'fixed',\n // Insets, not constants (AGL-2486). The console chrome leaves\n // the bottom-right corner empty, but the besigner does not:\n // its properties panel is a full-height column on that edge,\n // and a fixed launcher lands on the Styles form and its\n // scrollbar. A surface that owns the corner publishes these\n // variables to move the launcher clear of itself; everywhere\n // else the fallback is the corner it has always used. Read as\n // CSS rather than passed as props so the offset can follow a\n // panel the launcher knows nothing about — one that is\n // resizable and collapsible — without this component growing\n // a dependency on the editor.\n right: 'var(--aglyn-dock-inset-right, 20px)',\n bottom: 'var(--aglyn-dock-inset-bottom, 20px)',\n zIndex: (theme) => theme.zIndex.drawer - 1,\n }}\n >\n {/* Sized at the call site (AGL-2486). `MdiIcon` defaults to\n `fontSize=\"inherit\"`, which is right for the startIcon and\n caption slots most of this file uses it in — but inside a\n Fab the inherited size is the BUTTON typography, 14px, so\n the glyph painted at 14px in a 48px control and read as\n broken. `medium` is the 24px MUI puts in its own FABs. Not\n fixed in `MdiIcon`: that default is depended on across the\n console, including twice in this file. */}\n {/* A job running is a dot; a job that needs the person is a count in\n the warning color, the same precedence as the top-bar chip\n (AGL-3593). The Fab's own label says it in words. */}\n <Badge\n color={jobsActivity && jobsActivity.state !== 'running' ? 'warning' : 'secondary'}\n variant={jobsActivity?.state === 'running' ? 'dot' : 'standard'}\n badgeContent={jobsActivity ? jobsActivity.count : 0}\n invisible={!jobsActivity}\n overlap=\"circular\"\n data-ai-jobs-badge={jobsActivity?.state ?? undefined}\n >\n <MdiIcon path={mdiCreation.path} fontSize=\"medium\" />\n </Badge>\n </Fab>\n </Tooltip>\n )}\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={() => setOpen(false)}\n slotProps={{\n paper: {\n sx: { width: { xs: '100%', sm: 420 }, display: 'flex' },\n },\n }}\n >\n <Stack sx={{ height: '100%' }}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{\n px: 2,\n py: 1.5,\n borderBottom: 1,\n borderColor: 'divider',\n alignItems: 'center',\n }}\n >\n {/* Same reason as the launcher: this one sits beside an `h6`\n title in a plain Stack, so `inherit` gave it the 16px body\n size against a 20px heading. */}\n <MdiIcon path={mdiCreation.path} fontSize=\"medium\" />\n <Typography variant=\"h6\" sx={{ flexGrow: 1 }}>\n {`${branding.productName} Assist`}\n </Typography>\n {verdict.staffPreview && (\n <Chip size=\"small\" color=\"warning\" label=\"Staff preview\" />\n )}\n {/* Released and still changing (AGL-4052). Never beside the staff\n preview marker: an assistant only staff can see is rolling\n out, not in beta. */}\n {verdict.visible &&\n !verdict.staffPreview &&\n isBetaStaged('release_assist') && <BetaChip />}\n {/* Assist answers from the docs but never says so, and the three\n questions it provokes — what it can and can't do, why it\n stopped answering, what happens to what I typed — are exactly\n the four headings on its docs page (AGL-1943). Nothing in this\n panel's chrome can carry those, and a chat box is the one\n surface where a user is most likely to keep asking rather\n than go and read. */}\n <HelpTip\n {...pluginDocsHelp('aglynAssist', { anchor: '#what-it-can-do' })}\n sx={{ color: 'text.secondary' }}\n />\n <Tooltip title={`Close ${branding.productName} Assist`}>\n <IconButton\n aria-label={`Close ${branding.productName} Assist`}\n onClick={() => setOpen(false)}\n >\n {/* An IconButton does not set a font-size of its own, so\n `inherit` reached the same 14px button typography. */}\n <MdiIcon path={mdiClose.path} fontSize=\"medium\" />\n </IconButton>\n </Tooltip>\n </Stack>\n\n <Box ref={scrollRef} sx={{ flexGrow: 1, overflowY: 'auto', p: 2 }}>\n {/* The generation jobs (AGL-2904), scoped to the same org the\n thread is: a job listed here is one this page may act as. */}\n <AssistJobsDrawer\n orgId={scopedOrgId}\n org={org}\n orgReady={orgReady}\n orgSlug={billingSlug}\n user={user}\n visible={generativeVisible}\n isStaff={isStaff}\n hostId={hostId}\n // A question about the figures, where the page reports them\n // (AGL-2915); hidden with the rest of AI jobs, and refused by\n // the jobs door where the member may not generate.\n insight={ai.generate ? aiInsightSurfaceForPath(pathname) : null}\n inFlight={jobsVisible ? inFlight : undefined}\n focus={jobsFocus}\n pageHref={siteJobsHref}\n />\n {!messages.length && (\n <Alert severity=\"info\" sx={{ mb: 2 }}>\n {`Ask anything about using ${branding.productName} — building `}\n {'your site, publishing, domains, commerce, billing. Answers '}\n {'link the docs and the console page to use.'}\n {orgReady && !entitled && !isStaff && (\n <>\n {' Free workspaces get a limited number of messages a day. '}\n {`Page-aware guidance is included from ${\n planLabelGrantingFeature('aiAssist') ?? 'a paid plan'\n }. `}\n {billingSlug ? (\n <AppLink href={`/${billingSlug}/billing#plans`}>\n {'Upgrade'}\n </AppLink>\n ) : null}\n </>\n )}\n </Alert>\n )}\n <Stack spacing={1.5}>\n {messages.map((message, index) => (\n <Box\n key={index}\n sx={{\n alignSelf:\n message.role === 'user' ? 'flex-end' : 'flex-start',\n maxWidth: '90%',\n borderRadius: 2,\n px: 1.5,\n py: 1,\n bgcolor:\n message.role === 'user'\n ? 'primary.main'\n : 'action.hover',\n color:\n message.role === 'user'\n ? 'primary.contrastText'\n : 'text.primary',\n }}\n >\n <Typography\n variant=\"body2\"\n component=\"div\"\n sx={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}\n >\n {message.role === 'assistant' ? (\n message.text ? (\n renderAssistText(\n splitAssistDisclosure(message.text).plain,\n )\n ) : (\n <CircularProgress size={14} />\n )\n ) : (\n message.text\n )}\n </Typography>\n {message.role === 'assistant' &&\n splitAssistDisclosure(message.text).technical && (\n <UnderTheHood\n technical={splitAssistDisclosure(message.text).technical}\n />\n )}\n {message.role === 'assistant' && (\n <AssistSources text={message.text} docs={message.docs} />\n )}\n {message.role === 'assistant' &&\n message.proposal &&\n !message.proposalResolved && (\n <ProposalCard\n proposal={message.proposal}\n brand={productName}\n onConfirm={() => {\n trackEvent('assistant_proposal_confirmed', {\n action: message.proposal?.id ?? '',\n })\n resolveProposal(index)\n // A follow-up keeps the panel open: its answer\n // arrives here once the draft's canvas is.\n if (message.proposal?.followUp) holdFollowUp(message.proposal)\n else setOpen(false)\n }}\n onDismiss={() => resolveProposal(index)}\n />\n )}\n {message.role === 'assistant' &&\n message.edit &&\n message.editOutcome?.kind !== 'dismissed' &&\n message.editOutcome?.kind !== 'applied' && (\n <AssistEditCard\n proposal={message.edit}\n brand={productName}\n session={editorSession}\n failure={\n message.editOutcome?.kind === 'failed'\n ? message.editOutcome.message\n : null\n }\n onApply={() => applyEdit(index)}\n onCreateVersion={() => editorSession?.createVersion?.()}\n onDismiss={() => dismissEdit(index)}\n />\n )}\n {message.role === 'assistant' && message.pageChange && scopedOrgId && (\n <AssistPageChangeCard\n proposal={message.pageChange}\n job={message.pageChangeJob ?? null}\n notice={message.pageChangeNotice ?? null}\n orgId={scopedOrgId}\n orgSlug={orgSlug}\n user={user}\n busy={retryingChange === index}\n onJob={(job) => patchPageChange(index, { pageChangeJob: job })}\n onRetry={() => void retryPageChange(index)}\n />\n )}\n {message.role === 'assistant' && message.build && message.buildReplaced && (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\" sx={{ mt: 0.5 }}>\n {ASSIST_BUILD_REPLACED_COPY}\n </Typography>\n )}\n {message.role === 'assistant' && message.build && !message.buildReplaced && scopedOrgId && (\n <AssistBuildCard\n proposal={message.build}\n job={message.buildJob ?? null}\n notice={message.buildNotice ?? null}\n orgId={scopedOrgId}\n user={user}\n staff={isStaff}\n onJob={(job) => patchBuild(index, { buildJob: job })}\n onNotice={(notice) => patchBuild(index, { buildNotice: notice })}\n orgSlug={orgSlug}\n />\n )}\n {message.role === 'assistant' &&\n message.editOutcome?.kind === 'applied' && (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n component=\"div\"\n sx={{ mt: 0.5 }}\n >\n Applied to the canvas as unsaved changes.\n </Typography>\n )}\n {message.role === 'assistant' && message.exchangeId && (\n <Stack direction=\"row\" spacing={0.5} sx={{ mt: 0.5 }}>\n {/* The span is load-bearing (AGL-2128): a disabled MUI\n button fires no pointer events, so a Tooltip on it\n directly never opens — and \"already answered\" is\n precisely the state a reader most needs explained,\n because the greyed thumbs otherwise look broken. */}\n <Tooltip\n title={\n message.feedback\n ? 'Thanks — you already rated this answer'\n : 'Helpful answer'\n }\n >\n <span>\n <IconButton\n size=\"small\"\n aria-label=\"Helpful answer\"\n color={message.feedback === 'up' ? 'primary' : 'default'}\n disabled={Boolean(message.feedback)}\n onClick={() => void sendFeedback(index, 'up')}\n >\n <MdiIcon\n path={mdiThumbUpOutline.path}\n sx={{ fontSize: 16 }}\n />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip\n title={\n message.feedback\n ? 'Thanks — you already rated this answer'\n : 'Unhelpful answer'\n }\n >\n <span>\n <IconButton\n size=\"small\"\n aria-label=\"Unhelpful answer\"\n color={message.feedback === 'down' ? 'primary' : 'default'}\n disabled={Boolean(message.feedback)}\n onClick={() => void sendFeedback(index, 'down')}\n >\n <MdiIcon\n path={mdiThumbDownOutline.path}\n sx={{ fontSize: 16 }}\n />\n </IconButton>\n </span>\n </Tooltip>\n </Stack>\n )}\n </Box>\n ))}\n </Stack>\n </Box>\n\n <Stack\n spacing={1}\n sx={{ p: 2, borderTop: 1, borderColor: 'divider' }}\n >\n {ai.loaded && !ai.use ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Your role does not include the assistant — ask an ' +\n 'organization admin to grant \"Use AI assistance\".'}\n </Typography>\n ) : null}\n {/* The reader's credits while they work (AGL-2942), from the\n envelope the last answer carried — no read of its own. */}\n <AiUsageStrip orgId={scopedOrgId} orgSlug={billingSlug} />\n {quota && quota.period === 'day' && (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {quota.remaining} of {quota.limit} free messages left today\n {/* `useOrgSlug()`, not `useOrgScope().orgSlug` — the latter\n is the SUBDOMAIN slug, which is null on `app.aglyn.com`,\n so this upgrade link silently vanished on every apex org\n route: the one place a capped free workspace is told it\n is capped, with no way to act on it. Safe to fall back to\n the resolved org's slug here because the render gate\n above has already established the URL names it. */}\n {billingSlug ? (\n <>\n {' — '}\n <AppLink\n componentVariant=\"naked\"\n href={`/${billingSlug}/billing`}\n >\n upgrade for more\n </AppLink>\n </>\n ) : null}\n </Typography>\n )}\n {/* The model switch (AGL-2942), for a workspace whose plan\n answers with a model at all; its options load when opened. */}\n {entitled ? (\n <Stack direction=\"row\" sx={{ justifyContent: 'flex-end', mb: -0.5 }}>\n <AiModelSelector\n choice={modelChoice}\n disabled={busy || !ai.loaded || !ai.use}\n />\n </Stack>\n ) : null}\n <AssistComposer\n busy={busy}\n loaded={ai.loaded}\n allowed={ai.use}\n onSend={send}\n />\n </Stack>\n </Stack>\n </Drawer>\n </>\n )\n}\n\nexport default AssistPanelComponent\n"],"names":["canvas","checkEntitlement","isBetaStaged","lockdownRefusalText","parseLockdownRefusal","planLabelGrantingFeature","editorSessionsRevision","openEditorSession","subscribeEditorSessions","trackEvent","CANVAS_ROOT_ELEMENT_ID","mdiChevronDown","mdiCreation","mdiChevronUp","mdiClose","mdiOpenInNew","mdiSend","mdiThumbDownOutline","mdiThumbUpOutline","AppLink","MdiIcon","BetaChip","useSnackbar","Alert","Badge","Box","Button","Chip","CircularProgress","Collapse","Drawer","Fab","IconButton","Link","Paper","Stack","TextField","Tooltip","Typography","usePathname","useRouter","Fragment","memo","useCallback","useEffect","useRef","useState","useSyncExternalStore","useUser","authorizedFetch","assistEditDocumentOf","isAssistEditProposal","applyAssistEdit","describeAssistEditCanvas","AssistEditCard","AssistBuildCard","isAssistBuildProposal","assistBuildDraftLinks","isAssistFollowUpDue","isLiveAssistFollowUp","cancelAiJobRequest","startAssistBuildRequest","startAssistPageChangeRequest","assistPageChangeDraftVersion","isAssistPageChangeProposal","AssistPageChangeCard","aiInsightSurfaceForPath","AssistJobsDrawer","AI_JOB_LINK_PARAM","openAiJobs","useAiJobsInFlight","useAiJobsOpenRequest","aiJobPhase","aiJobsActivity","aiJobsLauncherLabel","AI_SITE_BUILD_HREF","AiModelSelector","AiUsageStrip","useAiModelChoice","followAiJobsForUsageMeter","refreshAiUsageMeterFree","readAiUsageMeter","usePublishAiUsageMeter","pluginDocsHelp","HelpTip","followUpKey","orgId","loadFollowUp","sessionStorage","parsed","JSON","parse","getItem","Date","now","removeItem","saveFollowUp","followUp","setItem","stringify","assistThreadDraftLinks","messages","orgSlug","jobs","flatMap","message","buildJob","reverse","assistUnconfirmedBuilds","index","job","build","buildReplaced","phase","jobId","id","ASSIST_BUILD_REPLACED_COPY","BUILD_NOT_STARTED","PAGE_CHANGE_NOT_STARTED","HISTORY_TURNS_SENT","assistThreadKey","hostId","NO_MESSAGES","assistSiteAiJobsHref","pathname","parts","split","filter","Boolean","site","undefined","loadThread","key","raw","Array","isArray","map","buildNotice","pageChange","pageChangeJob","pageChangeNotice","saveThread","renderAssistText","text","pattern","cursor","match","matchAll","push","slice","label","href","length","part","i","startsWith","componentVariant","target","rel","splitAssistDisclosure","plain","technical","trimEnd","trim","UnderTheHood","open","setOpen","sx","mt","component","type","variant","underline","onClick","prior","display","alignItems","gap","path","fontSize","in","unmountOnExit","color","whiteSpace","wordBreak","AssistSources","docs","unseen","shown","Set","doc","url","includes","has","add","spacing","title","ProposalCard","proposal","onConfirm","onDismiss","brand","p","borderRadius","bgcolor","outcome","values","prefill","m","pl","name","value","strong","direction","size","startIcon","AssistComposer","busy","loaded","allowed","onSend","inputRef","hasText","setHasText","disabled","noteText","next","submit","node","current","question","fullWidth","multiline","maxRows","placeholder","autoFocus","onChange","event","onKeyDown","shiftKey","preventDefault","span","aria-label","AssistPanelComponent","props","org","orgReady","scopedOrgId","productName","assistVisible","assistStaffPreview","generativeVisible","isStaff","aiPermissions","ai","verdict","visible","staffPreview","branding","billingSlug","data","user","enqueueSnackbar","setBusy","threadKey","threads","setThreads","updateThread","update","setMessages","quota","setQuota","scrollRef","modelChoice","surface","kind","publishMeter","editorRevision","editorSession","savedThreads","list","Object","entries","scrollTop","scrollHeight","entitled","editRungHint","generate","jobsVisible","inFlight","jobsActivity","siteJobsHref","router","openRequest","jobsFocus","setJobsFocus","answeredSeq","seq","encodeURIComponent","globalThis","URLSearchParams","location","search","get","send","asked","use","draftLinks","history","role","askedIn","patchAnswer","patch","last","failAnswer","notice","proposedBuild","proposedChange","editDocument","session","canvasOutline","documentKind","documentId","versionId","selectedNodeId","response","method","headers","body","context","route","model","drafts","ref","noun","ok","payload","json","catch","locked","status","reason","meter","String","error","reader","getReader","decoder","TextDecoder","buffer","lines","done","read","decode","stream","pop","line","resolved","draftLink","draft","find","link","edit","exchangeId","tier","grounded","action","replaced","entry","then","decision","uid","review","freeCredits","pageId","console","setFollowUp","followUpVersion","stand","canvasLoaded","getNode","holdFollowUp","pending","at","resolveProposal","proposalResolved","applyEdit","result","editOutcome","persist","report","opCounts","patchBuild","patchPageChange","retryingChange","setRetryingChange","retryPageChange","dismissEdit","sendFeedback","feedback","placement","position","right","bottom","zIndex","theme","drawer","state","badgeContent","count","invisible","overlap","data-ai-jobs-badge","anchor","onClose","slotProps","paper","width","xs","sm","height","px","py","borderBottom","borderColor","flexGrow","overflowY","insight","focus","pageHref","severity","mb","alignSelf","maxWidth","failure","onApply","onCreateVersion","createVersion","onJob","onRetry","staff","onNotice","borderTop","period","remaining","limit","justifyContent","choice"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;;AAEA,SACEA,MAAM,EACNC,gBAAgB,EAChBC,YAAY,EACZC,mBAAmB,EACnBC,oBAAoB,EACpBC,wBAAwB,QAEnB,eAAc;AACrB,SACEC,sBAAsB,EACtBC,iBAAiB,EACjBC,uBAAuB,QAClB,8CAA6C;AACpD,SAASC,UAAU,QAAQ,0CAAyC;AACpE,SAASC,sBAAsB,QAAQ,2CAA0C;AACjF,SACEC,cAAc,EACdC,WAAW,EACXC,YAAY,EACZC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACPC,mBAAmB,EACnBC,iBAAiB,QACZ,yBAAwB;AAC/B,SAASC,OAAO,EAAEC,OAAO,QAAQ,uBAAsB;AACvD,SAASC,QAAQ,QAAQ,sDAAqD;AAC9E,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SACEC,KAAK,EACLC,KAAK,EACLC,GAAG,EACHC,MAAM,EACNC,IAAI,EACJC,gBAAgB,EAChBC,QAAQ,EACRC,MAAM,EACNC,GAAG,EACHC,UAAU,EACVC,IAAI,EACJC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,OAAO,EACPC,UAAU,QACL,gBAAe;AACtB,SAASC,WAAW,EAAEC,SAAS,QAAQ,kBAAiB;AACxD,SACEC,QAAQ,EACRC,IAAI,EACJC,WAAW,EACXC,SAAS,EACTC,MAAM,EACNC,QAAQ,EACRC,oBAAoB,QACf,QAAO;AACd,SAASC,OAAO,QAAQ,iCAAgC;AACxD,SAASC,eAAe,QAAQ,2CAA0C;AAC1E,SACEC,oBAAoB,EACpBC,oBAAoB,QAGf,0BAAsB;AAC7B,SAASC,eAAe,EAAEC,wBAAwB,QAAQ,0BAAsB;AAChF,SAASC,cAAc,QAAQ,kCAA8B;AAC7D,SAASC,eAAe,QAAQ,mCAA+B;AAC/D,SAASC,qBAAqB,QAAkC,2BAAuB;AACvF,SACEC,qBAAqB,EACrBC,mBAAmB,EACnBC,oBAAoB,QAIf,+BAA2B;AAElC,SAASC,kBAAkB,EAAEC,uBAAuB,EAAEC,4BAA4B,QAAQ,uBAAmB;AAC7G,SACEC,4BAA4B,EAC5BC,0BAA0B,QAErB,iCAA6B;AACpC,SAASC,oBAAoB,QAAQ,yCAAqC;AAC1E,SAASC,uBAAuB,QAAQ,yBAAqB;AAC7D,SAASC,gBAAgB,QAAQ,oCAAgC;AACjE,SACEC,iBAAiB,EACjBC,UAAU,EACVC,iBAAiB,EACjBC,oBAAoB,QAEf,qBAAiB;AACxB,SAASC,UAAU,EAAEC,cAAc,EAAEC,mBAAmB,QAAQ,8BAA0B;AAC1F,SAASC,kBAAkB,QAAQ,4BAAwB;AAC3D,SAASC,eAAe,QAAQ,mCAA+B;AAC/D,SAASC,YAAY,QAAQ,gCAA4B;AACzD,SAASC,gBAAgB,QAAQ,2BAAuB;AACxD,SAASC,yBAAyB,EAAEC,uBAAuB,QAAQ,8BAA0B;AAC7F,SAASC,gBAAgB,EAAEC,sBAAsB,QAAQ,0BAAsB;AAC/E,SAASC,cAAc,QAAQ,mCAAkC;AACjE,SAASC,OAAO,QAAQ,uBAAsB;AA4G9C,kFAAkF,GAClF,MAAMC,cAAc,CAACC,QAAkB,CAAC,uBAAuB,EAAEA,OAAO;AAExE,SAASC,aAAaD,KAAyB;IAC7C,IAAI,CAACA,SAAS,OAAOE,mBAAmB,aAAa,OAAO;IAC5D,IAAI;YACiCA;QAAnC,MAAMC,SAAkBC,KAAKC,KAAK,EAACH,0BAAAA,eAAeI,OAAO,CAACP,YAAYC,mBAAnCE,0BAA8C;QACjF,IAAI7B,qBAAqB8B,QAAQI,KAAKC,GAAG,KAAK,OAAOL;QACrD,+CAA+C;QAC/C,IAAIA,WAAW,MAAMD,eAAeO,UAAU,CAACV,YAAYC;QAC3D,OAAO;IACT,EAAE,eAAM;QACN,OAAO;IACT;AACF;AAEA,SAASU,aAAaV,KAAyB,EAAEW,QAAsC;IACrF,IAAI,CAACX,SAAS,OAAOE,mBAAmB,aAAa;IACrD,IAAI;QACF,IAAIS,UAAUT,eAAeU,OAAO,CAACb,YAAYC,QAAQI,KAAKS,SAAS,CAACF;aACnET,eAAeO,UAAU,CAACV,YAAYC;IAC7C,EAAE,eAAM;IACN,qEAAqE;IACvE;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASc,uBACdC,QAA2D,EAC3DC,OAAe;IAEf,MAAMC,OAAOF,SAASG,OAAO,CAAC,CAACC,UAAaA,QAAQC,QAAQ,GAAG;YAACD,QAAQC,QAAQ;SAAC,GAAG,EAAE,EAAGC,OAAO;IAChG,OAAOlD,sBAAsB8C,MAAMD;AACrC;AAEA;;;;;CAKC,GACD,OAAO,SAASM,wBACdP,QAAoF;IAEpF,OAAOA,SAASG,OAAO,CAAC,CAACC,SAASI;QAChC,MAAMC,MAAML,QAAQM,KAAK,IAAI,CAACN,QAAQO,aAAa,GAAGP,QAAQC,QAAQ,GAAG;QACzE,IAAI,CAACI,KAAK,OAAO,EAAE;QACnB,MAAMG,QAAQzC,WAAWsC;QACzB,OAAOG,UAAU,YAAYA,UAAU,cAAcA,UAAU,eAAe;YAAC;gBAAEJ;gBAAOK,OAAOJ,IAAIK,EAAE;YAAC;SAAE,GAAG,EAAE;IAC/G;AACF;AAEA,0EAA0E,GAC1E,OAAO,MAAMC,6BAA6B,uEAAsE;AAEhH,mFAAmF,GACnF,MAAMC,oBAAoB;AAE1B,sEAAsE,GACtE,MAAMC,0BAA0B;AAShC,MAAMC,qBAAqB;AAE3B;;;;;CAKC,GACD,OAAO,SAASC,gBAAgBlC,KAAa,EAAEmC,MAAiC;IAC9E,OAAOA,SAAS,CAAC,aAAa,EAAEnC,MAAM,CAAC,EAAEmC,QAAQ,GAAG,CAAC,aAAa,EAAEnC,OAAO;AAC7E;AAEA,MAAMoC,cAA+B,EAAE;AAEvC;;;;CAIC,GACD,OAAO,SAASC,qBACdC,QAAmC,EACnCtB,OAAkC,EAClCmB,MAAiC;IAEjC,IAAI,CAACG,YAAY,CAACtB,WAAW,CAACmB,QAAQ,OAAO;IAC7C,MAAMI,QAAQD,SAASE,KAAK,CAAC,KAAKC,MAAM,CAACC;IACzC,MAAMC,OAAOJ,KAAK,CAAC,EAAE,KAAKvB,WAAWuB,KAAK,CAAC,EAAE,KAAK,UAAUA,KAAK,CAAC,EAAE,GAAGK;IACvE,OAAOD,OAAO,CAAC,CAAC,EAAE3B,QAAQ,OAAO,EAAE2B,OAAOtD,oBAAoB,GAAG;AACnE;AAEA,SAASwD,WAAWC,GAAW;IAC7B,IAAI,OAAO5C,mBAAmB,aAAa,OAAO,EAAE;IACpD,IAAI;QACF,MAAM6C,MAAM7C,eAAeI,OAAO,CAACwC;QACnC,MAAM3C,SAAS4C,MAAO3C,KAAKC,KAAK,CAAC0C,OAA2B,EAAE;QAC9D,IAAI,CAACC,MAAMC,OAAO,CAAC9C,SAAS,OAAO,EAAE;QACrC,uEAAuE;QACvE,yEAAyE;QACzE,qCAAqC;QACrC,OAAOA,OAAO+C,GAAG,CAAC,CAAC/B,UACjBA,QAAQM,KAAK,IAAI,CAACN,QAAQC,QAAQ,IAAI,CAACD,QAAQgC,WAAW,GACtD,aAAKhC;gBAASgC,aAAapB;iBAC3BZ,QAAQiC,UAAU,IAAI,CAACjC,QAAQkC,aAAa,IAAI,CAAClC,QAAQmC,gBAAgB,GACvE,aAAKnC;gBAASmC,kBAAkBtB;iBAChCb;IAEV,EAAE,eAAM;QACN,OAAO,EAAE;IACX;AACF;AAEA,SAASoC,WAAWT,GAAW,EAAE/B,QAAyB;IACxD,IAAI,OAAOb,mBAAmB,aAAa;IAC3C,IAAI;QACFA,eAAeU,OAAO,CAACkC,KAAK1C,KAAKS,SAAS,CAACE;IAC7C,EAAE,eAAM;IACN,wCAAwC;IAC1C;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASyC,iBAAiBC,IAAY;IAC3C,MAAMlB,QAAyD,EAAE;IACjE,MAAMmB,UAAU;IAChB,IAAIC,SAAS;IACb,KAAK,MAAMC,SAASH,KAAKI,QAAQ,CAACH,SAAU;YAC5BE;QAAd,MAAMrC,SAAQqC,eAAAA,MAAMrC,KAAK,YAAXqC,eAAe;QAC7B,IAAIrC,QAAQoC,QAAQpB,MAAMuB,IAAI,CAACL,KAAKM,KAAK,CAACJ,QAAQpC;QAClD,IAAIqC,KAAK,CAAC,EAAE,IAAIA,KAAK,CAAC,EAAE,EAAErB,MAAMuB,IAAI,CAAC;YAAEE,OAAOJ,KAAK,CAAC,EAAE;YAAEK,MAAML,KAAK,CAAC,EAAE;QAAC;aAClErB,MAAMuB,IAAI,CAAC;YAAEE,OAAOJ,KAAK,CAAC,EAAE;YAAEK,MAAML,KAAK,CAAC,EAAE;QAAC;QAClDD,SAASpC,QAAQqC,KAAK,CAAC,EAAE,CAACM,MAAM;IAClC;IACA,IAAIP,SAASF,KAAKS,MAAM,EAAE3B,MAAMuB,IAAI,CAACL,KAAKM,KAAK,CAACJ;IAChD,qBACE;kBACGpB,MAAMW,GAAG,CAAC,CAACiB,MAAMC;YAChB,IAAI,OAAOD,SAAS,UAAU;gBAC5B,qBAAO,KAAChH;8BAAkBgH;mBAAJC;YACxB;YACA,IAAID,KAAKF,IAAI,CAACI,UAAU,CAAC,MAAM;gBAC7B,qBACE,KAACxI;oBAAgByI,kBAAiB;oBAAQL,MAAME,KAAKF,IAAI;8BACtDE,KAAKH,KAAK;mBADCI;YAIlB;YACA,qBACE,KAACzH;gBAAasH,MAAME,KAAKF,IAAI;gBAAEM,QAAO;gBAASC,KAAI;0BAChDL,KAAKH,KAAK;eADFI;QAIf;;AAGN;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASK,sBAAsBhB,IAAY;IAIhD,MAAMG,QAAQH,KAAKG,KAAK,CAAC;IACzB,IAAI,CAACA,SAASA,MAAMrC,KAAK,KAAKqB,WAAW,OAAO;QAAE8B,OAAOjB;QAAMkB,WAAW;IAAG;IAC7E,MAAMD,QAAQjB,KAAKM,KAAK,CAAC,GAAGH,MAAMrC,KAAK,EAAEqD,OAAO;IAChD,MAAMD,YAAYlB,KAAKM,KAAK,CAACH,MAAMrC,KAAK,GAAGqC,KAAK,CAAC,EAAE,CAACM,MAAM,EAAEW,IAAI;IAChE,0EAA0E;IAC1E,qEAAqE;IACrE,IAAI,CAACH,SAAS,CAACC,WAAW,OAAO;QAAED,OAAOjB;QAAMkB,WAAW;IAAG;IAC9D,OAAO;QAAED;QAAOC;IAAU;AAC5B;AAEA,mCAAmC,GACnC,SAASG,aAAa,EAAEH,SAAS,EAAyB;IACxD,MAAM,CAACI,MAAMC,QAAQ,GAAGxH,SAAS;IACjC,qBACE,MAACrB;QAAI8I,IAAI;YAAEC,IAAI;QAAI;;0BACjB,MAACvI;gBACCwI,WAAU;gBACVC,MAAK;gBACLC,SAAQ;gBACRC,WAAU;gBACVC,SAAS,IAAMP,QAAQ,CAACQ,QAAU,CAACA;gBACnCP,IAAI;oBAAEQ,SAAS;oBAAeC,YAAY;oBAAUC,KAAK;gBAAK;;oBAC/D;kCAEC,KAAC7J;wBACC8J,MAAMb,OAAOxJ,aAAaqK,IAAI,GAAGvK,eAAeuK,IAAI;wBACpDX,IAAI;4BAAEY,UAAU;wBAAG;;;;0BAGvB,KAACtJ;gBAASuJ,IAAIf;gBAAMgB,aAAa;0BAC/B,cAAA,KAAC/I;oBACCqI,SAAQ;oBACRF,WAAU;oBACVa,OAAM;oBACNf,IAAI;wBAAEC,IAAI;wBAAKe,YAAY;wBAAYC,WAAW;oBAAa;8BAE9D1C,iBAAiBmB;;;;;AAK5B;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GACD,OAAO,SAASwB,cAAc,EAC5B1C,IAAI,EACJ2C,IAAI,EAIL;IACC,MAAMC,SAA0B,EAAE;IAClC,MAAMC,QAAQ,IAAIC;IAClB,KAAK,MAAMC,OAAOJ,eAAAA,OAAQ,EAAE,CAAE;QAC5B,yEAAyE;QACzE,sDAAsD;QACtD,IAAI,EAACI,uBAAAA,IAAKC,GAAG,KAAIhD,KAAKiD,QAAQ,CAACF,IAAIC,GAAG,KAAKH,MAAMK,GAAG,CAACH,IAAIC,GAAG,GAAG;QAC/DH,MAAMM,GAAG,CAACJ,IAAIC,GAAG;QACjBJ,OAAOvC,IAAI,CAAC0C;IACd;IACA,IAAI,CAACH,OAAOnC,MAAM,EAAE,OAAO;IAC3B,qBACE,MAAC/H;QAAI8I,IAAI;YAAEC,IAAI;QAAK;;0BAClB,KAAClI;gBAAWqI,SAAQ;gBAAUW,OAAM;gBAAiBb,WAAU;0BAC5DkB,OAAOnC,MAAM,KAAK,IAAI,WAAW;;0BAEpC,KAACrH;gBAAMgK,SAAS;gBAAM5B,IAAI;oBAAEC,IAAI;gBAAK;0BAClCmB,OAAOnD,GAAG,CAAC,CAACsD,oBACX,KAACxJ;wBAAyBqI,SAAQ;wBAAUF,WAAU;kCACnDqB,IAAIC,GAAG,CAACpC,UAAU,CAAC,qBAClB,KAACxI;4BAAQyI,kBAAiB;4BAAQL,MAAMuC,IAAIC,GAAG;sCAC5CD,IAAIM,KAAK;2CAGZ,KAACnK;4BAAKsH,MAAMuC,IAAIC,GAAG;4BAAElC,QAAO;4BAASC,KAAI;sCACtCgC,IAAIM,KAAK;;uBAPCN,IAAIC,GAAG;;;;AAelC;AAEA;;;;;;;;;;;;;;;;CAgBC,GACD,SAASM,aAAa,EACpBC,QAAQ,EACRC,SAAS,EACTC,SAAS,EACTC,KAAK,EAMN;IACC,qBACE,MAACvK;QACCyI,SAAQ;QACRJ,IAAI;YAAEC,IAAI;YAAGkC,GAAG;YAAKC,cAAc;YAAGC,SAAS;QAAmB;;0BAElE,KAACtK;gBAAWqI,SAAQ;0BAAa2B,SAAShD,KAAK;;0BAC/C,MAAChH;gBAAWqI,SAAQ;gBAAUW,OAAM;gBAAiBb,WAAU;;oBAAM;oBAC5D6B,SAASO,OAAO;oBAAC;;;YAEzBP,SAASrG,QAAQ,kBAChB,KAAC3D;gBAAWqI,SAAQ;gBAAUW,OAAM;gBAAiBb,WAAU;gBAAMF,IAAI;oBAAEC,IAAI;gBAAE;0BAC9E,GAAGiC,MAAM,cAAc,EAAEH,SAASrG,QAAQ,CAAC,oEAAoE,CAAC;;YAGpHqG,SAASQ,MAAM,CAACtD,MAAM,GAAG,mBACxB,MAAC/H;gBAAI8I,IAAI;oBAAEC,IAAI;gBAAE;;kCACf,KAAClI;wBAAWqI,SAAQ;wBAAUW,OAAM;wBAAiBb,WAAU;kCAC5D6B,SAASS,OAAO,GAAG,uBAAuB;;kCAE7C,KAAC5K;wBAAMsI,WAAU;wBAAKF,IAAI;4BAAEyC,GAAG;4BAAGC,IAAI;wBAAI;kCACvCX,SAASQ,MAAM,CAACtE,GAAG,CAAC,CAAC,EAAE0E,IAAI,EAAEC,KAAK,EAAE,iBACnC,MAAC7K;gCAAsBmI,WAAU;gCAAKE,SAAQ;;oCAC3CuC;oCAAK;kDAAE,KAACE;kDAAQD;;;+BADFD;;;;YAOxB,CAACZ,SAASrG,QAAQ,kBACjB,MAAC3D;gBACCqI,SAAQ;gBACRW,OAAM;gBACNb,WAAU;gBACVF,IAAI;oBAAEC,IAAI;gBAAE;;oBAEX,GAAGiC,MAAM,wDAAwD,CAAC;oBAClE;;;0BAGL,MAACtK;gBAAMkL,WAAU;gBAAMlB,SAAS;gBAAG5B,IAAI;oBAAEC,IAAI;gBAAI;;kCAC/C,KAACrJ;wBACCyI,kBAAiB;wBACjBL,MAAM+C,SAAS/C,IAAI;wBACnBoB,SAAQ;wBACR2C,MAAK;wBACLzC,SAAS0B;wBACTgB,yBAAW,KAACnM;4BAAQ8J,MAAMnK,aAAamK,IAAI;;kCAC5C;;kCAGD,KAACxJ;wBAAO4L,MAAK;wBAAQhC,OAAM;wBAAUT,SAAS2B;kCAAW;;;;;;AAMjE;AAEA;;;;;;;;;;;;;;CAcC,GACD,MAAMgB,+BAAiB9K,KAAK,SAAS8K,eAAe,EAClDC,IAAI,EACJC,MAAM,EACNC,OAAO,EACPC,MAAM,EAQP;IACC,MAAMC,WAAWhL,OAA4B;IAC7C,MAAM,CAACiL,SAASC,WAAW,GAAGjL,SAAS;IACvC,MAAMkL,WAAWP,QAAQ,CAACC,UAAU,CAACC;IACrC,MAAMM,WAAW,CAACd;QAChB,MAAMe,OAAOf,MAAMhD,IAAI,GAAGX,MAAM,GAAG;QACnC,IAAI0E,SAASJ,SAASC,WAAWG;IACnC;IACA,MAAMC,SAAS;;QACb,MAAMC,OAAOP,SAASQ,OAAO;QAC7B,MAAMC,mBAAWF,wBAAAA,KAAMjB,KAAK,CAAChD,IAAI,qBAAM;QACvC,IAAI,CAACiE,QAAQ,CAACE,YAAYN,UAAU;QACpCI,KAAKjB,KAAK,GAAG;QACbY,WAAW;QACX,KAAKH,OAAOU;IACd;IACA,qBACE,MAACnM;QAAMkL,WAAU;QAAMlB,SAAS;QAAG5B,IAAI;YAAES,YAAY;QAAW;;0BAC9D,KAAC5I;gBACCmM,SAAS;gBACTC,SAAS;gBACTC,SAAS;gBACTnB,MAAK;gBACLoB,aAAY;gBACZC,SAAS;gBACTd,UAAUA;gBACVG,UAAUA;gBACVY,UAAU,CAACC,QAAUZ,SAASY,MAAMhF,MAAM,CAACsD,KAAK;gBAChD2B,WAAW,CAACD;oBACV,IAAIA,MAAMzG,GAAG,KAAK,WAAW,CAACyG,MAAME,QAAQ,EAAE;wBAC5CF,MAAMG,cAAc;wBACpBb;oBACF;gBACF;;0BAEF,KAAC9L;gBACC+J,OACEqB,OACI,2BACA,CAACC,SACC,+BACA,CAACC,UACC,6CACA;0BAGV,cAAA,KAACsB;8BACC,cAAA,KAACjN;wBACCsJ,OAAM;wBACN4D,cAAW;wBACXlB,UAAUA,YAAY,CAACF;wBACvBjD,SAASsD;kCAERV,qBACC,KAAC7L;4BAAiB0L,MAAM;6BAExB,0DAA0D;wBAC1D,6DAA6D;wBAC7D,2BAA2B;sCAC3B,KAAClM;4BAAQ8J,MAAMlK,QAAQkK,IAAI;4BAAEX,IAAI;gCAAEY,UAAU;4BAAG;;;;;;;AAO9D;AA4CA,OAAO,SAASgE,qBAAqBC,KAAsB;qBA0vBrC/O;IAzvBpB,MAAM,EACJgP,GAAG,EACH/J,KAAK,EACLgK,QAAQ,EACRC,WAAW,EACXjJ,OAAO,EACPmB,MAAM,EACN+H,WAAW,EACXC,aAAa,EACbC,kBAAkB,EAClBC,iBAAiB,EACjBC,OAAO,EACPC,eAAeC,EAAE,EAClB,GAAGV;IACJ,MAAMW,UAAU;QAAEC,SAASP;QAAeQ,cAAcP;IAAmB;IAC3E,MAAMQ,WAAW;QAAEV;IAAY;IAC/B,MAAMW,cAAc7J;IACpB,MAAMsB,WAAWrF;IACjB,MAAM,EAAE6N,MAAMC,IAAI,EAAE,GAAGrN;IACvB,MAAM,EAAEsN,eAAe,EAAE,GAAGhP;IAE5B,MAAM,CAAC+I,MAAMC,QAAQ,GAAGxH,SAAS;IACjC,MAAM,CAAC2K,MAAM8C,QAAQ,GAAGzN,SAAS;IACjC,wEAAwE;IACxE,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM0N,YAAYjB,cAAc/H,gBAAgB+H,aAAa9H,UAAU;IACvE,MAAM,CAACgJ,SAASC,WAAW,GAAG5N,SAAoD,CAAC;IACnF,MAAMuD,WAAW,AAACmK,aAAaC,OAAO,CAACD,UAAU,IAAK9I;IACtD,MAAMiJ,eAAehO,YACnB,CAACyF,KAAoBwI;QACnB,IAAI,CAACxI,KAAK;QACVsI,WAAW,CAAC5F;gBAAqCA;mBAA1B,aAAKA;gBAAO,CAAC1C,IAAI,EAAEwI,QAAO9F,aAAAA,KAAK,CAAC1C,IAAI,YAAV0C,aAAc3C,WAAWC;;;IAC5E,GACA,EAAE;IAEJ,MAAMyI,cAAclO,YAClB,CAACiO,SAAwDD,aAAaH,WAAWI,SACjF;QAACJ;QAAWG;KAAa;IAE3B,MAAM,CAACG,OAAOC,SAAS,GAAGjO,SAAiC;IAC3D,MAAMkO,YAAYnO,OAAuB;IACzC,sEAAsE;IACtE,yEAAyE;IACzE,MAAMoO,cAAcnM,iBAAiB;QACnCQ,OAAOiK;QACP9H;QACAyJ,SAAS;QACTC,MAAM;IACR;IACA,MAAMC,eAAelM,uBAAuBqK;IAC5C,4EAA4E;IAC5E,0EAA0E;IAC1E,gBAAgB;IAChB,MAAM8B,iBAAiBtO,qBACrBvC,yBACAF,wBACAA;IAEF,MAAMgR,gBAAgB/Q;IAEtB,sEAAsE;IACtE,4EAA4E;IAC5E,qEAAqE;IACrE,0EAA0E;IAC1E,gBAAgB;IAChBqC,UAAU;QACR,IAAI,CAAC4N,WAAW;QAChBE,WAAW,CAAC5F,QAAW0F,aAAa1F,QAAQA,QAAQ,aAAKA;gBAAO,CAAC0F,UAAU,EAAErI,WAAWqI;;IAC1F,GAAG;QAACA;KAAU;IACd5N,UAAU;QACRmO,SAAS;IACX,GAAG;QAACxB;KAAY;IAEhB,2EAA2E;IAC3E,kCAAkC;IAClC,MAAMgC,eAAe1O,OAAwC,CAAC;IAC9DD,UAAU;QACR,KAAK,MAAM,CAACwF,KAAKoJ,KAAK,IAAIC,OAAOC,OAAO,CAACjB,SAAU;YACjD,IAAIc,aAAalD,OAAO,CAACjG,IAAI,KAAKoJ,MAAM;YACxCD,aAAalD,OAAO,CAACjG,IAAI,GAAGoJ;YAC5B3I,WAAWT,KAAKoJ;QAClB;IACF,GAAG;QAACf;KAAQ;IAEZ7N,UAAU;QACR,MAAMwL,OAAO4C,UAAU3C,OAAO;QAC9B,IAAID,MAAMA,KAAKuD,SAAS,GAAGvD,KAAKwD,YAAY;IAC9C,GAAG;QAACvL;KAAS;IAEb,MAAMwL,WAAWvC,YAAYrP,iBAAiBoP,KAAc;IAC5D,uEAAuE;IACvE,0EAA0E;IAC1E,sDAAsD;IACtD,MAAMyC,eACJnC,qBACAG,GAAGpC,MAAM,IACToC,GAAGiC,QAAQ,IACXzC,YACArP,iBAAiBoP,KAAc;IAEjC,0EAA0E;IAC1E,EAAE;IACF,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM2C,cAAchK,QAAQuH,gBAAgBuC;IAC5C,MAAMG,WAAW3N,kBAAkB+L,MAAMd,aAAayC;IACtD,yEAAyE;IACzE,4DAA4D;IAC5DpP,UAAU,IAAMmC,6BAA6B,EAAE;IAC/C,MAAMmN,eAAezN,eAAewN;IACpC,2EAA2E;IAC3E,wEAAwE;IACxE,WAAW;IACX,MAAME,eAAexK,qBAAqBC,UAAUtB,SAASmB;IAC7D,MAAM2K,SAAS5P;IACf,qEAAqE;IACrE,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,kEAAkE;IAClE,MAAM6P,cAAc9N;IACpB,MAAM,CAAC+N,WAAWC,aAAa,GAAGzP,SAAmC;IACrE,oEAAoE;IACpE,sEAAsE;IACtE,kEAAkE;IAClE,MAAM0P,cAAc3P,OAAOwP,YAAYI,GAAG;IAC1C7P,UAAU;QACR,IAAIyP,YAAYI,GAAG,IAAID,YAAYnE,OAAO,EAAE;QAC5CmE,YAAYnE,OAAO,GAAGgE,YAAYI,GAAG;QACrC,IAAIN,cAAc;YAChB7H,QAAQ;YACR8H,OAAOhJ,IAAI,CAACiJ,YAAYnL,KAAK,GAAG,GAAGiL,aAAa,CAAC,EAAEO,mBAAmBL,YAAYnL,KAAK,GAAG,GAAGiL;YAC7F;QACF;QACAI,aAAaF;QACb/H,QAAQ;IACR,iEAAiE;IACjE,uDAAuD;IACzD,GAAG;QAAC+H,YAAYI,GAAG;KAAC;IACpB7P,UAAU;QACR,IAAI,CAACyH,MAAMkI,aAAa;IAC1B,GAAG;QAAClI;KAAK;IACT,0EAA0E;IAC1E,8DAA8D;IAC9DzH,UAAU;;YAE0B+P;QADlC,IAAI,CAACX,aAAa;QAClB,MAAM9K,QAAQ,IAAI0L,yBAAgBD,uBAAAA,WAAWE,QAAQ,qBAAnBF,qBAAqBG,MAAM,mBAAI,IAAIC,GAAG,CAAC3O;QACzE,IAAI8C,OAAO7C,WAAW;YAAE6C;QAAM;IAChC,GAAG;QAAC8K;QAAapK;KAAS;IAE1B,MAAMoL,OAAOrQ,YAAY,OAAOsQ;QAC9B,MAAM3E,WAAW2E,MAAM9I,IAAI;QAC3B,IAAI,CAACmE,YAAYb,QAAQ,CAAC8B,eAAe,CAACO,GAAGoD,GAAG,EAAE;QAClD3C,QAAQ;QACR,0EAA0E;QAC1E,oEAAoE;QACpE,MAAM4C,aAAa1L,SAASrB,uBAAuBC,UAAUC,WAAW,EAAE;QAC1E,sEAAsE;QACtE,uCAAuC;QACvC,MAAM8M,UAAU/M,SACbgD,KAAK,CAAC,CAAC9B,oBACPiB,GAAG,CAAC,CAAC,EAAE6K,IAAI,EAAEtK,IAAI,EAAE,GAAM,CAAA;gBAAEsK;gBAAMtK;YAAK,CAAA;QACzC,MAAMuK,UAAU9C;QAChBG,aAAa2C,SAAS,CAACxI,QAAU;mBAC5BA;gBACH;oBAAEuI,MAAM;oBAAQtK,MAAMuF;gBAAS;gBAC/B;oBAAE+E,MAAM;oBAAatK,MAAM;gBAAG;aAC/B;QACD,MAAMwK,cAAc,CAACC;YACnB7C,aAAa2C,SAAS,CAACxI;gBACrB,MAAMoD,OAAO;uBAAIpD;iBAAM;gBACvB,MAAM2I,OAAOvF,IAAI,CAACA,KAAK1E,MAAM,GAAG,EAAE;gBAClC,IAAIiK,CAAAA,wBAAAA,KAAMJ,IAAI,MAAK,aAAanF,IAAI,CAACA,KAAK1E,MAAM,GAAG,EAAE,GAAGgK,MAAMC;gBAC9D,OAAOvF;YACT;QACF;QACA,qEAAqE;QACrE,wEAAwE;QACxE,mEAAmE;QACnE,6CAA6C;QAC7C,MAAMwF,aAAa,CAACC;YAClBJ,YAAY,CAAC9M,UAAa,aACrBA;oBACHsC,MAAMtC,QAAQsC,IAAI,GAAG,GAAGtC,QAAQsC,IAAI,CAAC,IAAI,EAAE4K,QAAQ,GAAGA;;QAE1D;QACA,2EAA2E,GAC3E,IAAIC,gBAA4C;QAChD,kFAAkF,GAClF,IAAIC,iBAAkD;QACtD,IAAI;;YACF,qEAAqE;YACrE,uEAAuE;YACvE,oEAAoE;YACpE,kEAAkE;YAClE,MAAMC,eAAehC,eAAe5O,qBAAqB0E,mBAAAA,WAAY,MAAM;YAC3E,MAAMmM,UAAUD,eAAevT,sBAAsB2H;YACrD,MAAM8L,gBACJF,gBACAC,WACAA,QAAQE,YAAY,KAAKH,aAAa3C,IAAI,IAC1C4C,QAAQG,UAAU,KAAKJ,aAAaI,UAAU,IAC9CH,QAAQI,SAAS,KAAKL,aAAaK,SAAS,GACxC9Q,yBAAyBrD,gBAAQ+T,QAAQK,cAAc,oBAAtBL,QAAQK,cAAc,MAAtBL,2BAA8B,QAC/D;YACN,MAAMM,WAAW,MAAMpR,gBAAgBoN,MAAM,oBAAoB;gBAC/DiE,QAAQ;gBACRC,SAAS;oBAAE,gBAAgB;gBAAmB;gBAC9CC,MAAM9O,KAAKS,SAAS,CAAC;oBACnBb,OAAOiK;oBACPjB;oBACA8E;oBACA,8DAA8D;oBAC9D,gEAAgE;oBAChE,2BAA2B;oBAC3BqB,SAAS;wBAAEC,KAAK,EAAE9M,mBAAAA,WAAY;wBAAIH,MAAM,EAAEA,iBAAAA,SAAU;wBAAInB;oBAAQ;mBAE5D2K,YAAY0D,KAAK,GAAG;oBAAEA,OAAO1D,YAAY0D,KAAK;gBAAC,IAAI,CAAC,GACpDX,gBAAgB;oBAAEhU,QAAQgU;gBAAc,IAAI,CAAC,GAI7Cb,WAAW3J,MAAM,GACjB;oBACEoL,QAAQzB,WAAW3K,GAAG,CAAC,CAAC,EAAEqM,GAAG,EAAEvL,KAAK,EAAEwL,IAAI,EAAEvL,IAAI,EAAE,GAAM;4BACtDsL;4BACAvL;4BACAwL;2BACId,iBAAiBzK,SAAS3B,WAAW;4BAAEyC,MAAM;wBAAK,IAAI,CAAC;gBAE/D,IACA,CAAC;YAET;YACA,IAAI,CAACgK,SAASU,EAAE,IAAI,CAACV,SAASG,IAAI,EAAE;gBAClC,MAAMQ,UAAU,MAAMX,SAASY,IAAI,GAAGC,KAAK,CAAC,IAAM;gBAClD,MAAMC,SAAS/U,qBAAqBiU,SAASe,MAAM,EAAEJ;gBACrD,IAAIG,QAAQ;oBACVzB,WAAWvT,oBAAoBgV;gBACjC,OAAO,IAAId,SAASe,MAAM,KAAK,KAAK;oBAClC,gEAAgE;oBAChE,kEAAkE;oBAClE,gEAAgE;oBAChE,kDAAkD;oBAClD,EAAE;oBACF,0DAA0D;oBAC1D,oEAAoE;oBACpE,kEAAkE;oBAClE,mEAAmE;oBACnE,oEAAoE;oBACpE,gEAAgE;oBAChE,UAAU;oBACV,mEAAmE;oBACnE,6CAA6C;oBAC7C1B,WACE,CAAC,8GAA8G,CAAC,GAC9G,GAAGxD,SAASV,WAAW,CAAC,6CAA6C,CAAC,GACtE,CAAC,qGAAqG,CAAC;gBAE7G,OAAO,IACL,AAAC6E,CAAAA,SAASe,MAAM,KAAK,OAAOf,SAASe,MAAM,KAAK,GAAE,KAClDJ,CAAAA,2BAAAA,QAASK,MAAM,MAAK,SACpB;;oBACA,gEAAgE;oBAChE,4DAA4D;oBAC5D,kEAAkE;oBAClE,oDAAoD;oBACpD,IAAIL,QAAQlE,KAAK,EAAEC,SAASiE,QAAQlE,KAAK;oBACzCM,aAAa4D,2BAAAA,QAASM,KAAK;oBAC3B5B,WAAW6B,gBAAOP,2BAAAA,QAASQ,KAAK,oBAAI;gBACtC,OAAO;;oBACL9B,WAAW6B,gBAAOP,2BAAAA,QAASQ,KAAK,oBAAI;gBACtC;gBACA;YACF;YACA,MAAMC,SAASpB,SAASG,IAAI,CAACkB,SAAS;YACtC,MAAMC,UAAU,IAAIC;YACpB,IAAIC,SAAS;YACb,OAAS;oBAKEC;gBAJT,MAAM,EAAEC,IAAI,EAAE5I,KAAK,EAAE,GAAG,MAAMsI,OAAOO,IAAI;gBACzC,IAAID,MAAM;gBACVF,UAAUF,QAAQM,MAAM,CAAC9I,OAAO;oBAAE+I,QAAQ;gBAAK;gBAC/C,MAAMJ,QAAQD,OAAO/N,KAAK,CAAC;gBAC3B+N,UAASC,aAAAA,MAAMK,GAAG,cAATL,aAAe;gBACxB,KAAK,MAAMM,QAAQN,MAAO;oBACxB,IAAI,CAACM,KAAKzM,UAAU,CAAC,WAAW;oBAChC,IAAIkF;oBACJ,IAAI;wBACFA,QAAQnJ,KAAKC,KAAK,CAACyQ,KAAK/M,KAAK,CAAC,SAASG,MAAM;oBAC/C,EAAE,eAAM;wBACN;oBACF;oBACA,IAAIqF,MAAMnE,IAAI,KAAK,WAAW,OAAOmE,MAAM9F,IAAI,KAAK,UAAU;wBAC5D,MAAMA,OAAO8F,MAAM9F,IAAI;wBACvBwK,YAAY,CAAC9M,UAAa,aAAKA;gCAASsC,MAAMtC,QAAQsC,IAAI,GAAGA;;oBAC/D,OAAO,IAAI8F,MAAMnE,IAAI,KAAK,QAAQ;4BAClBmE,aAKIA;wBALlB,MAAMnD,QAAQmD,cAAAA,MAAMnD,IAAI,YAAVmD,cAA8C,EAAE;wBAC9D,gEAAgE;wBAChE,8DAA8D;wBAC9D,+DAA+D;wBAC/D,kCAAkC;wBAClC,MAAMwH,YAAYxH,kBAAAA,MAAMvC,QAAQ,YAAduC,kBAA4C;wBAC9D,iEAAiE;wBACjE,+DAA+D;wBAC/D,iEAAiE;wBACjE,gDAAgD;wBAChD,MAAMyH,YAAYD,CAAAA,4BAAAA,SAAUE,KAAK,IAC7BpD,WAAWqD,IAAI,CAAC,CAACC;gCAAsBJ;mCAAbI,KAAK5B,GAAG,OAAKwB,kBAAAA,SAASE,KAAK,qBAAdF,gBAAgBxB,GAAG,KAAI4B,KAAKlN,IAAI,KAAK3B;6BAC5E;wBACJ,MAAM0E,WACJ+J,CAAAA,4BAAAA,SAAUE,KAAK,IACXD,YACE,aAAKD;4BAAU9M,MAAM+M,UAAU/M,IAAI;4BAAEtD,UAAUqI;6BAC/C,OACF+H;wBACN,kEAAkE;wBAClE,wCAAwC;wBACxC,MAAMK,OAAOvT,qBAAqB0L,MAAM6H,IAAI,IAAI7H,MAAM6H,IAAI,GAAG;wBAC7D,0EAA0E;wBAC1E,MAAM3P,QAAQvD,sBAAsBqL,MAAM9H,KAAK,IAAI8H,MAAM9H,KAAK,GAAG;wBACjE6M,gBAAgB7M;wBAChB,uEAAuE;wBACvE,MAAM2B,aAAa1E,2BAA2B6K,MAAMnG,UAAU,IAAImG,MAAMnG,UAAU,GAAG;wBACrFmL,iBAAiBnL;wBACjB6K,YAAY,CAAC9M;gCAEEoI;mCAFW,aACrBpI;gCACHkQ,UAAU,GAAG9H,oBAAAA,MAAM8H,UAAU,YAAhB9H,oBAAsC;gCACnDnD;gCACAY;gCACAoK;+BACI3P,QAAQ;gCAAEA;gCAAOL,UAAU;gCAAM+B,aAAa;4BAAK,IAAI,CAAC,GACxDC,aAAa;gCAAEA;gCAAYC,eAAe;gCAAMC,kBAAkB;4BAAK,IAAI,CAAC;;wBAElF,IAAIiG,MAAMiC,KAAK,EAAEC,SAASlC,MAAMiC,KAAK;wBACrCM,aAAavC,MAAMyG,KAAK;wBACxB7U,WAAW,0BAA0B;4BACnCmW,MAAM/E,WAAW,aAAa;4BAC9BgF,UAAUnL,KAAKlC,MAAM,GAAG;wBAC1B;wBACA,IAAI8C,UAAU;4BACZ7L,WAAW,4BAA4B;gCAAEqW,QAAQxK,SAASnF,EAAE;4BAAC;wBAC/D;wBACA,IAAIuP,MAAM;4BACRjW,WAAW,4BAA4B;gCAAEqW,QAAQJ,KAAKvP,EAAE;4BAAC;wBAC3D;wBACA,IAAIJ,OAAO;4BACTtG,WAAW,4BAA4B;gCAAEqW,QAAQ/P,MAAMI,EAAE;4BAAC;wBAC5D;wBACA,IAAIuB,YAAY;4BACdjI,WAAW,4BAA4B;gCAAEqW,QAAQpO,WAAWvB,EAAE;4BAAC;wBACjE;oBACF,OAAO,IAAI0H,MAAMnE,IAAI,KAAK,SAAS;4BACfmE;wBAAlB6E,WAAW6B,QAAO1G,eAAAA,MAAM2G,KAAK,YAAX3G,eAAe;oBACnC;gBACF;YACF;YACA,oEAAoE;YACpE,mEAAmE;YACnE,IAAI+E,eAAe;gBACjB,oEAAoE;gBACpE,qEAAqE;gBACrE,qEAAqE;gBACrE,6DAA6D;gBAC7D,KAAK,MAAMmD,YAAYnQ,wBAAwBP,UAAW;oBACxDsK,aAAa2C,SAAS,CAACxI,QACrBA,MAAMtC,GAAG,CAAC,CAACwO,OAAOtN,IAAOA,MAAMqN,SAASlQ,KAAK,GAAG,aAAKmQ;gCAAOhQ,eAAe;iCAASgQ;oBAEtF,KAAKpT,mBAAmByM,MAAMd,aAAawH,SAAS7P,KAAK,EAAE+P,IAAI,CAAC,CAAC,EAAEnQ,GAAG,EAAE;wBACtE,IAAI,CAACA,KAAK;wBACV6J,aAAa2C,SAAS,CAACxI,QACrBA,MAAMtC,GAAG,CAAC,CAACwO,OAAOtN,IAAOA,MAAMqN,SAASlQ,KAAK,GAAG,aAAKmQ;oCAAOtQ,UAAUI;qCAAQkQ;oBAElF;gBACF;gBACA,MAAME,WAAW,MAAMrT,wBAAwBwM,MAAMd,aAAaqE;gBAClE,uEAAuE;gBACvE,sEAAsE;gBACtE,uEAAuE;gBACvE,kEAAkE;gBAClE,sEAAsE;gBACtE,mDAAmD;gBACnDxC,aAAa8F,SAAS5B,KAAK;gBAC3B,MAAM6B,MAAM9G,wBAAAA,KAAM8G,GAAG;gBACrB,IAAIA,OAAO5H,aAAa;wBACoB2H,sBAAAA;oBAA1ClS,wBAAwBmS,KAAK5H,cAAa2H,gBAAAA,SAASpQ,GAAG,sBAAZoQ,uBAAAA,cAAcE,MAAM,qBAApBF,qBAAsBG,WAAW,EAAEpS,iBAAiBkS,KAAK5H;gBACrG;gBACAgE,YAAY,CAAC9M,UAAa,aAAKA;wBAASC,UAAUwQ,SAASpQ,GAAG;wBAAE2B,aAAayO,SAAS1B,KAAK;;YAC7F;YACA,sEAAsE;YACtE,sEAAsE;YACtE,kDAAkD;YAClD,IAAI3B,gBAAgB;gBAClB,MAAMqD,WAAW,MAAMpT,6BACrBuM,MACAd,aACAsE,gBACA9P,6BAA6BsC,UAAUwN,eAAeyD,MAAM;gBAE9DlG,aAAa8F,SAAS5B,KAAK;gBAC3B/B,YAAY,CAAC9M,UAAa,aAAKA;wBAASkC,eAAeuO,SAASpQ,GAAG;wBAAE8B,kBAAkBsO,SAAS1B,KAAK;;YACvG;QACF,EAAE,OAAOA,OAAO;YACd+B,QAAQ/B,KAAK,CAACA;YACd9B,WAAW;QACb,SAAU;YACRnD,QAAQ;QACV;IACF,GAAG;QACDT,GAAGoD,GAAG;QACNzF;QACAqE;QACAD;QACApK;QACApB;QACA4K,YAAY0D,KAAK;QACjBvD;QACA7B;QACAjJ;QACAsB;QACA4I;QACAG;QACAN;KACD;IAED,4EAA4E;IAC5E,2DAA2D;IAC3D,MAAM,CAACpK,UAAUuR,YAAY,GAAG1U,SAAuC;IACvEF,UAAU;QACR4U,YAAYjS,aAAagK;IAC3B,GAAG;QAACA;KAAY;IAChB,MAAMkI,0BAAkBnG,iCAAAA,cAAe6C,SAAS,mBAAI;IACpDvR,UAAU;QACR,IAAI,CAACqD,UAAU;QACf,IAAI,CAACtC,qBAAqBsC,UAAUJ,KAAKC,GAAG,KAAK;YAC/C0R,YAAY;YACZxR,aAAauJ,aAAa;YAC1B;QACF;QACA,yEAAyE;QACzE,2EAA2E;QAC3E,iEAAiE;QACjE,IAAI9B,QAAQ,CAACqC,GAAGoD,GAAG,EAAE;QACrB,MAAMwE,QAAQ;YACZxM,IAAI,EAAEtD,mBAAAA,WAAY;YAClBuM,WAAWsD;YACXE,cAAc3P,QAAQhI,OAAO4X,OAAO,CAAClX;QACvC;QACA,IAAI,CAACgD,oBAAoBuC,UAAUyR,QAAQ;QAC3CF,YAAY;QACZxR,aAAauJ,aAAa;QAC1BjF,QAAQ;QACR,KAAK0I,KAAK/M,SAASqI,QAAQ;IAC3B,0EAA0E;IAC5E,GAAG;QAACwB,GAAGoD,GAAG;QAAEzF;QAAMxH;QAAUwR;QAAiBpG;QAAgBzJ;QAAU2H;QAAayD;KAAK;IAEzF,2EAA2E,GAC3E,MAAM6E,eAAelV,YACnB,CAAC2J;QACC,IAAI,CAACA,SAASrG,QAAQ,EAAE;QACxB,MAAM6R,UAAU;YAAE5M,MAAMoB,SAAS/C,IAAI;YAAE+E,UAAUhC,SAASrG,QAAQ;YAAE8R,IAAIlS,KAAKC,GAAG;QAAG;QACnF0R,YAAYM;QACZ9R,aAAauJ,aAAauI;IAC5B,GACA;QAACvI;KAAY;IAGf;;;;GAIC,GACD,MAAMyI,kBAAkBrV,YAAY,CAACkE;QACnCgK,YAAY,CAAC/F,QACXA,MAAMtC,GAAG,CAAC,CAACwO,OAAOtN,IAChBA,MAAM7C,QAAQ,aAAKmQ;oBAAOiB,kBAAkB;qBAASjB;IAG3D,GAAG;QAACnG;KAAY;IAEhB;;;;GAIC,GACD,MAAMqH,YAAYvV,YAChB,CAACkE;QACC,MAAMJ,UAAUJ,QAAQ,CAACQ,MAAM;QAC/B,MAAMyF,WAAW7F,2BAAAA,QAASiQ,IAAI;QAC9B,IAAI,CAACpK,YAAY,CAACiD,aAAa;QAC/B,MAAMwE,UAAUxT;QAChB,MAAM4X,SAAS/U,gBAAgBpD,QAAQsM,UAAUyH;QACjD,IAAIoE,OAAOpD,EAAE,KAAK,OAAO;YACvBlE,YAAY,CAAC/F,QACXA,MAAMtC,GAAG,CACP,CAACwO,OAAOtN,IACNA,MAAM7C,QACF,aAAKmQ;wBAAOoB,aAAa;4BAAEjH,MAAM;4BAAU1K,SAAS0R,OAAO1R,OAAO;wBAAC;yBACnEuQ;YAGV;QACF;QACAnG,YAAY,CAAC/F,QACXA,MAAMtC,GAAG,CACP,CAACwO,OAAOtN,IACNA,MAAM7C,QAAQ,aAAKmQ;oBAAOoB,aAAa;wBAAEjH,MAAM;oBAAU;qBAAM6F;QAGrEvW,WAAW,gCAAgC;YAAEqW,QAAQxK,SAASnF,EAAE;QAAC;QACjEmJ,gBAAgB,qDAAqD;YACnE3F,SAAS;YACT0N,SAAS;QACX;QACA,IAAI,CAAC5R,QAAQkQ,UAAU,IAAI,CAAC5C,SAAS;QACrC,MAAMuE,SAAkC;YACtChT,OAAOiK;YACP9H,QAAQ6E,SAASzC,MAAM,CAACpC,MAAM;YAC9BkP,YAAYlQ,QAAQkQ,UAAU;YAC9B1C,cAAc3H,SAASzC,MAAM,CAACsH,IAAI;YAClC+C,YAAY5H,SAASzC,MAAM,CAACqK,UAAU;YACtCC,WAAWJ,QAAQI,SAAS;YAC5BoE,UAAUJ,OAAOI,QAAQ;QAC3B;QACA,wEAAwE;QACxE,sDAAsD;QACtD,KAAKtV,gBAAgBoN,MAAM,4BAA4B;YACrDiE,QAAQ;YACRC,SAAS;gBAAE,gBAAgB;YAAmB;YAC9CC,MAAM9O,KAAKS,SAAS,CAACmS;QACvB,GAAGpD,KAAK,CAAC,IAAMhN;IACjB,GACA;QAACoI;QAAiBjK;QAAUkJ;QAAasB;QAAaR;KAAK;IAG7D,gFAAgF,GAChF,MAAMmI,aAAa7V,YACjB,CAACkE,OAAe2M;QACd3C,YAAY,CAAC/F,QAAUA,MAAMtC,GAAG,CAAC,CAACwO,OAAOtN,IAAOA,MAAM7C,QAAQ,aAAKmQ,OAAUxD,SAAUwD;IACzF,GACA;QAACnG;KAAY;IAGf,sFAAsF,GACtF,MAAM4H,kBAAkB9V,YACtB,CAACkE,OAAe2M;QACd3C,YAAY,CAAC/F,QAAUA,MAAMtC,GAAG,CAAC,CAACwO,OAAOtN,IAAOA,MAAM7C,QAAQ,aAAKmQ,OAAUxD,SAAUwD;IACzF,GACA;QAACnG;KAAY;IAGf,oFAAoF,GACpF,MAAM,CAAC6H,gBAAgBC,kBAAkB,GAAG7V,SAAwB;IACpE,MAAM8V,kBAAkBjW,YACtB,OAAOkE;YACYR;QAAjB,MAAMiG,YAAWjG,kBAAAA,QAAQ,CAACQ,MAAM,qBAAfR,gBAAiBqC,UAAU;QAC5C,IAAI,CAAC4D,YAAY,CAACiD,aAAa;QAC/BoJ,kBAAkB9R;QAClB4R,gBAAgB5R,OAAO;YAAE8B,eAAe;YAAMC,kBAAkB;QAAK;QACrE,MAAMsO,WAAW,MAAMpT,6BACrBuM,MACAd,aACAjD,UACAvI,6BAA6BsC,SAASgD,KAAK,CAAC,GAAGxC,QAAQyF,SAASgL,MAAM;QAExElG,aAAa8F,SAAS5B,KAAK;QAC3BmD,gBAAgB5R,OAAO;YAAE8B,eAAeuO,SAASpQ,GAAG;YAAE8B,kBAAkBsO,SAAS1B,KAAK;QAAC;QACvFmD,kBAAkB;IACpB,GACA;QAACtS;QAAUoS;QAAiBrH;QAAc7B;QAAac;KAAK;IAG9D,0EAA0E,GAC1E,MAAMwI,cAAclW,YAAY,CAACkE;QAC/BgK,YAAY,CAAC/F,QACXA,MAAMtC,GAAG,CACP,CAACwO,OAAOtN,IACNA,MAAM7C,QAAQ,aAAKmQ;oBAAOoB,aAAa;wBAAEjH,MAAM;oBAAY;qBAAM6F;IAGzE,GAAG;QAACnG;KAAY;IAEhB,MAAMiI,eAAenW,YACnB,OAAOkE,OAAekS;QACpB,MAAMtS,UAAUJ,QAAQ,CAACQ,MAAM;QAC/B,IAAI,EAACJ,2BAAAA,QAASkQ,UAAU,KAAI,CAACpH,aAAa;QAC1CsB,YAAY,CAAC/F,QACXA,MAAMtC,GAAG,CAAC,CAACwO,OAAOtN,IAAOA,MAAM7C,QAAQ,aAAKmQ;oBAAO+B;qBAAa/B;QAElEvW,WAAW,sBAAsB;YAAEsY;QAAS;QAC5C,IAAI;YACF,MAAM9V,gBAAgBoN,MAAM,wBAAwB;gBAClDiE,QAAQ;gBACRC,SAAS;oBAAE,gBAAgB;gBAAmB;gBAC9CC,MAAM9O,KAAKS,SAAS,CAAC;oBACnBb,OAAOiK;oBACPoH,YAAYlQ,QAAQkQ,UAAU;oBAC9BoC;gBACF;YACF;QACF,EAAE,eAAM;YACNzI,gBAAgB,kCAAkC;gBAChD3F,SAAS;gBACT0N,SAAS;YACX;QACF;IACF,GACA;QAAC/H;QAAiBjK;QAAUkJ;QAAasB;QAAaR;KAAK;IAG7D,uEAAuE;IACvE,sEAAsE;IACtE,uEAAuE;IACvE,sEAAsE;IACtE,0EAA0E;IAC1E,gDAAgD;IAChD,IAAI,CAACN,QAAQC,OAAO,IAAI,CAACT,aAAa,OAAO;IAE7C,qBACE;;YACG,CAAClF,sBACA,KAAChI;gBAAQ+J,OAAO,GAAG8D,SAASV,WAAW,CAAC,OAAO,CAAC;gBAAEwJ,WAAU;0BAC1D,cAAA,KAACjX;oBACCuJ,OAAM;oBACNgC,MAAK;oBACL,8DAA8D;oBAC9D4B,cAAYxK,oBAAoBwL,SAASV,WAAW,EAAE0C;oBACtDrH,SAAS,IAAMP,QAAQ;oBACvBC,IAAI;wBACF0O,UAAU;wBACV,8DAA8D;wBAC9D,4DAA4D;wBAC5D,6DAA6D;wBAC7D,wDAAwD;wBACxD,4DAA4D;wBAC5D,6DAA6D;wBAC7D,8DAA8D;wBAC9D,6DAA6D;wBAC7D,uDAAuD;wBACvD,6DAA6D;wBAC7D,8BAA8B;wBAC9BC,OAAO;wBACPC,QAAQ;wBACRC,QAAQ,CAACC,QAAUA,MAAMD,MAAM,CAACE,MAAM,GAAG;oBAC3C;8BAaA,cAAA,KAAC9X;wBACC8J,OAAO4G,gBAAgBA,aAAaqH,KAAK,KAAK,YAAY,YAAY;wBACtE5O,SAASuH,CAAAA,gCAAAA,aAAcqH,KAAK,MAAK,YAAY,QAAQ;wBACrDC,cAActH,eAAeA,aAAauH,KAAK,GAAG;wBAClDC,WAAW,CAACxH;wBACZyH,SAAQ;wBACRC,oBAAkB,WAAE1H,gCAAAA,aAAcqH,KAAK,oBAAIrR;kCAE3C,cAAA,KAAC9G;4BAAQ8J,MAAMtK,YAAYsK,IAAI;4BAAEC,UAAS;;;;;0BAKlD,KAACrJ;gBACC+X,QAAO;gBACPxP,MAAMA;gBACNyP,SAAS,IAAMxP,QAAQ;gBACvByP,WAAW;oBACTC,OAAO;wBACLzP,IAAI;4BAAE0P,OAAO;gCAAEC,IAAI;gCAAQC,IAAI;4BAAI;4BAAGpP,SAAS;wBAAO;oBACxD;gBACF;0BAEA,cAAA,MAAC5I;oBAAMoI,IAAI;wBAAE6P,QAAQ;oBAAO;;sCAC1B,MAACjY;4BACCkL,WAAU;4BACVlB,SAAS;4BACT5B,IAAI;gCACF8P,IAAI;gCACJC,IAAI;gCACJC,cAAc;gCACdC,aAAa;gCACbxP,YAAY;4BACd;;8CAKA,KAAC5J;oCAAQ8J,MAAMtK,YAAYsK,IAAI;oCAAEC,UAAS;;8CAC1C,KAAC7I;oCAAWqI,SAAQ;oCAAKJ,IAAI;wCAAEkQ,UAAU;oCAAE;8CACxC,GAAGvK,SAASV,WAAW,CAAC,OAAO,CAAC;;gCAElCO,QAAQE,YAAY,kBACnB,KAACtO;oCAAK2L,MAAK;oCAAQhC,OAAM;oCAAUhC,OAAM;;gCAK1CyG,QAAQC,OAAO,IACd,CAACD,QAAQE,YAAY,IACrB/P,aAAa,mCAAqB,KAACmB;8CAQrC,KAAC+D,sBACKD,eAAe,eAAe;oCAAE0U,QAAQ;gCAAkB;oCAC9DtP,IAAI;wCAAEe,OAAO;oCAAiB;;8CAEhC,KAACjJ;oCAAQ+J,OAAO,CAAC,MAAM,EAAE8D,SAASV,WAAW,CAAC,OAAO,CAAC;8CACpD,cAAA,KAACxN;wCACCkN,cAAY,CAAC,MAAM,EAAEgB,SAASV,WAAW,CAAC,OAAO,CAAC;wCAClD3E,SAAS,IAAMP,QAAQ;kDAIvB,cAAA,KAAClJ;4CAAQ8J,MAAMpK,SAASoK,IAAI;4CAAEC,UAAS;;;;;;sCAK7C,MAAC1J;4BAAIoT,KAAK7D;4BAAWzG,IAAI;gCAAEkQ,UAAU;gCAAGC,WAAW;gCAAQhO,GAAG;4BAAE;;8CAG9D,KAACvI;oCACCmB,OAAOiK;oCACPF,KAAKA;oCACLC,UAAUA;oCACVhJ,SAAS6J;oCACTE,MAAMA;oCACNL,SAASL;oCACTC,SAASA;oCACTnI,QAAQA;oCACR,4DAA4D;oCAC5D,8DAA8D;oCAC9D,mDAAmD;oCACnDkT,SAAS7K,GAAGiC,QAAQ,GAAG7N,wBAAwB0D,YAAY;oCAC3DqK,UAAUD,cAAcC,WAAW/J;oCACnC0S,OAAOtI;oCACPuI,UAAU1I;;gCAEX,CAAC9L,SAASmD,MAAM,kBACf,MAACjI;oCAAMuZ,UAAS;oCAAOvQ,IAAI;wCAAEwQ,IAAI;oCAAE;;wCAChC,CAAC,yBAAyB,EAAE7K,SAASV,WAAW,CAAC,YAAY,CAAC;wCAC9D;wCACA;wCACAF,YAAY,CAACuC,YAAY,CAACjC,yBACzB;;gDACG;gDACA,CAAC,qCAAqC,GACrCvP,4BAAAA,yBAAyB,uBAAzBA,4BAAwC,cACzC,EAAE,CAAC;gDACH8P,4BACC,KAAChP;oDAAQoI,MAAM,CAAC,CAAC,EAAE4G,YAAY,cAAc,CAAC;8DAC3C;qDAED;;;;;8CAKZ,KAAChO;oCAAMgK,SAAS;8CACb9F,SAASmC,GAAG,CAAC,CAAC/B,SAASI;4CAsFXJ,wBACGA,2BAiBHA,mBACGA;4CAtCVA,sBACAA,uBAMMA,uBAyCNA;6DAlHJ,MAAChF;4CAEC8I,IAAI;gDACFyQ,WACEvU,QAAQ4M,IAAI,KAAK,SAAS,aAAa;gDACzC4H,UAAU;gDACVtO,cAAc;gDACd0N,IAAI;gDACJC,IAAI;gDACJ1N,SACEnG,QAAQ4M,IAAI,KAAK,SACb,iBACA;gDACN/H,OACE7E,QAAQ4M,IAAI,KAAK,SACb,yBACA;4CACR;;8DAEA,KAAC/Q;oDACCqI,SAAQ;oDACRF,WAAU;oDACVF,IAAI;wDAAEgB,YAAY;wDAAYC,WAAW;oDAAa;8DAErD/E,QAAQ4M,IAAI,KAAK,cAChB5M,QAAQsC,IAAI,GACVD,iBACEiB,sBAAsBtD,QAAQsC,IAAI,EAAEiB,KAAK,kBAG3C,KAACpI;wDAAiB0L,MAAM;yDAG1B7G,QAAQsC,IAAI;;gDAGftC,QAAQ4M,IAAI,KAAK,eAChBtJ,sBAAsBtD,QAAQsC,IAAI,EAAEkB,SAAS,kBAC3C,KAACG;oDACCH,WAAWF,sBAAsBtD,QAAQsC,IAAI,EAAEkB,SAAS;;gDAG7DxD,QAAQ4M,IAAI,KAAK,6BAChB,KAAC5H;oDAAc1C,MAAMtC,QAAQsC,IAAI;oDAAE2C,MAAMjF,QAAQiF,IAAI;;gDAEtDjF,QAAQ4M,IAAI,KAAK,eAChB5M,QAAQ6F,QAAQ,IAChB,CAAC7F,QAAQwR,gBAAgB,kBACvB,KAAC5L;oDACCC,UAAU7F,QAAQ6F,QAAQ;oDAC1BG,OAAO+C;oDACPjD,WAAW;;4DAEC9F,mBAKNA;wDANJhG,WAAW,gCAAgC;4DACzCqW,MAAM,WAAErQ,oBAAAA,QAAQ6F,QAAQ,qBAAhB7F,kBAAkBU,EAAE,mBAAI;wDAClC;wDACA6Q,gBAAgBnR;wDAChB,+CAA+C;wDAC/C,2CAA2C;wDAC3C,KAAIJ,qBAAAA,QAAQ6F,QAAQ,qBAAhB7F,mBAAkBR,QAAQ,EAAE4R,aAAapR,QAAQ6F,QAAQ;6DACxDhC,QAAQ;oDACf;oDACAkC,WAAW,IAAMwL,gBAAgBnR;;gDAGtCJ,QAAQ4M,IAAI,KAAK,eAChB5M,QAAQiQ,IAAI,IACZjQ,EAAAA,uBAAAA,QAAQ2R,WAAW,qBAAnB3R,qBAAqB0K,IAAI,MAAK,eAC9B1K,EAAAA,wBAAAA,QAAQ2R,WAAW,qBAAnB3R,sBAAqB0K,IAAI,MAAK,2BAC5B,KAAC7N;oDACCgJ,UAAU7F,QAAQiQ,IAAI;oDACtBjK,OAAO+C;oDACPuE,SAASzC;oDACT4J,SACEzU,EAAAA,wBAAAA,QAAQ2R,WAAW,qBAAnB3R,sBAAqB0K,IAAI,MAAK,WAC1B1K,QAAQ2R,WAAW,CAAC3R,OAAO,GAC3B;oDAEN0U,SAAS,IAAMjD,UAAUrR;oDACzBuU,iBAAiB;4DAAM9J;+DAAAA,kCAAAA,+BAAAA,cAAe+J,aAAa,qBAA5B/J,kCAAAA;;oDACvB9E,WAAW,IAAMqM,YAAYhS;;gDAGlCJ,QAAQ4M,IAAI,KAAK,eAAe5M,QAAQiC,UAAU,IAAI6G,6BACrD,KAACtL;oDACCqI,UAAU7F,QAAQiC,UAAU;oDAC5B5B,GAAG,GAAEL,yBAAAA,QAAQkC,aAAa,YAArBlC,yBAAyB;oDAC9BkN,MAAM,GAAElN,4BAAAA,QAAQmC,gBAAgB,YAAxBnC,4BAA4B;oDACpCnB,OAAOiK;oDACPjJ,SAASA;oDACT+J,MAAMA;oDACN5C,MAAMiL,mBAAmB7R;oDACzByU,OAAO,CAACxU,MAAQ2R,gBAAgB5R,OAAO;4DAAE8B,eAAe7B;wDAAI;oDAC5DyU,SAAS,IAAM,KAAK3C,gBAAgB/R;;gDAGvCJ,QAAQ4M,IAAI,KAAK,eAAe5M,QAAQM,KAAK,IAAIN,QAAQO,aAAa,kBACrE,KAAC1E;oDAAWqI,SAAQ;oDAAUW,OAAM;oDAAiBb,WAAU;oDAAMF,IAAI;wDAAEC,IAAI;oDAAI;8DAChFpD;;gDAGJX,QAAQ4M,IAAI,KAAK,eAAe5M,QAAQM,KAAK,IAAI,CAACN,QAAQO,aAAa,IAAIuI,6BAC1E,KAAChM;oDACC+I,UAAU7F,QAAQM,KAAK;oDACvBD,GAAG,GAAEL,oBAAAA,QAAQC,QAAQ,YAAhBD,oBAAoB;oDACzBkN,MAAM,GAAElN,uBAAAA,QAAQgC,WAAW,YAAnBhC,uBAAuB;oDAC/BnB,OAAOiK;oDACPc,MAAMA;oDACNmL,OAAO5L;oDACP0L,OAAO,CAACxU,MAAQ0R,WAAW3R,OAAO;4DAAEH,UAAUI;wDAAI;oDAClD2U,UAAU,CAAC9H,SAAW6E,WAAW3R,OAAO;4DAAE4B,aAAakL;wDAAO;oDAC9DrN,SAASA;;gDAGZG,QAAQ4M,IAAI,KAAK,eAChB5M,EAAAA,wBAAAA,QAAQ2R,WAAW,qBAAnB3R,sBAAqB0K,IAAI,MAAK,2BAC5B,KAAC7O;oDACCqI,SAAQ;oDACRW,OAAM;oDACNb,WAAU;oDACVF,IAAI;wDAAEC,IAAI;oDAAI;8DACf;;gDAIJ/D,QAAQ4M,IAAI,KAAK,eAAe5M,QAAQkQ,UAAU,kBACjD,MAACxU;oDAAMkL,WAAU;oDAAMlB,SAAS;oDAAK5B,IAAI;wDAAEC,IAAI;oDAAI;;sEAMjD,KAACnI;4DACC+J,OACE3F,QAAQsS,QAAQ,GACZ,2CACA;sEAGN,cAAA,KAAC9J;0EACC,cAAA,KAACjN;oEACCsL,MAAK;oEACL4B,cAAW;oEACX5D,OAAO7E,QAAQsS,QAAQ,KAAK,OAAO,YAAY;oEAC/C/K,UAAUhG,QAAQvB,QAAQsS,QAAQ;oEAClClO,SAAS,IAAM,KAAKiO,aAAajS,OAAO;8EAExC,cAAA,KAACzF;wEACC8J,MAAMhK,kBAAkBgK,IAAI;wEAC5BX,IAAI;4EAAEY,UAAU;wEAAG;;;;;sEAK3B,KAAC9I;4DACC+J,OACE3F,QAAQsS,QAAQ,GACZ,2CACA;sEAGN,cAAA,KAAC9J;0EACC,cAAA,KAACjN;oEACCsL,MAAK;oEACL4B,cAAW;oEACX5D,OAAO7E,QAAQsS,QAAQ,KAAK,SAAS,YAAY;oEACjD/K,UAAUhG,QAAQvB,QAAQsS,QAAQ;oEAClClO,SAAS,IAAM,KAAKiO,aAAajS,OAAO;8EAExC,cAAA,KAACzF;wEACC8J,MAAMjK,oBAAoBiK,IAAI;wEAC9BX,IAAI;4EAAEY,UAAU;wEAAG;;;;;;;;2CAzK1BtE;;;;;sCAqLb,MAAC1E;4BACCgK,SAAS;4BACT5B,IAAI;gCAAEmC,GAAG;gCAAGgP,WAAW;gCAAGlB,aAAa;4BAAU;;gCAEhD1K,GAAGpC,MAAM,IAAI,CAACoC,GAAGoD,GAAG,iBACnB,KAAC5Q;oCAAWqI,SAAQ;oCAAUW,OAAM;8CACjC,uDACC;qCAEF;8CAGJ,KAACzG;oCAAaS,OAAOiK;oCAAajJ,SAAS6J;;gCAC1CW,SAASA,MAAM6K,MAAM,KAAK,uBACzB,MAACrZ;oCAAWqI,SAAQ;oCAAUW,OAAM;;wCACjCwF,MAAM8K,SAAS;wCAAC;wCAAK9K,MAAM+K,KAAK;wCAAC;wCAQjC1L,4BACC;;gDACG;8DACD,KAAChP;oDACCyI,kBAAiB;oDACjBL,MAAM,CAAC,CAAC,EAAE4G,YAAY,QAAQ,CAAC;8DAChC;;;6CAID;;;gCAKP0B,yBACC,KAAC1P;oCAAMkL,WAAU;oCAAM9C,IAAI;wCAAEuR,gBAAgB;wCAAYf,IAAI,CAAC;oCAAI;8CAChE,cAAA,KAACnW;wCACCmX,QAAQ9K;wCACRjD,UAAUP,QAAQ,CAACqC,GAAGpC,MAAM,IAAI,CAACoC,GAAGoD,GAAG;;qCAGzC;8CACJ,KAAC1F;oCACCC,MAAMA;oCACNC,QAAQoC,GAAGpC,MAAM;oCACjBC,SAASmC,GAAGoD,GAAG;oCACftF,QAAQoF;;;;;;;;;AAOtB;AAEA,eAAe7D,qBAAoB"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/assist-panel.component.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 {\n canvas,\n checkEntitlement,\n isBetaStaged,\n lockdownRefusalText,\n parseLockdownRefusal,\n planLabelGrantingFeature,\n type AglynOrgBilling,\n} from '@aglyn/aglyn'\nimport {\n editorSessionsRevision,\n openEditorSession,\n subscribeEditorSessions,\n} from '@aglyn/aglyn/plugin-manager/editor-sessions'\nimport { trackEvent } from '@aglyn/aglyn/app-utils/analytics-events'\nimport { CANVAS_ROOT_ELEMENT_ID } from '@aglyn/aglyn/foundation/constants/canvas'\nimport {\n mdiChevronDown,\n mdiCreation,\n mdiChevronUp,\n mdiClose,\n mdiOpenInNew,\n mdiSend,\n mdiThumbDownOutline,\n mdiThumbUpOutline,\n} from '@aglyn/shared-data-mdi'\nimport { AppLink, MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { BetaChip } from '@aglyn/shared-ui-jsx/components/beta-chip.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Alert,\n Badge,\n Box,\n Button,\n Chip,\n CircularProgress,\n Collapse,\n Drawer,\n Fab,\n IconButton,\n Link,\n Paper,\n Stack,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { usePathname, useRouter } from 'next/navigation'\nimport {\n Fragment,\n memo,\n useCallback,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n} from 'react'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n assistEditDocumentOf,\n isAssistEditProposal,\n type AssistEditAppliedReport,\n type AssistEditProposal,\n} from '../model/assist-edit'\nimport { applyAssistEdit, describeAssistEditCanvas } from './assist-edit-canvas'\nimport { AssistEditCard } from './assist-edit-card.component'\nimport { AssistBuildCard } from './assist-build-card.component'\nimport { isAssistBuildProposal, type AssistBuildProposal } from '../model/assist-build'\nimport {\n assistBuildDraftLinks,\n isAssistFollowUpDue,\n isLiveAssistFollowUp,\n type AssistBuildDraft,\n type AssistBuildDraftLink,\n type AssistPendingFollowUp,\n} from '../model/assist-follow-up'\nimport type { AiJobSummary } from '../model/ai-jobs.types'\nimport { cancelAiJobRequest, startAssistBuildRequest, startAssistPageChangeRequest } from './ai-job-requests'\nimport {\n assistPageChangeDraftVersion,\n assistPageChangeHistoryNote,\n isAssistPageChangeProposal,\n type AssistPageChangeProposal,\n} from '../model/assist-page-change'\nimport { AssistPageChangeCard } from './assist-page-change-card.component'\nimport { aiInsightSurfaceForPath } from '../model/ai-insight'\nimport { AssistJobsDrawer } from './assist-jobs-drawer.component'\nimport {\n AI_JOB_LINK_PARAM,\n openAiJobs,\n useAiJobsInFlight,\n useAiJobsOpenRequest,\n type AiJobsOpenRequest,\n} from './ai-jobs-store'\nimport { aiJobPhase, aiJobsActivity, aiJobsLauncherLabel } from '../model/ai-job-activity'\nimport { AI_SITE_BUILD_HREF } from '../model/ai-job-notice'\nimport { AiModelSelector } from './ai-model-selector.component'\nimport { AiUsageStrip } from './ai-usage-strip.component'\nimport { useAiModelChoice } from './use-ai-model-choice'\nimport { followAiJobsForUsageMeter, refreshAiUsageMeterFree } from './ai-usage-meter-refresh'\nimport { readAiUsageMeter, usePublishAiUsageMeter } from './use-ai-usage-meter'\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { HelpTip } from '@aglyn/shared-ui-jsx'\n\n/**\n * Aglyn Assist (AGL-1860, phase 1 — answer + guide): the floating chat\n * helper mounted on every authenticated console page. Docs-grounded answers\n * with deep links for everyone the release flag admits; Pro+ (`aiAssist`)\n * adds page-context awareness. The panel never answers the entitlement\n * question from a loading default — capability messaging waits for\n * `useCurrentOrg().ready` (the checkQuota(undefined)=Free lesson).\n *\n * ## It also never runs against an org the URL did not name (AGL-1934)\n *\n * `useCurrentOrg()` deliberately keeps a fallback — org-less pages still need\n * an org to ACT on — so on the workspace picker it answers with a real org\n * and a truthy plan: a remembered selection, or simply the user's first. This\n * panel used to gate on nothing but `orgId` being present, which that\n * fallback always satisfies. The result was the whole component running for a\n * workspace nobody opened: the entitlement decided by its plan, the upgrade\n * nudge pitched on its behalf, the session thread filed under its id, and —\n * the reason this ranked High rather than cosmetic — every question POSTed\n * with its `orgId`, so the message was METERED to it. Billing data attributed\n * to the wrong customer.\n *\n * The gate is AGL-1130's `useUrlNamesOrg()`, the same predicate AGL-1916\n * applied to `QuotaWarningsBanner` on the same page, plus the positive\n * contradiction check that goes with it. It is expressed once, as\n * `scopedOrgId`, so that no send path can reach `orgId` around it — and the\n * server refuses an unscoped request independently (`assistScopeRefusal` in\n * `app/api/assist/chat/route.ts`), because a metering boundary the client\n * alone decides is not a boundary.\n */\n\ninterface AssistDocLink {\n title: string\n url: string\n}\n\n/**\n * A level-2 proposal, exactly as the server resolved it (AGL-1988).\n *\n * Every field here is inert. There is no method, no endpoint and no body,\n * because the server type has none: the assistant proposes, the user\n * confirms, and confirming NAVIGATES. The destination form's own submit\n * button stays the only thing that writes.\n */\ninterface AssistProposal {\n id: string\n label: string\n outcome: string\n href: string\n values: Array<{ name: string; value: string }>\n prefill: boolean\n /** The draft an open-draft proposal names (AGL-3616), as the server held it. */\n draft?: AssistBuildDraft\n /**\n * The request a confirmed open-draft proposal asks again once the draft's\n * canvas is open; `href` is then that draft's own Besigner, from the\n * panel's own record of its build.\n */\n followUp?: string\n}\n\ninterface AssistMessage {\n role: 'user' | 'assistant'\n text: string\n exchangeId?: string | null\n feedback?: 'up' | 'down'\n docs?: AssistDocLink[]\n proposal?: AssistProposal | null\n /** Set once the user acts on or waves away the card, so it does not linger. */\n proposalResolved?: boolean\n /**\n * A level-3 edit proposal, exactly as the server validated it (AGL-2906):\n * operations for the open canvas, applied only when the author presses\n * Apply, and never by a request.\n */\n edit?: AssistEditProposal | null\n /** What became of the edit card: applied, waved away, or refused with a reason. */\n editOutcome?:\n | { kind: 'applied' }\n | { kind: 'dismissed' }\n | { kind: 'failed'; message: string }\n /**\n * A build proposed from this turn (AGL-3616): the panel starts its one\n * `build` job when the turn ends, and the card shows that job's plan to\n * confirm, then where it stands.\n */\n build?: AssistBuildProposal | null\n /** The job the build started, as last seen. */\n buildJob?: AiJobSummary | null\n /** Why the build could not be planned or confirmed. */\n buildNotice?: string | null\n /**\n * A later turn's plan replaced this one before it was confirmed (AGL-4116):\n * its job was canceled, and the card gives way to one line.\n */\n buildReplaced?: boolean\n /**\n * A change to a page the site already has (AGL-4116): the panel starts its\n * `edit` job when the turn ends, and the card links the draft it makes.\n */\n pageChange?: AssistPageChangeProposal | null\n /** The edit job the change started, as last seen. */\n pageChangeJob?: AiJobSummary | null\n /** Why the change could not be started. */\n pageChangeNotice?: string | null\n}\n\n/**\n * A turn as the next question's history carries it (AGL-4116): its words, and\n * what became of the change it made, which the words alone never say.\n */\nfunction assistHistoryText(message: AssistMessage): string {\n const note =\n assistPageChangeHistoryNote(message) ??\n (message.edit && message.editOutcome?.kind === 'applied'\n ? `(Applied to the open canvas as an unsaved change: ${message.edit.summary})`\n : null)\n return note ? `${message.text}\\n\\n${note}` : message.text\n}\n\n/** The key a follow-up waiting for its canvas is kept under, per org (AGL-3616). */\nconst followUpKey = (orgId: string) => `aglyn-assist-follow-up:${orgId}`\n\nfunction loadFollowUp(orgId: string | undefined): AssistPendingFollowUp | null {\n if (!orgId || typeof sessionStorage === 'undefined') return null\n try {\n const parsed: unknown = JSON.parse(sessionStorage.getItem(followUpKey(orgId)) ?? 'null')\n if (isLiveAssistFollowUp(parsed, Date.now())) return parsed\n // One past its time is never asked: forget it.\n if (parsed !== null) sessionStorage.removeItem(followUpKey(orgId))\n return null\n } catch {\n return null\n }\n}\n\nfunction saveFollowUp(orgId: string | undefined, followUp: AssistPendingFollowUp | null) {\n if (!orgId || typeof sessionStorage === 'undefined') return\n try {\n if (followUp) sessionStorage.setItem(followUpKey(orgId), JSON.stringify(followUp))\n else sessionStorage.removeItem(followUpKey(orgId))\n } catch {\n // Storage that refuses only loses the re-ask; the draft still opens.\n }\n}\n\n/**\n * The drafts this thread's builds made that open in the Besigner, newest\n * build first (AGL-3616): what a follow-up such as \"make the about page\n * shorter\" may open.\n */\nexport function assistThreadDraftLinks(\n messages: ReadonlyArray<{ buildJob?: AiJobSummary | null }>,\n orgSlug: string,\n): AssistBuildDraftLink[] {\n const jobs = messages.flatMap((message) => (message.buildJob ? [message.buildJob] : [])).reverse()\n return assistBuildDraftLinks(jobs, orgSlug)\n}\n\n/**\n * The builds in a thread whose plan is still waiting on the person\n * (AGL-4116): queued, being planned, or planned and not yet confirmed. A new\n * plan in the same thread replaces them, so a conversation that keeps\n * changing a plan holds one plan, not one per message.\n */\nexport function assistUnconfirmedBuilds(\n messages: ReadonlyArray<Pick<AssistMessage, 'build' | 'buildJob' | 'buildReplaced'>>,\n): Array<{ index: number; jobId: string }> {\n return messages.flatMap((message, index) => {\n const job = message.build && !message.buildReplaced ? message.buildJob : null\n if (!job) return []\n const phase = aiJobPhase(job)\n return phase === 'queued' || phase === 'planning' || phase === 'plan-ready' ? [{ index, jobId: job.id }] : []\n })\n}\n\n/** What a plan a later one replaced says in its card's place (AGL-4116). */\nexport const ASSIST_BUILD_REPLACED_COPY = 'Replaced by the updated plan below. Nothing from this one was built.'\n\n/** What a stored build that never got its job says, rather than planning forever. */\nconst BUILD_NOT_STARTED = 'This build was not started. Ask again to plan it.'\n\n/** What a stored page change that never got its job says (AGL-4116). */\nconst PAGE_CHANGE_NOT_STARTED = 'This change was not started. Ask again to make it.'\n\ninterface AssistQuotaInfo {\n period: 'day' | 'month'\n used: number\n limit: number\n remaining: number\n}\n\nconst HISTORY_TURNS_SENT = 12\n\n/**\n * The thread a question belongs to: one per site, and one for the\n * workspace's own pages (AGL-4116). A workspace-wide thread carried one\n * site's request into a build on another site, because the history that\n * rides each question is the thread's last turns.\n */\nexport function assistThreadKey(orgId: string, hostId: string | null | undefined): string {\n return hostId ? `aglyn-assist:${orgId}:${hostId}` : `aglyn-assist:${orgId}`\n}\n\nconst NO_MESSAGES: AssistMessage[] = []\n\n/**\n * The AI jobs page of the site a console page is on (AGL-4116), or `null`\n * off a site: `/{orgSlug}/hosts/{site}/ai-jobs`, the site named as the\n * address names it.\n */\nexport function assistSiteAiJobsHref(\n pathname: string | null | undefined,\n orgSlug: string | null | undefined,\n hostId: string | null | undefined,\n): string | null {\n if (!pathname || !orgSlug || !hostId) return null\n const parts = pathname.split('/').filter(Boolean)\n const site = parts[0] === orgSlug && parts[1] === 'hosts' ? parts[2] : undefined\n return site ? `/${orgSlug}/hosts/${site}${AI_SITE_BUILD_HREF}` : null\n}\n\nfunction loadThread(key: string): AssistMessage[] {\n if (typeof sessionStorage === 'undefined') return []\n try {\n const raw = sessionStorage.getItem(key)\n const parsed = raw ? (JSON.parse(raw) as AssistMessage[]) : []\n if (!Array.isArray(parsed)) return []\n // A build whose job was still being created when the page went away is\n // not started again from a stored thread (AGL-3616): it says so instead.\n // A page change likewise (AGL-4116).\n return parsed.map((message) =>\n message.build && !message.buildJob && !message.buildNotice\n ? { ...message, buildNotice: BUILD_NOT_STARTED }\n : message.pageChange && !message.pageChangeJob && !message.pageChangeNotice\n ? { ...message, pageChangeNotice: PAGE_CHANGE_NOT_STARTED }\n : message,\n )\n } catch {\n return []\n }\n}\n\nfunction saveThread(key: string, messages: AssistMessage[]) {\n if (typeof sessionStorage === 'undefined') return\n try {\n sessionStorage.setItem(key, JSON.stringify(messages))\n } catch {\n // Quota/full storage never breaks chat.\n }\n}\n\n/**\n * Minimal renderer for assistant text: markdown links and bare URLs become\n * links (internal root-relative paths ride AppLink, external open in a new\n * tab); everything else renders as plain text with line breaks. Phase 1 on\n * purpose — no full markdown surface inside the panel.\n */\nexport function renderAssistText(text: string): JSX.Element {\n const parts: Array<string | { label: string; href: string }> = []\n const pattern = /\\[([^\\]]+)\\]\\((\\/[^)\\s]*|https?:\\/\\/[^)\\s]+)\\)|https?:\\/\\/[^\\s)]+/g\n let cursor = 0\n for (const match of text.matchAll(pattern)) {\n const index = match.index ?? 0\n if (index > cursor) parts.push(text.slice(cursor, index))\n if (match[1] && match[2]) parts.push({ label: match[1], href: match[2] })\n else parts.push({ label: match[0], href: match[0] })\n cursor = index + match[0].length\n }\n if (cursor < text.length) parts.push(text.slice(cursor))\n return (\n <>\n {parts.map((part, i) => {\n if (typeof part === 'string') {\n return <Fragment key={i}>{part}</Fragment>\n }\n if (part.href.startsWith('/')) {\n return (\n <AppLink key={i} componentVariant=\"naked\" href={part.href}>\n {part.label}\n </AppLink>\n )\n }\n return (\n <Link key={i} href={part.href} target=\"_blank\" rel=\"noreferrer\">\n {part.label}\n </Link>\n )\n })}\n </>\n )\n}\n\n/**\n * Split an answer into its plain layer and its technical tail (AGL-1988).\n *\n * Aglyn's users run from first-time business owners to working developers,\n * and they get the same message. Two modes would be the obvious build and\n * the wrong one — it asks a beginner to label themselves before they have a\n * question, and asks a developer to opt in to being taken seriously. So the\n * model writes one answer with a technical paragraph at the end, and the\n * panel collapses it: the beginner never has to read past the plain steps,\n * the developer never has to ask for the route or the field name.\n *\n * Degrades to \"no tail\" when the marker is absent, which is the common case\n * and not a failure — plenty of answers have nothing technical to add.\n */\nexport function splitAssistDisclosure(text: string): {\n plain: string\n technical: string\n} {\n const match = text.match(/(?:^|\\n)[ \\t]*Under the hood:[ \\t]*/)\n if (!match || match.index === undefined) return { plain: text, technical: '' }\n const plain = text.slice(0, match.index).trimEnd()\n const technical = text.slice(match.index + match[0].length).trim()\n // An answer that is ONLY a technical tail is still the answer. Collapsing\n // the whole thing would show the user an empty bubble with a toggle.\n if (!plain || !technical) return { plain: text, technical: '' }\n return { plain, technical }\n}\n\n/** The collapsed developer layer. */\nfunction UnderTheHood({ technical }: { technical: string }) {\n const [open, setOpen] = useState(false)\n return (\n <Box sx={{ mt: 0.5 }}>\n <Link\n component=\"button\"\n type=\"button\"\n variant=\"caption\"\n underline=\"hover\"\n onClick={() => setOpen((prior) => !prior)}\n sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.25 }}\n >\n Under the hood\n <MdiIcon\n path={open ? mdiChevronUp.path : mdiChevronDown.path}\n sx={{ fontSize: 14 }}\n />\n </Link>\n <Collapse in={open} unmountOnExit>\n <Typography\n variant=\"caption\"\n component=\"div\"\n color=\"text.secondary\"\n sx={{ mt: 0.5, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}\n >\n {renderAssistText(technical)}\n </Typography>\n </Collapse>\n </Box>\n )\n}\n\n/**\n * The source links under an answer (AGL-2486).\n *\n * `docs` is server-resolved retrieval output and has ridden every `done`\n * event since Assist shipped, but NOTHING rendered it: it set the `grounded`\n * analytics flag and stopped there. So every answer carried its citations to\n * a reader who never saw them, and on the MODEL path that array is the only\n * citation there is — the completion is prose, and nothing obliges it to name\n * the page it was grounded in.\n *\n * ## Why this FILTERS rather than rendering the array straight\n *\n * The DEFLECTED path is the opposite case. `composeDocsAnswer` deliberately\n * puts the citation in the answer TEXT as `[label](url)`, because a link is\n * the one markup this panel speaks (`renderAssistText`) — that is a recorded\n * decision, not an oversight, and its own docstring names this array as the\n * tempting-but-wrong home for the citation *because* nothing renders it.\n * Rendering the array underneath would therefore print every heading a second\n * time on exactly the answers that already cite well. Anything whose url is\n * already linked in the text is dropped, which leaves a deflected answer\n * reading precisely as it does today and gives the model answer the sources\n * it has never shown.\n *\n * ## Why the array is not simply suppressed server-side instead\n *\n * That was the other candidate and it is a trap: `docs.length > 0` is what\n * sets the `grounded` analytics flag, so a docs-QUOTING answer would report\n * itself ungrounded. The most grounded turn the product serves would be\n * counted as a documentation gap, which is precisely backwards for the signal\n * `assist-signal-mining` exists to read.\n */\nexport function AssistSources({\n text,\n docs,\n}: {\n text: string\n docs?: readonly AssistDocLink[]\n}) {\n const unseen: AssistDocLink[] = []\n const shown = new Set<string>()\n for (const doc of docs ?? []) {\n // Already a link in the prose, or already listed here. Both are the same\n // failure to the reader: the same page offered twice.\n if (!doc?.url || text.includes(doc.url) || shown.has(doc.url)) continue\n shown.add(doc.url)\n unseen.push(doc)\n }\n if (!unseen.length) return null\n return (\n <Box sx={{ mt: 0.75 }}>\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n {unseen.length === 1 ? 'Source' : 'Sources'}\n </Typography>\n <Stack spacing={0.25} sx={{ mt: 0.25 }}>\n {unseen.map((doc) => (\n <Typography key={doc.url} variant=\"caption\" component=\"div\">\n {doc.url.startsWith('/') ? (\n <AppLink componentVariant=\"naked\" href={doc.url}>\n {doc.title}\n </AppLink>\n ) : (\n <Link href={doc.url} target=\"_blank\" rel=\"noreferrer\">\n {doc.title}\n </Link>\n )}\n </Typography>\n ))}\n </Stack>\n </Box>\n )\n}\n\n/**\n * The confirm card — the whole of \"automate current view\", and the whole of\n * its boundary.\n *\n * The assistant proposes; this card is the human confirmation; confirming\n * navigates. There is deliberately no submit path anywhere in this\n * component, and no network call: a chat assistant that writes without\n * consent is a far worse launch story than one that only advises, and the\n * cheapest way to be sure it cannot is for the code that could do it not to\n * exist. `assist-panel-proposal.spec.tsx` greps this file for exactly that.\n *\n * The copy is held to the same standard. While `prefill` is false — no\n * console page reads `assist_*` params yet — the card says it will open the\n * page and lists the values to use. It does not say it filled anything in,\n * because a form that comes up empty after that promise is worse than no\n * card at all.\n */\nfunction ProposalCard({\n proposal,\n onConfirm,\n onDismiss,\n brand,\n}: {\n proposal: AssistProposal\n onConfirm: () => void\n onDismiss: () => void\n brand: string\n}) {\n return (\n <Paper\n variant=\"outlined\"\n sx={{ mt: 1, p: 1.5, borderRadius: 2, bgcolor: 'background.paper' }}\n >\n <Typography variant=\"subtitle2\">{proposal.label}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n Opens {proposal.outcome}.\n </Typography>\n {proposal.followUp && (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\" sx={{ mt: 1 }}>\n {`${brand} Assist asks “${proposal.followUp}” again there. Nothing changes until you apply the edit it proposes.`}\n </Typography>\n )}\n {proposal.values.length > 0 && (\n <Box sx={{ mt: 1 }}>\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\">\n {proposal.prefill ? 'Filled in for you:' : 'Values to use:'}\n </Typography>\n <Stack component=\"ul\" sx={{ m: 0, pl: 2.5 }}>\n {proposal.values.map(({ name, value }) => (\n <Typography key={name} component=\"li\" variant=\"caption\">\n {name}: <strong>{value}</strong>\n </Typography>\n ))}\n </Stack>\n </Box>\n )}\n {!proposal.followUp && (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n component=\"div\"\n sx={{ mt: 1 }}\n >\n {`${brand} Assist only opens the page. Nothing is saved until you `}\n {'fill the form in and submit it yourself.'}\n </Typography>\n )}\n <Stack direction=\"row\" spacing={1} sx={{ mt: 1.5 }}>\n <AppLink\n componentVariant=\"button\"\n href={proposal.href}\n variant=\"contained\"\n size=\"small\"\n onClick={onConfirm}\n startIcon={<MdiIcon path={mdiOpenInNew.path} />}\n >\n Take me there\n </AppLink>\n <Button size=\"small\" color=\"inherit\" onClick={onDismiss}>\n No thanks\n </Button>\n </Stack>\n </Paper>\n )\n}\n\n/**\n * The chat box and its Send button (AGL-3616).\n *\n * What is typed lives in the text field itself, not in state: a keystroke\n * commits nothing but the moment the box goes from empty to not, which is\n * the one thing the Send button draws. It used to be the panel's state, so\n * every keystroke committed the whole panel — the thread, the AI jobs list,\n * the usage strip — and React 19 counts each commit that leaves an update\n * pending as a nested one. On a busy page the browser delivers queued\n * keystrokes back to back, the 51st `setState` threw \"Maximum update depth\n * exceeded\" (#185), and the keystrokes it carried were lost. Memoized, so\n * nothing the panel redraws for redraws the box either.\n *\n * Focused when the panel opens, so the first keystroke lands in it.\n */\nconst AssistComposer = memo(function AssistComposer({\n busy,\n loaded,\n allowed,\n onSend,\n}: {\n busy: boolean\n /** The reader's AI permissions have answered. */\n loaded: boolean\n /** The reader may ask the assistant. */\n allowed: boolean\n onSend: (question: string) => unknown\n}) {\n const inputRef = useRef<HTMLTextAreaElement>(null)\n const [hasText, setHasText] = useState(false)\n const disabled = busy || !loaded || !allowed\n const noteText = (value: string) => {\n const next = value.trim().length > 0\n if (next !== hasText) setHasText(next)\n }\n const submit = () => {\n const node = inputRef.current\n const question = node?.value.trim() ?? ''\n if (!node || !question || disabled) return\n node.value = ''\n setHasText(false)\n void onSend(question)\n }\n return (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'flex-end' }}>\n <TextField\n fullWidth\n multiline\n maxRows={4}\n size=\"small\"\n placeholder=\"How do I…\"\n autoFocus\n inputRef={inputRef}\n disabled={disabled}\n onChange={(event) => noteText(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n submit()\n }\n }}\n />\n <Tooltip\n title={\n busy\n ? 'Waiting for an answer…'\n : !loaded\n ? 'Checking your permissions…'\n : !allowed\n ? 'Your role does not include the assistant'\n : 'Send message'\n }\n >\n <span>\n <IconButton\n color=\"primary\"\n aria-label=\"Send message\"\n disabled={disabled || !hasText}\n onClick={submit}\n >\n {busy ? (\n <CircularProgress size={20} />\n ) : (\n // 20px to match the CircularProgress it swaps with on the\n // line above — at the inherited 14px the button visibly grew\n // its contents while busy.\n <MdiIcon path={mdiSend.path} sx={{ fontSize: 20 }} />\n )}\n </IconButton>\n </span>\n </Tooltip>\n </Stack>\n )\n})\n\n/** The reader's AI verdict, on their own membership axis (AGL-2927). */\nexport interface AssistAiPermissions {\n /** True only once every read the answer depends on has answered. */\n loaded: boolean\n /** May the reader ask the assistant, rewrite copy, generate a section? */\n use: boolean\n /** May the reader run an AI generation job or an AI edit? */\n generate: boolean\n}\n\n/**\n * What the shell hands the assistant dock (AGL-2940): its own answers to\n * the questions only the shell can answer. The panel reads no console hook.\n */\nexport interface AssistDockProps {\n orgId?: string\n org?: Partial<AglynOrgBilling> | null\n orgReady: boolean\n /**\n * The org this panel may speak for, act as, and be METERED against — or\n * `undefined` where the page named none (AGL-1130, AGL-1934). Every use\n * of the org below goes through this rather than `orgId`, so a send path\n * cannot be added later that quietly reaches around the gate; the thread\n * key, the two POST bodies and the render gate all read the same value.\n */\n scopedOrgId?: string\n /** Path slug for building `/[orgSlug]/…` links (AGL-621). */\n orgSlug: string\n /** The site in view, or null off a host route. */\n hostId: string | null\n /** The product's name as this org reads it (AGL-2319). */\n productName: string\n /** The `release_assist` verdict, staff bypass applied. */\n assistVisible: boolean\n /** True when only the staff bypass makes the assistant visible. */\n assistStaffPreview: boolean\n /** The `release_ai_generative` verdict, staff bypass applied. */\n generativeVisible: boolean\n isStaff: boolean\n aiPermissions: AssistAiPermissions\n}\n\nexport function AssistPanelComponent(props: AssistDockProps) {\n const {\n org,\n orgId,\n orgReady,\n scopedOrgId,\n orgSlug,\n hostId,\n productName,\n assistVisible,\n assistStaffPreview,\n generativeVisible,\n isStaff,\n aiPermissions: ai,\n } = props\n const verdict = { visible: assistVisible, staffPreview: assistStaffPreview }\n const branding = { productName }\n const billingSlug = orgSlug\n const pathname = usePathname()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n\n const [open, setOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n // Every thread this panel has opened, by its key (AGL-4116): the one on\n // screen is this site's, and an answer still streaming lands in the thread\n // it was asked in, even after the page moved to another site.\n const threadKey = scopedOrgId ? assistThreadKey(scopedOrgId, hostId) : null\n const [threads, setThreads] = useState<Readonly<Record<string, AssistMessage[]>>>({})\n const messages = (threadKey && threads[threadKey]) || NO_MESSAGES\n const updateThread = useCallback(\n (key: string | null, update: (prior: AssistMessage[]) => AssistMessage[]) => {\n if (!key) return\n setThreads((prior) => ({ ...prior, [key]: update(prior[key] ?? loadThread(key)) }))\n },\n [],\n )\n const setMessages = useCallback(\n (update: (prior: AssistMessage[]) => AssistMessage[]) => updateThread(threadKey, update),\n [threadKey, updateThread],\n )\n const [quota, setQuota] = useState<AssistQuotaInfo | null>(null)\n const scrollRef = useRef<HTMLDivElement>(null)\n // The model switch and the usage strip (AGL-2942): the pick rides the\n // chat request, and each answer's `meter` moves every strip for the org.\n const modelChoice = useAiModelChoice({\n orgId: scopedOrgId,\n hostId,\n surface: 'assist',\n kind: 'assist.chat',\n })\n const publishMeter = usePublishAiUsageMeter(scopedOrgId)\n // The open editor, re-read whenever one opens, closes or reports a change —\n // so a card raised on a live version offers Apply once its new version is\n // the one open.\n const editorRevision = useSyncExternalStore(\n subscribeEditorSessions,\n editorSessionsRevision,\n editorSessionsRevision,\n )\n const editorSession = openEditorSession()\n\n // A thread per site, session-persisted; moving to another site or org\n // swaps threads (AGL-4116). Keyed on the SCOPED org (AGL-1934): gating only\n // the render would still load — and, on the next keystroke, save — a\n // thread under the fallback org's key on every mount of a page that named\n // no workspace.\n useEffect(() => {\n if (!threadKey) return\n setThreads((prior) => (threadKey in prior ? prior : { ...prior, [threadKey]: loadThread(threadKey) }))\n }, [threadKey])\n useEffect(() => {\n setQuota(null)\n }, [scopedOrgId])\n\n // Each thread is written back when it changes, the one on screen or one an\n // answer is still streaming into.\n const savedThreads = useRef<Record<string, AssistMessage[]>>({})\n useEffect(() => {\n for (const [key, list] of Object.entries(threads)) {\n if (savedThreads.current[key] === list) continue\n savedThreads.current[key] = list\n saveThread(key, list)\n }\n }, [threads])\n\n useEffect(() => {\n const node = scrollRef.current\n if (node) node.scrollTop = node.scrollHeight\n }, [messages])\n\n const entitled = orgReady && checkEntitlement(org as never, 'aiAssist')\n // Whether a question asked from a besigner document carries its canvas\n // (AGL-2906). A hint, not a grant: the server decides the edit rung again\n // from its own reads, and drops the outline below it.\n const editRungHint =\n generativeVisible &&\n ai.loaded &&\n ai.generate &&\n orgReady &&\n checkEntitlement(org as never, 'aiGenerative')\n\n // ── AI jobs, findable from anywhere (AGL-3593) ─────────────────────────\n //\n // The workspace's unsettled jobs, from the one list the top-bar indicator\n // reads — read only where the reader could run a job at all: the flag, the\n // plan's `aiGenerative` and their own `ai.generate`, as the drawer's gate.\n const jobsVisible = Boolean(scopedOrgId) && editRungHint\n const inFlight = useAiJobsInFlight(user, scopedOrgId, jobsVisible)\n // The same read tells the usage strip what a Free workspace has left, so\n // jobs that spend between chat messages move it (AGL-3722).\n useEffect(() => followAiJobsForUsageMeter(), [])\n const jobsActivity = aiJobsActivity(inFlight)\n // On a site, its jobs are read on its AI jobs page (AGL-4116): the list in\n // the chat was too cramped to read, and opening it scrolled the chat to\n // its top.\n const siteJobsHref = assistSiteAiJobsHref(pathname, orgSlug, hostId)\n const router = useRouter()\n // Any surface asking to open AI jobs — an \"Open AI jobs\" button, the\n // indicator, a notification's link — goes to the site's AI jobs page, on\n // the job it names. Off a site, it opens the panel on its drawer, and the\n // request is handed to the drawer until the panel closes, so opening the\n // panel again later does not re-highlight a job asked for before.\n const openRequest = useAiJobsOpenRequest()\n const [jobsFocus, setJobsFocus] = useState<AiJobsOpenRequest | null>(null)\n // The request outlives the panel: it is module state, and a page in\n // another layout mounts a fresh panel. Only a request made after this\n // panel mounted opens it — one already answered never reopens it.\n const answeredSeq = useRef(openRequest.seq)\n useEffect(() => {\n if (openRequest.seq <= answeredSeq.current) return\n answeredSeq.current = openRequest.seq\n if (siteJobsHref) {\n setOpen(false)\n router.push(openRequest.jobId ? `${siteJobsHref}/${encodeURIComponent(openRequest.jobId)}` : siteJobsHref)\n return\n }\n setJobsFocus(openRequest)\n setOpen(true)\n // A new `seq` is a new request; the object is read as it stands.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [openRequest.seq])\n useEffect(() => {\n if (!open) setJobsFocus(null)\n }, [open])\n // A notification's link names the job as `?aiJob={id}` on a console page:\n // arriving on it opens AI jobs on that job, once per address.\n useEffect(() => {\n if (!jobsVisible) return\n const jobId = new URLSearchParams(globalThis.location?.search ?? '').get(AI_JOB_LINK_PARAM)\n if (jobId) openAiJobs({ jobId })\n }, [jobsVisible, pathname])\n\n const send = useCallback(async (asked: string) => {\n const question = asked.trim()\n if (!question || busy || !scopedOrgId || !ai.use) return\n setBusy(true)\n // The drafts this thread's builds made (AGL-3616): the chat sees refs and\n // labels; the addresses stay here, for the card a follow-up raises.\n const draftLinks = hostId ? assistThreadDraftLinks(messages, orgSlug) : []\n // Only this site's turns ride the question (AGL-4116), and the answer\n // lands in the thread it was asked in.\n const history = messages\n .slice(-HISTORY_TURNS_SENT)\n .map((message) => ({ role: message.role, text: assistHistoryText(message) }))\n const askedIn = threadKey\n updateThread(askedIn, (prior) => [\n ...prior,\n { role: 'user', text: question },\n { role: 'assistant', text: '' },\n ])\n const patchAnswer = (patch: (message: AssistMessage) => AssistMessage) => {\n updateThread(askedIn, (prior) => {\n const next = [...prior]\n const last = next[next.length - 1]\n if (last?.role === 'assistant') next[next.length - 1] = patch(last)\n return next\n })\n }\n // A notice must not be swallowed by a partial answer: a refusal or a\n // max_tokens cut arrives AFTER text has streamed, and substituting only\n // when the bubble is empty would leave the user staring at half an\n // answer with nothing saying why it stopped.\n const failAnswer = (notice: string) => {\n patchAnswer((message) => ({\n ...message,\n text: message.text ? `${message.text}\\n\\n${notice}` : notice,\n }))\n }\n /** The build this turn proposed, started once its stream ends (AGL-3616). */\n let proposedBuild: AssistBuildProposal | null = null\n /** The page change this turn asked for, started once its stream ends (AGL-4116). */\n let proposedChange: AssistPageChangeProposal | null = null\n try {\n // The canvas outline rides along from the besigner document the open\n // editor holds, every element with its settings and styles (AGL-4116),\n // and only while that editor is on the version the route names, so the\n // outline and the selection are the ones on screen.\n const editDocument = editRungHint ? assistEditDocumentOf(pathname ?? '') : null\n const session = editDocument ? openEditorSession() : undefined\n const canvasOutline =\n editDocument &&\n session &&\n session.documentKind === editDocument.kind &&\n session.documentId === editDocument.documentId &&\n session.versionId === editDocument.versionId\n ? describeAssistEditCanvas(canvas, session.selectedNodeId?.() ?? null, { whole: true })\n : null\n const response = await authorizedFetch(user, '/api/assist/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n orgId: scopedOrgId,\n question,\n history,\n // Page context rides along; the server drops it for free orgs\n // (level 2 is Pro+). Sending it is not a grant — the capability\n // decision is server-side.\n context: { route: pathname ?? '', hostId: hostId ?? '', orgSlug },\n // A pick, when the reader made one; the server decides again.\n ...(modelChoice.model ? { model: modelChoice.model } : {}),\n ...(canvasOutline ? { canvas: canvasOutline } : {}),\n // The draft open here is marked, with its canvas riding beside it,\n // so the answer edits it rather than offering to open it again\n // (AGL-3833).\n ...(draftLinks.length\n ? {\n drafts: draftLinks.map(({ ref, label, noun, href }) => ({\n ref,\n label,\n noun,\n ...(canvasOutline && href === pathname ? { open: true } : {}),\n })),\n }\n : {}),\n }),\n })\n if (!response.ok || !response.body) {\n const payload = await response.json().catch(() => null)\n const locked = parseLockdownRefusal(response.status, payload)\n if (locked) {\n failAnswer(lockdownRefusalText(locked))\n } else if (response.status === 501) {\n // 501 means the narrow thing it says: no model is available AND\n // the documentation had nothing to offer for this question either\n // — the server hands back the closest pages whenever it has any\n // (AGL-2486), so reaching here means it had none.\n //\n // Written for the person who is actually reading it. \"Not\n // configured on this deployment\" names a deployment the reader does\n // not administer and a configuration they cannot see, and landing\n // mid-thread after a working answer it reads as a breakage. What a\n // user needs here is what happened, what to try, and who can fix it\n // — in that order, in words that assume no idea what an API key\n // is. The\n // operator's half (the env var) stays in the API error body, where\n // an operator looks and a customer does not.\n failAnswer(\n `I could not find anything in the documentation about that, and I cannot work it through with you myself yet — ` +\n `${branding.productName} Assist has not been fully switched on here. ` +\n `Try asking in different words, or ask whoever set up this workspace to finish enabling the assistant.`,\n )\n } else if (\n (response.status === 429 || response.status === 402) &&\n payload?.reason === 'quota'\n ) {\n // 402 is the org's own hard cap (AGL-2653): the band would sell\n // past itself and this workspace switched the sale off. The\n // sentence names the switch, and the credit standing beside it is\n // as real as a 429's, so it lands on the same line.\n if (payload.quota) setQuota(payload.quota as AssistQuotaInfo)\n publishMeter(payload?.meter)\n failAnswer(String(payload?.error ?? 'Message limit reached.'))\n } else {\n failAnswer(String(payload?.error ?? 'The assistant request failed — try again.'))\n }\n return\n }\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue\n let event: Record<string, unknown>\n try {\n event = JSON.parse(line.slice('data: '.length))\n } catch {\n continue\n }\n if (event.type === 'delta' && typeof event.text === 'string') {\n const text = event.text as string\n patchAnswer((message) => ({ ...message, text: message.text + text }))\n } else if (event.type === 'done') {\n const docs = (event.docs as AssistDocLink[] | undefined) ?? []\n // Server-resolved and inert: an id from the closed set attached\n // to the view the question was asked from, plus a destination\n // this client did not choose. Null on every turn that proposed\n // nothing, which is most of them.\n const resolved = (event.proposal as AssistProposal | null) ?? null\n // An open-draft proposal goes to that draft's own Besigner, from\n // this panel's record of its build, and asks the request again\n // there; one naming a draft this panel does not hold is dropped.\n // Never the draft already open here (AGL-3833).\n const draftLink = resolved?.draft\n ? draftLinks.find((link) => link.ref === resolved.draft?.ref && link.href !== pathname)\n : null\n const proposal: AssistProposal | null =\n resolved?.draft\n ? draftLink\n ? { ...resolved, href: draftLink.href, followUp: question }\n : null\n : resolved\n // The edit proposal (AGL-2906), shape-checked before it can reach\n // a card whose Apply drives the canvas.\n const edit = isAssistEditProposal(event.edit) ? event.edit : null\n // The build proposal (AGL-3616), shape-checked before it can start a job.\n const build = isAssistBuildProposal(event.build) ? event.build : null\n proposedBuild = build\n // The page change (AGL-4116), shape-checked before it can start a job.\n const pageChange = isAssistPageChangeProposal(event.pageChange) ? event.pageChange : null\n proposedChange = pageChange\n patchAnswer((message) => ({\n ...message,\n exchangeId: (event.exchangeId as string | null) ?? null,\n docs,\n proposal,\n edit,\n ...(build ? { build, buildJob: null, buildNotice: null } : {}),\n ...(pageChange ? { pageChange, pageChangeJob: null, pageChangeNotice: null } : {}),\n }))\n if (event.quota) setQuota(event.quota as AssistQuotaInfo)\n publishMeter(event.meter)\n trackEvent('assistant_message_sent', {\n tier: entitled ? 'entitled' : 'free',\n grounded: docs.length > 0,\n })\n if (proposal) {\n trackEvent('assistant_proposal_shown', { action: proposal.id })\n }\n if (edit) {\n trackEvent('assistant_proposal_shown', { action: edit.id })\n }\n if (build) {\n trackEvent('assistant_proposal_shown', { action: build.id })\n }\n if (pageChange) {\n trackEvent('assistant_proposal_shown', { action: pageChange.id })\n }\n } else if (event.type === 'error') {\n failAnswer(String(event.error ?? 'The assistant stream failed.'))\n }\n }\n }\n // One request, one build (AGL-3616): the job is created here, once,\n // through the job door, and plans inline; its card shows the plan.\n if (proposedBuild) {\n // One plan per conversation (AGL-4116): a plan this thread proposed\n // and the person has not confirmed is replaced by the new one, which\n // the chat wrote from the whole request as it now stands. Its job is\n // canceled, so it never builds and never warns another door.\n for (const replaced of assistUnconfirmedBuilds(messages)) {\n updateThread(askedIn, (prior) =>\n prior.map((entry, i) => (i === replaced.index ? { ...entry, buildReplaced: true } : entry)),\n )\n void cancelAiJobRequest(user, scopedOrgId, replaced.jobId).then(({ job }) => {\n if (!job) return\n updateThread(askedIn, (prior) =>\n prior.map((entry, i) => (i === replaced.index ? { ...entry, buildJob: job } : entry)),\n )\n })\n }\n const decision = await startAssistBuildRequest(user, scopedOrgId, proposedBuild)\n // The plan the door ran inline has just spent (AGL-3722), so the strip\n // moves with it, to the figure the plan card quotes. Left to the jobs\n // list's next read it said what was left BEFORE the plan, under a card\n // that had it right: \"117 free AI credits left\" over \"You have 71\n // left\", 2026-10-10. The card's figure is read after the plan's spend\n // is counted once, so the strip takes it as it is.\n publishMeter(decision.meter)\n const uid = user?.uid\n if (uid && scopedOrgId) {\n refreshAiUsageMeterFree(uid, scopedOrgId, decision.job?.review?.freeCredits, readAiUsageMeter(uid, scopedOrgId))\n }\n patchAnswer((message) => ({ ...message, buildJob: decision.job, buildNotice: decision.error }))\n }\n // A change to a page (AGL-4116): its edit job starts here, once, with\n // no plan to confirm. A follow-up to a page this conversation already\n // changed starts from the draft that change made.\n if (proposedChange) {\n const decision = await startAssistPageChangeRequest(\n user,\n scopedOrgId,\n proposedChange,\n assistPageChangeDraftVersion(messages, proposedChange.pageId),\n )\n publishMeter(decision.meter)\n patchAnswer((message) => ({ ...message, pageChangeJob: decision.job, pageChangeNotice: decision.error }))\n }\n } catch (error) {\n console.error(error)\n failAnswer('The assistant request failed — check your connection and try again.')\n } finally {\n setBusy(false)\n }\n }, [\n ai.use,\n busy,\n editRungHint,\n entitled,\n hostId,\n messages,\n modelChoice.model,\n publishMeter,\n scopedOrgId,\n orgSlug,\n pathname,\n threadKey,\n updateThread,\n user,\n ])\n\n // A follow-up waiting for its draft's canvas (AGL-3616): kept per org, so a\n // panel the Besigner's layout mounts afresh still asks it.\n const [followUp, setFollowUp] = useState<AssistPendingFollowUp | null>(null)\n useEffect(() => {\n setFollowUp(loadFollowUp(scopedOrgId))\n }, [scopedOrgId])\n const followUpVersion = editorSession?.versionId ?? null\n useEffect(() => {\n if (!followUp) return\n if (!isLiveAssistFollowUp(followUp, Date.now())) {\n setFollowUp(null)\n saveFollowUp(scopedOrgId, null)\n return\n }\n // Asked once the draft's own canvas is open AND loaded, so the edit rung\n // reads it (AGL-3833). The editor reports its version as it mounts, before\n // the document reaches the canvas; it reports again once it has.\n if (busy || !ai.use) return\n const stand = {\n path: pathname ?? '',\n versionId: followUpVersion,\n canvasLoaded: Boolean(canvas.getNode(CANVAS_ROOT_ELEMENT_ID)),\n }\n if (!isAssistFollowUpDue(followUp, stand)) return\n setFollowUp(null)\n saveFollowUp(scopedOrgId, null)\n setOpen(true)\n void send(followUp.question)\n // The revision is how a canvas that finished loading reaches this effect.\n }, [ai.use, busy, followUp, followUpVersion, editorRevision, pathname, scopedOrgId, send])\n\n /** Keep a confirmed open-draft proposal's request for the draft's canvas. */\n const holdFollowUp = useCallback(\n (proposal: AssistProposal) => {\n if (!proposal.followUp) return\n const pending = { path: proposal.href, question: proposal.followUp, at: Date.now() }\n setFollowUp(pending)\n saveFollowUp(scopedOrgId, pending)\n },\n [scopedOrgId],\n )\n\n /**\n * Retire a card once it has been acted on or waved away. Local state only\n * — there is nothing to tell the server, because the proposal was never\n * anything the server was waiting on.\n */\n const resolveProposal = useCallback((index: number) => {\n setMessages((prior) =>\n prior.map((entry, i) =>\n i === index ? { ...entry, proposalResolved: true } : entry,\n ),\n )\n }, [setMessages])\n\n /**\n * Land a confirmed edit on the open editor (AGL-2906): through the canvas's\n * own mutators, as one undo step, unsaved. The only request that follows is\n * the activity record, and it carries counts, never content.\n */\n const applyEdit = useCallback(\n (index: number) => {\n const message = messages[index]\n const proposal = message?.edit\n if (!proposal || !scopedOrgId) return\n const session = openEditorSession()\n const result = applyAssistEdit(canvas, proposal, session)\n if (result.ok === false) {\n setMessages((prior) =>\n prior.map(\n (entry, i): AssistMessage =>\n i === index\n ? { ...entry, editOutcome: { kind: 'failed', message: result.message } }\n : entry,\n ),\n )\n return\n }\n setMessages((prior) =>\n prior.map(\n (entry, i): AssistMessage =>\n i === index ? { ...entry, editOutcome: { kind: 'applied' } } : entry,\n ),\n )\n trackEvent('assistant_proposal_confirmed', { action: proposal.id })\n enqueueSnackbar('Applied as unsaved changes — undo takes them back', {\n variant: 'success',\n persist: false,\n })\n if (!message.exchangeId || !session) return\n const report: AssistEditAppliedReport = {\n orgId: scopedOrgId,\n hostId: proposal.target.hostId,\n exchangeId: message.exchangeId,\n documentKind: proposal.target.kind,\n documentId: proposal.target.documentId,\n versionId: session.versionId,\n opCounts: result.opCounts,\n }\n // Fire and forget: the edit is already on the canvas, and a record that\n // fails to land must not read as an edit that failed.\n void authorizedFetch(user, '/api/assist/edit-applied', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(report),\n }).catch(() => undefined)\n },\n [enqueueSnackbar, messages, scopedOrgId, setMessages, user],\n )\n\n /** Keep what a build card learned about its job on its own message (AGL-3616). */\n const patchBuild = useCallback(\n (index: number, patch: Pick<AssistMessage, 'buildJob'> | Pick<AssistMessage, 'buildNotice'>) => {\n setMessages((prior) => prior.map((entry, i) => (i === index ? { ...entry, ...patch } : entry)))\n },\n [setMessages],\n )\n\n /** Keep what a page change card learned about its job on its own message (AGL-4116). */\n const patchPageChange = useCallback(\n (index: number, patch: Pick<AssistMessage, 'pageChangeJob' | 'pageChangeNotice'>) => {\n setMessages((prior) => prior.map((entry, i) => (i === index ? { ...entry, ...patch } : entry)))\n },\n [setMessages],\n )\n\n /** Start a page change again after it failed: a new edit job, from the same draft. */\n const [retryingChange, setRetryingChange] = useState<number | null>(null)\n const retryPageChange = useCallback(\n async (index: number) => {\n const proposal = messages[index]?.pageChange\n if (!proposal || !scopedOrgId) return\n setRetryingChange(index)\n patchPageChange(index, { pageChangeJob: null, pageChangeNotice: null })\n const decision = await startAssistPageChangeRequest(\n user,\n scopedOrgId,\n proposal,\n assistPageChangeDraftVersion(messages.slice(0, index), proposal.pageId),\n )\n publishMeter(decision.meter)\n patchPageChange(index, { pageChangeJob: decision.job, pageChangeNotice: decision.error })\n setRetryingChange(null)\n },\n [messages, patchPageChange, publishMeter, scopedOrgId, user],\n )\n\n /** Wave an edit card away. Nothing to tell the server: nothing happened. */\n const dismissEdit = useCallback((index: number) => {\n setMessages((prior) =>\n prior.map(\n (entry, i): AssistMessage =>\n i === index ? { ...entry, editOutcome: { kind: 'dismissed' } } : entry,\n ),\n )\n }, [setMessages])\n\n const sendFeedback = useCallback(\n async (index: number, feedback: 'up' | 'down') => {\n const message = messages[index]\n if (!message?.exchangeId || !scopedOrgId) return\n setMessages((prior) =>\n prior.map((entry, i) => (i === index ? { ...entry, feedback } : entry)),\n )\n trackEvent('assistant_feedback', { feedback })\n try {\n await authorizedFetch(user, '/api/assist/feedback', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n orgId: scopedOrgId,\n exchangeId: message.exchangeId,\n feedback,\n }),\n })\n } catch {\n enqueueSnackbar('Feedback could not be recorded', {\n variant: 'warning',\n persist: false,\n })\n }\n },\n [enqueueSnackbar, messages, scopedOrgId, setMessages, user],\n )\n\n // A released-off feature does not exist (staff preview excepted) — and\n // without an org IN SCOPE there is nothing to meter or record against\n // (AGL-1934). `scopedOrgId`, never `orgId`: the fallback org is always\n // present, which is exactly why gating on it announced and billed the\n // assistant on the workspace picker. Every hook above has already run, so\n // this early return costs no hook-order hazard.\n if (!verdict.visible || !scopedOrgId) return null\n\n return (\n <>\n {!open && (\n <Tooltip title={`${branding.productName} Assist`} placement=\"left\">\n <Fab\n color=\"primary\"\n size=\"medium\"\n // Says what waits inside as well as what it opens (AGL-3593).\n aria-label={aiJobsLauncherLabel(branding.productName, jobsActivity)}\n onClick={() => setOpen(true)}\n sx={{\n position: 'fixed',\n // Insets, not constants (AGL-2486). The console chrome leaves\n // the bottom-right corner empty, but the besigner does not:\n // its properties panel is a full-height column on that edge,\n // and a fixed launcher lands on the Styles form and its\n // scrollbar. A surface that owns the corner publishes these\n // variables to move the launcher clear of itself; everywhere\n // else the fallback is the corner it has always used. Read as\n // CSS rather than passed as props so the offset can follow a\n // panel the launcher knows nothing about — one that is\n // resizable and collapsible — without this component growing\n // a dependency on the editor.\n right: 'var(--aglyn-dock-inset-right, 20px)',\n bottom: 'var(--aglyn-dock-inset-bottom, 20px)',\n zIndex: (theme) => theme.zIndex.drawer - 1,\n }}\n >\n {/* Sized at the call site (AGL-2486). `MdiIcon` defaults to\n `fontSize=\"inherit\"`, which is right for the startIcon and\n caption slots most of this file uses it in — but inside a\n Fab the inherited size is the BUTTON typography, 14px, so\n the glyph painted at 14px in a 48px control and read as\n broken. `medium` is the 24px MUI puts in its own FABs. Not\n fixed in `MdiIcon`: that default is depended on across the\n console, including twice in this file. */}\n {/* A job running is a dot; a job that needs the person is a count in\n the warning color, the same precedence as the top-bar chip\n (AGL-3593). The Fab's own label says it in words. */}\n <Badge\n color={jobsActivity && jobsActivity.state !== 'running' ? 'warning' : 'secondary'}\n variant={jobsActivity?.state === 'running' ? 'dot' : 'standard'}\n badgeContent={jobsActivity ? jobsActivity.count : 0}\n invisible={!jobsActivity}\n overlap=\"circular\"\n data-ai-jobs-badge={jobsActivity?.state ?? undefined}\n >\n <MdiIcon path={mdiCreation.path} fontSize=\"medium\" />\n </Badge>\n </Fab>\n </Tooltip>\n )}\n <Drawer\n anchor=\"right\"\n open={open}\n onClose={() => setOpen(false)}\n slotProps={{\n paper: {\n sx: { width: { xs: '100%', sm: 420 }, display: 'flex' },\n },\n }}\n >\n <Stack sx={{ height: '100%' }}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{\n px: 2,\n py: 1.5,\n borderBottom: 1,\n borderColor: 'divider',\n alignItems: 'center',\n }}\n >\n {/* Same reason as the launcher: this one sits beside an `h6`\n title in a plain Stack, so `inherit` gave it the 16px body\n size against a 20px heading. */}\n <MdiIcon path={mdiCreation.path} fontSize=\"medium\" />\n <Typography variant=\"h6\" sx={{ flexGrow: 1 }}>\n {`${branding.productName} Assist`}\n </Typography>\n {verdict.staffPreview && (\n <Chip size=\"small\" color=\"warning\" label=\"Staff preview\" />\n )}\n {/* Released and still changing (AGL-4052). Never beside the staff\n preview marker: an assistant only staff can see is rolling\n out, not in beta. */}\n {verdict.visible &&\n !verdict.staffPreview &&\n isBetaStaged('release_assist') && <BetaChip />}\n {/* Assist answers from the docs but never says so, and the three\n questions it provokes — what it can and can't do, why it\n stopped answering, what happens to what I typed — are exactly\n the four headings on its docs page (AGL-1943). Nothing in this\n panel's chrome can carry those, and a chat box is the one\n surface where a user is most likely to keep asking rather\n than go and read. */}\n <HelpTip\n {...pluginDocsHelp('aglynAssist', { anchor: '#what-it-can-do' })}\n sx={{ color: 'text.secondary' }}\n />\n <Tooltip title={`Close ${branding.productName} Assist`}>\n <IconButton\n aria-label={`Close ${branding.productName} Assist`}\n onClick={() => setOpen(false)}\n >\n {/* An IconButton does not set a font-size of its own, so\n `inherit` reached the same 14px button typography. */}\n <MdiIcon path={mdiClose.path} fontSize=\"medium\" />\n </IconButton>\n </Tooltip>\n </Stack>\n\n <Box ref={scrollRef} sx={{ flexGrow: 1, overflowY: 'auto', p: 2 }}>\n {/* The generation jobs (AGL-2904), scoped to the same org the\n thread is: a job listed here is one this page may act as. */}\n <AssistJobsDrawer\n orgId={scopedOrgId}\n org={org}\n orgReady={orgReady}\n orgSlug={billingSlug}\n user={user}\n visible={generativeVisible}\n isStaff={isStaff}\n hostId={hostId}\n // A question about the figures, where the page reports them\n // (AGL-2915); hidden with the rest of AI jobs, and refused by\n // the jobs door where the member may not generate.\n insight={ai.generate ? aiInsightSurfaceForPath(pathname) : null}\n inFlight={jobsVisible ? inFlight : undefined}\n focus={jobsFocus}\n pageHref={siteJobsHref}\n />\n {!messages.length && (\n <Alert severity=\"info\" sx={{ mb: 2 }}>\n {`Ask anything about using ${branding.productName} — building `}\n {'your site, publishing, domains, commerce, billing. Answers '}\n {'link the docs and the console page to use.'}\n {orgReady && !entitled && !isStaff && (\n <>\n {' Free workspaces get a limited number of messages a day. '}\n {`Page-aware guidance is included from ${\n planLabelGrantingFeature('aiAssist') ?? 'a paid plan'\n }. `}\n {billingSlug ? (\n <AppLink href={`/${billingSlug}/billing#plans`}>\n {'Upgrade'}\n </AppLink>\n ) : null}\n </>\n )}\n </Alert>\n )}\n <Stack spacing={1.5}>\n {messages.map((message, index) => (\n <Box\n key={index}\n sx={{\n alignSelf:\n message.role === 'user' ? 'flex-end' : 'flex-start',\n maxWidth: '90%',\n borderRadius: 2,\n px: 1.5,\n py: 1,\n bgcolor:\n message.role === 'user'\n ? 'primary.main'\n : 'action.hover',\n color:\n message.role === 'user'\n ? 'primary.contrastText'\n : 'text.primary',\n }}\n >\n <Typography\n variant=\"body2\"\n component=\"div\"\n sx={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}\n >\n {message.role === 'assistant' ? (\n message.text ? (\n renderAssistText(\n splitAssistDisclosure(message.text).plain,\n )\n ) : (\n <CircularProgress size={14} />\n )\n ) : (\n message.text\n )}\n </Typography>\n {message.role === 'assistant' &&\n splitAssistDisclosure(message.text).technical && (\n <UnderTheHood\n technical={splitAssistDisclosure(message.text).technical}\n />\n )}\n {message.role === 'assistant' && (\n <AssistSources text={message.text} docs={message.docs} />\n )}\n {message.role === 'assistant' &&\n message.proposal &&\n !message.proposalResolved && (\n <ProposalCard\n proposal={message.proposal}\n brand={productName}\n onConfirm={() => {\n trackEvent('assistant_proposal_confirmed', {\n action: message.proposal?.id ?? '',\n })\n resolveProposal(index)\n // A follow-up keeps the panel open: its answer\n // arrives here once the draft's canvas is.\n if (message.proposal?.followUp) holdFollowUp(message.proposal)\n else setOpen(false)\n }}\n onDismiss={() => resolveProposal(index)}\n />\n )}\n {message.role === 'assistant' &&\n message.edit &&\n message.editOutcome?.kind !== 'dismissed' &&\n message.editOutcome?.kind !== 'applied' && (\n <AssistEditCard\n proposal={message.edit}\n brand={productName}\n session={editorSession}\n failure={\n message.editOutcome?.kind === 'failed'\n ? message.editOutcome.message\n : null\n }\n onApply={() => applyEdit(index)}\n onCreateVersion={() => editorSession?.createVersion?.()}\n onDismiss={() => dismissEdit(index)}\n />\n )}\n {message.role === 'assistant' && message.pageChange && scopedOrgId && (\n <AssistPageChangeCard\n proposal={message.pageChange}\n job={message.pageChangeJob ?? null}\n notice={message.pageChangeNotice ?? null}\n orgId={scopedOrgId}\n orgSlug={orgSlug}\n user={user}\n busy={retryingChange === index}\n onJob={(job) => patchPageChange(index, { pageChangeJob: job })}\n onRetry={() => void retryPageChange(index)}\n />\n )}\n {message.role === 'assistant' && message.build && message.buildReplaced && (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"div\" sx={{ mt: 0.5 }}>\n {ASSIST_BUILD_REPLACED_COPY}\n </Typography>\n )}\n {message.role === 'assistant' && message.build && !message.buildReplaced && scopedOrgId && (\n <AssistBuildCard\n proposal={message.build}\n job={message.buildJob ?? null}\n notice={message.buildNotice ?? null}\n orgId={scopedOrgId}\n user={user}\n staff={isStaff}\n onJob={(job) => patchBuild(index, { buildJob: job })}\n onNotice={(notice) => patchBuild(index, { buildNotice: notice })}\n orgSlug={orgSlug}\n />\n )}\n {message.role === 'assistant' &&\n message.editOutcome?.kind === 'applied' && (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n component=\"div\"\n sx={{ mt: 0.5 }}\n >\n Applied to the canvas as unsaved changes.\n </Typography>\n )}\n {message.role === 'assistant' && message.exchangeId && (\n <Stack direction=\"row\" spacing={0.5} sx={{ mt: 0.5 }}>\n {/* The span is load-bearing (AGL-2128): a disabled MUI\n button fires no pointer events, so a Tooltip on it\n directly never opens — and \"already answered\" is\n precisely the state a reader most needs explained,\n because the greyed thumbs otherwise look broken. */}\n <Tooltip\n title={\n message.feedback\n ? 'Thanks — you already rated this answer'\n : 'Helpful answer'\n }\n >\n <span>\n <IconButton\n size=\"small\"\n aria-label=\"Helpful answer\"\n color={message.feedback === 'up' ? 'primary' : 'default'}\n disabled={Boolean(message.feedback)}\n onClick={() => void sendFeedback(index, 'up')}\n >\n <MdiIcon\n path={mdiThumbUpOutline.path}\n sx={{ fontSize: 16 }}\n />\n </IconButton>\n </span>\n </Tooltip>\n <Tooltip\n title={\n message.feedback\n ? 'Thanks — you already rated this answer'\n : 'Unhelpful answer'\n }\n >\n <span>\n <IconButton\n size=\"small\"\n aria-label=\"Unhelpful answer\"\n color={message.feedback === 'down' ? 'primary' : 'default'}\n disabled={Boolean(message.feedback)}\n onClick={() => void sendFeedback(index, 'down')}\n >\n <MdiIcon\n path={mdiThumbDownOutline.path}\n sx={{ fontSize: 16 }}\n />\n </IconButton>\n </span>\n </Tooltip>\n </Stack>\n )}\n </Box>\n ))}\n </Stack>\n </Box>\n\n <Stack\n spacing={1}\n sx={{ p: 2, borderTop: 1, borderColor: 'divider' }}\n >\n {ai.loaded && !ai.use ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Your role does not include the assistant — ask an ' +\n 'organization admin to grant \"Use AI assistance\".'}\n </Typography>\n ) : null}\n {/* The reader's credits while they work (AGL-2942), from the\n envelope the last answer carried — no read of its own. */}\n <AiUsageStrip orgId={scopedOrgId} orgSlug={billingSlug} />\n {quota && quota.period === 'day' && (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {quota.remaining} of {quota.limit} free messages left today\n {/* `useOrgSlug()`, not `useOrgScope().orgSlug` — the latter\n is the SUBDOMAIN slug, which is null on `app.aglyn.com`,\n so this upgrade link silently vanished on every apex org\n route: the one place a capped free workspace is told it\n is capped, with no way to act on it. Safe to fall back to\n the resolved org's slug here because the render gate\n above has already established the URL names it. */}\n {billingSlug ? (\n <>\n {' — '}\n <AppLink\n componentVariant=\"naked\"\n href={`/${billingSlug}/billing`}\n >\n upgrade for more\n </AppLink>\n </>\n ) : null}\n </Typography>\n )}\n {/* The model switch (AGL-2942), for a workspace whose plan\n answers with a model at all; its options load when opened. */}\n {entitled ? (\n <Stack direction=\"row\" sx={{ justifyContent: 'flex-end', mb: -0.5 }}>\n <AiModelSelector\n choice={modelChoice}\n disabled={busy || !ai.loaded || !ai.use}\n />\n </Stack>\n ) : null}\n <AssistComposer\n busy={busy}\n loaded={ai.loaded}\n allowed={ai.use}\n onSend={send}\n />\n </Stack>\n </Stack>\n </Drawer>\n </>\n )\n}\n\nexport default AssistPanelComponent\n"],"names":["canvas","checkEntitlement","isBetaStaged","lockdownRefusalText","parseLockdownRefusal","planLabelGrantingFeature","editorSessionsRevision","openEditorSession","subscribeEditorSessions","trackEvent","CANVAS_ROOT_ELEMENT_ID","mdiChevronDown","mdiCreation","mdiChevronUp","mdiClose","mdiOpenInNew","mdiSend","mdiThumbDownOutline","mdiThumbUpOutline","AppLink","MdiIcon","BetaChip","useSnackbar","Alert","Badge","Box","Button","Chip","CircularProgress","Collapse","Drawer","Fab","IconButton","Link","Paper","Stack","TextField","Tooltip","Typography","usePathname","useRouter","Fragment","memo","useCallback","useEffect","useRef","useState","useSyncExternalStore","useUser","authorizedFetch","assistEditDocumentOf","isAssistEditProposal","applyAssistEdit","describeAssistEditCanvas","AssistEditCard","AssistBuildCard","isAssistBuildProposal","assistBuildDraftLinks","isAssistFollowUpDue","isLiveAssistFollowUp","cancelAiJobRequest","startAssistBuildRequest","startAssistPageChangeRequest","assistPageChangeDraftVersion","assistPageChangeHistoryNote","isAssistPageChangeProposal","AssistPageChangeCard","aiInsightSurfaceForPath","AssistJobsDrawer","AI_JOB_LINK_PARAM","openAiJobs","useAiJobsInFlight","useAiJobsOpenRequest","aiJobPhase","aiJobsActivity","aiJobsLauncherLabel","AI_SITE_BUILD_HREF","AiModelSelector","AiUsageStrip","useAiModelChoice","followAiJobsForUsageMeter","refreshAiUsageMeterFree","readAiUsageMeter","usePublishAiUsageMeter","pluginDocsHelp","HelpTip","assistHistoryText","message","note","edit","editOutcome","kind","summary","text","followUpKey","orgId","loadFollowUp","sessionStorage","parsed","JSON","parse","getItem","Date","now","removeItem","saveFollowUp","followUp","setItem","stringify","assistThreadDraftLinks","messages","orgSlug","jobs","flatMap","buildJob","reverse","assistUnconfirmedBuilds","index","job","build","buildReplaced","phase","jobId","id","ASSIST_BUILD_REPLACED_COPY","BUILD_NOT_STARTED","PAGE_CHANGE_NOT_STARTED","HISTORY_TURNS_SENT","assistThreadKey","hostId","NO_MESSAGES","assistSiteAiJobsHref","pathname","parts","split","filter","Boolean","site","undefined","loadThread","key","raw","Array","isArray","map","buildNotice","pageChange","pageChangeJob","pageChangeNotice","saveThread","renderAssistText","pattern","cursor","match","matchAll","push","slice","label","href","length","part","i","startsWith","componentVariant","target","rel","splitAssistDisclosure","plain","technical","trimEnd","trim","UnderTheHood","open","setOpen","sx","mt","component","type","variant","underline","onClick","prior","display","alignItems","gap","path","fontSize","in","unmountOnExit","color","whiteSpace","wordBreak","AssistSources","docs","unseen","shown","Set","doc","url","includes","has","add","spacing","title","ProposalCard","proposal","onConfirm","onDismiss","brand","p","borderRadius","bgcolor","outcome","values","prefill","m","pl","name","value","strong","direction","size","startIcon","AssistComposer","busy","loaded","allowed","onSend","inputRef","hasText","setHasText","disabled","noteText","next","submit","node","current","question","fullWidth","multiline","maxRows","placeholder","autoFocus","onChange","event","onKeyDown","shiftKey","preventDefault","span","aria-label","AssistPanelComponent","props","org","orgReady","scopedOrgId","productName","assistVisible","assistStaffPreview","generativeVisible","isStaff","aiPermissions","ai","verdict","visible","staffPreview","branding","billingSlug","data","user","enqueueSnackbar","setBusy","threadKey","threads","setThreads","updateThread","update","setMessages","quota","setQuota","scrollRef","modelChoice","surface","publishMeter","editorRevision","editorSession","savedThreads","list","Object","entries","scrollTop","scrollHeight","entitled","editRungHint","generate","jobsVisible","inFlight","jobsActivity","siteJobsHref","router","openRequest","jobsFocus","setJobsFocus","answeredSeq","seq","encodeURIComponent","globalThis","URLSearchParams","location","search","get","send","asked","use","draftLinks","history","role","askedIn","patchAnswer","patch","last","failAnswer","notice","proposedBuild","proposedChange","editDocument","session","canvasOutline","documentKind","documentId","versionId","selectedNodeId","whole","response","method","headers","body","context","route","model","drafts","ref","noun","ok","payload","json","catch","locked","status","reason","meter","String","error","reader","getReader","decoder","TextDecoder","buffer","lines","done","read","decode","stream","pop","line","resolved","draftLink","draft","find","link","exchangeId","tier","grounded","action","replaced","entry","then","decision","uid","review","freeCredits","pageId","console","setFollowUp","followUpVersion","stand","canvasLoaded","getNode","holdFollowUp","pending","at","resolveProposal","proposalResolved","applyEdit","result","persist","report","opCounts","patchBuild","patchPageChange","retryingChange","setRetryingChange","retryPageChange","dismissEdit","sendFeedback","feedback","placement","position","right","bottom","zIndex","theme","drawer","state","badgeContent","count","invisible","overlap","data-ai-jobs-badge","anchor","onClose","slotProps","paper","width","xs","sm","height","px","py","borderBottom","borderColor","flexGrow","overflowY","insight","focus","pageHref","severity","mb","alignSelf","maxWidth","failure","onApply","onCreateVersion","createVersion","onJob","onRetry","staff","onNotice","borderTop","period","remaining","limit","justifyContent","choice"],"mappings":"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"}
|
|
@@ -233,7 +233,27 @@ export interface AiJobEditStepDeps {
|
|
|
233
233
|
readTarget?: typeof readAiEditTarget;
|
|
234
234
|
writeEdit?: typeof writeAiEdit;
|
|
235
235
|
readDatasets?: typeof readAiSiteDatasets;
|
|
236
|
+
clearMirror?: typeof clearAiEditMirror;
|
|
236
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Clears the co-edit mirror of the version whose draft a job just wrote
|
|
240
|
+
* (AGL-4116), as the Besigner's own Save draft does.
|
|
241
|
+
*
|
|
242
|
+
* The mirror holds unsaved canvas work and replays everything newer than the
|
|
243
|
+
* version's last save to whoever opens it. A draft write does not move the
|
|
244
|
+
* version's save, so without this the canvas of someone who had opened the
|
|
245
|
+
* older draft replays over the change the job just saved, and a room with
|
|
246
|
+
* replayed work offers no draft at all: the newer draft can only be reached by
|
|
247
|
+
* a Discard that deletes it. Best effort: a mirror that cannot be cleared
|
|
248
|
+
* leaves the draft saved, and the job reports what it wrote.
|
|
249
|
+
*/
|
|
250
|
+
export declare function clearAiEditMirror(input: {
|
|
251
|
+
orgId: string;
|
|
252
|
+
hostId: string;
|
|
253
|
+
kind: AiEditTargetKind;
|
|
254
|
+
id: string;
|
|
255
|
+
versionId: string;
|
|
256
|
+
}): Promise<void>;
|
|
237
257
|
/** What an edit wrote, as the job's output: a link into the Besigner on the version written. */
|
|
238
258
|
export declare function aiEditOutput(read: Pick<AiEditTargetRead, 'kind' | 'id' | 'name' | 'hostSubdomain'>, hostId: string, written: {
|
|
239
259
|
versionId: string;
|