@aglyn/plugins-ai 1.0.0-beta.246 → 1.0.0-beta.249

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/package.json +17 -17
  2. package/src/lib/activity/ai-activity-actions.js +5 -1
  3. package/src/lib/activity/ai-activity-actions.js.map +1 -1
  4. package/src/lib/components/ai-job-links.js +14 -0
  5. package/src/lib/components/ai-job-links.js.map +1 -1
  6. package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
  7. package/src/lib/components/ai-site-start-card.component.js +92 -19
  8. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  9. package/src/lib/declarations.server.js +12 -0
  10. package/src/lib/declarations.server.js.map +1 -1
  11. package/src/lib/jobs/ai-build-capabilities.js +56 -2
  12. package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
  13. package/src/lib/jobs/ai-job-build-step.d.ts +3 -8
  14. package/src/lib/jobs/ai-job-build-step.js +49 -12
  15. package/src/lib/jobs/ai-job-build-step.js.map +1 -1
  16. package/src/lib/jobs/ai-job-form-dataset.d.ts +8 -5
  17. package/src/lib/jobs/ai-job-form-dataset.js +28 -10
  18. package/src/lib/jobs/ai-job-form-dataset.js.map +1 -1
  19. package/src/lib/jobs/ai-job-form-step.d.ts +20 -4
  20. package/src/lib/jobs/ai-job-form-step.js +98 -28
  21. package/src/lib/jobs/ai-job-form-step.js.map +1 -1
  22. package/src/lib/jobs/ai-job-layout-language.d.ts +6 -2
  23. package/src/lib/jobs/ai-job-layout-language.js +16 -5
  24. package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
  25. package/src/lib/jobs/ai-job-layout-step.js +4 -1
  26. package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
  27. package/src/lib/jobs/ai-job-media-step.d.ts +239 -0
  28. package/src/lib/jobs/ai-job-media-step.js +610 -0
  29. package/src/lib/jobs/ai-job-media-step.js.map +1 -0
  30. package/src/lib/jobs/ai-job-page-language.d.ts +2 -0
  31. package/src/lib/jobs/ai-job-page-language.js +9 -0
  32. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  33. package/src/lib/jobs/ai-job-page-sections.js +4 -3
  34. package/src/lib/jobs/ai-job-page-sections.js.map +1 -1
  35. package/src/lib/jobs/ai-job-page-step.js +3 -2
  36. package/src/lib/jobs/ai-job-page-step.js.map +1 -1
  37. package/src/lib/jobs/ai-job-plan-step.d.ts +10 -1
  38. package/src/lib/jobs/ai-job-plan-step.js +73 -15
  39. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  40. package/src/lib/jobs/ai-job-settings-step.d.ts +0 -4
  41. package/src/lib/jobs/ai-job-settings-step.js +2 -7
  42. package/src/lib/jobs/ai-job-settings-step.js.map +1 -1
  43. package/src/lib/jobs/ai-job-site-content.d.ts +2 -2
  44. package/src/lib/jobs/ai-job-site-content.js +5 -3
  45. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  46. package/src/lib/jobs/ai-job-site-datasets.d.ts +1 -1
  47. package/src/lib/jobs/ai-job-site-datasets.js +3 -2
  48. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  49. package/src/lib/jobs/ai-job-site-events.d.ts +148 -0
  50. package/src/lib/jobs/ai-job-site-events.js +313 -0
  51. package/src/lib/jobs/ai-job-site-events.js.map +1 -0
  52. package/src/lib/jobs/ai-job-site-step.d.ts +9 -3
  53. package/src/lib/jobs/ai-job-site-step.js +63 -17
  54. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  55. package/src/lib/jobs/ai-job-tracking-step.d.ts +184 -0
  56. package/src/lib/jobs/ai-job-tracking-step.js +501 -0
  57. package/src/lib/jobs/ai-job-tracking-step.js.map +1 -0
  58. package/src/lib/jobs/ai-layout-stock-photos.d.ts +41 -0
  59. package/src/lib/jobs/ai-layout-stock-photos.js +71 -3
  60. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  61. package/src/lib/jobs/ai-site-publish.js +2 -3
  62. package/src/lib/jobs/ai-site-publish.js.map +1 -1
  63. package/src/lib/jobs/ai-stock-photo-picker.d.ts +24 -0
  64. package/src/lib/jobs/ai-stock-photo-picker.js +108 -0
  65. package/src/lib/jobs/ai-stock-photo-picker.js.map +1 -0
  66. package/src/lib/jobs/fixtures/ai-jazz-events-build-plan-recording.d.ts +37 -0
  67. package/src/lib/jobs/fixtures/ai-jazz-events-build-plan-recording.js +47 -0
  68. package/src/lib/jobs/fixtures/ai-jazz-events-build-plan-recording.js.map +1 -0
  69. package/src/lib/jobs/fixtures/ai-stock-photo-agl3760-recordings.d.ts +21 -0
  70. package/src/lib/jobs/fixtures/ai-stock-photo-agl3760-recordings.js +128 -0
  71. package/src/lib/jobs/fixtures/ai-stock-photo-agl3760-recordings.js.map +1 -0
  72. package/src/lib/jobs/fixtures/ai-stock-photo-agl3769-recordings.d.ts +21 -0
  73. package/src/lib/jobs/fixtures/ai-stock-photo-agl3769-recordings.js +126 -0
  74. package/src/lib/jobs/fixtures/ai-stock-photo-agl3769-recordings.js.map +1 -0
  75. package/src/lib/layout-language/ai-layout-compiler.d.ts +10 -4
  76. package/src/lib/layout-language/ai-layout-compiler.js +38 -19
  77. package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
  78. package/src/lib/layout-language/ai-layout-frame.d.ts +7 -5
  79. package/src/lib/layout-language/ai-layout-frame.js +12 -9
  80. package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
  81. package/src/lib/layout-language/ai-layout-gaps.js +3 -1
  82. package/src/lib/layout-language/ai-layout-gaps.js.map +1 -1
  83. package/src/lib/layout-language/ai-layout-labels.d.ts +70 -0
  84. package/src/lib/layout-language/ai-layout-labels.js +162 -0
  85. package/src/lib/layout-language/ai-layout-labels.js.map +1 -0
  86. package/src/lib/layout-language/ai-layout-links.js +5 -2
  87. package/src/lib/layout-language/ai-layout-links.js.map +1 -1
  88. package/src/lib/layout-language/ai-layout-listings.d.ts +14 -1
  89. package/src/lib/layout-language/ai-layout-listings.js +32 -5
  90. package/src/lib/layout-language/ai-layout-listings.js.map +1 -1
  91. package/src/lib/model/ai-build-event-page.d.ts +70 -0
  92. package/src/lib/model/ai-build-event-page.js +145 -0
  93. package/src/lib/model/ai-build-event-page.js.map +1 -0
  94. package/src/lib/model/ai-build-job.d.ts +21 -0
  95. package/src/lib/model/ai-build-job.js +39 -0
  96. package/src/lib/model/ai-build-job.js.map +1 -1
  97. package/src/lib/model/ai-build-plan.d.ts +25 -14
  98. package/src/lib/model/ai-build-plan.js +33 -23
  99. package/src/lib/model/ai-build-plan.js.map +1 -1
  100. package/src/lib/model/ai-job-activity.js +3 -1
  101. package/src/lib/model/ai-job-activity.js.map +1 -1
  102. package/src/lib/model/ai-jobs.types.d.ts +10 -2
  103. package/src/lib/model/ai-jobs.types.js +3 -1
  104. package/src/lib/model/ai-jobs.types.js.map +1 -1
  105. package/src/lib/model/ai-plan-capabilities.d.ts +8 -0
  106. package/src/lib/model/ai-plan-capabilities.js.map +1 -1
  107. package/src/lib/model/ai-site-inventory.d.ts +2 -0
  108. package/src/lib/model/ai-site-inventory.js +5 -0
  109. package/src/lib/model/ai-site-inventory.js.map +1 -1
  110. package/src/lib/model/ai-site-job.d.ts +2 -2
  111. package/src/lib/model/ai-site-job.js +3 -3
  112. package/src/lib/model/ai-site-job.js.map +1 -1
  113. package/src/lib/runtime/ai-doctrine-validators.d.ts +25 -3
  114. package/src/lib/runtime/ai-doctrine-validators.js +53 -6
  115. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  116. package/src/lib/runtime/ai-doctrine.d.ts +6 -1
  117. package/src/lib/runtime/ai-doctrine.js +13 -9
  118. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  119. package/src/lib/runtime/ai-eval-live.d.ts +1 -1
  120. package/src/lib/runtime/ai-eval-live.js +1 -1
  121. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  122. package/src/lib/runtime/ai-palette.d.ts +3 -1
  123. package/src/lib/runtime/ai-palette.generated.js +498 -10
  124. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  125. package/src/lib/runtime/ai-palette.js +5 -3
  126. package/src/lib/runtime/ai-palette.js.map +1 -1
  127. package/src/lib/runtime/ai-template-examples.js +8 -2
  128. package/src/lib/runtime/ai-template-examples.js.map +1 -1
  129. package/src/lib/server.js +8 -0
  130. package/src/lib/server.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-doctrine-validators.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { sanitizeAuthorHtml } from '@aglyn/aglyn/app-utils/author-html'\nimport {\n formatBytes,\n measureNodeMap,\n nodeMapBytes,\n} from '@aglyn/aglyn/app-utils/measure-node-map'\nimport {\n MEDIA_CDN_VARIANT_WIDTHS,\n parseMediaRef,\n} from '@aglyn/aglyn/app-utils/media-ref'\nimport { ESTIMATED_PAGE_TRANSFER_BYTES } from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport { createIdUrlSafe } from '@aglyn/aglyn/foundation/constants/app'\nimport { FREE_AI_TASTE_CREDITS_PER_MONTH } from '../plan-entitlements'\nimport {\n REUSABLE_INSTANCE_COMPONENT_ID,\n REUSABLE_INSTANCE_PROP_VALUES_KEY,\n} from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { parseBreakpointSpan } from '@aglyn/shared-data-enums/breakpoint-span'\nimport { renderEmailHtml } from '@aglyn/shared-util-email/email-render'\nimport {\n AI_BUILD_PLAN_CREATION_NOUNS,\n AI_BUILD_PLAN_EMBED_HOST_NAMES,\n AI_BUILD_PLAN_LIMITS,\n AI_PLAN_ASKS_FOR_VIDEO,\n aiEmbedHostOf,\n aiEmbedVideoKey,\n AI_PLAN_DATASET_ITEM_OP,\n aiPlanCreateFor,\n aiPlanFormDatasetNames,\n aiPlanItemFor,\n aiPlanSlugKey,\n aiPlanUndeclaredRefs,\n isAiPlanNewRef,\n type AiBuildPlan,\n type AiBuildPlanCreateKind,\n type AiBuildPlanEmbed,\n type AiBuildPlanRecord,\n type AiBuildPlanSection,\n type AiPlanUndeclaredRef,\n} from '../model/ai-build-plan'\nimport {\n aiCreationNoun,\n aiPlanCanPlaceForm,\n aiPlanUncreatable,\n aiPlanUncreatableKind,\n type AiPlanCapabilities,\n} from '../model/ai-plan-capabilities'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport { aiFreeSiteSectionsWithin, aiSiteHomeMinSections, aiSitePlanIsHome } from '../model/ai-site-job'\nimport { aiLayoutIsShopPage, aiLayoutShopGridSection } from '../layout-language/ai-layout-listings'\nimport { aiStorefrontSays } from '../layout-language/ai-layout-storefront'\nimport {\n AI_INSTANCE_REF_PROP,\n validateAiNodeTree,\n type AiNodeTreeContext,\n type AiNodeTreeResult,\n} from './ai-node-tree'\nimport { AI_PAGE_SCROLL_TO_PROP, aiPageLinkTarget, aiStoredScrollTargets } from './ai-page-links'\nimport {\n AI_EMAIL_CLIP_BYTES,\n AI_OUTPUT_BUDGETS,\n AI_OUTPUT_SURFACE,\n AI_TEXT_LIMITS,\n isHeadlineVariant,\n type AiBudgetMetric,\n type AiLoadEstimate,\n type AiOutputKind,\n} from './ai-palette'\nimport { AI_PALETTE, AI_SX_TOKENS } from './ai-palette.generated'\n\n/**\n * The building doctrine's validators (AGL-2935): the rules a generated\n * document is held to, each checked by code rather than asked of a prompt.\n *\n * A generator's system prompt carries the doctrine (`ai-doctrine.ts`), and a\n * model mostly follows it. \"Mostly\" is what these are for. Every tree and\n * every plan passes through them inside `runValidatedGeneration`; a finding\n * is a VIOLATION that names its rule and says, in a sentence a customer can\n * read, what was refused and what to do instead. The runtime re-asks the\n * model once with the findings, and stops for a person when the second\n * answer still breaks one.\n *\n * Trees are checked AFTER `validateAiNodeTree` (AGL-2905) has admitted them,\n * never instead of it: the palette validator decides what may be stored at\n * all, and these decide whether it was built the way a careful author would\n * build it. Plans are checked against the site inventory, which is where\n * \"reuse before create\" becomes checkable.\n *\n * Rule 17 is a MEASUREMENT, in the platform's existing units: the stored\n * node map in the bytes the save counts (`nodeMapBytes`), images at the size\n * the media library recorded, an email's HTML as the send path renders it,\n * and a page's load on top of the page weight the platform already measured.\n * Nothing here invents a second measure of a page.\n */\n\nexport type AiDoctrineRuleNumber =\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n\n/** Each rule's title, in the words the proposal and the docs page use. */\nexport const AI_DOCTRINE_RULES: Readonly<Record<AiDoctrineRuleNumber, string>> = {\n 1: 'Repeats become one reusable component',\n 2: 'Site-wide regions live in the layout',\n 3: 'Forms are built on the Forms page, then placed',\n 4: 'Similar pages share one template',\n 5: 'Colors, spacing and type come from the theme',\n 6: 'Emails use the brand',\n 7: 'Reuse before creating',\n 8: 'Data is bound, not typed',\n 9: 'Images come from the media library, with alt text',\n 10: 'Navigation and SEO travel with a page',\n 11: 'One main landmark and an ordered outline',\n 12: \"Responsive by the theme's breakpoints\",\n 13: 'Drafts only',\n 14: 'Your voice, with no filler copy',\n 15: 'Start from a duplicate of the nearest thing',\n 16: 'The smallest document that does the job',\n 17: 'A measured budget for every output',\n}\n\nexport const AI_DOCTRINE_RULE_NUMBERS = Object.keys(AI_DOCTRINE_RULES).map(\n Number,\n) as AiDoctrineRuleNumber[]\n\nexport interface AiDoctrineViolation {\n /**\n * The rule broken; `null` when the answer could not be read as the output\n * at all, or asks for what its job does not build rather than breaking a\n * building rule.\n */\n rule: AiDoctrineRuleNumber | null\n /** Stable per finding, for specs and logs. */\n code: string\n /** One customer-safe sentence: what was refused and what to do instead. */\n message: string\n /** What the model is told beyond `message`, when the validator's own words say more. */\n detail?: string\n /** Offending nodes, by the ids of the tree that was checked. */\n nodeIds?: string[]\n /** Offending plan entries or answer fields, as `screens[1].sections[2]`. */\n paths?: string[]\n /** Rule 17: the measured figure against its budget. */\n figure?: { metric: AiBudgetMetric; value: number; budget: number }\n}\n\n/** A violation as one line: the rule's number and title, then its sentence. */\nexport function aiDoctrineViolationText(violation: AiDoctrineViolation): string {\n return violation.rule === null\n ? violation.message\n : `Rule ${violation.rule} (${AI_DOCTRINE_RULES[violation.rule]}): ${violation.message}`\n}\n\n/** Who the copy is framed for; agency and enterprise copy holds to the judgment-word rule. */\nexport type AiCopyFraming = 'agency' | 'enterprise' | null\n\n// ── Trees ────────────────────────────────────────────────────────────────\n\nexport interface AiDoctrineNode {\n componentId: string\n props?: Record<string, unknown>\n sx?: Record<string, unknown>\n nodes?: string[]\n}\n\n/** A validated flat node map, as `validateAiNodeTree` returns it. */\nexport interface AiDoctrineTree {\n rootId: string\n nodes: Record<string, AiDoctrineNode>\n}\n\n/** What a library asset records about itself, for the image weight. */\nexport interface AiAssetFacts {\n sizeBytes?: number\n width?: number\n height?: number\n}\n\nexport interface AiDoctrineTreeContext extends AiNodeTreeContext {\n /** The brand an email is held to: palette path → color, and the families. */\n brand?: { colors: Record<string, string>; fonts: string[] } | null\n /** Placed library assets by media id. */\n assets?: Record<string, AiAssetFacts>\n /**\n * The third-party players the confirmed plan lists for this output\n * (AGL-3433): a Video embed is admitted only where one is listed, playing\n * the link the brief gave or none. Absent or empty admits none.\n */\n plannedEmbeds?: readonly Pick<AiBuildPlanEmbed, 'host' | 'url'>[]\n framing?: AiCopyFraming\n /**\n * Whether the workspace keeps reusable components (AGL-3030). `false`\n * draws a repeated block where it repeats. Absent is `true`, the doctrine\n * whole. Forms do not read it: a form is a saved form placed by its id on\n * every plan, counted against `formsPerHost`, or none (AGL-3596).\n */\n reusableComponents?: boolean\n /**\n * A page the layout language compiled (AGL-3660), whose picture cards — a\n * picture over its title and words, one to a cell of a grid — the compiler\n * draws from the site's design. Rule 1 asks no component of those cards;\n * every other repeat on the page is still held to it. The page half of the\n * plan capability of the same name (`AiPlanCapabilities.repeatsCompiled`,\n * AGL-3616), which spares a build's plan a component for a section's items:\n * the plan leaves them to the compiler, and this lets the page it compiles\n * draw them.\n */\n repeatsCompiled?: boolean\n /**\n * The site's home screens, by id (AGL-3056): the screen a link falls back\n * to when the site has none for what it promises. Absent: none is known.\n */\n homeScreenIds?: readonly string[]\n /**\n * The site's pages that place its form, by id (AGL-3729): where a link whose\n * words ask a visitor to get in touch (`aiAsksToGetInTouch`) does what it\n * says, even when that page is home. A guided start's café put its\n * pre-order form on Home, and its Menu page's \"Request weekend pickup\"\n * links there. Absent: none is known, and a link home is held to its words.\n */\n formScreenIds?: readonly string[]\n /**\n * The node as the model wrote it, by the id the checked tree gives it\n * (AGL-3078), for a tree that was stored before it is checked: a page\n * section is checked as part of the page, whose props the palette validator\n * has already read, and a value it could not read is absent there. Absent,\n * the tree the check is given is what the model wrote.\n */\n writtenNode?: (id: string) => unknown\n /**\n * The page's sections by their names in its plan, in order, where the tree\n * is a page a plan lays out (AGL-3097). A Button or a Screen Link may then go\n * to one of them, by `scrollTo` naming it or an `href` fragment its name's\n * words make up, which the page step writes as the platform's Scroll to\n * element interaction. Absent: a link goes only where its `screenId` or\n * `href` says.\n */\n pageSections?: readonly string[]\n /**\n * The section roots of the page, by id, where the tree checked is the page as\n * the page step stores it (AGL-3097): a link there that carries a Scroll to\n * element interaction to one of them, built or still to come, goes there.\n * Only a stored page is given them. The palette validator drops every\n * interaction a model writes before anything is stored, and an answer's own\n * are never read.\n */\n scrollTargetIds?: readonly string[]\n}\n\n/** One node of a walk: its id, its depth, and its ancestors' ids from the root down. */\nexport interface Visit {\n id: string\n node: AiDoctrineNode\n depth: number\n ancestors: string[]\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Every reachable node in document order, each once. Exported for a door's\n * own checks (`extend`), which read a tree the way these detectors do.\n */\nexport function walkTree(tree: AiDoctrineTree): Visit[] {\n const visits: Visit[] = []\n const seen = new Set<string>()\n const stack: Array<{ id: string; depth: number; ancestors: string[] }> = [\n { id: tree.rootId, depth: 0, ancestors: [] },\n ]\n while (stack.length) {\n const { id, depth, ancestors } = stack.pop() as (typeof stack)[number]\n const node = tree.nodes[id]\n if (!node || seen.has(id)) continue\n seen.add(id)\n visits.push({ id, node, depth, ancestors })\n const children = node.nodes ?? []\n for (let index = children.length - 1; index >= 0; index -= 1) {\n stack.push({ id: children[index], depth: depth + 1, ancestors: [...ancestors, id] })\n }\n }\n return visits\n}\n\nfunction displayName(componentId: string): string {\n return AI_PALETTE[componentId]?.displayName ?? componentId\n}\n\n/** The HTML element a node was told to render as. */\nfunction elementOf(node: AiDoctrineNode | undefined): string {\n const value = node?.props?.['component'] ?? node?.props?.['element']\n return typeof value === 'string' ? value : ''\n}\n\nfunction hasAncestor(\n tree: AiDoctrineTree,\n visit: Visit,\n test: (node: AiDoctrineNode) => boolean,\n): boolean {\n return visit.ancestors.some((id) => {\n const node = tree.nodes[id]\n return node ? test(node) : false\n })\n}\n\nfunction unique<T>(values: T[]): T[] {\n return [...new Set(values)]\n}\n\nfunction listNames(ids: string[], tree: AiDoctrineTree): string {\n const names = unique(ids.map((id) => displayName(tree.nodes[id]?.componentId ?? '')))\n return names.length <= 1\n ? names.join('')\n : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n}\n\n// Rule 1 and rule 8 read the same index: which subtrees share a shape.\n\n/** Below this, a repeat is a row of buttons, not a block worth a component. */\nexport const AI_REPEAT_MIN_NODES = 3\n/** Rule 1: a block on one page this many times is a component. */\nexport const AI_REPEAT_MIN_COUNT = 3\n/** Rule 1 across pages: a block this large on two pages is a component. */\nexport const AI_REPEAT_ACROSS_PAGES_MIN_NODES = 5\n/** Rule 8: a hand-typed list this long is data. */\nexport const AI_TYPED_LIST_MIN_ITEMS = 8\n\ninterface ShapeIndex {\n visits: Visit[]\n shapeOf: Map<string, string>\n sizeOf: Map<string, number>\n}\n\n/**\n * A subtree's shape: element ids, the prop NAMES it sets, and the values of\n * the props that change structure (enums, switches, numbers) — but never the\n * values of copy, links or media, which is what differs between the twelve\n * cards that should have been one component.\n */\nfunction indexShapes(tree: AiDoctrineTree): ShapeIndex {\n const shapeOf = new Map<string, string>()\n const sizeOf = new Map<string, number>()\n const visits = walkTree(tree)\n for (let index = visits.length - 1; index >= 0; index -= 1) {\n const { id, node } = visits[index]\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n const props = Object.keys(node.props ?? {})\n .sort()\n .map((key) => {\n const declared = schema[key]\n const structural =\n Boolean(declared?.enum) ||\n declared?.type === 'boolean' ||\n declared?.type === 'number' ||\n declared?.type === 'integer'\n return structural ? `${key}=${String(node.props?.[key])}` : key\n })\n .join(',')\n const children = (node.nodes ?? []).filter((child) => shapeOf.has(child))\n shapeOf.set(\n id,\n `${node.componentId}(${props})[${children.map((child) => shapeOf.get(child)).join('|')}]`,\n )\n sizeOf.set(id, 1 + children.reduce((sum, child) => sum + (sizeOf.get(child) ?? 0), 0))\n }\n return { visits, shapeOf, sizeOf }\n}\n\n/** Whether a node sits inside a collection repeater, whose child is authored once and repeated by data. */\nfunction repeatedByData(tree: AiDoctrineTree, visit: Visit): boolean {\n return hasAncestor(tree, visit, (node) => node.componentId === 'collectionEntries')\n}\n\n/**\n * Shapes that repeat at least `minCount` times, reported only where they are\n * the outermost repeat: the header inside each of twelve cards repeats\n * because the card does, and the fix is the card. `groupOf` counts each\n * group's repeats apart; absent, the whole tree is one group.\n */\nfunction repeatedShapes(\n tree: AiDoctrineTree,\n index: ShapeIndex,\n minNodes: number,\n minCount: number,\n groupOf: (visit: Visit) => string = () => tree.rootId,\n skip: (visit: Visit) => boolean = () => false,\n): Array<{ shape: string; ids: string[] }> {\n const byShape = new Map<string, string[]>()\n for (const visit of index.visits) {\n if (visit.id === tree.rootId) continue\n if ((index.sizeOf.get(visit.id) ?? 0) < minNodes) continue\n if (repeatedByData(tree, visit) || skip(visit)) continue\n const shape = JSON.stringify([groupOf(visit), index.shapeOf.get(visit.id)])\n byShape.set(shape, [...(byShape.get(shape) ?? []), visit.id])\n }\n const repeated = [...byShape.entries()].filter(([, ids]) => ids.length >= minCount)\n const repeatedIds = new Set(repeated.flatMap(([, ids]) => ids))\n const ancestorsOf = new Map(index.visits.map((visit) => [visit.id, visit.ancestors]))\n return repeated\n .filter(\n ([, ids]) =>\n !ids.every((id) => (ancestorsOf.get(id) ?? []).some((ancestor) => repeatedIds.has(ancestor))),\n )\n .map(([shape, ids]) => ({ shape, ids }))\n}\n\n/** Elements that frame and space what they hold, as rule 1 reads a frame. */\nconst REPEAT_FRAMES = new Set(['muiBox', 'muiStack', 'muiContainer', 'muiGrid', 'section', 'muiList'])\n\n/**\n * What rule 1 does not call a block (AGL-3660), however like another it is:\n *\n * - a part of the page's OUTLINE — anything holding a heading at h1 or h2.\n * Three sections that each open with an h2 over a row of items share a\n * shape because a page has sections, and a component cannot carry the\n * page's outline: a heading inside one is no heading of the page.\n * - a FRAME OF ITEMS — a Grid container, a List, or a Stack of like\n * elements — and any frame that holds only such frames. What repeats in\n * it is its items, which are judged on their own: two rows of three\n * instances of two different components are not one block.\n *\n * So rule 1 still refuses three like cards, and the same card on two pages;\n * it no longer refuses a page for having more than two sections, or more than\n * two groups.\n */\nfunction aiRepeatFrameOrSection(tree: AiDoctrineTree): (visit: Visit) => boolean {\n const memo = new Map<string, boolean>()\n const childrenOf = (id: string) => (tree.nodes[id]?.nodes ?? []).filter((child) => tree.nodes[child])\n const holdsOutline = (id: string): boolean => {\n const node = tree.nodes[id]\n const level = node ? aiHeadingLevel(node) : null\n return (level !== null && level <= 2) || childrenOf(id).some(holdsOutline)\n }\n const itemFrame = (id: string): boolean => {\n const node = tree.nodes[id]\n if (!node) return false\n if (node.componentId === 'muiGrid' && node.props?.['container'] === true) return true\n if (node.componentId === 'muiList') return true\n const children = childrenOf(id)\n // A Stack of like blocks — cards, rows, panels — and never of lines of text.\n const kinds = new Set(children.map((child) => tree.nodes[child].componentId))\n return (\n node.componentId === 'muiStack' &&\n children.length >= 2 &&\n kinds.size === 1 &&\n children.every((child) => (tree.nodes[child].nodes ?? []).length > 0)\n )\n }\n const parentOf = new Map<string, string>()\n for (const [id, node] of Object.entries(tree.nodes)) for (const child of node?.nodes ?? []) parentOf.set(child, id)\n const exempt = (id: string): boolean => {\n const known = memo.get(id)\n if (known !== undefined) return known\n const node = tree.nodes[id]\n const children = childrenOf(id)\n const parent = parentOf.get(id)\n const result =\n // An item of a frame is an item, whatever heading it carries.\n (holdsOutline(id) && !(parent !== undefined && itemFrame(parent))) ||\n itemFrame(id) ||\n (!!node && REPEAT_FRAMES.has(node.componentId) && children.length > 0 && children.every(exempt))\n memo.set(id, result)\n return result\n }\n return (visit) => exempt(visit.id)\n}\n\n/**\n * Rule 1. A block repeated on one page, or a block this page shares with\n * another page generated beside it, is one component placed as instances.\n *\n * A workspace that keeps no reusable components can place no instance, so\n * there a repeated block is drawn where it repeats, and nothing is refused.\n */\nexport function detectRepeatedSubtrees(\n tree: AiDoctrineTree,\n otherPages: readonly AiDoctrineTree[] = [],\n context: Pick<AiDoctrineTreeContext, 'reusableComponents' | 'repeatsCompiled'> = {},\n): AiDoctrineViolation[] {\n if (context.reusableComponents === false) return []\n const index = indexShapes(tree)\n /**\n * A compiled picture card (AGL-3660): a Stack that opens with its picture,\n * in a cell of a grid — or that cell, holding only the card. A storefront's\n * icon column (AGL-3676), a Stack that opens with its library icon, is the\n * compiler's the same way: no model writes an Icon on a page.\n */\n const card = (id: string | undefined): boolean => {\n const node = id === undefined ? undefined : tree.nodes[id]\n const first = node?.nodes?.[0]\n const opens = first === undefined ? undefined : tree.nodes[first]?.componentId\n return node?.componentId === 'muiStack' && (opens === 'image' || opens === 'icon')\n }\n const pictureCard = (id: string): boolean => {\n const node = tree.nodes[id]\n if (node?.componentId === 'muiGrid' && node.props?.['container'] !== true) return node.nodes?.length === 1 && card(node.nodes[0])\n const parentId = index.visits.find((visit) => visit.id === id)?.ancestors.at(-1)\n return card(id) && parentId !== undefined && tree.nodes[parentId]?.componentId === 'muiGrid'\n }\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES,\n AI_REPEAT_MIN_COUNT,\n // Counted within the band of the page it sits in (AGL-3660), as rule 8\n // counts a typed list: a heading over its words in the About band and in\n // the Services band are two parts of two stories, not one block placed twice.\n (visit) => [...visit.ancestors].reverse().find((id) => tree.nodes[id]?.componentId === 'section') ?? tree.rootId,\n aiRepeatFrameOrSection(tree),\n )\n .filter(({ ids }) => !(context.repeatsCompiled && ids.every(pictureCard)))\n .map(({ ids }) => {\n const name = displayName(tree.nodes[ids[0]].componentId)\n return {\n rule: 1,\n code: 'repeated-subtree',\n message: `The same ${name} block appears ${ids.length} times. Make it one reusable component with props for what changes, and place it ${ids.length} times.`,\n nodeIds: ids,\n }\n })\n if (otherPages.length) {\n const elsewhere = new Set<string>()\n for (const other of otherPages) {\n const otherIndex = indexShapes(other)\n for (const visit of otherIndex.visits) {\n if (visit.id === other.rootId) continue\n if ((otherIndex.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES) {\n elsewhere.add(otherIndex.shapeOf.get(visit.id) as string)\n }\n }\n }\n const shared = index.visits.filter(\n (visit) =>\n visit.id !== tree.rootId &&\n (index.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES &&\n elsewhere.has(index.shapeOf.get(visit.id) as string),\n )\n const sharedIds = new Set(shared.map((visit) => visit.id))\n const outermost = shared.filter((visit) => !visit.ancestors.some((id) => sharedIds.has(id)))\n for (const visit of outermost) {\n violations.push({\n rule: 1,\n code: 'repeated-across-pages',\n message: `This page and another share the same ${displayName(visit.node.componentId)} block. Make it one reusable component and place it on both.`,\n nodeIds: [visit.id],\n })\n }\n }\n return violations\n}\n\n/**\n * How many copies of one repeated thing a document shows, read as\n * generously as the tree allows (AGL-3024): the largest group of nodes the\n * shape index calls the same shape — the index rule 1 counts repeats with —\n * or, where a node's children outnumber that, its fan-out.\n *\n * GENEROUS ON PURPOSE. The one caller compares this against a count a plan\n * promised and speaks only when the count is SHORT, so every reading that\n * finds more items makes the check quieter, never louder: three cards whose\n * headings a hero's subtitle happens to match read as four and are let\n * through, and four cards laid out as two rows of two read as four either by\n * their shared shape or by the rows' fan-out. What it cannot do is find four\n * items in a document that holds three of everything.\n */\nexport function aiRepeatedItemCount(tree: AiDoctrineTree): number {\n const index = indexShapes(tree)\n const byShape = new Map<string, number>()\n let most = 0\n for (const visit of index.visits) {\n if (visit.id !== tree.rootId) {\n const shape = index.shapeOf.get(visit.id)\n if (shape) {\n const count = (byShape.get(shape) ?? 0) + 1\n byShape.set(shape, count)\n if (count > most) most = count\n }\n }\n const children = (visit.node.nodes ?? []).filter((id) => tree.nodes[id]).length\n if (children > most) most = children\n }\n return most\n}\n\n/** Whether a document draws its repeated items from a collection, which fills them at render. */\nexport function aiBindsRepeatedItems(tree: AiDoctrineTree): boolean {\n return walkTree(tree).some(({ node }) => node.componentId === 'collectionEntries')\n}\n\nconst REGION_ELEMENTS = new Set(['header', 'footer', 'nav'])\nconst REGION_WORDS: Record<string, string> = {\n header: 'header',\n footer: 'footer',\n nav: 'navigation',\n}\n\n/**\n * The regions a layout is built out of, and how each one is found in a tree\n * (AGL-3024): the landmark elements it may be written as, and the palette\n * elements that ARE one wherever they appear.\n *\n * A CLOSED vocabulary, because it is what a plan's promise of a region is\n * checked against: a planner naming a region outside it has promised\n * something no check can find, which the plan rules refuse rather than let\n * pass as built.\n */\nexport const AI_LAYOUT_REGIONS = {\n header: { elements: ['header'], componentIds: ['muiAppBar'] },\n nav: { elements: ['nav'], componentIds: [] },\n sidebar: { elements: ['aside'], componentIds: [] },\n main: { elements: ['main'], componentIds: ['layoutSlot'] },\n footer: { elements: ['footer'], componentIds: [] },\n} as const satisfies Record<string, { elements: readonly string[]; componentIds: readonly string[] }>\n\nexport type AiLayoutRegion = keyof typeof AI_LAYOUT_REGIONS\n\nexport const AI_LAYOUT_REGION_NAMES = Object.keys(AI_LAYOUT_REGIONS) as AiLayoutRegion[]\n\n/** The words a plan may name each region by, beyond the region's own name. */\nconst LAYOUT_REGION_ALIASES: Readonly<Record<string, AiLayoutRegion>> = {\n 'app bar': 'header',\n masthead: 'header',\n 'top bar': 'header',\n navigation: 'nav',\n 'nav bar': 'nav',\n menu: 'nav',\n aside: 'sidebar',\n 'side bar': 'sidebar',\n 'side nav': 'sidebar',\n drawer: 'sidebar',\n rail: 'sidebar',\n slot: 'main',\n 'layout slot': 'main',\n content: 'main',\n}\n\n/**\n * The region a plan's word names, or `null` for a word the vocabulary does\n * not hold.\n *\n * Read the way a recorded plan writes one. A planner names a region as\n * `header`, as `layoutSlot:slot` or as `footer:region (firm name, address)`,\n * so the name is what stands before the first colon, capitals are word\n * breaks, and a trailing \"region\" or \"area\" is filler once the whole name has\n * been tried: \"Sidebar region\", \"side-bar\" and `sidebar:links` are one thing.\n */\nexport function aiLayoutRegionOf(word: string): AiLayoutRegion | null {\n const cleaned = word\n .split(':')[0]\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n const read = (value: string): AiLayoutRegion | null =>\n (AI_LAYOUT_REGION_NAMES as string[]).includes(value)\n ? (value as AiLayoutRegion)\n : (LAYOUT_REGION_ALIASES[value] ?? null)\n if (!cleaned) return null\n return read(cleaned) ?? read(cleaned.replace(/\\s+(?:region|area)$/, ''))\n}\n\n/** Every region a built tree carries, by the elements and palette elements it holds. */\nexport function aiTreeLayoutRegions(tree: AiDoctrineTree): Set<AiLayoutRegion> {\n const found = new Set<AiLayoutRegion>()\n for (const { node } of walkTree(tree)) {\n const element = elementOf(node)\n for (const region of AI_LAYOUT_REGION_NAMES) {\n const where = AI_LAYOUT_REGIONS[region]\n if (\n (element && (where.elements as readonly string[]).includes(element)) ||\n (where.componentIds as readonly string[]).includes(node.componentId)\n ) {\n found.add(region)\n }\n }\n }\n return found\n}\n\n/**\n * Rule 2. A page carries no copy of what every page carries: an app bar, or\n * a header, navigation or footer element near the top of the document. The\n * header of an article inside the page is the article's, not the site's.\n */\nexport function detectLayoutRegions(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind !== 'page' && outputKind !== 'template') return []\n const found: Array<{ id: string; region: string }> = []\n for (const visit of walkTree(tree)) {\n if (visit.id === tree.rootId) continue\n if (visit.node.componentId === 'muiAppBar') {\n found.push({ id: visit.id, region: 'header' })\n continue\n }\n const element = elementOf(visit.node)\n if (\n REGION_ELEMENTS.has(element) &&\n visit.depth <= 3 &&\n !hasAncestor(tree, visit, (node) => elementOf(node) === 'article')\n ) {\n found.push({ id: visit.id, region: REGION_WORDS[element] })\n }\n }\n if (!found.length) return []\n const regions = unique(found.map((entry) => entry.region)).join(' and ')\n return [\n {\n rule: 2,\n code: 'layout-region-in-screen',\n message: `This page carries its own site ${regions}. Headers, navigation and footers live in the site's layout; put the page in the layout instead of copying them onto it.`,\n nodeIds: found.map((entry) => entry.id),\n },\n ]\n}\n\n/**\n * Rule 3. A form on a page is a Form bound by id to a form built on the\n * Forms page — fields, validation, consent and routing kept in one place.\n * Loose fields, an unbound Form, and fields drawn inside a bound Form (which\n * the page never renders: the placed form's own design replaces them) are\n * refused. A form's own design is the one place fields are drawn.\n *\n * On every plan (AGL-3596). A workspace that can save no form once drew an\n * unbound Form holding its fields (AGL-3030): inputs on a page with no saved\n * form behind them, no routing, no consent and nothing in the Forms list —\n * which is what a guided start shipped on its first production run. A page\n * with no saved form to place now places no form, so there is no exception\n * left to read: `reusableComponents` decides repeats only.\n */\nexport function detectInlineForms(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'form' || outputKind === 'email') return []\n const loose: string[] = []\n const unbound: string[] = []\n const shadowed: string[] = []\n for (const visit of walkTree(tree)) {\n if (\n visit.node.componentId === 'formField' &&\n !hasAncestor(tree, visit, (node) => node.componentId === 'form')\n ) {\n loose.push(visit.id)\n }\n if (visit.node.componentId === 'form') {\n const bound = visit.node.props?.['formId']\n if (typeof bound === 'string' && bound) {\n if ((visit.node.nodes ?? []).length) shadowed.push(visit.id)\n } else {\n unbound.push(visit.id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (loose.length || unbound.length) {\n violations.push({\n rule: 3,\n code: 'inline-form',\n message:\n 'This draws a form inline. Place a saved form from the Forms page by its id, or, where the site has none to place, leave the form off the page.',\n nodeIds: [...unbound, ...loose],\n })\n }\n if (shadowed.length) {\n violations.push({\n rule: 3,\n code: 'fields-inside-bound-form',\n message:\n 'This form is placed by its id, so its fields come from the Forms page. Remove the copies of the fields drawn inside it.',\n nodeIds: shadowed,\n })\n }\n return violations\n}\n\nconst COLOR_SX_KEYS = new Set(['color', 'bgcolor', 'backgroundColor', 'borderColor'])\nconst COLOR_IN_VALUE_SX_KEYS = new Set([\n 'border',\n 'borderTop',\n 'borderRight',\n 'borderBottom',\n 'borderLeft',\n 'boxShadow',\n])\nconst SPACING_SX_KEYS = new Set([\n 'm',\n 'mt',\n 'mr',\n 'mb',\n 'ml',\n 'mx',\n 'my',\n 'margin',\n 'marginTop',\n 'marginRight',\n 'marginBottom',\n 'marginLeft',\n 'p',\n 'pt',\n 'pr',\n 'pb',\n 'pl',\n 'px',\n 'py',\n 'padding',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'gap',\n 'rowGap',\n 'columnGap',\n])\nconst TYPE_SX_KEYS = new Set(['fontSize', 'lineHeight', 'letterSpacing'])\nconst COLOR_KEYWORDS = new Set([\n 'inherit',\n 'transparent',\n 'currentcolor',\n 'initial',\n 'unset',\n 'none',\n])\nconst LITERAL_COLOR =\n /#[0-9a-f]{3,8}\\b|\\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\\s*\\(|\\b(?:black|white|red|green|blue|yellow|orange|purple|pink|gray|grey|brown|cyan|magenta|navy|teal|maroon|olive|lime|aqua|silver|gold|indigo|violet|beige|coral|crimson|salmon|tomato|turquoise|khaki|lavender|ivory|azure)\\b/i\nconst LENGTH_WITH_UNIT = /-?\\d*\\.?\\d+\\s*(?:px|rem|em|pt|vh|vw|ch)\\b/i\nconst paletteTokens = new Set<string>(AI_SX_TOKENS.palette)\n\n/** Whether a value names a color by value rather than by theme token. */\nfunction hasLiteralColor(value: unknown): boolean {\n if (typeof value !== 'string') return false\n const parts = value\n .trim()\n .split(/\\s+/)\n .filter((part) => !paletteTokens.has(part) && !COLOR_KEYWORDS.has(part.toLowerCase()))\n return LITERAL_COLOR.test(parts.join(' '))\n}\n\n/** An `sx` value and each of its responsive values. */\nfunction sxValues(value: unknown): unknown[] {\n return isRecord(value) ? Object.values(value) : [value]\n}\n\n/**\n * Rule 5. Every color, spacing, radius and type size is a theme token. A\n * color the theme lacks is a theme change for the theme door to draft, not a\n * value written onto one element.\n */\nexport function detectLiteralStyles(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const colors: string[] = []\n const lengths: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n for (const value of sxValues(raw)) {\n if ((COLOR_SX_KEYS.has(key) || COLOR_IN_VALUE_SX_KEYS.has(key)) && hasLiteralColor(value)) {\n colors.push(id)\n } else if (\n (SPACING_SX_KEYS.has(key) || key === 'borderRadius' || TYPE_SX_KEYS.has(key)) &&\n typeof value === 'string' &&\n LENGTH_WITH_UNIT.test(value)\n ) {\n lengths.push(id)\n } else if (key === 'fontSize' && typeof value === 'number' && value > 0) {\n lengths.push(id)\n }\n }\n }\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (\n /(?:^|[a-z])(?:color|Color|bgcolor)$/.test(name) &&\n !schema[name]?.enum &&\n hasLiteralColor(value)\n ) {\n colors.push(id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (colors.length) {\n violations.push({\n rule: 5,\n code: 'literal-color',\n message:\n \"This sets colors by value. Use the theme's color tokens, and propose a theme change for a color the theme does not have.\",\n nodeIds: unique(colors),\n })\n }\n if (lengths.length) {\n violations.push({\n rule: 5,\n code: 'literal-length',\n message:\n \"This sets spacing, corners or type sizes in fixed units. Use the theme's spacing scale, shape and typography styles.\",\n nodeIds: unique(lengths),\n })\n }\n return violations\n}\n\nfunction normalizeHex(value: string): string {\n const hex = value.trim().toLowerCase()\n return /^#[0-9a-f]{3}$/.test(hex)\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex\n}\n\n/**\n * Rule 6. An email is painted with the brand: its colors are the site's\n * brand colors and its fonts the brand's. A mail client cannot resolve a\n * theme token, so the brand's own values are what an email may name — and\n * with no brand recorded, the blocks' own defaults.\n */\nexport function detectOffBrandEmail(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n brand: AiDoctrineTreeContext['brand'],\n): AiDoctrineViolation[] {\n if (outputKind !== 'email') return []\n const allowed = new Set(Object.values(brand?.colors ?? {}).map(normalizeHex))\n const fonts = new Set((brand?.fonts ?? []).map((font) => font.toLowerCase()))\n const offBrand: string[] = []\n const values: string[] = []\n for (const { id, node } of walkTree(tree)) {\n const candidates: unknown[] = []\n for (const name of ['color', 'backgroundColor']) candidates.push(node.props?.[name])\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (COLOR_SX_KEYS.has(key)) candidates.push(...sxValues(raw))\n if (key === 'fontFamily') {\n for (const family of sxValues(raw)) {\n if (typeof family === 'string' && !fonts.has(family.trim().toLowerCase())) {\n offBrand.push(id)\n values.push(family.trim())\n }\n }\n }\n }\n for (const candidate of candidates) {\n if (typeof candidate !== 'string' || !candidate.trim()) continue\n if (!allowed.has(normalizeHex(candidate))) {\n offBrand.push(id)\n values.push(candidate.trim())\n }\n }\n }\n if (!offBrand.length) return []\n return [\n {\n rule: 6,\n code: 'off-brand-email',\n message: `This email uses ${unique(values).slice(0, 3).join(', ')}, outside the brand. Use the brand's colors and fonts so every email reads as the same sender.`,\n nodeIds: unique(offBrand),\n },\n ]\n}\n\n/** The props an email block is colored by, the ones rule 6 reads. */\nconst EMAIL_COLOR_PROPS = ['color', 'backgroundColor'] as const\n\ninterface Rgb {\n r: number\n g: number\n b: number\n}\n\n/**\n * A color as opaque RGB: hex of 3, 4, 6 or 8 digits, or `rgb()`/`rgba()`. A\n * translucent value is laid over white, the page an email is read on. `null`\n * for anything else, a name or a token included.\n */\nfunction emailRgbOf(value: string): (Rgb & { alpha: number }) | null {\n const text = value.trim().toLowerCase()\n const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.exec(text)?.[1]\n let r: number\n let g: number\n let b: number\n let alpha = 1\n if (hex) {\n const full = hex.length <= 4 ? [...hex].map((digit) => digit + digit).join('') : hex\n r = parseInt(full.slice(0, 2), 16)\n g = parseInt(full.slice(2, 4), 16)\n b = parseInt(full.slice(4, 6), 16)\n if (full.length === 8) alpha = parseInt(full.slice(6, 8), 16) / 255\n } else {\n const fn = /^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)$/.exec(text)\n if (!fn) return null\n r = Number(fn[1])\n g = Number(fn[2])\n b = Number(fn[3])\n if (fn[4] !== undefined) alpha = Number(fn[4])\n if (![r, g, b, alpha].every(Number.isFinite) || r > 255 || g > 255 || b > 255 || alpha > 1) return null\n }\n const over = (channel: number) => Math.round(channel * alpha + 255 * (1 - alpha))\n return { r: over(r), g: over(g), b: over(b), alpha }\n}\n\n/** How far apart two colors look: the weighted \"redmean\" RGB distance. */\nfunction emailColorDistance(a: Rgb, b: Rgb): number {\n const mean = (a.r + b.r) / 2\n const dr = a.r - b.r\n const dg = a.g - b.g\n const db = a.b - b.b\n return Math.sqrt((2 + mean / 256) * dr * dr + 4 * dg * dg + (2 + (255 - mean) / 256) * db * db)\n}\n\n/**\n * An email's off-brand colors, settled where each has one reading (AGL-3676).\n * Rule 6 holds an email to the brand's own values, and the guided start's\n * welcome email kept writing tints of them — a pale wash of the primary color\n * behind a section — and stopped on rule 6 after its re-ask. Before the tree\n * is checked, each `color` and `backgroundColor` outside the brand is:\n *\n * - a palette path the brand lists, such as `primary.main`: its value;\n * - a color that parses: the NEAREST opaque brand color, so a pale tint\n * becomes the brand's pale surface and a deep one its deep color;\n * - with no brand color recorded at all: dropped, leaving the block's own\n * default, which is what rule 6 asks of an email with no brand.\n *\n * A value that does not parse (a name, a CSS variable) is left for the\n * re-ask, and so is the whole tree when a snapped color would leave words\n * below 3:1 against what they sit on. Nothing is relaxed: the settled tree\n * is the one rule 6 checks.\n * Reads and returns the tree as the model wrote it.\n */\nexport function aiSettleOffBrandEmailColors(\n input: unknown,\n brand: AiDoctrineTreeContext['brand'],\n): unknown {\n if (!isRecord(input) || !isRecord(input['nodes'])) return input\n const entries = Object.entries(brand?.colors ?? {}).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].trim() !== '',\n )\n const allowed = new Set(entries.map(([, value]) => normalizeHex(value)))\n const byPath = new Map(entries.map(([path, value]) => [path.toLowerCase(), value.trim()]))\n const targets = entries.flatMap(([, value]) => {\n const rgb = emailRgbOf(value)\n return rgb && rgb.alpha === 1 ? [{ value: value.trim(), rgb }] : []\n })\n const settle = (value: string): string | null | undefined => {\n if (!entries.length) return null\n const named = byPath.get(value.trim().toLowerCase())\n if (named) return named\n const rgb = emailRgbOf(value)\n if (!rgb || !targets.length) return undefined\n let best = targets[0]\n for (const target of targets) {\n if (emailColorDistance(rgb, target.rgb) < emailColorDistance(rgb, best.rgb)) best = target\n }\n return best.value\n }\n let nodes: Record<string, unknown> | null = null\n for (const [id, node] of Object.entries(input['nodes'])) {\n if (!isRecord(node) || !isRecord(node['props'])) continue\n let props: Record<string, unknown> | null = null\n for (const name of EMAIL_COLOR_PROPS) {\n const value = node['props'][name]\n if (typeof value !== 'string' || !value.trim() || allowed.has(normalizeHex(value))) continue\n const settled = settle(value)\n if (settled === undefined) continue\n props ??= { ...node['props'] }\n if (settled === null) delete props[name]\n else props[name] = settled\n }\n if (!props) continue\n nodes ??= { ...input['nodes'] }\n nodes[id] = { ...node, props }\n }\n if (!nodes || !targets.length) return nodes ? { ...input, nodes } : input\n // Two colors snapped onto one brand value can leave words the color of what\n // they sit on — a pale green heading on a cream band both become the cream.\n // A settle that leaves any color it touched unreadable is not one reading,\n // so the tree goes back as written and rule 6 asks the model.\n return emailSettleKeepsContrast(input['nodes'], nodes) ? { ...input, nodes } : input\n}\n\n/** The least contrast words keep on what they sit on once settled: WCAG's large-text floor. */\nconst EMAIL_SETTLED_MIN_CONTRAST = 3\n\nfunction emailLuminance({ r, g, b }: Rgb): number {\n const channel = (value: number) => {\n const c = value / 255\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4\n }\n return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b)\n}\n\nfunction emailContrast(a: Rgb, b: Rgb): number {\n const [light, dark] = [emailLuminance(a), emailLuminance(b)].sort((x, y) => y - x)\n return (light + 0.05) / (dark + 0.05)\n}\n\n/**\n * Whether every block whose words or ground the settle changed can still be\n * read: its `color` against its own `backgroundColor` (a button's fill), else\n * the nearest enclosing one, else the white an email is read on. A button\n * with no fill of its own is left out: its fill is the block's default.\n */\nfunction emailSettleKeepsContrast(\n written: Record<string, unknown>,\n settled: Record<string, unknown>,\n): boolean {\n const parentOf = new Map<string, string>()\n for (const [id, node] of Object.entries(settled)) {\n if (!isRecord(node) || !Array.isArray(node['nodes'])) continue\n for (const child of node['nodes']) if (typeof child === 'string') parentOf.set(child, id)\n }\n const propOf = (nodes: Record<string, unknown>, id: string, name: string): unknown => {\n const node = nodes[id]\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n /** The id whose background a node's words sit on, or `null` for the email's white. */\n const groundOf = (id: string): string | null | undefined => {\n if (typeof propOf(settled, id, 'backgroundColor') === 'string') return id\n const node = settled[id]\n if (isRecord(node) && node['componentId'] === 'emailButton') return undefined\n const seen = new Set<string>([id])\n for (let at = parentOf.get(id); at && !seen.has(at); at = parentOf.get(at)) {\n seen.add(at)\n if (typeof propOf(settled, at, 'backgroundColor') === 'string') return at\n }\n return null\n }\n const WHITE: Rgb = { r: 255, g: 255, b: 255 }\n for (const id of Object.keys(settled)) {\n const color = propOf(settled, id, 'color')\n if (typeof color !== 'string') continue\n const ground = groundOf(id)\n if (ground === undefined) continue\n const touched =\n color !== propOf(written, id, 'color') ||\n (ground !== null &&\n propOf(settled, ground, 'backgroundColor') !== propOf(written, ground, 'backgroundColor'))\n if (!touched) continue\n const text = emailRgbOf(color)\n const background = ground === null ? WHITE : emailRgbOf(String(propOf(settled, ground, 'backgroundColor')))\n if (!text || !background) continue\n if (emailContrast(text, background) < EMAIL_SETTLED_MIN_CONTRAST) return false\n }\n return true\n}\n\n/**\n * Rule 8 (tree). A long list typed out item by item is data: bound to a\n * dataset or a content collection it stays current; typed, it is a copy that\n * goes stale. Instances of one component filled in side by side are the same\n * list in a component's clothes, and are counted the same way.\n *\n * A list is counted within the Section it sits in, the unit a plan counts a\n * section's items in (AGL-3061): a page's four practice areas and its four\n * steps are two short lists that happen to share a card, not one long one,\n * and a plan that kept them must not build a page this refuses. The same\n * list split across a section's columns is still one list. A tree with no\n * Section is one group.\n */\nexport function detectTypedData(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const index = indexShapes(tree)\n const sectionOf = (visit: Visit): string =>\n [...visit.ancestors].reverse().find((id) => tree.nodes[id]?.componentId === 'section') ?? tree.rootId\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES - 1,\n AI_TYPED_LIST_MIN_ITEMS,\n sectionOf,\n ).map(({ ids }) => ({\n rule: 8,\n code: 'typed-list',\n message: `${ids.length} ${displayName(tree.nodes[ids[0]].componentId)} items are typed out by hand. Bind the list to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n }))\n for (const visit of index.visits) {\n if (repeatedByData(tree, visit) || visit.node.componentId === 'collectionEntries') continue\n const byComponent = new Map<string, string[]>()\n for (const childId of visit.node.nodes ?? []) {\n const child = tree.nodes[childId]\n const ref = child?.props?.[AI_INSTANCE_REF_PROP]\n if (child?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID || typeof ref !== 'string') continue\n byComponent.set(ref, [...(byComponent.get(ref) ?? []), childId])\n }\n for (const ids of byComponent.values()) {\n if (ids.length < AI_TYPED_LIST_MIN_ITEMS) continue\n violations.push({\n rule: 8,\n code: 'typed-instances',\n message: `${ids.length} copies of one component are filled in by hand. Bind them to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n })\n }\n }\n return violations\n}\n\n/**\n * An instance that fills none of the props its component declares (AGL-3024).\n *\n * Rule 1 says an instance is `\"reusableInstance\"` whose `refId` names the\n * component and whose `propValues` FILL its props, and until now nothing read\n * the second half back. A placed instance with no `propValues` is not empty on\n * the page: it renders the component's own `defaultValue` for every prop, so\n * three of them render three identical cards of placeholder text.\n *\n * MEASURED 2026-09-21 on `attorney-profile-template-v2` (`sak5ei_9Wv`), whose\n * three instances of `practice-area-card` each carried `{\"refId\": …}` and\n * nothing else. It was recorded as the component shipping placeholder content;\n * the component is correct and declares `title`, `description` and `icon` with\n * labels and descriptions. The template placed it three times and filled\n * nothing, so every attorney's page showed the same `[Practice area name]`.\n *\n * Only an instance filling NOTHING is refused. A component may declare a prop\n * whose default is right for most placements, and a partly filled instance is\n * a judgment the doctrine does not have the information to second-guess.\n */\nexport function detectUnfilledInstances(\n tree: AiDoctrineTree,\n context: Pick<AiDoctrineTreeContext, 'componentProps'>,\n): AiDoctrineViolation[] {\n const declared = context.componentProps ?? {}\n const unfilled: string[] = []\n for (const [id, node] of Object.entries(tree.nodes)) {\n if (node?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) continue\n const ref = node.props?.[AI_INSTANCE_REF_PROP]\n if (typeof ref !== 'string') continue\n const props = declared[ref]\n if (!props || !Object.keys(props).length) continue\n const values = node.props?.['propValues']\n const filled =\n typeof values === 'object' && values !== null && !Array.isArray(values)\n ? Object.keys(values as Record<string, unknown>).filter((name) => name in props)\n : []\n if (!filled.length) unfilled.push(id)\n }\n if (!unfilled.length) return []\n const first = tree.nodes[unfilled[0]]\n const ref = first?.props?.[AI_INSTANCE_REF_PROP] as string\n const names = Object.keys(declared[ref] ?? {})\n const one = unfilled.length === 1\n return [\n {\n rule: 1,\n code: 'instance-props-unfilled',\n message: `${\n one ? 'An instance places' : `${unfilled.length} instances place`\n } a component and fill none of its props, so ${\n one ? 'it shows' : 'they all show'\n } the placeholder text the component falls back to. Fill \"propValues\" with what ${\n one ? 'this one' : 'each one'\n } should say: ${names.join(', ')}.`,\n nodeIds: unfilled,\n },\n ]\n}\n\n/** The media-role props of a node, with the declared image props of an instance. */\nfunction mediaValues(\n node: AiDoctrineNode,\n context: AiNodeTreeContext,\n): Array<{ name: string; value: string }> {\n const out: Array<{ name: string; value: string }> = []\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'media' && typeof value === 'string' && value.trim()) {\n out.push({ name, value: value.trim() })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n if (declared[name] === 'image' && typeof value === 'string' && value.trim()) {\n out.push({ name: `${REUSABLE_INSTANCE_PROP_VALUES_KEY}.${name}`, value: value.trim() })\n }\n }\n }\n return out\n}\n\n/**\n * Rule 9. Images are placed from the media library — an asset, or an empty\n * slot for the author to fill — never hot-linked from another site, and\n * every picture carries alt text (or says it is decorative).\n */\nexport function detectImageSources(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiDoctrineViolation[] {\n const hotlinked: string[] = []\n const missingAlt: string[] = []\n for (const { id, node } of walkTree(tree)) {\n if (mediaValues(node, context).some(({ value }) => /^https?:\\/\\//i.test(value))) {\n hotlinked.push(id)\n }\n if (node.componentId === 'image' || node.componentId === 'emailImage') {\n const alt = node.props?.['alt']\n const decorative = node.props?.['decorative'] === true\n if (!decorative && (typeof alt !== 'string' || !alt.trim())) missingAlt.push(id)\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (hotlinked.length) {\n violations.push({\n rule: 9,\n code: 'hotlinked-image',\n message:\n 'This loads images from another website. Place images from the media library, or leave the slot empty for an upload.',\n nodeIds: hotlinked,\n })\n }\n if (missingAlt.length) {\n violations.push({\n rule: 9,\n code: 'missing-alt',\n message:\n 'An image has no alt text. Describe what each picture shows, or mark a purely decorative one as decorative.',\n nodeIds: missingAlt,\n })\n }\n return violations\n}\n\n/**\n * A heading's level: the element it renders as, else the variant's own.\n * Exported for a door's own checks, which read an outline the way rule 11\n * reads a page's.\n */\nexport function aiHeadingLevel(node: AiDoctrineNode): number | null {\n if (node.componentId !== 'muiTypography') return null\n const element =\n typeof node.props?.['component'] === 'string' ? String(node.props['component']) : ''\n const match = /^h([1-6])$/.exec(element || String(node.props?.['variant'] ?? ''))\n return match ? Number(match[1]) : null\n}\n\n/**\n * Rule 11. One `main` landmark per document, and a heading outline that\n * starts at one `h1` and never skips a level. The platform places the one\n * landmark on the layout's slot, or on a page's root when it has no layout\n * (`stampDocumentLandmark`); a tree that declares two leaves it to pick the\n * wrong one. A component, a form or an email is placed inside pages, so it\n * carries no landmark of its own, and a layout carries no `h1`: every page\n * placed in it brings its own.\n */\nexport function detectDocumentStructure(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const mains = visits.filter((visit) => elementOf(visit.node) === 'main').map((visit) => visit.id)\n const violations: AiDoctrineViolation[] = []\n if (outputKind === 'component' || outputKind === 'email' || outputKind === 'form') {\n if (mains.length) {\n violations.push({\n rule: 11,\n code: 'landmark-in-fragment',\n message: `A ${outputKind} is placed inside pages, so it cannot carry the main landmark. Leave the element unset.`,\n nodeIds: mains,\n })\n }\n } else if (mains.length > 1) {\n violations.push({\n rule: 11,\n code: 'multiple-main',\n message: 'This declares more than one main landmark. A page has exactly one.',\n nodeIds: mains,\n })\n }\n if (outputKind === 'layout') {\n const slots = visits.filter((visit) => visit.node.componentId === 'layoutSlot')\n const rootElement = elementOf(tree.nodes[tree.rootId])\n const slotElement = slots[0] ? elementOf(slots[0].node) : ''\n // The landmark goes on the slot, else on the root — unless an author\n // chose another element for each.\n const chosenAway =\n rootElement !== '' &&\n rootElement !== 'main' &&\n (!slots.length || (slotElement !== '' && slotElement !== 'main'))\n if (slots.length !== 1 || chosenAway) {\n violations.push({\n rule: 11,\n code: 'layout-slot',\n message:\n 'A layout has exactly one Layout Slot, where each page renders, and the slot is the main landmark.',\n nodeIds: slots.map((slot) => slot.id),\n })\n }\n }\n if (outputKind === 'email' || outputKind === 'form') return violations\n\n const headings = visits\n .map((visit) => ({ id: visit.id, level: aiHeadingLevel(visit.node) }))\n .filter((entry): entry is { id: string; level: number } => entry.level !== null)\n const h1s = headings.filter((heading) => heading.level === 1).map((heading) => heading.id)\n const page = outputKind === 'page' || outputKind === 'template'\n if (page && h1s.length !== 1) {\n violations.push({\n rule: 11,\n code: h1s.length ? 'multiple-h1' : 'missing-h1',\n message: h1s.length\n ? `This page has ${h1s.length} top-level headings. A page has one h1; make the others h2.`\n : \"This page has no top-level heading. Give the page's title one h1.\",\n nodeIds: h1s,\n })\n } else if (!page && h1s.length > (outputKind === 'layout' ? 0 : 1)) {\n violations.push({\n rule: 11,\n code: 'multiple-h1',\n message:\n outputKind === 'layout'\n ? 'A layout wraps pages that bring their own h1, so it carries none.'\n : 'A component carries at most one h1.',\n nodeIds: h1s,\n })\n }\n const skipped: string[] = []\n let previous = page ? 0 : (headings[0]?.level ?? 1) - 1\n for (const heading of headings) {\n if (heading.level > previous + 1) skipped.push(heading.id)\n previous = heading.level\n }\n if (skipped.length) {\n violations.push({\n rule: 11,\n code: 'skipped-heading',\n message:\n 'The heading outline skips a level. Step down one level at a time — an h2 before any h3.',\n nodeIds: skipped,\n })\n }\n return violations\n}\n\nconst WIDTH_SX_KEYS = new Set(['width', 'minWidth', 'maxWidth'])\n\n/**\n * Rule 12. Widths follow the theme's breakpoints and the palette's\n * responsive props — a Container's max width, a Grid's span — never a fixed\n * pixel or viewport width that holds at one screen size. An email's column\n * is fixed by the medium, and is exempt.\n */\nexport function detectAdHocWidths(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const fixed: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (!WIDTH_SX_KEYS.has(key)) continue\n for (const value of sxValues(raw)) {\n // MUI reads a number up to 1 as a fraction of the parent.\n if (\n (typeof value === 'number' && value > 1) ||\n (typeof value === 'string' && LENGTH_WITH_UNIT.test(value))\n ) {\n fixed.push(id)\n }\n }\n }\n }\n return fixed.length\n ? [\n {\n rule: 12,\n code: 'fixed-width',\n message:\n \"This sets fixed widths. Size elements with the theme's breakpoints — a Container's max width, a Grid span, or a percentage.\",\n nodeIds: unique(fixed),\n },\n ]\n : []\n}\n\nconst GRID = 'muiGrid'\n/** A Grid's props that only a container reads; on an item they do nothing. */\nconst GRID_CONTAINER_PROPS = ['direction', 'wrap', 'spacing', 'rowSpacing', 'columnSpacing', 'columns']\n/** A container's props that set what it holds side by side, which a group that only stacks never needs. */\nconst GRID_ROW_PROPS = ['wrap', 'columns', 'columnSpacing']\n/** The directions the palette keeps for a Grid, which lays out rows. */\nconst GRID_ROW_DIRECTIONS = ['row', 'row-reverse']\n/** A direction a Stack has and a Grid does not; the palette validator drops it from a Grid. */\nconst GRID_COLUMN_DIRECTION = /^column(?:-reverse)?$/i\n/** The elements an answer wraps a container's items in, where they belong in the container itself. */\nconst GRID_ITEM_WRAPPERS = new Set(['muiBox', 'muiStack'])\n/** `sx` keys that space a container's columns outside the widths its items are sized by. */\nconst GRID_GAP_SX_KEYS = ['gap', 'columnGap']\n/** The columns a container divides a row into when it names none. */\nconst GRID_DEFAULT_COLUMNS = 12\n/** The most characters of a written value a re-ask quotes back. */\nconst GRID_QUOTED_MAX_CHARS = 24\n\n/** A value as the model wrote it, as a re-ask quotes it: text in quotes, anything else as JSON, cut short. */\nfunction writtenValueText(value: unknown): string {\n const text = typeof value === 'string' ? value : (JSON.stringify(value) ?? String(value))\n const cut = text.length > GRID_QUOTED_MAX_CHARS ? `${text.slice(0, GRID_QUOTED_MAX_CHARS)}…` : text\n return typeof value === 'string' ? `the text \"${cut}\"` : cut\n}\n\n/** A Grid's columns: its own `columns` when it names a count, else the renderer's twelve. */\nfunction gridColumns(node: AiDoctrineNode): number {\n const columns = Number(node.props?.['columns'])\n return Number.isInteger(columns) && columns > 0 ? columns : GRID_DEFAULT_COLUMNS\n}\n\n/**\n * Whether a Grid item's size is one the renderer reads, full width on a phone,\n * and whether it steps down to a column at a larger width. The size is the\n * stored string the besigner's breakpoint row writes and the Grid renderer\n * parses (`parseBreakpointSpan`): a bare span at every width, or pairs such as\n * `xs:12 md:4`.\n */\nfunction gridItemSpan(size: unknown, columns: number): { phoneFull: boolean; steps: boolean } {\n if (typeof size !== 'string' && typeof size !== 'number') return { phoneFull: false, steps: false }\n const span = parseBreakpointSpan(size)\n if (span.raw !== undefined) return { phoneFull: false, steps: false }\n if (span.base !== undefined) return { phoneFull: span.base === columns, steps: false }\n const values = span.values ?? {}\n return {\n phoneFull: values.xs === columns,\n steps: Object.entries(values).some(([breakpoint, value]) => breakpoint !== 'xs' && value !== columns),\n }\n}\n\n/** The size a container's column is asked for: full width on a phone, a row of up to four from md. */\nfunction gridItemSizeFor(items: number, columns: number): string {\n const across = Math.min(Math.max(items, 2), 4)\n const md = Math.max(1, Math.floor(columns / (items > 4 ? 3 : across)))\n const sm = Math.floor(columns / 2)\n return items >= 4 && sm !== md ? `xs:${columns} sm:${sm} md:${md}` : `xs:${columns} md:${md}`\n}\n\n/**\n * Rule 12, for a Grid (AGL-3055). The palette's Grid is one element in both\n * roles: a CONTAINER lays its direct Grid children out in columns, and an ITEM\n * takes a size. The sizes are fractions of the container's columns, so an\n * item under a Grid that is not a container is sized against nothing, and a\n * row of them stacks one under another at every width; a size that holds at\n * every width keeps a phone's columns as narrow as a desktop's; and an `sx`\n * gap on a container spaces the columns outside the widths the items were\n * sized by, so the last column wraps onto a row of its own. A live About\n * page's practice areas were the first: a Grid with no container holding three\n * items sized \"4\", one column at every width.\n *\n * A Grid that is not a container is told what to do by what it was written as\n * (AGL-3078), because one sentence does not mend every shape: a live About\n * page's section was refused twice for rule 12, with a re-ask that only ever\n * said to make the Grid a container of sized columns.\n *\n * - `grid-not-container`: a row that is not a container. A Grid that holds\n * sized Grid items, sets a prop only a row reads, or holds two or more\n * elements of one shape side by side. The rule's intent: a row of cards is a\n * container of sized items.\n * - `grid-as-stack`: any other Grid that is not a container and sets a prop\n * only a container reads, or holds two or more elements without being an\n * item: a group that only stacks, such as a heading over its text, or one\n * written with a column direction, which a Grid does not have. The re-ask\n * offers a Stack or a Box for the group, or a container of sized items.\n * - `grid-item-outside-container`: a sized Grid item that sits in another\n * element, such as a Box inside its container. A container sizes only the\n * items directly in it, so the re-ask asks to move the item there. A Box or a\n * Stack in a container that holds nothing but sized items is refused through\n * its items, not as a child of the container that is no item.\n * - `grid-container-text`: a Grid whose `container` was written as a value the\n * palette validator cannot read as true or false, such as the text \"True\". The\n * re-ask names the value as the fault.\n * - `grid-item-size`: a container's child that is not a Grid item sized full\n * width on a phone, or a container of several whose items never step down\n * to columns at a larger width.\n * - `grid-gap`: a container spaced by an `sx` gap rather than its spacing.\n *\n * Each re-ask names the Grid or its items by the model's own ids and says what\n * to write, in the size format the renderer reads. `written` is the node as\n * the model wrote it, by an id of `tree`, where that is known: the palette\n * validator reads a `container` it cannot parse, and a column direction, as\n * absent, and only what was written can name them.\n */\nexport function detectUnresponsiveGrids(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n written: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n // Shapes are indexed only once a Grid needs its children compared.\n let shapes: ShapeIndex | null = null\n const shapeOf = (id: string): string | undefined => (shapes ??= indexShapes(tree)).shapeOf.get(id)\n const childrenOf = (id: string): string[] => (tree.nodes[id]?.nodes ?? []).filter((child) => tree.nodes[child])\n const isGrid = (id: string | undefined): boolean => id !== undefined && tree.nodes[id]?.componentId === GRID\n const isContainer = (id: string | undefined): boolean =>\n isGrid(id) && tree.nodes[id as string].props?.['container'] === true\n const isSized = (id: string): boolean => isGrid(id) && tree.nodes[id].props?.['size'] !== undefined\n const writtenProp = (id: string, name: string): unknown => {\n const node = written(id)\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n /** A `container` the model wrote that the palette validator could not read as true or false. */\n const unreadContainer = (id: string): unknown => {\n const value = writtenProp(id, 'container')\n return tree.nodes[id].props?.['container'] === undefined && value !== null ? value : undefined\n }\n /** A Box or a Stack holding nothing but sized Grid items, which belong directly in a container. */\n const wrapsItems = (id: string): boolean => {\n const children = childrenOf(id)\n return GRID_ITEM_WRAPPERS.has(tree.nodes[id].componentId) && children.length > 0 && children.every(isSized)\n }\n /** A direction the model wrote as a column, which the palette validator drops from a Grid. */\n const writtenColumn = (id: string): boolean => {\n const direction = writtenProp(id, 'direction')\n return typeof direction === 'string' && GRID_COLUMN_DIRECTION.test(direction.trim())\n }\n /** A Grid set out as a row: a row direction, a prop only a row reads, or elements of one shape. */\n const setsOutRow = (id: string, children: readonly string[]): boolean =>\n GRID_ROW_DIRECTIONS.includes(String(tree.nodes[id].props?.['direction'])) ||\n GRID_ROW_PROPS.some((name) => tree.nodes[id].props?.[name] !== undefined) ||\n (children.length >= 2 && new Set(children.map(shapeOf)).size === 1)\n\n const refused = new Set<string>()\n const rows: string[] = []\n const stacks: Array<{ id: string; column: boolean }> = []\n const outside: Array<{ id: string; within: string }> = []\n const texts: Array<{ id: string; value: unknown }> = []\n const unsized: string[] = []\n const suggested: string[] = []\n const gapped: Array<{ id: string; spacing: unknown }> = []\n for (const visit of walkTree(tree)) {\n const { id, node } = visit\n if (node.componentId !== GRID) continue\n const children = childrenOf(id)\n const [parentId, grandparentId] = [...visit.ancestors].reverse()\n const parent = parentId === undefined ? undefined : tree.nodes[parentId]\n const sized = node.props?.['size'] !== undefined\n // An item whose container sits one element above it: a Box or a Stack holding only items.\n const wrappedItem = sized && parentId !== undefined && wrapsItems(parentId) && isContainer(grandparentId)\n if (node.props?.['container'] !== true) {\n const holdsSized = children.some(isSized)\n // An item of a container, or of a Grid refused here for not being the container it is written as.\n const isItem =\n parentId !== undefined &&\n isGrid(parentId) &&\n (isContainer(parentId) ||\n childrenOf(parentId).some(isSized) ||\n (refused.has(parentId) && unreadContainer(parentId) !== undefined))\n const setsContainerProps = GRID_CONTAINER_PROPS.some((name) => node.props?.[name] !== undefined)\n if (!holdsSized && !setsContainerProps && (isItem || children.length < 2) && !wrappedItem) continue\n refused.add(id)\n const text = unreadContainer(id)\n if (text !== undefined) texts.push({ id, value: text })\n else if (holdsSized) rows.push(id)\n else if (sized && parent && parent.componentId !== GRID) outside.push({ id, within: parent.componentId })\n else if (writtenColumn(id)) stacks.push({ id, column: true })\n else if (setsOutRow(id, children)) rows.push(id)\n else stacks.push({ id, column: false })\n continue\n }\n if (wrappedItem && parent) outside.push({ id, within: parent.componentId })\n const columns = gridColumns(node)\n // The items a Box or a Stack holds for it are sized against it, and refused where they sit.\n const items = children.flatMap((child) => (wrapsItems(child) ? childrenOf(child) : [child]))\n let steps = false\n const offending: string[] = []\n for (const child of items) {\n const item = tree.nodes[child]\n const span = item.componentId === GRID ? gridItemSpan(item.props?.['size'], columns) : null\n if (!span?.phoneFull) offending.push(child)\n if (span?.steps) steps = true\n }\n if (offending.length) {\n unsized.push(...offending)\n } else if (items.length >= 2 && !steps) {\n unsized.push(...items)\n }\n if (offending.length || (items.length >= 2 && !steps)) {\n suggested.push(gridItemSizeFor(items.length, columns))\n }\n const sx = node.sx ?? {}\n const gap = GRID_GAP_SX_KEYS.find((key) => sx[key] !== undefined)\n if (gap) gapped.push({ id, spacing: sx[gap] })\n }\n const violations: AiDoctrineViolation[] = []\n if (rows.length) {\n violations.push({\n rule: 12,\n code: 'grid-not-container',\n message:\n 'A Grid lays out columns only as a container: this one is not, so what it holds stacks at every width. Set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".',\n nodeIds: unique(rows),\n })\n }\n if (stacks.length) {\n violations.push({\n rule: 12,\n code: 'grid-as-stack',\n message: `${\n stacks[0].column\n ? 'A Grid lays out rows and has no \"column\" direction, so this one only stacks what it holds.'\n : 'A Grid that is not a container lays nothing out, so this one only stacks what it holds.'\n } Use a Stack (or a Box) for a group that only stacks, such as a heading over its text, or make it a container of sized items: set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".`,\n nodeIds: unique(stacks.map((entry) => entry.id)),\n })\n }\n if (outside.length) {\n const within = displayName(outside[0].within)\n violations.push({\n rule: 12,\n code: 'grid-item-outside-container',\n message: `A Grid item is sized only by the Grid container it sits directly in, and this one sits in a ${within}, so its size does nothing and it stacks at every width. Move it directly under its Grid container, or, where it has none, put it and the items beside it in one (\"container\": true).`,\n nodeIds: unique(outside.map((entry) => entry.id)),\n })\n }\n if (texts.length) {\n const [first] = texts\n violations.push({\n rule: 12,\n code: 'grid-container-text',\n message: `This Grid's \"container\" is ${writtenValueText(first.value)}, not true, so it is not a container and what it holds stacks at every width. Write \"container\": true${\n typeof first.value === 'string' ? ', with no quotes around true' : ''\n }.`,\n nodeIds: unique(texts.map((entry) => entry.id)),\n })\n }\n if (unsized.length) {\n violations.push({\n rule: 12,\n code: 'grid-item-size',\n message: `Every child of a Grid container is a Grid item whose size is full width on a phone and steps up to columns at a larger width, written as one string. Size these like \"${suggested[0]}\", and wrap any other element in such an item.`,\n nodeIds: unique(unsized),\n })\n }\n if (gapped.length) {\n const [first] = gapped\n const spacing = typeof first.spacing === 'number' ? first.spacing : 2\n violations.push({\n rule: 12,\n code: 'grid-gap',\n message: `A Grid container's items are sized by its \"spacing\", so an sx gap pushes its last column onto a row of its own. Remove the sx gap and set \"spacing\": ${spacing}.`,\n nodeIds: gapped.map((entry) => entry.id),\n })\n }\n return violations\n}\n\n/** The breakpoints a size names, in the order the renderer's string writes them. */\nconst GRID_SIZE_BREAKPOINTS = ['xs', 'sm', 'md', 'lg', 'xl']\n\n/**\n * A size the model wrote as an object of breakpoints (`{ \"xs\": 12, \"md\": 4 }`),\n * which the palette validator drops because a size is stored as one string,\n * written as that string (`xs:12 md:4`). Anything else is not read.\n */\nfunction writtenGridSizeText(size: unknown): string | null {\n if (!isRecord(size)) return null\n const pairs: string[] = []\n for (const [breakpoint, value] of Object.entries(size)) {\n const span = typeof value === 'string' && value.trim() !== '' ? Number(value) : value\n if (!GRID_SIZE_BREAKPOINTS.includes(breakpoint) || typeof span !== 'number' || !Number.isInteger(span)) return null\n pairs.push(`${breakpoint}:${span}`)\n }\n pairs.sort((a, b) => GRID_SIZE_BREAKPOINTS.indexOf(a.split(':')[0]) - GRID_SIZE_BREAKPOINTS.indexOf(b.split(':')[0]))\n return pairs.length ? pairs.join(' ') : null\n}\n\n/**\n * Rule 12's `grid-item-size`, settled before the check reads it where it has\n * one answer (AGL-3596), as `aiSettlePlanRefs` settles a plan. The re-ask for\n * it states the very size to write, and a production Home page was refused and\n * refunded after its re-ask still left a container's items unsized: the model\n * breaks a different rule each run, and a rule whose answer the validator\n * already knows is applied rather than asked for.\n *\n * For every Grid container, its items are read exactly as\n * `detectUnresponsiveGrids` counts them, a Box or a Stack holding nothing but\n * sized Grid items lending its items to the container:\n *\n * - an item whose size is missing, or is not full width on a phone, takes the\n * size the model wrote as an object of breakpoints where that one is full\n * width on a phone, and otherwise the size the re-ask would ask for\n * (`gridItemSizeFor`);\n * - an element that is no Grid, directly in the container, is wrapped in a new\n * Grid item of that size, minted the way the palette validator mints ids;\n * - a container of several items none of which steps down to columns at a\n * larger width takes that size on every item, which is what the re-ask asks;\n * - a `container` written as the text \"true\" in any case or spacing\n * (`grid-container-text`) is true, since it can mean nothing else.\n *\n * A size that is already full width on a phone is kept. Nothing else rule 12\n * names is touched: a Grid that is not a container may be meant as a row or as\n * a stack (`grid-not-container`, `grid-as-stack`), and a sized item inside a\n * Box (`grid-item-outside-container`) is moved only by changing the Box.\n *\n * `written` is the node as the model wrote it, by an id of `tree`, as\n * `detectUnresponsiveGrids` reads it, for a tree the palette validator has\n * read; a tree as the model wrote it is read as it stands, which is how the\n * tree check settles a layout, a template or a component (`aiSettleWrittenGridItems`).\n * A tree with nothing to settle comes back\n * as the same object, so settling is idempotent. A node that is changed is\n * copied, never edited in place.\n */\nexport function aiSettleGridItems<T extends AiDoctrineTree>(\n tree: T,\n options: { written?: (id: string) => unknown; mintId?: () => string } = {},\n): T {\n const written = options.written ?? (() => undefined)\n const mintId = options.mintId ?? createIdUrlSafe\n const nodes: Record<string, AiDoctrineNode> = { ...tree.nodes }\n const copied = new Set<string>()\n const edit = (id: string): AiDoctrineNode & Record<string, unknown> => {\n if (!copied.has(id)) {\n const node = nodes[id]\n nodes[id] = { ...node, props: { ...node.props }, ...(node.nodes ? { nodes: [...node.nodes] } : {}) }\n copied.add(id)\n }\n return nodes[id] as AiDoctrineNode & Record<string, unknown>\n }\n const setSize = (id: string, size: string): void => {\n if (nodes[id].props?.['size'] === size) return\n ;(edit(id).props as Record<string, unknown>)['size'] = size\n }\n const writtenProp = (id: string, name: string): unknown => {\n const node = written(id)\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n const childrenOf = (id: string): string[] => (nodes[id]?.nodes ?? []).filter((child) => nodes[child])\n const isSized = (id: string): boolean => nodes[id]?.componentId === GRID && nodes[id].props?.['size'] !== undefined\n const wrapsItems = (id: string): boolean => {\n const children = childrenOf(id)\n return GRID_ITEM_WRAPPERS.has(nodes[id].componentId) && children.length > 0 && children.every(isSized)\n }\n\n for (const { id } of walkTree(tree)) {\n if (nodes[id].componentId !== GRID) continue\n if (nodes[id].props?.['container'] !== true) {\n // Text the palette validator dropped, or, in a tree as the model wrote it, the prop itself.\n const own = nodes[id].props?.['container']\n const text = own === undefined ? writtenProp(id, 'container') : own\n if (typeof text !== 'string' || text.trim().toLowerCase() !== 'true') continue\n ;(edit(id).props as Record<string, unknown>)['container'] = true\n }\n const container = nodes[id]\n const columns = gridColumns(container)\n const children = childrenOf(id)\n const items = children.flatMap((child) => (wrapsItems(child) ? childrenOf(child) : [child]))\n if (!items.length) continue\n const size = gridItemSizeFor(items.length, columns)\n const settledItems: string[] = []\n for (const item of items) {\n if (nodes[item].componentId !== GRID) {\n // Only a direct child can be no Grid: a wrapper lends only sized Grid items.\n const wrapperId = mintId()\n const host = edit(id)\n host.nodes = (host.nodes ?? []).map((child) => (child === item ? wrapperId : child))\n const shape = container as AiDoctrineNode & Record<string, unknown>\n nodes[wrapperId] = {\n ...('$id' in shape ? { $id: wrapperId } : {}),\n ...('type' in shape ? { type: shape['type'] } : {}),\n componentId: GRID,\n ...('pluginId' in shape ? { pluginId: shape['pluginId'] } : {}),\n ...('parentId' in shape ? { parentId: id } : {}),\n nodes: [item],\n props: { size },\n } as AiDoctrineNode\n copied.add(wrapperId)\n if ('parentId' in (nodes[item] as unknown as Record<string, unknown>)) edit(item)['parentId'] = wrapperId\n settledItems.push(wrapperId)\n continue\n }\n if (!gridItemSpan(nodes[item].props?.['size'], columns).phoneFull) {\n const own = writtenGridSizeText(writtenProp(item, 'size') ?? nodes[item].props?.['size'])\n setSize(item, own !== null && gridItemSpan(own, columns).phoneFull ? own : size)\n }\n settledItems.push(item)\n }\n const steps = settledItems.some((item) => gridItemSpan(nodes[item].props?.['size'], columns).steps)\n if (settledItems.length >= 2 && !steps) for (const item of settledItems) setSize(item, size)\n }\n return copied.size ? ({ ...tree, nodes } as T) : tree\n}\n\n/**\n * `aiSettleGridItems` on a tree as the model wrote it, before the palette\n * validator reads it (AGL-3596): the tree check every kind but a page section\n * goes through stores what the validator makes of its answer, so the answer\n * is settled first. Anything that is no flat node map comes back as it was.\n */\nexport function aiSettleWrittenGridItems(input: unknown): unknown {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return input\n const nodes = Object.fromEntries(Object.entries(input['nodes']).filter(([, node]) => isRecord(node)))\n const tree = { rootId: input['rootId'], nodes: nodes as unknown as Record<string, AiDoctrineNode> }\n const settled = aiSettleGridItems(tree)\n return settled === tree ? input : { ...input, nodes: { ...input['nodes'], ...settled.nodes } }\n}\n\n/** The palette colors a link or a button can take, and a band can be painted in. */\nconst LINK_COLOR_FAMILIES = new Set(['primary', 'secondary', 'success', 'error', 'info', 'warning'])\n/** The elements a page links with; each draws its words in its `color` unless told otherwise. */\nconst LINK_COMPONENTS = new Set(['muiButton', 'muiScreenLink'])\n\n/** Whether an element is one rule 10 holds to a destination: a Button or a Screen Link. */\nexport function isAiLinkElement(componentId: unknown): boolean {\n return typeof componentId === 'string' && LINK_COMPONENTS.has(componentId)\n}\n\n/** Surfaces that paint their own background, whatever band they sit on. */\nconst PAPER_COMPONENTS = new Set(['muiCard', 'muiPaper', 'muiAccordion', 'muiDrawer'])\n/** A palette color token of a link family: `primary.main`, `secondary.dark`. */\nconst FAMILY_TOKEN = /^([a-z]+)\\.(?:main|dark|light)$/\n\n/** The link family a color value names, if it names one. */\nfunction familyOf(value: unknown): string | null {\n const family = typeof value === 'string' ? FAMILY_TOKEN.exec(value.trim())?.[1] : undefined\n return family && LINK_COLOR_FAMILIES.has(family) ? family : null\n}\n\n/**\n * The band a node sits on: the nearest ancestor that paints a background. An\n * `sx` background in a link family's color is a band of that family, and an\n * App Bar is one in its `color`, which is primary when it names none. Any\n * other background, and every paper surface, is not.\n */\nfunction bandOf(tree: AiDoctrineTree, visit: Visit): { family: string; token: string } | null {\n for (const id of [...visit.ancestors].reverse()) {\n const node = tree.nodes[id]\n if (!node) continue\n const background = node.sx?.['bgcolor'] ?? node.sx?.['backgroundColor']\n if (background !== undefined) {\n const token = sxValues(background).find((value) => familyOf(value) !== null)\n return typeof token === 'string' ? { family: familyOf(token) as string, token: token.trim() } : null\n }\n if (node.componentId === 'muiAppBar') {\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n return LINK_COLOR_FAMILIES.has(color) ? { family: color, token: `${color}.main` } : null\n }\n if (PAPER_COMPONENTS.has(node.componentId)) return null\n }\n return null\n}\n\n/**\n * The palette family a link or a button draws its words in: its own `sx`\n * color when it sets one, else its `color` (primary when it names none). A\n * link told to inherit takes the band's own, and a contained button draws its\n * label in the family's contrast text on a fill of its own.\n */\nfunction linkWordsFamily(node: AiDoctrineNode): string | null {\n const own = node.sx?.['color']\n if (own !== undefined) {\n return sxValues(own).map(familyOf).find((family) => family !== null) ?? null\n }\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n if (!LINK_COLOR_FAMILIES.has(color)) return null\n const styledAsButton = node.componentId === 'muiButton' || node.props?.['renderAs'] !== 'link'\n return styledAsButton && node.props?.['variant'] === 'contained' ? null : color\n}\n\n/**\n * Rule 5, for a link on a colored band (AGL-3056). The doctrine asks for\n * palette tokens, and a band in `primary.main` holding a Screen Link that\n * sets no color is two valid tokens: but the link keeps the theme's primary\n * color, so its words are navy on navy. A live About page's footer was the\n * first, a \"Request a Consultation\" link on a primary band. A link or a button\n * whose words are drawn in the family of the band it sits on is refused, with\n * a re-ask to inherit the band's contrast text or to set it.\n */\nexport function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const hidden: Array<{ id: string; family: string; token: string }> = []\n for (const visit of walkTree(tree)) {\n if (!LINK_COMPONENTS.has(visit.node.componentId)) continue\n const family = linkWordsFamily(visit.node)\n const band = family ? bandOf(tree, visit) : null\n if (band && band.family === family) hidden.push({ id: visit.id, ...band })\n }\n if (!hidden.length) return []\n const [first] = hidden\n return [\n {\n rule: 5,\n code: 'link-color-on-band',\n message: `A link or button on a ${first.token} band draws its words in the theme's ${first.family} color, the band's own, so they cannot be read. Give it \"color\": \"inherit\" under a band whose sx color is ${first.family}.contrastText, or set its own sx color to ${first.family}.contrastText.`,\n nodeIds: unique(hidden.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A link's words that say it goes home. */\nconst HOME_WORDS = /\\bhome(?:\\s?page)?\\b/i\n\n/** Words that ask a visitor to get in touch, which the site's form answers. */\nconst GET_IN_TOUCH_WORDS =\n /\\b(?:contact|book|booking|call|quote|estimate|appointment|schedule|reserve|reservation|get in touch|request|visit|enquire|inquire|enquiry|inquiry|message|talk|consult|consultation|order|pre-?order|sign up|join|apply|start)\\b/i\n\n/**\n * Whether a link's words ask a visitor to get in touch — contact, book, quote,\n * request, order, pre-order, enquire — which the site's form answers\n * (AGL-3729). The layout language sends such a link to the form.\n */\nexport function aiAsksToGetInTouch(label: string): boolean {\n return GET_IN_TOUCH_WORDS.test(label)\n}\n\n/**\n * The links rule 10 refuses as sent home for nothing (`detectUnrelatedScreenLinks`),\n * in document order. A link whose words ask a visitor to get in touch, sent to\n * a home page that places the site's form, does what it says (AGL-3729).\n */\nfunction unrelatedScreenLinks(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds'>,\n): Array<{ id: string; label: string }> {\n if (outputKind === 'email' || outputKind === 'form') return []\n const home = new Set(context.homeScreenIds ?? [])\n const forms = new Set(context.formScreenIds ?? [])\n const sent: Array<{ id: string; label: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n const screenId = node.props?.['screenId']\n const linksHome = (typeof screenId === 'string' && home.has(screenId)) || node.props?.['href'] === '/'\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n if (!linksHome || !label || HOME_WORDS.test(label)) continue\n // Home holds the site's form, and the words ask for what it does (AGL-3729).\n if (typeof screenId === 'string' && forms.has(screenId) && aiAsksToGetInTouch(label)) continue\n // The header and the navigation link home by name and by the site's own brand.\n const inNavigation = hasAncestor(\n tree,\n visit,\n (ancestor) => ancestor.componentId === 'muiAppBar' || ['header', 'nav'].includes(elementOf(ancestor)),\n )\n if (!inNavigation) sent.push({ id: visit.id, label })\n }\n return sent\n}\n\n/**\n * RULE 10'S LINK SENT HOME, REPAIRED IN CODE (AGL-3729).\n *\n * The rule's own advice is \"link the page that does, or leave the link out\",\n * and both halves are something code can do once it knows where the site's\n * form is. A Free guided start's café (beta.243, 2026-10-12) put its contact\n * and pre-order form on Home; its Menu page's \"Request weekend pickup\" was\n * sent to Home, and the page was refused on every answer, since the\n * destination was the compiler's, not the model's. So, before the check reads\n * the tree, each link `detectUnrelatedScreenLinks` would refuse is:\n *\n * - repointed to the page that places the site's form, when its words ask a\n * visitor to get in touch and the site has such a page that is not the page\n * being checked (`formScreenIds`, `ownScreenIds`). The platform reaches a\n * section of another page by no anchor (AGL-2867), so the link names the\n * page; a link to a section of its own page is the Scroll to element\n * interaction, which this never writes;\n * - otherwise left out: the node and everything under it are taken off the\n * page, and out of its parent's children.\n *\n * The root is never taken out. A tree with nothing to repair comes back as\n * the same object; a node that is changed is copied, never edited in place.\n */\nexport function aiSettleUnrelatedScreenLinks<T extends AiDoctrineTree>(\n tree: T,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds'> & {\n /** The page being checked, by every id it goes by: a link never goes to itself. */\n ownScreenIds?: readonly string[]\n } = {},\n): T {\n const sent = unrelatedScreenLinks(tree, outputKind, context)\n if (!sent.length) return tree\n const own = new Set(context.ownScreenIds ?? [])\n const formScreen = (context.formScreenIds ?? []).find((id) => !own.has(id)) ?? null\n const nodes: Record<string, AiDoctrineNode> = { ...tree.nodes }\n const parents = new Map<string, string>()\n for (const visit of walkTree(tree)) {\n const parent = visit.ancestors[visit.ancestors.length - 1]\n if (parent !== undefined) parents.set(visit.id, parent)\n }\n for (const { id, label } of sent) {\n if (!nodes[id]) continue\n if (formScreen && aiAsksToGetInTouch(label)) {\n const props: Record<string, unknown> = { ...(nodes[id].props ?? {}), screenId: formScreen }\n delete props['href']\n nodes[id] = { ...nodes[id], props }\n continue\n }\n const parent = parents.get(id)\n if (parent === undefined || !nodes[parent]) continue\n nodes[parent] = { ...nodes[parent], nodes: (nodes[parent].nodes ?? []).filter((child) => child !== id) }\n const stack = [id]\n while (stack.length) {\n const next = stack.pop() as string\n stack.push(...(nodes[next]?.nodes ?? []))\n delete nodes[next]\n }\n }\n return { ...tree, nodes } as T\n}\n\n/**\n * Rule 10, for a link sent where the site has nothing for it (AGL-3056). A\n * link whose purpose the site has no screen for is left out; it never goes to\n * a screen that does something else. The site inventory cannot say what each\n * screen is for, but it can name the one a model falls back to: a live About\n * page's footer sent \"Request a Consultation\" to the home screen, because the\n * site had no consultation screen. So a Screen Link or a Button, outside the\n * header and the navigation, that links the home screen with words that do\n * not say home is refused, with a re-ask to link the screen that does what it\n * says, or to leave the link out.\n */\nexport function detectUnrelatedScreenLinks(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds'> = {},\n): AiDoctrineViolation[] {\n const sent = unrelatedScreenLinks(tree, outputKind, context)\n if (!sent.length) return []\n return [\n {\n rule: 10,\n code: 'link-unrelated-screen',\n message: `\"${sent[0].label}\" links the home page, which does not do what its words say. Link the page that does, or leave the link out when the site has none.`,\n nodeIds: unique(sent.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A prop value with something in it: a destination, or words. */\nfunction isFilled(value: unknown): boolean {\n return typeof value === 'string' && value.trim() !== ''\n}\n\n/**\n * Rule 10, for a link that goes nowhere (AGL-3072). A Button or a Screen Link\n * goes where its `screenId` or its `href` says, and those are the only\n * destinations either element carries: the palette validator keeps a\n * `screenId` the site has, and an `href` that is a path on the site, an\n * `https:` address or a binding the caller admitted. Nothing else can stand\n * in for one. A form is sent by the button the Form draws from its own\n * `submitLabel`, the elements a page places carry no id an anchor could name\n * (AGL-2867), and a generated node sets no interaction. So a link with\n * neither is a dead control: a live About page's hero carried a \"Request a\n * Consultation\" button with no destination. It is refused, with a re-ask\n * naming its words and what it may link.\n *\n * On a page a plan lays out (`context.pageSections`), a link may also go to a\n * section of the same page (AGL-3097). A live hero's re-ask was answered with\n * \"#consultation-form\", an anchor to the form the plan places last, and the\n * page stopped at its first section. A link that names a section, by\n * `scrollTo` or by a fragment that section's name's words make up, goes\n * there, and the page step writes the platform's Scroll to element\n * interaction for it. On a page as stored (`context.scrollTargetIds`), a link\n * carrying that interaction to one of its section roots goes there. Two\n * faults get a sentence of their own:\n *\n * - `link-fragment`: an `href` fragment that names no section. The palette\n * validator drops it, so what the link was written with goes nowhere.\n * - `scroll-target-unknown`: a `scrollTo` naming no section of the page.\n *\n * `written` is the node as the model wrote it and `stored` the node as the\n * check was given it, each by an id of `tree`.\n */\nexport function detectLinksWithoutDestination(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'pageSections' | 'scrollTargetIds'> = {},\n written: (id: string) => unknown = () => undefined,\n stored: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const sections = context.pageSections ?? []\n const targets = new Set(context.scrollTargetIds ?? [])\n const dead: Array<{ id: string; label: string; inForm: boolean }> = []\n const fragments: Array<{ id: string; label: string; value: string }> = []\n const unknown: Array<{ id: string; label: string; value: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n if (isFilled(node.props?.['screenId']) || isFilled(node.props?.['href'])) continue\n if (aiStoredScrollTargets(stored(visit.id)).some((target) => targets.has(target))) continue\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n const target = aiPageLinkTarget(written(visit.id), sections)\n if (target?.kind === 'section') continue\n if (target?.kind === 'unknown' && target.via === 'href') {\n fragments.push({ id: visit.id, label, value: target.value })\n } else if (target?.kind === 'unknown' && context.pageSections) {\n unknown.push({ id: visit.id, label, value: target.value })\n } else {\n dead.push({ id: visit.id, label, inForm: hasAncestor(tree, visit, (ancestor) => ancestor.componentId === 'form') })\n }\n }\n const wordsOf = (entry: { id: string; label: string }): string =>\n entry.label ? `\"${entry.label}\"` : `A ${displayName(tree.nodes[entry.id].componentId)}`\n const names = sections.map((name) => `\"${name}\"`)\n const listed = names.length > 1 ? `${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}` : names.join('')\n const toSection = `To take a visitor to a section of this page, set \"${AI_PAGE_SCROLL_TO_PROP}\" to that section's name in the plan: ${listed}.`\n const violations: AiDoctrineViolation[] = []\n if (fragments.length) {\n const [first] = fragments\n violations.push({\n rule: 10,\n code: 'link-fragment',\n message: `${wordsOf(first)} links \"${first.value}\", an anchor, and no element on a page carries an id an anchor could name, so it goes nowhere. ${\n context.pageSections\n ? `${toSection} Otherwise give it the \"screenId\" of a page the site has that does what its words say, or take it out.`\n : 'Give it the \"screenId\" of a page the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives, or take it out.'\n }`,\n nodeIds: unique(fragments.map((entry) => entry.id)),\n })\n }\n if (unknown.length) {\n const [first] = unknown\n violations.push({\n rule: 10,\n code: 'scroll-target-unknown',\n message: `${wordsOf(first)} scrolls to \"${first.value}\", and this page has no section of that name. Set \"${AI_PAGE_SCROLL_TO_PROP}\" to one of its sections' names in the plan: ${listed}, or take the link out.`,\n nodeIds: unique(unknown.map((entry) => entry.id)),\n })\n }\n if (dead.length) {\n const [first] = dead\n const instead = dead.some((entry) => entry.inForm)\n ? ' A Form draws its own send button from its \"submitLabel\", so take out a button drawn inside one and set that label instead.'\n : context.pageSections\n ? ` ${toSection} When none of these fits, take it out.`\n : ' When the site has no page for it, take it out: a form on this page is sent by its own button, and no element can be reached by an anchor.'\n violations.push({\n rule: 10,\n code: 'link-without-destination',\n message: `${wordsOf(first)} goes nowhere. Give it the \"screenId\" of a page the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives.${instead}`,\n nodeIds: unique(dead.map((entry) => entry.id)),\n })\n }\n return violations\n}\n\n/** Answer fields that say \"publish\", wherever the answer put them. */\nconst PUBLISH_KEYS = /^(?:publish|published|publishNow|publishAt|goLive|isLive|live|makeLive)$/i\n\n/**\n * Rule 13. The AI writes drafts. An answer that asks for anything to be\n * published, or to go live, is refused whatever else it got right; nothing\n * downstream reads such a field, and the refusal is what keeps a future\n * reader from starting to.\n */\nexport function detectPublishIntent(answer: unknown): AiDoctrineViolation[] {\n const paths: string[] = []\n const visit = (value: unknown, path: string, depth: number) => {\n if (depth > 12 || paths.length >= 5) return\n if (Array.isArray(value)) {\n value.forEach((inner, index) => visit(inner, `${path}[${index}]`, depth + 1))\n return\n }\n if (!isRecord(value)) return\n for (const [key, inner] of Object.entries(value)) {\n const here = path ? `${path}.${key}` : key\n // An element's props and styles are page content, not instructions.\n if (key === 'props' || key === 'sx') continue\n if (\n PUBLISH_KEYS.test(key) &&\n inner !== false &&\n inner !== null &&\n inner !== undefined &&\n inner !== ''\n ) {\n paths.push(here)\n } else if (\n key === 'status' &&\n typeof inner === 'string' &&\n /^(?:published|live|public)$/i.test(inner.trim())\n ) {\n paths.push(here)\n } else {\n visit(inner, here, depth + 1)\n }\n }\n }\n visit(answer, '', 0)\n return paths.length\n ? [\n {\n rule: 13,\n code: 'publish-intent',\n message:\n 'The answer asked to publish. Everything the AI builds is a new draft; review it and publish it yourself.',\n paths,\n },\n ]\n : []\n}\n\n/** A fact the brief never gave, marked in square brackets: `[Office phone number]`. */\nconst BRACKETED_FACT = /\\[([^[\\]{}\\n]{1,80})\\]/g\n\n/**\n * The facts in square brackets copy holds (rule 14), each once whatever its\n * case, in the order they first appear, as the copy spells them\n * (AGL-3056): what a member fills in before a draft is published.\n */\nexport function aiBracketedFacts(texts: Iterable<string>): string[] {\n const facts = new Map<string, string>()\n for (const text of texts) {\n for (const match of text.matchAll(BRACKETED_FACT)) {\n const fact = match[1].trim()\n if (fact && !facts.has(fact.toLowerCase())) facts.set(fact.toLowerCase(), `[${fact}]`)\n }\n }\n return [...facts.values()]\n}\n\n/**\n * Filler that stands in for copy. A bracketed marker for a fact the brief\n * never gave — `[phone number]` — is deliberately NOT here: it is the honest\n * alternative to inventing the fact, and refusing it would push the re-ask\n * toward a made-up number.\n */\nconst FILLER_COPY =\n /\\blorem\\b|\\bipsum\\b|\\bdolor sit\\b|\\b(?:your|insert|add) (?:text|copy|content|headline|title|description|tagline) here\\b|\\b(?:placeholder|sample|dummy|filler) (?:text|copy|content)\\b|\\b(?:text|copy|content) goes here\\b/i\nconst JUDGMENT =\n /\\b(?:simply|obviously|no-brainer|cheap|effortless(?:ly)?|dead simple|super easy|just (?:a|one) click)\\b/i\n\nexport interface AiCopySample {\n /** A node id for a tree, a path for a plan. */\n at: string\n text: string\n}\n\n/**\n * Rule 14. Copy in the site's voice: no lorem ipsum or \"your text here\"\n * filler, and — for copy framed for agencies and enterprises — no words that\n * judge the reader's work as simple or cheap.\n */\nexport function detectOffVoiceCopy(\n samples: readonly AiCopySample[],\n framing: AiCopyFraming = null,\n): AiDoctrineViolation[] {\n const filler = samples.filter((sample) => FILLER_COPY.test(sample.text))\n const judged =\n framing === 'agency' || framing === 'enterprise'\n ? samples.filter((sample) => JUDGMENT.test(sample.text))\n : []\n const at = (list: readonly AiCopySample[]) => {\n const ids = unique(list.map((sample) => sample.at))\n const paths = ids.filter((id) => /[.[\\]]/.test(id))\n const nodeIds = ids.filter((id) => !/[.[\\]]/.test(id))\n return { ...(nodeIds.length ? { nodeIds } : {}), ...(paths.length ? { paths } : {}) }\n }\n const violations: AiDoctrineViolation[] = []\n if (filler.length) {\n violations.push({\n rule: 14,\n code: 'filler-copy',\n message:\n \"This leaves filler copy. Write the real words in the site's voice, from what the brief and the site already say.\",\n ...at(filler),\n })\n }\n if (judged.length) {\n violations.push({\n rule: 14,\n code: 'judgment-words',\n message:\n 'This copy calls the work simple or cheap, which reads as a judgment to an agency or enterprise audience. Say what it does instead.',\n ...at(judged),\n })\n }\n return violations\n}\n\n/** Every piece of copy a tree carries, with the node it sits on. */\nexport function aiTreeCopy(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiCopySample[] {\n const samples: AiCopySample[] = []\n for (const { id, node } of walkTree(tree)) {\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'text' && typeof value === 'string' && value.trim()) {\n samples.push({ at: id, text: value })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n const type = declared[name] ?? 'text'\n if ((type === 'text' || type === 'richText') && typeof value === 'string') {\n samples.push({ at: id, text: value })\n }\n }\n }\n }\n return samples\n}\n\n/**\n * The props a heading, a subhead or a body text shows as a line a reader\n * reads, by element. A button's or a link's label, a form field's label, a\n * run of inline text inside a sentence and every accessible name are not\n * lines, and how they end is not held.\n */\nconst LINE_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiTypography: ['children'],\n muiListItemText: ['primary', 'secondary'],\n muiCardHeader: ['title', 'subheader'],\n muiAccordionSummary: ['children'],\n emailText: ['children'],\n}\n\n/** Text styles that label rather than say: a caption, an overline, a micro label. */\nconst LABEL_VARIANTS = new Set(['caption', 'overline', 'micro'])\n\n/**\n * Words no finished line ends on: an article, or a conjunction that joins two\n * parts. \"a\" counts only in lowercase, since \"Plan A\" ends on a name.\n */\nconst DANGLING_WORDS = new Set(['an', 'the', 'and', 'or', 'but', 'nor', '&'])\n\n/**\n * Words that open a phrase. A title may end on one it strands, as \"What we\n * help with\" does, but a line that ends on one right after a comma or a dash\n * opened a phrase it never wrote: \"…that matter most, with\".\n */\nconst OPENING_WORDS = new Set([\n 'about',\n 'across',\n 'after',\n 'against',\n 'along',\n 'among',\n 'as',\n 'at',\n 'because',\n 'before',\n 'between',\n 'by',\n 'for',\n 'from',\n 'if',\n 'in',\n 'into',\n 'like',\n 'of',\n 'on',\n 'onto',\n 'since',\n 'so',\n 'than',\n 'that',\n 'through',\n 'to',\n 'toward',\n 'towards',\n 'unless',\n 'until',\n 'upon',\n 'via',\n 'when',\n 'where',\n 'whereas',\n 'while',\n 'with',\n 'within',\n 'without',\n])\n\n/** A line that closes itself: a sentence's end, a closing quote or bracket, or a colon that introduces what follows. */\nconst CLOSED_LINE = /[.!?…:;\"'”’»)\\]]$/\n\n/**\n * The word a line ends on when that word leaves it unfinished (AGL-3072), or\n * `null`. A line that closes itself, ends on a binding or a bracketed fact the\n * member fills, or ends on any other word, is finished as far as a check can\n * tell. Exported for the specs that hold the closed list.\n */\nexport function aiDanglingWord(line: string): string | null {\n const text = line.trim()\n if (!text || CLOSED_LINE.test(text)) return null\n const word = /(?:^|[^A-Za-z&'’])([A-Za-z]+|&)$/.exec(text)?.[1]\n if (!word) return null\n const lower = word.toLowerCase()\n if (word === 'a' || DANGLING_WORDS.has(lower)) return word\n // A comma, a semicolon or a dash breaks the line before the word; the hyphen\n // of \"Drop-in\" or \"Add-on\" joins one word and breaks nothing.\n const before = text.slice(0, text.length - word.length)\n return OPENING_WORDS.has(lower) && /(?:[,;—–]|\\s-)\\s*$/.test(before) ? word : null\n}\n\n/** The last words of a line, as a re-ask quotes them. */\nfunction lineTail(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 6 ? `…${words.slice(-6).join(' ')}` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut short (AGL-3072). Copy in the site's voice is\n * finished copy: a heading, a subhead or a body text that ends on an article\n * or a joining conjunction, or on a word that opens a phrase right after a\n * comma, with no closing punctuation, reads as a sentence cut off mid-thought.\n * A live About page's hero subhead ended \"…that matter most, with\". A closed\n * list of words, on the lines a reader reads, keeps it deterministic: a\n * label, a button, a caption and a bracketed fact are never held to it.\n */\nexport function detectDanglingWords(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const found: Array<{ id: string; line: string; word: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const props = LINE_PROPS[node.componentId]\n if (!props) continue\n if (node.componentId === 'muiTypography' && LABEL_VARIANTS.has(String(node.props?.['variant'] ?? ''))) continue\n if (node.componentId === 'emailText' && node.props?.['variant'] === 'caption') continue\n for (const name of props) {\n const line = node.props?.[name]\n const word = typeof line === 'string' ? aiDanglingWord(line) : null\n if (word) found.push({ id, line: line as string, word })\n }\n }\n if (!found.length) return []\n const [first] = found\n return [\n {\n rule: 14,\n code: 'dangling-word',\n message: `\"${lineTail(first.line)}\" has no closing punctuation, and its last word, \"${first.word}\", leaves the sentence unfinished. Finish the sentence, or end the line before \"${first.word}\".`,\n nodeIds: unique(found.map((entry) => entry.id)),\n },\n ]\n}\n\n/** The labels a button or a link shows, beside the lines: cut, they read as broken too. */\nconst LABEL_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiButton: ['children'],\n muiScreenLink: ['children'],\n emailButton: ['children'],\n}\n\n/** The line the palette validator writes when it cuts a prop at its ceiling. */\nconst CUT_REPAIR = /^(.+)\\.([A-Za-z0-9_]+) was over (\\d+) characters; truncated$/\n\n/** The first words of a line, as a re-ask quotes them. */\nfunction lineHead(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 8 ? `${words.slice(0, 8).join(' ')}…` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut at its ceiling (AGL-3076). The palette validator\n * holds copy to a ceiling for its role and cuts what runs past it, and says so\n * only in its repairs. A cut line is unfinished wherever the cut falls, after\n * a word or inside one, and a heading style's ceiling of\n * `AI_TEXT_LIMITS.headline` characters is one the catalog never shows a model:\n * a live About page's hero subhead, a Typography in the h5 style, was cut at\n * 120 characters to \"…that matter most, with\". So a heading, a subhead, a body\n * line, or a button's or a link's label the validator cut is refused, with a\n * re-ask naming the ceiling.\n *\n * `repairs` are the palette validator's, naming nodes by the ids of the tree\n * it was given, `written`; `idOf` turns such an id into the id the violation\n * names.\n */\nexport function detectCutLines(\n repairs: readonly string[],\n written: Readonly<Record<string, unknown>>,\n idOf: (id: string) => string = (id) => id,\n): AiDoctrineViolation[] {\n const cut: Array<{ id: string; line: string; limit: number; heading: boolean }> = []\n for (const repair of repairs) {\n const match = CUT_REPAIR.exec(repair)\n if (!match) continue\n const [, nodeId, name, limit] = match\n const node = written[nodeId]\n if (!isRecord(node) || typeof node['componentId'] !== 'string') continue\n const props = isRecord(node['props']) ? node['props'] : {}\n const shown = LINE_PROPS[node['componentId']] ?? LABEL_PROPS[node['componentId']] ?? []\n const line = props[name]\n if (!shown.includes(name) || typeof line !== 'string') continue\n cut.push({\n id: idOf(nodeId),\n line,\n limit: Number(limit),\n heading: node['componentId'] === 'muiTypography' && isHeadlineVariant(props['variant']),\n })\n }\n if (!cut.length) return []\n const [first] = cut\n const message = first.heading\n ? `A line in a heading style holds at most ${first.limit} characters, and \"${lineHead(first.line)}\" runs past them, so it was cut off where they end. Write it whole within ${first.limit} characters, or give a longer line a subtitle or body style.`\n : `\"${lineHead(first.line)}\" runs past the ${first.limit} characters its element holds, so it was cut off where they end. Write it whole within ${first.limit} characters.`\n return [{ rule: 14, code: 'copy-cut-at-ceiling', message, nodeIds: unique(cut.map((entry) => entry.id)) }]\n}\n\nconst PURE_CONTAINERS = new Set(['muiBox', 'muiStack', 'muiContainer', 'muiGrid', 'section'])\nconst EMBED_COMPONENTS = new Set(['videoEmbed', 'custom-html'])\nconst DUPLICATE_SX_MIN_KEYS = 2\nconst DUPLICATE_SX_MIN_NODES = 4\n\n/**\n * Whether a third-party player is one the confirmed plan lists (AGL-3433). A\n * Video embed is admitted where the plan lists a player, playing the video\n * the brief gave or none yet, which the site owner pastes. Raw HTML never is.\n */\nfunction embedVerdict(\n node: AiDoctrineNode,\n planned: readonly Pick<AiBuildPlanEmbed, 'host' | 'url'>[],\n): 'planned' | 'unplanned' | 'unplanned-link' {\n if (node.componentId !== 'videoEmbed' || !planned.length) return 'unplanned'\n const url = typeof node.props?.['url'] === 'string' ? node.props['url'].trim() : ''\n if (!url) return 'planned'\n const key = aiEmbedVideoKey(url)\n return key && planned.some((embed) => embed.url && aiEmbedVideoKey(embed.url) === key)\n ? 'planned'\n : 'unplanned-link'\n}\n\n/**\n * Containers whose empty state is something they draw themselves, so an empty\n * one is a placement and not a gap (AGL-3716): the Music player, placed with\n * no tracks, asks its owner to add their own; a model never fills it.\n */\nconst OWNS_ITS_EMPTY_STATE: ReadonlySet<string> = new Set(['musicPlayer'])\n\n/**\n * Rule 16. The flattest tree that renders the design: no container that\n * wraps one other container and adds nothing, no empty containers, no inline\n * style repeated where a token or a component prop would carry it, no font\n * beyond the theme's, images lazy below the first, video by poster rather\n * than autoplay, no third-party player the confirmed plan does not list, and\n * none playing a video the brief did not give.\n */\nexport function detectHeavyDocument(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const wrappers: string[] = []\n const empty: string[] = []\n const fonts: string[] = []\n const eager: string[] = []\n const video: string[] = []\n const embeds: string[] = []\n const embedLinks: string[] = []\n const sxSeen = new Map<string, string[]>()\n let images = 0\n for (const { id, node } of visits) {\n const entry = AI_PALETTE[node.componentId]\n const children = (node.nodes ?? []).filter((child) => tree.nodes[child])\n const ownProps = Object.entries(node.props ?? {}).filter(\n ([name, value]) => !(name === 'component' && value === 'div'),\n )\n if (\n id !== tree.rootId &&\n PURE_CONTAINERS.has(node.componentId) &&\n children.length === 1 &&\n PURE_CONTAINERS.has(tree.nodes[children[0]].componentId) &&\n !ownProps.length &&\n !Object.keys(node.sx ?? {}).length\n ) {\n wrappers.push(id)\n }\n const boundForm = node.componentId === 'form' && typeof node.props?.['formId'] === 'string'\n if (entry?.acceptsChildren && !children.length && !boundForm && !OWNS_ITS_EMPTY_STATE.has(node.componentId)) {\n empty.push(id)\n }\n if (outputKind !== 'email' && node.sx?.['fontFamily'] !== undefined) fonts.push(id)\n if (node.componentId === 'image') {\n images += 1\n if (images > 1 && node.props?.['loading'] === 'eager') eager.push(id)\n }\n if (\n node.componentId === 'video' &&\n (node.props?.['autoPlay'] === true ||\n node.props?.['preload'] === 'auto' ||\n (typeof node.props?.['src'] === 'string' && node.props['src'] && !node.props?.['poster']))\n ) {\n video.push(id)\n }\n if (EMBED_COMPONENTS.has(node.componentId)) {\n const verdict = embedVerdict(node, context.plannedEmbeds ?? [])\n if (verdict === 'unplanned') embeds.push(id)\n if (verdict === 'unplanned-link') embedLinks.push(id)\n }\n const sx = node.sx ?? {}\n if (Object.keys(sx).length >= DUPLICATE_SX_MIN_KEYS) {\n const key = JSON.stringify(Object.keys(sx).sort().map((name) => [name, sx[name]]))\n sxSeen.set(key, [...(sxSeen.get(key) ?? []), id])\n }\n }\n const duplicatedSx = [...sxSeen.values()]\n .filter((ids) => ids.length >= DUPLICATE_SX_MIN_NODES)\n .flat()\n const violations: AiDoctrineViolation[] = []\n const add = (code: string, ids: string[], message: string) => {\n if (ids.length) violations.push({ rule: 16, code, message, nodeIds: ids })\n }\n add(\n 'wrapper-in-wrapper',\n wrappers,\n 'A container wraps a single container and adds nothing. Remove the outer one.',\n )\n add('empty-container', empty, 'An element meant to hold content is empty. Remove it, or fill it.')\n add(\n 'duplicated-inline-style',\n duplicatedSx,\n 'The same inline style repeats across elements. Carry it in a theme token or a component prop, once.',\n )\n add('extra-font', fonts, \"This names a font the theme does not load. Use the theme's typography.\")\n add(\n 'eager-image',\n eager,\n 'An image below the first loads eagerly. Leave loading unset so images further down the page load when they are reached.',\n )\n add(\n 'autoplay-video',\n video,\n 'A video loads its file before anyone plays it. Give it a poster, and let it play on click.',\n )\n add(\n 'third-party-embed',\n embeds,\n \"This embeds a third-party player, which loads its host's code on every visit, and the confirmed plan lists none here. Remove it; a film from the media library plays in a Video (video).\",\n )\n add(\n 'embed-link-unplanned',\n embedLinks,\n 'This player plays a video the brief did not give. Use the link the plan lists, or leave the link empty for the site owner to paste.',\n )\n return violations\n}\n\n/** The items a list or a row of cards repeats, as a re-ask names them. */\nconst ITEM_NOUNS: Readonly<Record<string, string>> = { muiListItem: 'list item', muiCard: 'card' }\n\n/** Elements that frame or space what they hold and show nothing of their own. */\nconst FRAME_COMPONENTS = new Set([\n 'div',\n 'section',\n 'muiBox',\n 'muiStack',\n 'muiContainer',\n 'muiGrid',\n 'muiPaper',\n 'muiCard',\n 'muiCardContent',\n 'muiCardActions',\n 'muiListItem',\n 'muiAccordion',\n 'muiAccordionDetails',\n])\n\n/** Elements that show only their words, by the props that hold them. */\nconst WORD_PROPS: Readonly<Record<string, readonly string[]>> = {\n ...LINE_PROPS,\n muiList: ['subheader'],\n muiInlineText: ['children'],\n muiButton: ['children'],\n muiScreenLink: ['children'],\n}\n\n/** Whether a node shows anything of its own: its words, or whatever an element that is neither a frame nor words draws. */\nfunction showsOwn(node: AiDoctrineNode): boolean {\n const words = WORD_PROPS[node.componentId]\n if (words) return words.some((name) => isFilled(node.props?.[name]))\n return !FRAME_COMPONENTS.has(node.componentId)\n}\n\n/**\n * Rule 16, for an item with nothing in it (AGL-3072). A list item or a card\n * that holds elements, none of which shows a word, a picture or anything\n * else, is an empty row or an empty box on the page: a live About page's list\n * of estate planning services ended on a List Item whose List Item Text had\n * no words. An item that holds no element at all is `empty-container`'s, and\n * is not reported twice.\n */\nexport function detectEmptyItems(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const empty: Array<{ id: string; noun: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const noun = ITEM_NOUNS[node.componentId]\n if (!noun || !(node.nodes ?? []).some((child) => tree.nodes[child])) continue\n if (!walkTree({ rootId: id, nodes: tree.nodes }).some((inner) => showsOwn(inner.node))) {\n empty.push({ id, noun })\n }\n }\n if (!empty.length) return []\n const nouns = unique(empty.map((entry) => entry.noun))\n const message =\n nouns.length > 1\n ? 'A list item and a card hold nothing to read or see. Give each its words, or take it out.'\n : nouns[0] === 'list item'\n ? 'A list item holds no words, so its row shows empty. Write the words of its List Item Text, or take the item out.'\n : 'A card holds nothing to read or see. Give it its words, or take the card out.'\n return [{ rule: 16, code: 'empty-item', message, nodeIds: empty.map((entry) => entry.id) }]\n}\n\n// ── Rule 17: the budget, measured ────────────────────────────────────────\n\nexport interface AiOutputScore {\n nodes: number\n /** The stored node map, in the save's own bytes. */\n bytes: number\n /** What the placed library images request, from their recorded sizes. */\n imageBytes: number\n /** Placed images the media library could not size: hot-linked, or no facts supplied. */\n imagesUnmeasured: number\n embeds: number\n fontFamilies: number\n /** An email's rendered HTML; `null` for every other output. */\n emailHtmlBytes: number | null\n}\n\nconst EMAIL_COLUMN_PX = 600\nconst MEDIA_IMAGE_PROPS: Record<string, readonly string[]> = {\n image: ['src'],\n emailImage: ['src'],\n video: ['poster'],\n collectionEntryAuthor: ['image'],\n contentAuthorProfile: ['image'],\n}\n\n/** The variant a slot of this width is served. */\nfunction servedVariantWidth(slotWidth: number | null): number {\n const widest = MEDIA_CDN_VARIANT_WIDTHS[MEDIA_CDN_VARIANT_WIDTHS.length - 1]\n if (!slotWidth) return widest\n return MEDIA_CDN_VARIANT_WIDTHS.find((width) => width >= slotWidth) ?? widest\n}\n\nfunction pixels(value: unknown): number | null {\n const parsed = typeof value === 'number' ? value : Number.parseFloat(String(value ?? ''))\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null\n}\n\nfunction imageRequests(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): Array<{ id: string; bytes: number | null }> {\n const requests: Array<{ id: string; bytes: number | null }> = []\n for (const { id, node } of walkTree(tree)) {\n const named = MEDIA_IMAGE_PROPS[node.componentId] ?? []\n const values = mediaValues(node, context).filter(\n ({ name }) =>\n named.includes(name) || name.startsWith(`${REUSABLE_INSTANCE_PROP_VALUES_KEY}.`),\n )\n for (const { value } of values) {\n const ref = parseMediaRef(value)\n const facts = ref ? context.assets?.[ref.mediaId] : undefined\n if (!facts?.sizeBytes) {\n requests.push({ id, bytes: null })\n continue\n }\n const slot = pixels(node.props?.['width'])\n const variant = servedVariantWidth(\n outputKind === 'email' ? Math.min(slot ?? EMAIL_COLUMN_PX, EMAIL_COLUMN_PX) : slot,\n )\n // A variant is the original scaled down, so its bytes scale with its\n // area; a variant wider than the original is the original.\n const ratio = facts.width ? Math.min(1, variant / facts.width) : 1\n requests.push({ id, bytes: Math.round(facts.sizeBytes * ratio * ratio) })\n }\n }\n return requests\n}\n\n/** The rule-17 measurements of one validated tree. */\nexport function scoreAiOutput(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiOutputScore {\n const visits = walkTree(tree)\n const images = imageRequests(tree, outputKind, context)\n const families = new Set<string>()\n for (const { node } of visits) {\n for (const family of sxValues(node.sx?.['fontFamily'])) {\n if (typeof family === 'string' && family.trim()) families.add(family.trim().toLowerCase())\n }\n }\n let emailHtmlBytes: number | null = null\n if (outputKind === 'email') {\n const { html } = renderEmailHtml({\n nodes: tree.nodes as Parameters<typeof renderEmailHtml>[0]['nodes'],\n rootId: tree.rootId,\n sanitize: (value: string) => sanitizeAuthorHtml(value),\n })\n emailHtmlBytes = new TextEncoder().encode(html).length\n }\n return {\n nodes: visits.length,\n bytes: nodeMapBytes(tree.nodes),\n imageBytes: images.reduce((sum, image) => sum + (image.bytes ?? 0), 0),\n imagesUnmeasured: images.filter((image) => image.bytes === null).length,\n embeds: visits.filter(({ node }) => EMBED_COMPONENTS.has(node.componentId)).length,\n fontFamilies: families.size,\n emailHtmlBytes,\n }\n}\n\nconst METRIC_LABELS: Record<AiBudgetMetric, string> = {\n nodes: 'elements',\n bytes: 'stored size',\n imageBytes: 'image weight',\n embeds: 'third-party embeds',\n fontFamilies: 'extra font families',\n emailHtmlBytes: `rendered size (mail clients clip past ${formatBytes(AI_EMAIL_CLIP_BYTES)})`,\n}\n\nfunction figure(metric: AiBudgetMetric, value: number): string {\n return metric === 'nodes' || metric === 'embeds' || metric === 'fontFamilies'\n ? value.toLocaleString('en-US')\n : formatBytes(value)\n}\n\n/** The parts of a tree that weigh most under one metric, heaviest first. */\nfunction heaviest(\n metric: AiBudgetMetric,\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): string[] {\n switch (metric) {\n case 'bytes':\n case 'emailHtmlBytes':\n return measureNodeMap(tree.nodes).largest.map((entry) => entry.id)\n case 'nodes': {\n const index = indexShapes(tree)\n return index.visits\n .filter((visit) => visit.depth >= 1 && visit.depth <= 2)\n .sort((a, b) => (index.sizeOf.get(b.id) ?? 0) - (index.sizeOf.get(a.id) ?? 0))\n .slice(0, 3)\n .map((visit) => visit.id)\n }\n case 'imageBytes':\n return imageRequests(tree, outputKind, context)\n .filter((image) => image.bytes !== null)\n .sort((a, b) => (b.bytes ?? 0) - (a.bytes ?? 0))\n .slice(0, 3)\n .map((image) => image.id)\n case 'embeds':\n return walkTree(tree)\n .filter(({ node }) => EMBED_COMPONENTS.has(node.componentId))\n .map((visit) => visit.id)\n case 'fontFamilies':\n return walkTree(tree)\n .filter(({ node }) => node.sx?.['fontFamily'] !== undefined)\n .map((visit) => visit.id)\n }\n}\n\nconst BUDGET_METRICS: readonly AiBudgetMetric[] = [\n 'nodes',\n 'bytes',\n 'imageBytes',\n 'embeds',\n 'fontFamilies',\n 'emailHtmlBytes',\n]\n\n/**\n * Rule 17. An output over its kind's budget is refused with the figure, the\n * budget and the heaviest parts named, so the re-ask knows where to cut.\n */\nexport function detectOverBudget(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n tree: AiDoctrineTree,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const budget = AI_OUTPUT_BUDGETS[outputKind]\n const violations: AiDoctrineViolation[] = []\n for (const metric of BUDGET_METRICS) {\n const value = score[metric]\n const limit = budget[metric]\n if (value === null || limit === undefined || value <= limit) continue\n const offenders = heaviest(metric, tree, outputKind, context)\n const parts = offenders.length ? ` The heaviest parts: ${listNames(offenders, tree)}.` : ''\n violations.push({\n rule: 17,\n code: `over-budget-${metric}`,\n message: `This ${outputKind} measures ${figure(metric, value)} of ${METRIC_LABELS[metric]} against a budget of ${figure(metric, limit)}.${parts}`,\n nodeIds: offenders,\n figure: { metric, value, budget: limit },\n })\n }\n return violations\n}\n\n/**\n * What a first visit to a generated output is estimated to transfer.\n *\n * The page half is a MEASUREMENT the platform already holds, not a guess:\n * `ESTIMATED_PAGE_TRANSFER_BYTES` is the first-party weight a published page\n * measured at settle, which `check:page-view-rate` holds against the\n * tenant page budget and the bandwidth meter is priced from. The tenant's\n * real-user vitals (`web-vitals-rum.ts`) report to analytics per visit and\n * are not readable for a draft nobody has visited, so they are not a second\n * source here. On top of that weight go this output's own stored document\n * and the images it places. A component or a layout reports what it adds to\n * a page; an email is not a page load and has none.\n */\nexport function estimateAiOutputLoad(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n): AiLoadEstimate | null {\n if (outputKind === 'email') return null\n const pageBytes =\n outputKind === 'page' || outputKind === 'template' ? ESTIMATED_PAGE_TRANSFER_BYTES : 0\n return {\n pageBytes,\n documentBytes: score.bytes,\n imageBytes: score.imageBytes,\n imagesUnmeasured: score.imagesUnmeasured,\n embeds: score.embeds,\n totalBytes: Math.round(pageBytes + score.bytes + score.imageBytes),\n }\n}\n\n/**\n * A NODE MAP THAT DOES NOT AGREE WITH ITSELF (AGL-3143).\n *\n * A flat node map is two halves that have to match: what each node lists\n * under `nodes`, and what the map holds. A model writing one section in one\n * pass gets them out of step in two ways, and neither reaches it as\n * something it can act on.\n *\n * An element written but listed by nobody is dropped on the way in, so the\n * container that should have held it reads as empty and the answer comes\n * back \"an element meant to hold content is empty — remove it, or fill it\".\n * The content is already written; it is one line away from being placed, and\n * the re-ask does not say so. A live page build was told exactly that of a\n * card grid whose repeated card it had written and not placed; it answered by\n * naming four children and writing one.\n *\n * Which is the other half: a name listed under `nodes` that the map never\n * holds. That one is refused, but by the sanitizer under the palette\n * validator, as `Missing node \"card2\"` — which the door turns into \"the\n * answer could not be used as a section\", with no rule, no node and nothing\n * to change. It cost that page its last attempt and the build stopped three\n * sections in, so the page's form — the thing being measured — was never\n * reached at all.\n *\n * Both are read off the tree AS THE MODEL WROTE IT, before the palette\n * validator drops anything, so a re-ask can quote the node at fault.\n */\nexport function detectDisagreeingNodes(input: unknown): AiDoctrineViolation[] {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return []\n const rootId = input['rootId']\n const nodes = input['nodes']\n if (!isRecord(nodes[rootId])) return []\n const childrenOf = (id: string): string[] => {\n const node = nodes[id]\n const listed = isRecord(node) ? node['nodes'] : undefined\n return Array.isArray(listed) ? listed.filter((child): child is string => typeof child === 'string') : []\n }\n const reached = new Set<string>([rootId])\n const missing = new Map<string, string[]>()\n const queue = [rootId]\n while (queue.length) {\n const id = queue.shift() as string\n for (const child of childrenOf(id)) {\n if (!isRecord(nodes[child])) {\n missing.set(id, [...(missing.get(id) ?? []), child])\n continue\n }\n if (reached.has(child)) continue\n reached.add(child)\n queue.push(child)\n }\n }\n const orphans = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n const violations: AiDoctrineViolation[] = []\n if (missing.size) {\n const named = unique([...missing.values()].flat())\n violations.push({\n rule: null,\n code: 'missing-child',\n message:\n 'This holds elements that were never written, so the answer could not be read. Write each one, or take its name out of the list of what this holds.',\n detail: `Listed under \"nodes\" and missing from the answer: ${named.map((id) => `\"${id}\"`).join(', ')}.`,\n nodeIds: [...missing.keys()],\n })\n }\n if (orphans.length) {\n violations.push({\n rule: 16,\n code: 'orphan-node',\n message:\n 'This element was written, but nothing holds it, so none of it reaches the page. List it under the element it belongs in, or take it out.',\n nodeIds: orphans,\n })\n }\n return violations\n}\n\n/** The key a repeated item is written under (`AI_REPEAT_KEY` in `ai-repeated-items.ts`, which imports this file). */\nconst REPEAT_KEY = 'repeat'\n\n/**\n * A node map that does not agree with itself, settled where it has one\n * reading (AGL-3596), before `detectDisagreeingNodes` reads it. A guided\n * start's Home page stopped on each of these after its re-ask, and each is\n * one line the model left out, not a choice it made.\n *\n * - A name listed under `nodes` that the map never holds is taken out of the\n * list: there is nothing written to place there.\n * - An element written and listed by nobody goes where the model said it\n * goes, when its own `parentId` names an element the tree reaches that can\n * hold it. Failing that, a single such element goes in the single element\n * the tree reaches that can hold elements and holds none, which is the shape\n * of a row whose item was written beside it. Failing both, it is dropped,\n * with everything under it: nothing on the page holds it, and none of it\n * would ever be shown.\n * - A repeated item (`repeat`) is the exception: dropping it would lose every\n * card it draws, so one that cannot be placed is left for the re-ask.\n *\n * Reads and returns the tree as the model wrote it; an input with nothing to\n * settle comes back as the same object.\n */\nexport function aiSettleDisagreeingNodes(input: unknown): unknown {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return input\n const rootId = input['rootId']\n const source = input['nodes']\n if (!isRecord(source[rootId])) return input\n const nodes: Record<string, unknown> = { ...source }\n let changed = false\n const listed = (id: string): unknown[] => {\n const node = nodes[id]\n return isRecord(node) && Array.isArray(node['nodes']) ? node['nodes'] : []\n }\n const setListed = (id: string, children: unknown[]): void => {\n nodes[id] = { ...(nodes[id] as Record<string, unknown>), nodes: children }\n changed = true\n }\n const holds = (id: string): boolean => {\n const node = nodes[id]\n return isRecord(node) && typeof node['componentId'] === 'string' && AI_PALETTE[node['componentId']]?.acceptsChildren === true\n }\n const reach = (): Set<string> => {\n const reached = new Set<string>([rootId])\n const queue = [rootId]\n while (queue.length) {\n for (const child of listed(queue.shift() as string)) {\n if (typeof child !== 'string' || reached.has(child) || !isRecord(nodes[child])) continue\n reached.add(child)\n queue.push(child)\n }\n }\n return reached\n }\n\n // Names that were never written come out of the lists that name them.\n for (const id of Object.keys(nodes)) {\n const children = listed(id)\n const written = children.filter((child) => typeof child !== 'string' || isRecord(nodes[child]))\n if (written.length !== children.length) setListed(id, written)\n }\n\n let reached = reach()\n const orphans = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n if (orphans.length) {\n const inOrphan = new Set(orphans.flatMap((id) => listed(id)))\n const roots = orphans.filter((id) => !inOrphan.has(id))\n const empty = [...reached].filter((id) => id !== rootId && holds(id) && listed(id).length === 0)\n for (const id of roots) {\n const named = (nodes[id] as Record<string, unknown>)['parentId']\n const parent =\n typeof named === 'string' && reached.has(named) && holds(named)\n ? named\n : roots.length === 1 && empty.length === 1\n ? empty[0]\n : null\n if (parent) setListed(parent, [...listed(parent), id])\n }\n reached = reach()\n const unplaced = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n // A repeated item, and what it holds, is kept for the re-ask to place.\n const kept = new Set<string>()\n const queue = unplaced.filter((id) => (nodes[id] as Record<string, unknown>)[REPEAT_KEY] !== undefined)\n while (queue.length) {\n const id = queue.shift() as string\n if (kept.has(id) || !isRecord(nodes[id])) continue\n kept.add(id)\n for (const child of listed(id)) if (typeof child === 'string') queue.push(child)\n }\n for (const id of unplaced) {\n if (kept.has(id)) continue\n delete nodes[id]\n changed = true\n }\n }\n return changed ? { ...input, nodes } : input\n}\n\n\n/** The fewest words a heading cut at a boundary keeps, so a cut never leaves a stub. */\nconst HEADING_CUT_MIN_WORDS = 3\n/** The least share of the ceiling a heading cut at a boundary keeps. */\nconst HEADING_CUT_MIN_SHARE = 0.3\n/** Where a sentence ends: its stop is kept. */\nconst SENTENCE_END = /[.!?](?=\\s)/g\n/** Where a clause ends: the mark is dropped. */\nconst CLAUSE_END = /\\s*(?:[,;:]|\\s[—–-])\\s/g\n\n/**\n * The longest whole part of a heading that fits `limit`: up to the last\n * sentence that ends within it, else the last clause, or `null` where neither\n * does, or where what is left is a stub.\n */\nfunction headingWithin(line: string, limit: number): string | null {\n const keeps = (head: string): boolean =>\n head.split(/\\s+/).length >= HEADING_CUT_MIN_WORDS && head.length >= limit * HEADING_CUT_MIN_SHARE\n for (const [pattern, keepMark] of [\n [SENTENCE_END, true],\n [CLAUSE_END, false],\n ] as const) {\n let best: string | null = null\n for (const match of line.matchAll(pattern)) {\n const head = line.slice(0, (match.index ?? 0) + (keepMark ? match[0].length : 0)).trim()\n if (head.length > limit) break\n best = head\n }\n if (best !== null && keeps(best)) return best\n }\n return null\n}\n\n/**\n * A heading written past the headline ceiling, settled where it has one\n * reading (AGL-3596). The palette validator cuts such a line where the\n * ceiling falls, mid-word, and the check refuses the cut (rule 14,\n * `copy-cut-at-ceiling`); live guided starts' heroes stopped on it after\n * their re-ask. A heading whose first sentence or clause ends within the\n * ceiling is a whole line already, so it is kept to that, its later words\n * dropped: \"Free inspections after a storm, with photos of every shingle we\n * replace and a written…\" becomes \"Free inspections after a storm\". A heading\n * with no such boundary, or whose part within is a stub, is left for the\n * re-ask. Reads and returns the tree as the model wrote it.\n */\nexport function aiSettleCutHeadings(input: unknown): unknown {\n if (!isRecord(input) || !isRecord(input['nodes'])) return input\n const limit = Math.min(AI_PALETTE['muiTypography']?.textLimits?.['children'] ?? Infinity, AI_TEXT_LIMITS.headline)\n let nodes: Record<string, unknown> | null = null\n for (const [id, node] of Object.entries(input['nodes'])) {\n if (!isRecord(node) || node['componentId'] !== 'muiTypography' || !isRecord(node['props'])) continue\n const line = node['props']['children']\n if (!isHeadlineVariant(node['props']['variant']) || typeof line !== 'string') continue\n const trimmed = line.trim()\n if (trimmed.length <= limit || trimmed.includes('{{')) continue\n const head = headingWithin(trimmed, limit)\n if (head === null) continue\n nodes ??= { ...input['nodes'] }\n nodes[id] = { ...node, props: { ...node['props'], children: head } }\n }\n return nodes ? { ...input, nodes } : input\n}\n\n// ── Mechanical rules, settled in code (AGL-3660) ─────────────────────────\n\n/**\n * THE RULES A CHECK WOULD REFUSE FOR AN ATTRIBUTE, SETTLED IN CODE (AGL-3660).\n *\n * A finding whose fix is one attribute, one level or one key, with nothing to\n * decide about what the page says, is applied before the check reads the\n * tree, as `aiSettleGridItems` sizes a container's items. A live Free guided\n * start's Portfolio page (2026-10-10) was refused for rule 16's `eager-image`:\n * the pictures step loaded every photo of the opening section eagerly, the\n * last pass reads the stored page and asks no model, and Try again could only\n * refuse the same page for the same reason. None of these is a choice a model\n * makes better than the code that knows the answer:\n *\n * - `eager-image` (16): only the tree's first image may load eagerly; every\n * later one has `loading` unset, so the renderer loads it when reached;\n * - `autoplay-video` (16), its attribute half: `autoPlay` and `preload: auto`\n * are taken off. A film with no poster still needs a picture, and is left;\n * - `extra-font` (16): an `sx` font family outside an email is taken off, so\n * the element reads the theme's typography;\n * - `multiple-h1` and `skipped-heading` (11): every top-level heading after a\n * page's first renders as an h2 (a layout's all do, a component's after its\n * first), and a heading after it that skips a level renders one below the\n * heading before it. Only the element changes (`component`): the variant,\n * and so the look, is kept. A heading before a page's h1, and a page with no\n * h1, are the model's to mend;\n * - `multiple-main` and `landmark-in-fragment` (11): a `main` landmark after\n * the first, and any in a component, a form or an email, is unset;\n * - `grid-gap` (12): a Grid container's `sx` gap is taken off and becomes its\n * `spacing` where it sets none, a number gap as itself, anything else 2,\n * which is what the re-ask asks for;\n * - `link-color-on-band` (5): a link or a button whose words are drawn in its\n * band's own family is given that family's contrast text as its `sx` color,\n * which is what the re-ask asks for.\n *\n * A tree with nothing to settle comes back as the same object, so settling is\n * idempotent; a node that is changed is copied, never edited in place.\n */\nexport function aiSettleMechanicalRules<T extends AiDoctrineTree>(tree: T, outputKind: AiOutputKind): T {\n if (!tree.nodes[tree.rootId]) return tree\n const nodes: Record<string, AiDoctrineNode> = { ...tree.nodes }\n const copied = new Set<string>()\n const edit = (id: string): AiDoctrineNode => {\n if (!copied.has(id)) {\n const node = nodes[id]\n nodes[id] = {\n ...node,\n ...(node.props ? { props: { ...node.props } } : {}),\n ...(node.sx ? { sx: { ...node.sx } } : {}),\n }\n copied.add(id)\n }\n return nodes[id]\n }\n const unsetProp = (id: string, name: string): void => {\n if (nodes[id].props?.[name] === undefined) return\n delete (edit(id).props as Record<string, unknown>)[name]\n }\n const setProp = (id: string, name: string, value: unknown): void => {\n if (nodes[id].props?.[name] === value) return\n const node = edit(id)\n node.props = { ...(node.props ?? {}), [name]: value }\n }\n const unsetSx = (id: string, name: string): void => {\n if (nodes[id].sx?.[name] === undefined) return\n delete (edit(id).sx as Record<string, unknown>)[name]\n }\n const visits = walkTree(tree)\n const email = outputKind === 'email'\n const framed = !email && outputKind !== 'form'\n const fragment = outputKind === 'component' || email || outputKind === 'form'\n\n let images = 0\n let mains = 0\n for (const { id, node } of visits) {\n // Rule 16: one eager image, the first; the rest load when they are reached.\n if (node.componentId === 'image') {\n images += 1\n if (images > 1 && node.props?.['loading'] === 'eager') unsetProp(id, 'loading')\n }\n // Rule 16: a film loads nothing before it is played.\n if (node.componentId === 'video') {\n if (node.props?.['autoPlay'] === true) unsetProp(id, 'autoPlay')\n if (node.props?.['preload'] === 'auto') unsetProp(id, 'preload')\n }\n // Rule 16: the theme's typography, outside an email.\n if (!email && node.sx?.['fontFamily'] !== undefined) unsetSx(id, 'fontFamily')\n // Rule 11: one main landmark, and none in what is placed inside pages.\n if (elementOf(node) === 'main') {\n mains += 1\n if (fragment || mains > 1) {\n if (node.props?.['component'] === 'main') unsetProp(id, 'component')\n if (node.props?.['element'] === 'main') unsetProp(id, 'element')\n }\n }\n // Rule 12: a container is spaced by its `spacing`, never an sx gap.\n if (framed && node.componentId === GRID && node.props?.['container'] === true) {\n const gap = GRID_GAP_SX_KEYS.find((key) => node.sx?.[key] !== undefined)\n if (gap) {\n const value = node.sx?.[gap]\n for (const key of GRID_GAP_SX_KEYS) unsetSx(id, key)\n if (node.props?.['spacing'] === undefined) setProp(id, 'spacing', typeof value === 'number' ? value : 2)\n }\n }\n }\n\n // Rule 11: the heading outline, in document order.\n if (framed) {\n const headings = visits\n .map((visit) => ({ id: visit.id, level: aiHeadingLevel(nodes[visit.id]) }))\n .filter((entry): entry is { id: string; level: number } => entry.level !== null)\n const page = outputKind === 'page' || outputKind === 'template'\n const firstH1 = headings.findIndex((heading) => heading.level === 1)\n // A page's outline is settled from its h1 on; a layout's and a component's from their first heading.\n const start = page ? firstH1 : 0\n let previous: number | null = page ? 0 : null\n for (let index = Math.max(start, 0); start >= 0 && index < headings.length; index += 1) {\n const heading = headings[index]\n // A page keeps its first h1, a component its first, and a layout none.\n const keepsH1 = outputKind !== 'layout' && index === firstH1\n let level = heading.level === 1 && !keepsH1 ? 2 : heading.level\n previous ??= level - 1\n if (level > previous + 1) level = previous + 1\n if (level !== heading.level) setProp(heading.id, 'component', `h${level}`)\n previous = level\n }\n }\n\n // Rule 5: a link's words in its band's contrast text, read on the tree as settled so far.\n if (framed) {\n const settled: AiDoctrineTree = { rootId: tree.rootId, nodes }\n for (const visit of walkTree(settled)) {\n if (!LINK_COMPONENTS.has(visit.node.componentId)) continue\n const family = linkWordsFamily(visit.node)\n const band = family ? bandOf(settled, visit) : null\n if (!band || band.family !== family) continue\n const node = edit(visit.id)\n node.sx = { ...(node.sx ?? {}), color: `${family}.contrastText` }\n }\n }\n return copied.size ? ({ ...tree, nodes } as T) : tree\n}\n\n/**\n * `aiSettleMechanicalRules` on a tree as the model wrote it, before the\n * palette validator reads it (AGL-3660), as `aiSettleWrittenGridItems` settles\n * its items. Anything that is no flat node map comes back as it was, and a\n * node whose shape is not a palette node's is read as nothing and left as written.\n */\nexport function aiSettleWrittenMechanicalRules(input: unknown, outputKind: AiOutputKind): unknown {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return input\n const readable = Object.entries(input['nodes']).filter(\n ([, node]) =>\n isRecord(node) &&\n typeof node['componentId'] === 'string' &&\n (node['props'] === undefined || isRecord(node['props'])) &&\n (node['sx'] === undefined || isRecord(node['sx'])) &&\n (node['nodes'] === undefined ||\n (Array.isArray(node['nodes']) && node['nodes'].every((child) => typeof child === 'string'))),\n )\n const tree = {\n rootId: input['rootId'],\n nodes: Object.fromEntries(readable) as unknown as Record<string, AiDoctrineNode>,\n }\n const settled = aiSettleMechanicalRules(tree, outputKind)\n return settled === tree ? input : { ...input, nodes: { ...input['nodes'], ...settled.nodes } }\n}\n\nexport interface AiDoctrineTreeReport {\n ok: boolean\n /** The palette validator's result: the tree to store, its repairs and its id map. */\n tree: Extract<AiNodeTreeResult, { ok: true }> | null\n violations: AiDoctrineViolation[]\n score: AiOutputScore | null\n load: AiLoadEstimate | null\n}\n\n/**\n * The whole check on one emitted tree: the palette validator first, then\n * every tree rule, then the budget. `otherPages` are the trees generated\n * beside this one, for the across-pages half of rule 1.\n */\nexport function validateAiDoctrineTree(\n input: unknown,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n otherPages: readonly AiDoctrineTree[] = [],\n): AiDoctrineTreeReport {\n const publish = detectPublishIntent(input)\n // Asked of the answer as written, because the palette validator drops an\n // element nobody lists and refuses a name nobody wrote in words no re-ask\n // can act on (AGL-3143).\n const disagreeing = detectDisagreeingNodes(input)\n if (disagreeing.length) {\n return { ok: false, tree: null, violations: [...disagreeing, ...publish], score: null, load: null }\n }\n const validated = validateAiNodeTree(input, AI_OUTPUT_SURFACE[outputKind], context)\n if (validated.ok === false) {\n return {\n ok: false,\n tree: null,\n violations: [\n {\n rule: null,\n code: `tree-${validated.code}`,\n message: `The answer could not be used as a ${outputKind}.`,\n detail: validated.error,\n },\n ...publish,\n ],\n score: null,\n load: null,\n }\n }\n const tree: AiDoctrineTree = {\n rootId: validated.rootId,\n nodes: validated.nodes as unknown as Record<string, AiDoctrineNode>,\n }\n // The validator's repairs name the nodes as they were written; every finding names the minted ids.\n const minted = new Map(Object.entries(validated.sourceIds).map(([id, source]) => [source, id]))\n const written = isRecord(input) && isRecord(input['nodes']) ? input['nodes'] : {}\n // What the model wrote of a node, by its minted id: the answer this check was\n // given, or what the caller says was written of a tree it stored first.\n const writtenOf = (id: string): unknown => {\n const source = validated.sourceIds[id] ?? id\n return context.writtenNode ? context.writtenNode(source) : written[source]\n }\n // A node as this check was given it, by its minted id: for a page as stored, what the page carries.\n const storedOf = (id: string): unknown => written[validated.sourceIds[id] ?? id]\n const violations = [\n ...publish,\n ...detectRepeatedSubtrees(tree, otherPages, context),\n ...detectLayoutRegions(tree, outputKind),\n ...detectInlineForms(tree, outputKind),\n ...detectLiteralStyles(tree, outputKind),\n ...detectInvisibleLinks(tree, outputKind),\n ...detectOffBrandEmail(tree, outputKind, context.brand),\n ...detectTypedData(tree),\n ...detectUnfilledInstances(tree, context),\n ...detectImageSources(tree, context),\n ...detectUnrelatedScreenLinks(tree, outputKind, context),\n ...detectLinksWithoutDestination(tree, outputKind, context, writtenOf, storedOf),\n ...detectDocumentStructure(tree, outputKind),\n ...detectAdHocWidths(tree, outputKind),\n ...detectUnresponsiveGrids(tree, outputKind, writtenOf),\n ...detectOffVoiceCopy(aiTreeCopy(tree, context), context.framing),\n ...detectCutLines(validated.repairs, written, (id) => minted.get(id) ?? id),\n ...detectDanglingWords(tree),\n ...detectHeavyDocument(tree, outputKind, context),\n ...detectEmptyItems(tree),\n ]\n const score = scoreAiOutput(tree, outputKind, context)\n violations.push(...detectOverBudget(score, outputKind, tree, context))\n return {\n ok: violations.length === 0,\n tree: validated,\n violations,\n score,\n load: estimateAiOutputLoad(score, outputKind),\n }\n}\n\n// ── Plans ────────────────────────────────────────────────────────────────\n\ntype RecordKind =\n | 'component'\n | 'layout'\n | 'template'\n | 'form'\n | 'dataset'\n | 'collection'\n | 'screen'\n\nconst NAME_STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'the',\n 'of',\n 'for',\n 'to',\n 'our',\n 'your',\n 'my',\n 'us',\n 'we',\n 'page',\n 'pages',\n 'section',\n 'new',\n 'site',\n 'block',\n 'main',\n])\n\nfunction nameTokens(value: string): string[] {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map((word) =>\n word.length > 3 && word.endsWith('s') && !word.endsWith('ss') ? word.slice(0, -1) : word,\n )\n .filter((word) => !NAME_STOPWORDS.has(word))\n}\n\n/**\n * Whether two names name the same thing: the same words once filler is\n * dropped, or every word of a name of two or more words inside the other.\n */\nexport function aiNamesMatch(left: string, right: string): boolean {\n const a = new Set(nameTokens(left))\n const b = new Set(nameTokens(right))\n if (!a.size || !b.size) return false\n const [small, large] = a.size <= b.size ? [a, b] : [b, a]\n return (\n [...small].every((word) => large.has(word)) &&\n (small.size === large.size || small.size >= 2)\n )\n}\n\nfunction inventoryKinds(inventory: AiSiteInventory | null): Map<string, RecordKind> {\n const kinds = new Map<string, RecordKind>()\n if (!inventory) return kinds\n const add = (rows: Array<{ id: string }>, kind: RecordKind) => {\n for (const row of rows) kinds.set(row.id, kind)\n }\n add(inventory.components, 'component')\n add(inventory.layouts, 'layout')\n add(inventory.templates, 'template')\n add(inventory.forms, 'form')\n add(inventory.datasets, 'dataset')\n add(inventory.collections, 'collection')\n add(inventory.screens, 'screen')\n return kinds\n}\n\n/** What a plan reference resolves to: an inventory record's kind, or a creation's. */\nfunction refKind(\n ref: string | null,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): RecordKind | AiBuildPlanCreateKind | null {\n if (!ref) return null\n if (isAiPlanNewRef(ref)) return aiPlanCreateFor(plan, ref)?.kind ?? null\n return kinds.get(ref) ?? null\n}\n\nfunction sectionPaths(plan: AiBuildPlan) {\n return plan.screens.flatMap((screen, screenIndex) =>\n screen.sections.map((section, sectionIndex) => ({\n screen,\n screenIndex,\n section,\n path: `screens[${screenIndex}].sections[${sectionIndex}]`,\n })),\n )\n}\n\nconst LAYOUT_REGION_NAME =\n /\\b(?:site header|header|nav(?:igation)?|nav ?bar|footer|announcement(?: bar)?|cookie(?: notice| banner| consent)?|top ?bar)\\b/i\nconst FORM_SECTION_NAME =\n /\\bform\\b|\\bsign[- ]?up\\b|\\bsubscribe\\b|\\bnewsletter\\b|\\bcontact us\\b|\\b(?:get|request) a quote\\b|\\bregist(?:er|ration)\\b|\\b(?:en|in)quiry\\b/i\n\n/**\n * Rule 1 (plan): repeated items place a component, and a section two screens\n * share is one. A workspace that keeps no reusable components draws them in\n * their sections instead (AGL-3030), and nothing is refused.\n *\n * A job whose pages the layout language compiles (`repeatsCompiled`, a\n * build) is not asked for a component for a section's repeated items: the\n * compiler draws them in the section, compact where the plan places none, so\n * the page answers rule 1 itself (AGL-3660). Held to the first half anyway,\n * the canonical build request was refused twice for an About page's three\n * values (AGL-3616). A section two pages share is still one component.\n */\nexport function detectPlanRepeats(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (capabilities?.reusableComponents === false) return []\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const placesComponent = (uses: string[]) =>\n uses.some((ref) => refKind(ref, plan, kinds) === 'component')\n const bound = (uses: string[]) =>\n uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))\n const repeated = capabilities?.repeatsCompiled\n ? []\n : sectionPaths(plan).filter(\n ({ section }) =>\n section.items >= AI_REPEAT_MIN_COUNT && !placesComponent(section.uses) && !bound(section.uses),\n )\n if (repeated.length) {\n violations.push({\n rule: 1,\n code: 'plan-repeated-items',\n message:\n 'A section repeats items without a component. Plan one reusable component for the item, reuse one the site has, or bind the items to data.',\n paths: repeated.map((entry) => entry.path),\n })\n }\n const byName = new Map<string, ReturnType<typeof sectionPaths>>()\n for (const entry of sectionPaths(plan)) {\n const key = nameTokens(entry.section.name).join(' ')\n if (!key || LAYOUT_REGION_NAME.test(entry.section.name)) continue\n byName.set(key, [...(byName.get(key) ?? []), entry])\n }\n for (const entries of byName.values()) {\n const screens = new Set(entries.map((entry) => entry.screenIndex))\n if (screens.size < 2) continue\n const shared = entries\n .map((entry) => entry.section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component'))\n .reduce((common, refs) => common.filter((ref) => refs.includes(ref)))\n if (shared.length) continue\n violations.push({\n rule: 1,\n code: 'plan-section-across-screens',\n message: `The \"${entries[0].section.name}\" section is planned on ${screens.size} pages. Plan it as one reusable component and place it on each.`,\n paths: entries.map((entry) => entry.path),\n })\n }\n return violations\n}\n\n/** The fewest sections of one item, side by side and of one kind, that are one list split apart. */\nexport const AI_SPLIT_LIST_MIN_SECTIONS = 2\n\n/** A section name's label: what comes before a colon or a spaced dash, as \"practice area\" in \"practice area: family law\". */\nconst SECTION_LABEL = /^(.+?)\\s*(?::|\\s[-–—])\\s*\\S/\n\n/** A name for many of what a name names one of. */\nfunction pluralOf(name: string): string {\n const words = name.trim()\n if (/s$/i.test(words)) return words\n return /[^aeiou]y$/i.test(words) ? `${words.slice(0, -1)}ies` : `${words}s`\n}\n\n/**\n * What kind of item a section of one item shows, for telling a list split\n * into sections apart from sections that each show one different thing: the\n * components it places, else the label its name gives the item. `null` when\n * neither says, or when the section binds its item to data.\n */\nfunction sectionItemKind(\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n inventory: AiSiteInventory | null,\n): { key: string; name: string; components: string[] } | null {\n if (section.uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))) return null\n const label = SECTION_LABEL.exec(section.name)?.[1]?.trim() ?? ''\n const components = section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component')\n if (components.length) {\n const [first] = components\n const named = isAiPlanNewRef(first)\n ? aiPlanCreateFor(plan, first)?.name\n : inventory?.components.find((row) => row.id === first)?.name\n return {\n key: `component:${components.map((ref) => ref.toLowerCase()).sort().join('|')}`,\n name: pluralOf(label || named || first),\n components,\n }\n }\n const words = nameTokens(label).join(' ')\n return words ? { key: `label:${words}`, name: pluralOf(label), components: [] } : null\n}\n\n/**\n * Rule 1 (plan): a list is one section whose items repeat (AGL-3071). A\n * section's `items` counts what it repeats, so two or more sections side by\n * side that each show one item of the same kind — the same component, or a\n * name that labels the same kind of item — are one list split apart. A live\n * Free About page planned \"the four areas we practice\" as four sections of one\n * item: none was drawn from the one written-once item a repeated section is\n * built from, and the four came out in three different shapes. The re-ask\n * names the sections and gives the one section to plan instead. Where the\n * workspace keeps reusable components, a list long enough for rule 1 places\n * one for its item, so the section it gives places one too.\n *\n * Sections of several items are never joined: two lists that share a card\n * are two lists, and rule 8 counts each within its own section (AGL-3061).\n */\nexport function detectPlanSplitLists(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n plan.screens.forEach((screen, screenIndex) => {\n let run: Array<{ index: number; kind: NonNullable<ReturnType<typeof sectionItemKind>> }> = []\n const close = () => {\n if (run.length >= AI_SPLIT_LIST_MIN_SECTIONS) {\n const names = run.map(({ index }) => `\"${screen.sections[index].name}\"`)\n const listed = `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n const [{ kind }] = run\n // Rule 1 asks a list this long on a workspace that keeps components to place one for its item.\n const component =\n !kind.components.length &&\n capabilities?.reusableComponents !== false &&\n !capabilities?.repeatsCompiled &&\n run.length >= AI_REPEAT_MIN_COUNT\n const section = { name: kind.name, uses: component ? ['new:<name>'] : kind.components, items: run.length }\n const instead = component\n ? `, placing one reusable component for the item: reuse one the site has by its id, or declare one in create and place it as new:<name>, as in ${JSON.stringify(section)}.`\n : `: ${JSON.stringify(section)}.`\n violations.push({\n rule: 1,\n code: 'plan-split-list',\n message: `The sections ${listed} each show one item of the same kind, so they are one list split apart. Plan them as one section whose ${run.length} items repeat${instead}`,\n paths: run.map(({ index }) => `screens[${screenIndex}].sections[${index}]`),\n })\n }\n run = []\n }\n screen.sections.forEach((section, index) => {\n const kind = section.items === 1 ? sectionItemKind(section, plan, kinds, inventory) : null\n if (!kind || (run.length && run[0].kind.key !== kind.key)) close()\n if (kind) run.push({ index, kind })\n })\n close()\n })\n return violations\n}\n\n/** Where the plan's sections place a record of one kind, as `screens[0].sections[1].uses[0]`. */\nfunction placementsOf(\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n kind: RecordKind,\n): string[] {\n return sectionPaths(plan).flatMap(({ section, path }) =>\n section.uses.flatMap((ref, index) =>\n refKind(ref, plan, kinds) === kind ? [`${path}.uses[${index}]`] : [],\n ),\n )\n}\n\n/** A creation's name as a reference may spell it: letters and digits only. */\nfunction creationKey(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '')\n}\n\n/**\n * A `new:` reference that spells a creation differently — `new:cake-order-form`\n * for \"Cake order form\" (a live bakery plan, 2026-10-07) — is pointed at that\n * creation before the rules read the plan, when exactly one creation matches\n * it with case, spaces and punctuation ignored. Two that match, or none, are\n * left for the rules to ask about.\n *\n * So is a creation named without its prefix — `Contact form` in a section's\n * uses for the \"Contact form\" the plan creates — where the name is no record\n * the site has (AGL-3660). A re-asked plan told to place its form \"by id\"\n * can answer with the form's bare name, which is no reference at all.\n */\nexport function aiSettlePlanRefs(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null = null,\n): AiBuildPlan {\n if (!plan.create.length) return plan\n const kinds = inventoryKinds(inventory)\n const resolve = (ref: string | null): string | null => {\n if (!ref || kinds.has(ref) || aiPlanCreateFor(plan, ref)) return ref\n const key = creationKey(isAiPlanNewRef(ref) ? ref.slice('new:'.length) : ref)\n if (!key) return ref\n const matches = plan.create.filter((entry) => creationKey(entry.name) === key)\n return matches.length === 1 ? `new:${matches[0].name}` : ref\n }\n let changed = false\n const settle = (ref: string | null): string | null => {\n const next = resolve(ref)\n if (next !== ref) changed = true\n return next\n }\n const screens = plan.screens.map((screen) => ({\n ...screen,\n layout: settle(screen.layout),\n template: settle(screen.template),\n sections: screen.sections.map((section) => ({\n ...section,\n uses: section.uses.map((ref) => settle(ref) ?? ref),\n })),\n }))\n return changed ? { ...plan, screens } : plan\n}\n\n/**\n * What customers say, which no dataset of the site's holds: a review, a\n * testimonial, a rating, a quote (AGL-3616). A job never writes them for the\n * people who did not, so a dataset of them is one nothing can seed.\n */\nexport const AI_DATASET_SAID_NAME = /\\b(reviews?|testimonials?|ratings?|quotes?|stars?|endorsements?)\\b/i\n\n/**\n * A plan that creates more datasets than this job may make is settled in\n * code, never re-asked (AGL-3616). The live eval of 2026-10-10 refused a\n * dental practice's plan four times over for a fourth dataset, and a food\n * bank's re-ask for one broke a layout rule its first answer had kept.\n *\n * A dataset of what customers say (`AI_DATASET_SAID_NAME`, in its name or a\n * field) is let go first, whatever the cap: both of those plans made one of\n * testimonials, which nothing may seed.\n *\n * The datasets kept are the most useful: the ones the most sections list,\n * a record template counting double, plan order breaking ties. Each one let\n * go leaves the plan whole — its `new:` reference comes off every section,\n * a record template of it becomes a page of its own, and a section that\n * listed it shows fewer items than rule 8 binds, so its items are written\n * out on the page. Where the job may create no dataset at all, rule 7 still\n * asks, as it does for any creation.\n */\nexport function aiSettlePlanDatasets(plan: AiBuildPlan, capabilities: AiPlanCapabilities | null = null): AiBuildPlan {\n const entry = capabilities?.create.dataset\n if (!entry?.allowed) return plan\n const cap = Math.min(capabilities?.datasetsMax ?? Infinity, entry.left ?? Infinity)\n const datasets = plan.create.filter((one) => one.kind === 'dataset')\n // A dataset a form writes to holds what visitors send (AGL-3616): its\n // fields may well be a rating or a quote request, and nothing seeds it.\n const forForms = aiPlanFormDatasetNames(plan)\n const said = (one: (typeof datasets)[number]) =>\n !forForms.has(one.name.trim().toLowerCase()) &&\n (AI_DATASET_SAID_NAME.test(one.name) || one.fields.some((field) => AI_DATASET_SAID_NAME.test(field)))\n if (!datasets.some(said) && (!Number.isFinite(cap) || datasets.length <= cap)) return plan\n const named = (ref: string | null | undefined, name: string) =>\n !!ref && isAiPlanNewRef(ref) && ref.slice('new:'.length).trim().toLowerCase() === name.trim().toLowerCase()\n // A form's dataset counts as much as a record template: the form the\n // person asked for is built around it.\n const score = (name: string) =>\n (forForms.has(name.trim().toLowerCase()) ? 2 : 0) +\n plan.screens.reduce(\n (total, screen) =>\n total +\n (named(screen.record?.dataset, name) ? 2 : 0) +\n screen.sections.filter((section) => section.uses.some((ref) => named(ref, name))).length,\n 0,\n )\n const ranked = datasets\n .filter((one) => !said(one))\n .map((one, index) => ({ name: one.name, index, score: score(one.name) }))\n .sort((a, b) => b.score - a.score || a.index - b.index)\n const kept = new Set(ranked.slice(0, Math.max(0, cap)).map((one) => one.name.trim().toLowerCase()))\n const dropped = new Set(datasets.map((one) => one.name.trim().toLowerCase()).filter((name) => !kept.has(name)))\n const isDropped = (ref: string | null | undefined) => [...dropped].some((name) => named(ref, name))\n return {\n ...plan,\n create: plan.create\n .filter((one) => one.kind !== 'dataset' || !dropped.has(one.name.trim().toLowerCase()))\n // A form whose dataset was let go sends its submissions to the Inbox only.\n .map((one) => (one.kind === 'form' && isDropped(one.writesTo) ? withoutWritesTo(one) : one)),\n screens: plan.screens.map((screen) => ({\n ...screen,\n record: screen.record && isDropped(screen.record.dataset) ? null : screen.record,\n sections: screen.sections.map((section) =>\n section.uses.some(isDropped)\n ? {\n ...section,\n uses: section.uses.filter((ref) => !isDropped(ref)),\n items: Math.min(section.items, AI_TYPED_LIST_MIN_ITEMS - 1),\n }\n : section,\n ),\n })),\n }\n}\n\n/** A creation with no `writesTo`, as a plan that never said one reads. */\nfunction withoutWritesTo<T extends { writesTo?: string | null }>(creation: T): T {\n const rest = { ...creation }\n delete rest.writesTo\n return rest\n}\n\n/**\n * A form's dataset, settled in code before the rules read the plan\n * (AGL-3616, Zach 2026-10-10: Aglyn AI's forms write to its datasets).\n *\n * - A `writesTo` that names nothing the form can write to comes off: a\n * `new:` of no dataset this plan creates, an id the inventory does not\n * hold, or a dataset this job may not create. The form is then the\n * form it always was, its submissions in the Inbox. A dataset the\n * inventory holds, named by its name rather than its id, is given its id.\n * - A dataset this plan creates for a form holds the people who send it:\n * no page lists it and none is its record template, so its `new:` comes\n * off every section and record that named it, and a section that listed\n * it shows fewer items than rule 8 binds.\n */\nexport function aiSettlePlanFormDatasets(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n if (!plan.create.some((one) => one.kind === 'form' && one.writesTo)) return plan\n const held = inventory?.datasets ?? []\n const creatable = !capabilities || capabilities.create.dataset.allowed\n let changed = false\n const create = plan.create.map((one) => {\n if (one.kind !== 'form' || !one.writesTo) return one\n const ref = one.writesTo.trim()\n if (isAiPlanNewRef(ref)) {\n if (creatable && aiPlanCreateFor(plan, ref)?.kind === 'dataset') return one\n // A build's dataset item, which the data plugin's operation makes.\n if (aiPlanItemFor(plan, ref)?.op === AI_PLAN_DATASET_ITEM_OP) return one\n } else {\n if (held.some((row) => row.id === ref)) return one\n const byName = held.find((row) => aiNamesMatch(row.name, ref))\n if (byName) {\n changed = true\n return { ...one, writesTo: byName.id }\n }\n }\n changed = true\n return withoutWritesTo(one)\n })\n const settled = { ...plan, create }\n const forForms = aiPlanFormDatasetNames(settled)\n const listsOne = (ref: string | null | undefined) =>\n isAiPlanNewRef(ref) && forForms.has(ref.slice('new:'.length).trim().toLowerCase())\n const screens = plan.screens.map((screen) => {\n const record = screen.record && listsOne(screen.record.dataset) ? null : screen.record\n const sections = screen.sections.map((section) =>\n section.uses.some(listsOne)\n ? {\n ...section,\n uses: section.uses.filter((ref) => !listsOne(ref)),\n items: Math.min(section.items, AI_TYPED_LIST_MIN_ITEMS - 1),\n }\n : section,\n )\n if (record === screen.record && sections.every((section, index) => section === screen.sections[index])) return screen\n changed = true\n return { ...screen, record, sections }\n })\n return changed ? { ...settled, screens } : plan\n}\n\n/**\n * A page that names no layout, on a site where only one layout can frame it,\n * is put in that layout before the rules read the plan (2026-10-07). The\n * model sometimes leaves one page's layout empty — a live run's bookkeeper\n * plan did, beside a layout it created — and rule 2 refused the whole plan\n * for a choice with one answer. That answer exists only on a site with no\n * layout whose plan creates exactly one, which is every guided start. Where\n * the site has a layout of its own, a page that names none may mean another,\n * so the rule still asks.\n */\nexport function aiSettlePlanLayouts(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n if (!inventory || inventory.layouts.length > 0 || !plan.screens.length) return plan\n const kinds = inventoryKinds(inventory)\n const created = plan.create.filter((entry) => entry.kind === 'layout')\n const unlaid = plan.screens.filter((screen) => refKind(screen.layout, plan, kinds) !== 'layout')\n if (!unlaid.length) return plan\n if (created.length === 1) {\n const only = `new:${created[0].name}`\n return {\n ...plan,\n screens: plan.screens.map((screen) =>\n refKind(screen.layout, plan, kinds) === 'layout' ? screen : { ...screen, layout: only },\n ),\n }\n }\n // No layout planned at all on a site with none (a live dental plan named\n // \"default\" for both pages, twice): the site's one shared header and footer\n // is planned for it, with every region a layout is built of, and every page\n // goes in it. Only where this job may create a layout.\n const mayCreateLayout = !capabilities || capabilities.create.layout.allowed\n if (created.length > 0 || !mayCreateLayout) return plan\n const taken = new Set(plan.create.map((entry) => entry.name.toLowerCase()))\n const name = taken.has('site layout') ? 'Site header and footer' : 'Site layout'\n return {\n ...plan,\n create: [\n {\n kind: 'layout',\n name,\n why: 'Every page shares one header, navigation and footer.',\n duplicateOf: null,\n fields: ['header', 'nav', 'main', 'footer'],\n },\n ...plan.create,\n ],\n screens: plan.screens.map((screen) => ({ ...screen, layout: `new:${name}` })),\n }\n}\n\n/**\n * A page section that is a layout region — a header, navigation or footer,\n * read by the name rule 2's `plan-layout-region-section` reads — is taken off\n * the page before the rules read the plan (AGL-3750). The region is already\n * the layout's, so the rule's own answer, \"take the section off the page\", is\n * the only one: a live Free start of 2026-10-12 (a bakery that sells cakes to\n * order) planned a Header and a Footer on its pages three times and stopped.\n *\n * Only a section that places nothing, or nothing but a layout (which rule 2\n * refuses placing as well), is taken off: one that places a form or a\n * component may be a band misnamed, so the rule still asks. A page whose\n * every section is a region keeps them all, and is re-asked as before, since\n * a page of no sections has no answer here. A home this leaves under its\n * fewest sections, or a Free plan still past its wall, is the existing\n * checks' to settle or refuse.\n */\nexport function aiSettlePlanLayoutRegionSections(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiBuildPlan {\n const kinds = inventoryKinds(inventory)\n const removable = (section: AiBuildPlan['screens'][number]['sections'][number]) =>\n LAYOUT_REGION_NAME.test(section.name) &&\n section.uses.every((ref) => refKind(ref, plan, kinds) === 'layout')\n let changed = false\n const screens = plan.screens.map((screen) => {\n const kept = screen.sections.filter((section) => !removable(section))\n if (kept.length === screen.sections.length || !kept.length) return screen\n changed = true\n return { ...screen, sections: kept }\n })\n return changed ? { ...plan, screens } : plan\n}\n\n/** A saved form a plan section could place: one the plan creates, or one the site has. */\ninterface AiPlanFormChoice {\n /** As a section's uses names it: `new:<name>` or the inventory id. */\n ref: string\n name: string\n created: boolean\n}\n\n/** Every saved form a plan could place, the plan's own creations first. */\nfunction planFormChoices(plan: AiBuildPlan, inventory: AiSiteInventory | null): AiPlanFormChoice[] {\n return [\n ...plan.create\n .filter((entry) => entry.kind === 'form')\n .map((entry) => ({ ref: `new:${entry.name}`, name: entry.name, created: true })),\n ...(inventory?.forms ?? []).map((form) => ({ ref: form.id, name: form.name, created: false })),\n ]\n}\n\n/** The form a plan's own words would name for a section's reference, so placements count alike. */\nfunction formChoiceKey(ref: string, plan: AiBuildPlan): string {\n const created = isAiPlanNewRef(ref) ? aiPlanCreateFor(plan, ref) : undefined\n return created ? `new:${created.name}` : ref\n}\n\n/**\n * The form a section that collects answers places: the one whose name shares\n * the most words with the section's (\"Commission inquiry\" → \"Commission\n * inquiry form\"), then the one the plan already places most, then the plan's\n * own creation over a form the site has. `null` when there is none.\n */\nfunction bestPlanForm(\n section: AiBuildPlanSection,\n choices: readonly AiPlanFormChoice[],\n placed: ReadonlyMap<string, number>,\n): AiPlanFormChoice | null {\n const words = new Set(nameTokens(section.name).filter((word) => word !== 'form'))\n const score = (choice: AiPlanFormChoice) =>\n nameTokens(choice.name).filter((word) => word !== 'form' && words.has(word)).length\n const ranked = [...choices].sort(\n (a, b) =>\n score(b) - score(a) ||\n (placed.get(b.ref) ?? 0) - (placed.get(a.ref) ?? 0) ||\n Number(b.created) - Number(a.created),\n )\n return ranked[0] ?? null\n}\n\n/** The contact form a plan is given when a section collects answers and the plan makes no form. */\nexport const AI_PLAN_SETTLED_FORM = {\n name: 'Contact form',\n why: 'Visitors need a way to reach the owner, and the site has no saved form for it.',\n fields: ['name', 'email', 'message'],\n} as const\n\n/**\n * A section that collects answers and places no saved form is given one\n * before the rules read the plan (AGL-3660), rather than failing the build.\n * A production guided start for a ceramic artist's portfolio (2026-10-09,\n * five pages, 94 credits refunded) planned a section that asks for\n * commissions on its work page without placing the contact form the plan\n * made for its Contact page; the answer and its re-ask both did, and rule 3\n * failed the whole site for one section.\n *\n * The section places, in order of preference:\n * 1. the form whose name best matches it, among those the plan creates and\n * the site has, preferring one the plan already places — so a guided\n * start, which makes one form, places that same form again rather than a\n * second one;\n * 2. where there is no form at all and this job may create one, a form the\n * plan now creates: named for the `new:` reference the section already\n * holds when it names a form it never declared, the contact form\n * otherwise.\n *\n * Nothing is taken out of the plan: the section keeps its name, its other\n * uses and its items. Where the site has no form and the job may create none,\n * rule 3 asks for nothing (AGL-3596), and neither does this. A section whose\n * uses are already full is left for the rule to ask about.\n */\nexport function aiSettlePlanForms(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n if (!aiPlanCanPlaceForm(inventory, capabilities)) return plan\n const kinds = inventoryKinds(inventory)\n const unbound = (current: AiBuildPlan) =>\n sectionPaths(current).filter(\n ({ section }) =>\n FORM_SECTION_NAME.test(section.name) &&\n section.uses.length < AI_BUILD_PLAN_LIMITS.uses &&\n !section.uses.some((ref) => refKind(ref, current, kinds) === 'form'),\n )\n const first = unbound(plan)\n if (!first.length) return plan\n let next = plan\n if (!planFormChoices(next, inventory).length) {\n if (capabilities && !capabilities.create.form.allowed) return plan\n // A form the section already names and the plan never declared is the form it meant.\n const named = first\n .flatMap(({ section }) => section.uses)\n .find((ref) => isAiPlanNewRef(ref) && !aiPlanCreateFor(next, ref) && !aiPlanItemFor(next, ref))\n const taken = new Set(next.create.map((entry) => entry.name.toLowerCase()))\n const name = named\n ? named.slice('new:'.length).trim()\n : taken.has(AI_PLAN_SETTLED_FORM.name.toLowerCase())\n ? 'Get in touch form'\n : AI_PLAN_SETTLED_FORM.name\n next = {\n ...next,\n create: [\n ...next.create,\n {\n kind: 'form',\n name,\n why: AI_PLAN_SETTLED_FORM.why,\n duplicateOf: null,\n fields: [...AI_PLAN_SETTLED_FORM.fields],\n },\n ],\n }\n }\n const choices = planFormChoices(next, inventory)\n const placed = new Map<string, number>()\n for (const { section } of sectionPaths(next)) {\n for (const ref of section.uses) {\n if (refKind(ref, next, kinds) !== 'form') continue\n const key = formChoiceKey(ref, next)\n placed.set(key, (placed.get(key) ?? 0) + 1)\n }\n }\n const settle = new Map<string, string>()\n for (const { section, path } of unbound(next)) {\n const form = bestPlanForm(section, choices, placed)\n if (form) settle.set(path, form.ref)\n }\n if (!settle.size) return next\n return {\n ...next,\n screens: next.screens.map((screen, screenIndex) => ({\n ...screen,\n sections: screen.sections.map((section, sectionIndex) => {\n const ref = settle.get(`screens[${screenIndex}].sections[${sectionIndex}]`)\n if (!ref) return section\n // The undeclared reference the form was named for now names it; any other stays.\n const uses = section.uses.some((use) => formChoiceKey(use, next) === ref) ? section.uses : [...section.uses, ref]\n return { ...section, uses }\n }),\n })),\n }\n}\n\n/** The forms a section that collects answers can place, as the re-ask names them. */\nfunction planFormChoicesText(plan: AiBuildPlan, inventory: AiSiteInventory | null): string {\n const choices = planFormChoices(plan, inventory)\n if (!choices.length) return 'Plan one in create as a form, and put new:<its name> in the section\\'s uses.'\n return `Put one of these in the section's uses: ${choices\n .map((choice) => (choice.created ? choice.ref : `${choice.ref} (${choice.name})`))\n .join(', ')}.`\n}\n\n/**\n * Rule 2 (plan): every screen declares a layout, no section is a copy of a\n * layout region, and no section places a layout, which frames a whole screen\n * (AGL-3040). A site with no layout, where this job may not create one\n * (AGL-3030), has nothing to declare: its screens name none, and a screen\n * that names none is not refused there. A screen whose layout is a `new:`\n * reference the plan never creates is refused here, and only here.\n */\nexport function detectPlanLayoutRegions(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const mayCreateLayout = !capabilities || capabilities.create.layout.allowed\n const noLayoutToName = !mayCreateLayout && !(inventory?.layouts.length ?? 0)\n const unlaid = plan.screens\n .map((screen, index) => ({ screen, index }))\n .filter(\n ({ screen }) =>\n refKind(screen.layout, plan, kinds) !== 'layout' &&\n !(noLayoutToName && screen.layout === null),\n )\n if (unlaid.length) {\n violations.push({\n rule: 2,\n code: 'plan-screen-without-layout',\n message: noLayoutToName\n ? 'A page names a layout the site does not have, and this job may not create one. Leave the layout empty.'\n : mayCreateLayout\n ? \"A page names no layout the site has or the plan creates. Put every page in the site's layout, or plan one.\"\n : 'A page names no layout the site has, and this job may not create one. Put every page in a layout the site has.',\n paths: unlaid.map(({ index }) => `screens[${index}].layout`),\n })\n }\n const regions = sectionPaths(plan).filter(({ section }) =>\n LAYOUT_REGION_NAME.test(section.name),\n )\n if (regions.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-region-section',\n message:\n 'A page plans its own header, navigation or footer. Those live in the layout; take the section off the page.',\n paths: regions.map((entry) => entry.path),\n })\n }\n const placed = placementsOf(plan, kinds, 'layout')\n if (placed.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-in-section',\n message:\n \"A section places a layout. A layout frames a whole page and is never placed inside one: name it as the page's layout, and take it out of the section's uses.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/**\n * Rule 3 (plan): a section that collects answers places a saved form — one\n * the site has, or one the plan creates on the Forms page. Where neither is\n * possible (the site has no form and this job may create none), the page\n * places no form, and a section named for one is not refused: there is\n * nothing it could place (AGL-3596). It is never drawn inline instead.\n */\nexport function detectPlanInlineForms(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (!aiPlanCanPlaceForm(inventory, capabilities)) return []\n const kinds = inventoryKinds(inventory)\n const unbound = sectionPaths(plan).filter(\n ({ section }) =>\n FORM_SECTION_NAME.test(section.name) &&\n !section.uses.some((ref) => refKind(ref, plan, kinds) === 'form'),\n )\n return unbound.length\n ? [\n {\n rule: 3,\n code: 'plan-form-not-placed',\n message:\n 'A section collects answers without a form. Reuse a form from the Forms page, or plan one there, and place it by id.',\n detail: planFormChoicesText(plan, inventory),\n paths: unbound.map((entry) => entry.path),\n },\n ]\n : []\n}\n\n/** Pages sharing one shape this many times are a template applied. */\nexport const AI_SIMILAR_PAGES_MIN = 3\n\n/**\n * Rule 4 (plan): three or more screens with the same sections share one\n * template, and a template is what a screen applies, never what one of its\n * sections places (AGL-3040).\n *\n * A record-bound screen (AGL-3475) is the other answer: one page that the\n * data plugin serves once per record of a dataset. It stands for its pages\n * rather than copying them, so it joins no group, and it is held to naming a\n * dataset the site has or the plan creates, and a base no other record page\n * of the plan takes — the save route refuses a second template of one\n * dataset or one base, so a plan that promises either promises a binding the\n * member cannot save.\n */\nexport function detectUntemplatedSimilarPages(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const groups = new Map<string, number[]>()\n plan.screens.forEach((screen, index) => {\n if (screen.record || screen.sections.length < 2) return\n const signature = screen.sections\n .map((section) => nameTokens(section.name).join(' '))\n .join('|')\n groups.set(signature, [...(groups.get(signature) ?? []), index])\n })\n const violations: AiDoctrineViolation[] = []\n for (const indexes of groups.values()) {\n if (indexes.length < AI_SIMILAR_PAGES_MIN) continue\n const templates = new Set(indexes.map((index) => plan.screens[index].template))\n if (templates.size === 1 && !templates.has(null)) continue\n violations.push({\n rule: 4,\n code: 'plan-similar-pages',\n message: `${indexes.length} pages share one shape. Plan one template and apply it ${indexes.length} times with each page's copy, or bind it to a collection; when the pages are records of a dataset, plan one page bound to it by \"record\" instead.`,\n paths: indexes.map((index) => `screens[${index}].template`),\n })\n }\n const bound = plan.screens\n .map((screen, index) => ({ record: screen.record, index }))\n .filter((entry): entry is { record: AiBuildPlanRecord; index: number } => Boolean(entry.record))\n const unknown = bound.filter(({ record }) => refKind(record.dataset, plan, kinds) !== 'dataset')\n if (unknown.length) {\n violations.push({\n rule: 4,\n code: 'plan-record-dataset',\n message:\n 'A record page names no dataset the site has or the plan creates. Name one from the site inventory, or plan the dataset and name it as new:<name>.',\n paths: unknown.map(({ index }) => `screens[${index}].record.dataset`),\n })\n }\n const shared = bound.filter(({ record, index }) =>\n bound.some(\n (other) =>\n other.index !== index &&\n (other.record.base === record.base || other.record.dataset === record.dataset),\n ),\n )\n if (shared.length) {\n violations.push({\n rule: 4,\n code: 'plan-record-shared',\n message:\n 'Two record pages share a dataset or a base. A dataset has one record template on a site, and each base serves one: keep one page, or give each its own dataset and base.',\n paths: shared.map(({ index }) => `screens[${index}].record`),\n })\n }\n const placed = placementsOf(plan, kinds, 'template')\n if (placed.length) {\n violations.push({\n rule: 4,\n code: 'plan-template-in-section',\n message:\n \"A section places a template. A template is applied to a whole page and is never placed inside one: take it out of the section's uses, and name it as the page's template only when the whole page is built from it.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/** Rule 5 (plan): a color value belongs only in a theme change. */\nexport function detectPlanLiteralColors(plan: AiBuildPlan): AiDoctrineViolation[] {\n const paths: string[] = []\n plan.create.forEach((entry, index) => {\n if (entry.kind === 'theme-change') return\n if (hasLiteralColor(entry.why) || entry.fields.some(hasLiteralColor)) {\n paths.push(`create[${index}]`)\n }\n })\n for (const { section, path } of sectionPaths(plan)) {\n if (hasLiteralColor(section.name)) paths.push(path)\n }\n return paths.length\n ? [\n {\n rule: 5,\n code: 'plan-literal-color',\n message:\n 'The plan writes a color by value outside a theme change. Name theme tokens, and plan a theme change for a color the theme lacks.',\n paths,\n },\n ]\n : []\n}\n\nconst REUSE_BEFORE_CREATE_KINDS: ReadonlySet<AiBuildPlanCreateKind> = new Set([\n 'component',\n 'layout',\n 'form',\n 'dataset',\n])\n\n/** Rule 7 (plan): reuse names real records, and a creation is an exception that says why. */\nexport function detectCreateBeforeReuse(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unknown = plan.reuse\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => entry.kind !== 'theme' && kinds.get(entry.id) !== entry.kind)\n if (unknown.length) {\n violations.push({\n rule: 7,\n code: 'plan-reuse-unknown',\n message:\n 'The plan reuses something the site does not have. Reuse only what the site inventory lists.',\n paths: unknown.map(({ index }) => `reuse[${index}]`),\n })\n }\n const unexplained = plan.create\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => !entry.why.trim())\n if (unexplained.length) {\n violations.push({\n rule: 7,\n code: 'plan-create-without-why',\n message: 'The plan creates something without saying why nothing the site has will do.',\n paths: unexplained.map(({ index }) => `create[${index}].why`),\n })\n }\n const rows: Record<string, Array<{ id: string; name: string }>> = {\n component: inventory?.components ?? [],\n layout: inventory?.layouts ?? [],\n form: inventory?.forms ?? [],\n dataset: inventory?.datasets ?? [],\n }\n plan.create.forEach((entry, index) => {\n if (!REUSE_BEFORE_CREATE_KINDS.has(entry.kind) || entry.duplicateOf) return\n const existing = rows[entry.kind].find((row) => aiNamesMatch(row.name, entry.name))\n if (!existing) return\n violations.push({\n rule: 7,\n code: 'plan-duplicates-existing',\n message: `The site already has a ${entry.kind} named \"${existing.name}\". Reuse it, or propose extending it, instead of creating \"${entry.name}\".`,\n paths: [`create[${index}]`],\n })\n })\n return violations\n}\n\n/**\n * Rule 7 (plan): a plan creates only what the request says this job may\n * create on this site (AGL-3030) — what the workspace's plan includes, what\n * the site has room for, and what the job builds itself. One violation a\n * creation, each saying why and what to do instead.\n */\nexport function detectPlanUncreatable(\n plan: AiBuildPlan,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n if (!capabilities) return []\n return aiPlanUncreatable(plan, capabilities).map((entry) => ({\n rule: 7,\n code: 'plan-create-not-allowed',\n message: entry.message,\n paths: [entry.path],\n }))\n}\n\n/**\n * What a section most likely meant by a creation it places and the plan never\n * declares, so the refusal can name the way out: a form where the reference\n * or its section reads as one and the section places no form yet, otherwise\n * a component. Only the message reads it; the reference is refused whatever\n * it was meant to be.\n */\nfunction undeclaredPlacementKind(\n name: string,\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): 'form' | 'component' {\n if (FORM_SECTION_NAME.test(name)) return 'form'\n const placesForm = section.uses.some((ref) => refKind(ref, plan, kinds) === 'form')\n return FORM_SECTION_NAME.test(section.name) && !placesForm ? 'form' : 'component'\n}\n\n/**\n * Rule 7 (plan): what a plan places, it reuses or it creates (AGL-3040). The\n * doctrine has a plan refer to what it creates as new:<name>, so a reference\n * that names no entry of the create list is a creation nothing builds. A page\n * kept with one stops at its first pass, sending the member to make that\n * creation by hand, which a workspace that cannot make it never can. Each is\n * refused with the one re-ask, once a name however often it is placed, and\n * says what to do on THIS workspace: declare the creation where the job may\n * make one more of that kind, and otherwise build the page without it, drawn\n * on the page or placed from what the site has. A screen's layout is rule\n * 2's (`plan-screen-without-layout`), and is not reported twice.\n */\nexport function detectPlanUndeclaredCreations(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const byName = new Map<string, AiPlanUndeclaredRef[]>()\n for (const ref of aiPlanUndeclaredRefs(plan)) {\n if (ref.field === 'layout') continue\n const key = ref.name.toLowerCase()\n byName.set(key, [...(byName.get(key) ?? []), ref])\n }\n return [...byName.values()].map((refs): AiDoctrineViolation => {\n const [first] = refs\n const screen = plan.screens[first.screenIndex]\n const section = first.field === 'uses' ? screen.sections[first.sectionIndex] : null\n const kind: AiBuildPlanCreateKind = section\n ? undeclaredPlacementKind(first.name, section, plan, kinds)\n : 'template'\n const refused = capabilities ? aiPlanUncreatableKind(plan, kind, capabilities) : null\n const where = section\n ? `${section.name ? `The \"${section.name}\" section` : 'A section'} places a creation named \"${first.name}\", but the plan never creates it`\n : `${screen.title ? `The page \"${screen.title}\"` : 'A page'} applies a template named \"${first.name}\", but the plan never creates it`\n let message: string\n if (!refused) {\n const otherwise = section\n ? `place ${aiCreationNoun(kind)} the site already has by its id`\n : \"leave the page's template empty\"\n message = `${where}. Declare it in create as ${aiCreationNoun(kind)}, with why nothing the site has will do, or ${otherwise}.`\n } else if (section) {\n message = `${where}, and ${refused.reason}. ${refused.instead} Take it out of the section's uses.`\n } else {\n message = `${where}, and ${refused.reason}. Leave the page's template empty, or apply a template the site already has.`\n }\n return { rule: 7, code: 'plan-creation-undeclared', message, paths: refs.map((ref) => ref.path) }\n })\n}\n\n/**\n * Rule 8 (plan): long lists are bound, and a list the site already holds is\n * bound to it. Where this job may not create a dataset (AGL-3030), the way\n * out the refusal names is a shorter list rather than a dataset it would\n * only refuse next.\n */\nexport function detectPlanTypedData(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const data = [...(inventory?.datasets ?? []), ...(inventory?.collections ?? [])]\n const typed: string[] = []\n const unbound: Array<{ path: string; name: string }> = []\n for (const { section, path } of sectionPaths(plan)) {\n const bindsData = section.uses.some((ref) =>\n ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))),\n )\n if (bindsData) continue\n if (section.items >= AI_TYPED_LIST_MIN_ITEMS) typed.push(path)\n const match = data.find((row) => aiNamesMatch(row.name, section.name))\n if (match) unbound.push({ path, name: match.name })\n }\n if (typed.length) {\n violations.push({\n rule: 8,\n code: 'plan-typed-list',\n message:\n capabilities && !capabilities.create.dataset.allowed\n ? `A section plans a long list of typed-out items. Bind it to a dataset or collection the site has, or plan fewer than ${AI_TYPED_LIST_MIN_ITEMS} items.`\n : 'A section plans a long list of typed-out items. Bind it to a dataset or collection, or plan a dataset for data the site does not have yet.',\n paths: typed,\n })\n }\n if (unbound.length) {\n violations.push({\n rule: 8,\n code: 'plan-existing-data-unbound',\n message: `The site already holds \"${unbound[0].name}\" as data. Bind the section to it instead of copying it into the page.`,\n paths: unbound.map((entry) => entry.path),\n })\n }\n return violations\n}\n\nconst SLUG = /^\\/?[a-z0-9]+(?:-[a-z0-9]+)*(?:\\/[a-z0-9]+(?:-[a-z0-9]+)*)*\\/?$|^\\/$/\nexport const AI_SEO_TITLE_MAX = 70\nexport const AI_SEO_DESCRIPTION_MAX = 170\n\nfunction slugKey(slug: string): string {\n return slug.trim().toLowerCase().replace(/^\\/+|\\/+$/g, '')\n}\n\n/** Rule 10 (plan): every screen has a free, well-formed slug, an SEO title and description. */\nexport function detectMissingNavAndSeo(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const violations: AiDoctrineViolation[] = []\n // The starter home a planned home page replaces (AGL-3594) keeps no\n // address from the plan: publishing the page planned at `/` retires it.\n const taken = new Map(\n (inventory?.screens ?? [])\n .filter((screen) => !screen.replaceable)\n .map((screen) => [slugKey(screen.slug), screen.name]),\n )\n const clashes = new Set<string>()\n const seen = new Set<string>()\n const badSlugs: string[] = []\n const collisions: string[] = []\n const seo: string[] = []\n plan.screens.forEach((screen, index) => {\n const key = slugKey(screen.slug)\n if (!screen.slug.trim() || !SLUG.test(screen.slug.trim())) {\n badSlugs.push(`screens[${index}].slug`)\n } else if (seen.has(key) || taken.has(key)) {\n collisions.push(`screens[${index}].slug`)\n clashes.add(`/${key}`)\n }\n seen.add(key)\n if (!screen.seoTitle || screen.seoTitle.length > AI_SEO_TITLE_MAX) {\n seo.push(`screens[${index}].seoTitle`)\n }\n if (!screen.seoDescription || screen.seoDescription.length > AI_SEO_DESCRIPTION_MAX) {\n seo.push(`screens[${index}].seoDescription`)\n }\n })\n if (badSlugs.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug',\n message:\n 'A page has no usable address. Give each one a slug of lowercase words joined by hyphens.',\n paths: badSlugs,\n })\n }\n if (collisions.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug-taken',\n // Names the addresses, so the one re-ask can move the page off them.\n message: `A page reuses an address the site or the plan already uses (${[...clashes].join(', ')}). Give each page its own slug.`,\n paths: collisions,\n })\n }\n if (seo.length) {\n violations.push({\n rule: 10,\n code: 'plan-seo',\n message: `A page is missing its search title or description, or runs past ${AI_SEO_TITLE_MAX} and ${AI_SEO_DESCRIPTION_MAX} characters. Write both for every page.`,\n paths: seo,\n })\n }\n return violations\n}\n\n/** Every piece of copy a plan carries, with its path. */\nexport function aiPlanCopy(plan: AiBuildPlan): AiCopySample[] {\n const samples: AiCopySample[] = []\n plan.screens.forEach((screen, index) => {\n samples.push({ at: `screens[${index}].title`, text: screen.title })\n samples.push({ at: `screens[${index}].seoTitle`, text: screen.seoTitle })\n samples.push({ at: `screens[${index}].seoDescription`, text: screen.seoDescription })\n })\n plan.create.forEach((entry, index) => {\n samples.push({ at: `create[${index}].name`, text: entry.name })\n })\n return samples\n}\n\n/** Rule 15 (plan): a screen or template like one the site has starts as its duplicate. */\nexport function detectMissedDuplicate(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unresolved: string[] = []\n plan.screens.forEach((screen, index) => {\n if (screen.duplicateOf) {\n if (kinds.get(screen.duplicateOf) !== 'screen') {\n unresolved.push(`screens[${index}].duplicateOf`)\n }\n return\n }\n // A starter home is replaced, not duplicated (AGL-3594).\n const nearest = (inventory?.screens ?? []).find(\n (existing) =>\n !existing.template && !existing.replaceable && aiNamesMatch(existing.name, screen.title),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has \"${nearest.name}\". Start the new page from a duplicate of it, which keeps its bindings and SEO, and edit that.`,\n paths: [`screens[${index}].duplicateOf`],\n })\n }\n })\n plan.create.forEach((entry, index) => {\n if (entry.duplicateOf) {\n const kind = kinds.get(entry.duplicateOf)\n if (!kind || (kind !== entry.kind && !(entry.kind === 'template' && kind === 'screen'))) {\n unresolved.push(`create[${index}].duplicateOf`)\n }\n return\n }\n if (entry.kind !== 'template') return\n const nearest = (inventory?.templates ?? []).find((existing) =>\n aiNamesMatch(existing.name, entry.name),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has the \"${nearest.name}\" template. Start from a duplicate of it and edit that.`,\n paths: [`create[${index}].duplicateOf`],\n })\n }\n })\n if (unresolved.length) {\n violations.push({\n rule: 15,\n code: 'plan-duplicate-unknown',\n message:\n 'The plan duplicates something the site does not have. Duplicate only what the site inventory lists.',\n paths: unresolved,\n })\n }\n return violations\n}\n\n/** What each exchange of a Free page job comes to at its worst, in credits. */\nexport interface AiFreePageWorstCase {\n /** The page plan. */\n plan: number\n /** The one layout a Free plan includes, built first on a site with none (AGL-3031). */\n layout: number\n /** The first section pass, which writes the cached prefix. */\n firstSection: number\n /** Each later section pass, which reads it. */\n laterSection: number\n /** A page's listing. */\n listing: number\n}\n\n/**\n * The Free taste's wall at its worst (AGL-3030, AGL-3070): each exchange of a\n * Free page job in credits, every answer at its ceiling, as\n * `jobs/ai-job-free-page.spec.ts` derives them from the page plan and the\n * layout generation measured live and the requests as they stand. The spec\n * fails when a figure it derives moves and this does not, so the section cap\n * below cannot drift from the proof.\n */\nexport const AI_FREE_PAGE_WORST_CASE_CREDITS: Readonly<AiFreePageWorstCase> = {\n plan: 83,\n layout: 64,\n firstSection: 44,\n laterSection: 20,\n listing: 3,\n}\n\n/**\n * The most sections a Free job fits in `FREE_AI_TASTE_CREDITS_PER_MONTH` at\n * its worst: the plan, the layouts it builds first, a listing for each page\n * and the first section's pass, then as many later passes as the rest pays\n * for; none when that is already past the wall. A component or a form is never\n * a Free creation, since rule 7 refuses both on a workspace that keeps no\n * reusable components, so the wall's proof measures neither.\n */\nexport function aiFreePageSectionsWithin(\n creations: { layouts: number; pages?: number },\n credits: Readonly<AiFreePageWorstCase> = AI_FREE_PAGE_WORST_CASE_CREDITS,\n): number {\n const before =\n credits.plan + creations.layouts * credits.layout + (creations.pages ?? 1) * credits.listing + credits.firstSection\n if (before > FREE_AI_TASTE_CREDITS_PER_MONTH) return 0\n return 1 + Math.floor((FREE_AI_TASTE_CREDITS_PER_MONTH - before) / credits.laterSection)\n}\n\n/**\n * The layouts a Free plan's job builds before its sections: the ones it\n * creates that the workspace may make, and on a site with no layout where it\n * may make one, the one rule 2 asks the plan to create.\n */\nfunction freePlanLayouts(plan: AiBuildPlan, inventory: AiSiteInventory | null, capabilities: AiPlanCapabilities): number {\n const refused = aiPlanUncreatable(plan, capabilities).filter((entry) => entry.kind === 'layout').length\n const creates = plan.create.filter((entry) => entry.kind === 'layout').length - refused\n const needs = !(inventory?.layouts.length ?? 0) && capabilities.create.layout.allowed ? 1 : 0\n return Math.max(creates, needs)\n}\n\n/** What the Free wall holds a plan to: its sections, the sections it fits, and the home's fewest. */\ninterface AiFreePlanWall {\n /** The sections the plan asks for, across its pages. */\n asked: number\n /** The sections the wall fits beside what the job builds first. */\n fits: number\n layouts: number\n pages: number\n /** A site start's page cap (AGL-3594); undefined on a page job. */\n sitePages: number | undefined\n /** Whether a site start plans more pages than its cap, which the wall refuses before it counts sections. */\n overPages: boolean\n /** The fewest sections a site start's home at / keeps on this wall (AGL-3660); 0 where it keeps no minimum. */\n homeMin: number\n}\n\n/** The Free wall a plan is held to, or null where the job is not on the Free taste. */\nfunction freePlanWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null,\n): AiFreePlanWall | null {\n if (!capabilities?.freeTaste) return null\n const asked = plan.screens.reduce((sum, screen) => sum + screen.sections.length, 0)\n const layouts = freePlanLayouts(plan, inventory, capabilities)\n const pages = Math.max(plan.screens.length, 1)\n // A Free site scaffold (AGL-3594) is held to its page cap first, and then to\n // what a SITE plan's worst case leaves for sections, with room for a retry.\n const sitePages = capabilities.freeSitePages\n const overPages = sitePages !== undefined && plan.screens.length > sitePages\n // A site start's saved form is a step of its own (AGL-3596), counted on the wall since AGL-3660.\n const forms =\n plan.create.filter((entry) => entry.kind === 'form').length -\n aiPlanUncreatable(plan, capabilities).filter((entry) => entry.kind === 'form').length\n const fits =\n sitePages !== undefined\n ? aiFreeSiteSectionsWithin({ layouts, pages, forms: Math.max(0, forms) }, FREE_AI_TASTE_CREDITS_PER_MONTH)\n : aiFreePageSectionsWithin({ layouts, pages })\n // A site start's home keeps its full five (AGL-3660): told only \"plan at\n // most 8\", the live yoga start of 2026-10-08 cut a home of 6 to 4 and kept\n // its other page, so the redo names where the sections come from.\n const homeMin =\n sitePages !== undefined && plan.screens.some(aiSitePlanIsHome)\n ? aiSiteHomeMinSections({ pages, across: fits })\n : 0\n return { asked, fits, layouts, pages, sitePages, overPages, homeMin }\n}\n\n/**\n * The most sections past the Free wall a plan is trimmed by rather than\n * re-asked (AGL-3737). The live candle-shop start of 2026-10-12 planned 9\n * sections against a wall of 8 on all three answers, each with a home of 7:\n * the model reaching for the budget the site redo names (\"plan 7 to 8\") and\n * landing one band past it, which no re-ask cured. Within two, the plan's\n * shape is right and only a band or two the brief needs least is extra, so\n * taking those from the end loses nothing the plan depends on. Further over,\n * the shape itself is off — a list planned as sections, a page the wall\n * cannot pay for — and cutting more would drop content the model meant, so\n * that plan is still re-asked.\n */\nexport const AI_FREE_WALL_SETTLE_MAX_OVER = 2\n\n/** A section through which a visitor reaches the owner: contact, a visit, a booking. */\nconst REACH_SECTION_NAME =\n /\\b(?:contact|get in touch|visit(?: us)?|find us|locations?|hours|book(?:ing)?|reserve|reservations?)\\b/i\n\n/**\n * Whether the Free wall's trim keeps a section of a page (AGL-3737): the\n * page's opening, any section that places something (a dataset it lists, a\n * form, a component — dropping it would leave a creation unplaced), one that\n * collects answers or says how to reach the owner, and a storefront's\n * listing parts — the bestsellers, the collections, the sign-up, and a Shop\n * page's product grid.\n */\nfunction freeWallKeeps(screen: AiBuildPlan['screens'][number], index: number): boolean {\n const section = screen.sections[index]\n if (index === 0 || section.uses.length > 0) return true\n if (FORM_SECTION_NAME.test(section.name) || REACH_SECTION_NAME.test(section.name)) return true\n if (\n aiStorefrontSays('featured', section.name) ||\n aiStorefrontSays('collections', section.name) ||\n aiStorefrontSays('signup', section.name)\n ) {\n return true\n }\n return aiLayoutIsShopPage(screen) && aiLayoutShopGridSection(screen.sections) === index\n}\n\n/**\n * A Free plan a section or two past the wall is trimmed to fit before the\n * rules read the plan (AGL-3737), rather than re-asked: which sections go has\n * one answer, so the re-ask only costs the member a stopped start. The live\n * candle-shop start of 2026-10-12 asked for a home of 7 and a second page of\n * 2 against a wall of 8, three answers running, and stopped needing input.\n *\n * One section goes at a time, the last of its page that `freeWallKeeps`\n * does not hold, from the page furthest past its share: the home at / past\n * its fewest (`aiSiteHomeMinSections`, five on a site start whose wall pays\n * for a full home), any other page past two; on a tie, the longer page, then\n * the home. No home goes under its fewest and no page under one section. The\n * shares are what a site start is told to plan (a home of five or six, the\n * other page two or three): the candle shop's 7 + 2 becomes 6 + 2, never\n * 7 + 1, and the recorded yoga answer's 6 + 4 becomes 5 + 3, the shape its\n * own redo chose.\n *\n * A plan more than `AI_FREE_WALL_SETTLE_MAX_OVER` past the wall, a site\n * start past its page cap, a plan with a list split into sections, and a\n * plan the trim cannot fit without a section it keeps are returned\n * unchanged, for the wall to re-ask.\n */\nexport function aiSettlePlanFreeWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n const wall = freePlanWall(plan, inventory, capabilities)\n if (!wall || wall.overPages) return plan\n const over = wall.asked - wall.fits\n if (over <= 0 || over > AI_FREE_WALL_SETTLE_MAX_OVER) return plan\n // A list split into sections is joined by its re-ask, which frees the room;\n // a trim would cut one of its items and hide the split from the rule.\n if (detectPlanSplitLists(plan, inventory, capabilities).length) return plan\n const kept = plan.screens.map((screen) => screen.sections.map((section, index) => ({ section, index })))\n const home = plan.screens.findIndex(aiSitePlanIsHome)\n const floor = (screenIndex: number) => (screenIndex === home ? Math.max(wall.homeMin, 1) : 1)\n const target = (screenIndex: number) => (screenIndex === home ? Math.max(wall.homeMin, 1) : 2)\n // The last section of a page the trim may take, or -1.\n const last = (screenIndex: number) => {\n const entries = kept[screenIndex]\n if (entries.length <= floor(screenIndex)) return -1\n for (let at = entries.length - 1; at > 0; at -= 1) {\n if (!freeWallKeeps(plan.screens[screenIndex], entries[at].index)) return at\n }\n return -1\n }\n for (let left = over; left > 0; left -= 1) {\n let pick = -1\n for (let index = 0; index < kept.length; index += 1) {\n if (last(index) === -1) continue\n const room = kept[index].length - target(index)\n const best = pick === -1 ? null : kept[pick].length - target(pick)\n if (\n best === null ||\n room > best ||\n (room === best && (kept[index].length > kept[pick].length || (kept[index].length === kept[pick].length && index === home)))\n ) {\n pick = index\n }\n }\n if (pick === -1) return plan\n kept[pick].splice(last(pick), 1)\n }\n return {\n ...plan,\n screens: plan.screens.map((screen, index) =>\n kept[index].length === screen.sections.length\n ? screen\n : { ...screen, sections: kept[index].map((entry) => entry.section) },\n ),\n }\n}\n\n/**\n * The Free wall (plan): a plan asks for no more sections than the Free taste\n * pays for at its worst beside what the job builds first (AGL-3070). A live\n * Free plan asked for eight sections beside its layout, where the wall's worst\n * case pays for six, and fit only because every exchange ran under its\n * ceiling; one that does not runs out of credits with its page half built. The\n * cap only lowers what a plan may ask for, from the same figures the wall is\n * proven with, so no plan the proof admits is refused. It is no building rule,\n * so it names none.\n */\nexport function detectPlanOverFreeWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n const wall = freePlanWall(plan, inventory, capabilities)\n if (!wall) return []\n const { asked, layouts, pages, sitePages, fits, homeMin } = wall\n if (sitePages !== undefined && wall.overPages) {\n return [\n {\n rule: null,\n code: 'plan-over-free-wall',\n message: `This plan builds ${plan.screens.length} pages, and a Free workspace's site start builds at most ${sitePages}. Plan the home page and the one page the brief most needs.`,\n paths: ['screens'],\n },\n ]\n }\n if (asked <= fits) return []\n const job = pages > 1 ? `a Free plan of ${pages} pages` : 'a Free page'\n const beside = layouts ? ` that creates ${layouts > 1 ? `${layouts} layouts` : 'its layout'}` : ''\n const keepHome = homeMin\n ? ` Keep the home page at / at ${homeMin} or more sections, and take the rest from the other ${pages > 2 ? 'pages' : 'page'}.`\n : ''\n // A site start's redo keeps the plan full (AGL-3660): the wall's sections\n // are its budget to use, and a redo told only \"at most\" cuts far under it.\n const redo =\n sitePages !== undefined && fits >= 2\n ? `Plan ${fits - 1} to ${fits}: the ${fits} are the budget to use, not a ceiling to stay under. Draw a list's repeated items in one section, and take out only the sections the brief needs least.`\n : `Plan at most ${fits}: draw a list's repeated items in one section, and leave out a section the brief does not ask for.`\n return [\n {\n rule: null,\n code: 'plan-over-free-wall',\n message: `This plan asks for ${asked} sections, and ${job}${beside} fits ${fits} in the ${FREE_AI_TASTE_CREDITS_PER_MONTH} AI credits a Free workspace has a month. ${redo}${keepHome}`,\n paths: plan.screens.map((_, index) => `screens[${index}].sections`),\n },\n ]\n}\n\n/**\n * Rule 2 (plan): a layout the plan creates lists the regions it has, and\n * every one is a region this platform builds (AGL-3024).\n *\n * A layout has no properties, so its `fields` are its REGIONS — the promise\n * the build is later held to. A word the vocabulary does not hold is refused\n * HERE, on the plan, where the re-ask costs a sentence: a promise nothing can\n * look for would otherwise reach the build as a commitment no check can\n * settle, and a build that cannot settle its own plan stops for a person\n * instead of reporting itself done.\n */\nexport function detectPlanUnreadableRegions(plan: AiBuildPlan): AiDoctrineViolation[] {\n const unreadable: Array<{ word: string; path: string }> = []\n plan.create.forEach((entry, index) => {\n if (entry.kind !== 'layout') return\n entry.fields.forEach((field, fieldIndex) => {\n if (!aiLayoutRegionOf(field)) {\n unreadable.push({ word: field, path: `create[${index}].fields[${fieldIndex}]` })\n }\n })\n })\n if (!unreadable.length) return []\n const one = unreadable.length === 1\n return [\n {\n rule: 2,\n code: 'plan-layout-region-unknown',\n message: `A layout lists ${unreadable\n .map((entry) => `\"${entry.word}\"`)\n .join(', ')} among its regions, and a layout is built out of ${AI_LAYOUT_REGION_NAMES.join(\n ', ',\n )}. Name ${one ? 'it' : 'them'} with one of those, or leave ${one ? 'it' : 'them'} off the layout.`,\n paths: unreadable.map((entry) => entry.path),\n },\n ]\n}\n\n/**\n * Rule 16 (plan): a third-party player is planned where it can play\n * (AGL-3433). A screen of the plan or a component it creates carries at most\n * its kind's budget. A template renders for every record it serves and a\n * layout around every page, so neither carries one, and a form, an email or a\n * dataset has nowhere to. A link the plan gives is one its host plays.\n */\nexport function detectPlanEmbeds(plan: AiBuildPlan): AiDoctrineViolation[] {\n const nowhere: string[] = []\n const elsewhere: Array<{ kind: AiBuildPlanCreateKind; path: string }> = []\n const wrongHost: string[] = []\n const placed = new Map<string, { label: string; kind: 'page' | 'component'; paths: string[] }>()\n ;(plan.embeds ?? []).forEach((embed, index) => {\n const path = `embeds[${index}]`\n if (embed.url !== null && aiEmbedHostOf(embed.url) !== embed.host) wrongHost.push(`${path}.url`)\n let target: { key: string; label: string; kind: 'page' | 'component' } | null = null\n if (isAiPlanNewRef(embed.where)) {\n const creation = aiPlanCreateFor(plan, embed.where)\n if (creation && creation.kind !== 'component') {\n elsewhere.push({ kind: creation.kind, path: `${path}.where` })\n return\n }\n if (creation) target = { key: embed.where.trim().toLowerCase(), label: creation.name, kind: 'component' }\n } else {\n const screen = plan.screens.find((row) => aiPlanSlugKey(row.slug) === aiPlanSlugKey(embed.where))\n if (screen) target = { key: aiPlanSlugKey(screen.slug), label: screen.slug, kind: 'page' }\n }\n if (!target) {\n nowhere.push(`${path}.where`)\n return\n }\n const entry = placed.get(target.key) ?? { label: target.label, kind: target.kind, paths: [] }\n entry.paths.push(path)\n placed.set(target.key, entry)\n })\n const violations: AiDoctrineViolation[] = []\n if (nowhere.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-nowhere',\n message:\n 'A player is planned where the plan builds nothing. Name a screen of the plan by its slug, or new:<name> of a component it creates.',\n paths: nowhere,\n })\n }\n if (elsewhere.length) {\n const nouns = [...new Set(elsewhere.map((entry) => AI_BUILD_PLAN_CREATION_NOUNS[entry.kind].noun))]\n violations.push({\n rule: 16,\n code: 'plan-embed-refused',\n message: `Only a page or a component carries a third-party player, and this plan puts one on a ${nouns.join(\n ' and a ',\n )}. A template or a layout would load the player's code on every page it serves. Place it on a page or a component, or leave it off.`,\n paths: elsewhere.map((entry) => entry.path),\n })\n }\n for (const entry of placed.values()) {\n const limit = AI_OUTPUT_BUDGETS[entry.kind].embeds\n if (entry.paths.length <= limit) continue\n violations.push({\n rule: 16,\n code: 'plan-embed-over-budget',\n message: `${entry.label} is planned ${entry.paths.length} players, and a ${entry.kind} carries at most ${limit}. Keep the one the brief asks for most.`,\n paths: entry.paths,\n })\n }\n if (wrongHost.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-link-host',\n message: `A planned player's link is not a video link of its host, ${Object.values(\n AI_BUILD_PLAN_EMBED_HOST_NAMES,\n ).join(' or ')}. Give the brief's own link for that host, or null.`,\n paths: wrongHost,\n })\n }\n return violations\n}\n\n/** Text as two copies of one phrase compare: lowercase, no quotes, one space. */\nfunction phraseKey(text: string): string {\n return text\n .toLowerCase()\n .replace(/[“”\"‘’'`]/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\n/**\n * Rule 16 (plan, against the brief): a player is planned only where the brief\n * asks for one (AGL-3433). The plan quotes the brief's words, and those words\n * are found in the brief and ask for a video; a link it gives is one the brief\n * gives. The plan step holds this, being the one door that reads the brief\n * beside the plan.\n */\nexport function aiPlanEmbedBriefViolations(plan: AiBuildPlan, brief: string): AiDoctrineViolation[] {\n const said = phraseKey(brief)\n const given = new Set(\n (brief.match(/https:\\/\\/\\S+/g) ?? [])\n .map((link) => aiEmbedVideoKey(link.replace(/[).,;!?]+$/, '')))\n .filter((key): key is string => key !== null),\n )\n const unasked: string[] = []\n const ungiven: string[] = []\n ;(plan.embeds ?? []).forEach((embed, index) => {\n const asked = phraseKey(embed.asked)\n if (!asked || !said.includes(asked) || !AI_PLAN_ASKS_FOR_VIDEO.test(asked)) {\n unasked.push(`embeds[${index}].asked`)\n }\n if (embed.url !== null) {\n const key = aiEmbedVideoKey(embed.url)\n if (!key || !given.has(key)) ungiven.push(`embeds[${index}].url`)\n }\n })\n const violations: AiDoctrineViolation[] = []\n if (unasked.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-not-asked',\n message:\n 'A player is planned that the brief does not ask for: its words are not words of the brief asking for a video. Take it off the plan; a film from the media library plays in a Video.',\n paths: unasked,\n })\n }\n if (ungiven.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-link-not-given',\n message:\n \"A planned player's link is not one the brief gives. Give the brief's own link, or null for the site owner to paste.\",\n paths: ungiven,\n })\n }\n return violations\n}\n\n/**\n * Every plan rule, against the site inventory the plan was made from and,\n * where the job read them, what it may create there (AGL-3030). `null`\n * capabilities restrict nothing: the doctrine applies whole.\n */\nexport function validateAiBuildPlan(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n framing: AiCopyFraming = null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n return [\n ...detectPlanRepeats(plan, inventory, capabilities),\n ...detectPlanSplitLists(plan, inventory, capabilities),\n ...detectPlanOverFreeWall(plan, inventory, capabilities),\n ...detectPlanLayoutRegions(plan, inventory, capabilities),\n ...detectPlanUnreadableRegions(plan),\n ...detectPlanInlineForms(plan, inventory, capabilities),\n ...detectUntemplatedSimilarPages(plan, inventory),\n ...detectPlanLiteralColors(plan),\n ...detectPlanEmbeds(plan),\n ...detectCreateBeforeReuse(plan, inventory),\n ...detectPlanUncreatable(plan, capabilities),\n ...detectPlanUndeclaredCreations(plan, inventory, capabilities),\n ...detectPlanTypedData(plan, inventory, capabilities),\n ...detectMissingNavAndSeo(plan, inventory),\n ...detectOffVoiceCopy(aiPlanCopy(plan), framing),\n ...detectMissedDuplicate(plan, inventory),\n ]\n}\n"],"names":["sanitizeAuthorHtml","formatBytes","measureNodeMap","nodeMapBytes","MEDIA_CDN_VARIANT_WIDTHS","parseMediaRef","ESTIMATED_PAGE_TRANSFER_BYTES","createIdUrlSafe","FREE_AI_TASTE_CREDITS_PER_MONTH","REUSABLE_INSTANCE_COMPONENT_ID","REUSABLE_INSTANCE_PROP_VALUES_KEY","parseBreakpointSpan","renderEmailHtml","AI_BUILD_PLAN_CREATION_NOUNS","AI_BUILD_PLAN_EMBED_HOST_NAMES","AI_BUILD_PLAN_LIMITS","AI_PLAN_ASKS_FOR_VIDEO","aiEmbedHostOf","aiEmbedVideoKey","AI_PLAN_DATASET_ITEM_OP","aiPlanCreateFor","aiPlanFormDatasetNames","aiPlanItemFor","aiPlanSlugKey","aiPlanUndeclaredRefs","isAiPlanNewRef","aiCreationNoun","aiPlanCanPlaceForm","aiPlanUncreatable","aiPlanUncreatableKind","aiFreeSiteSectionsWithin","aiSiteHomeMinSections","aiSitePlanIsHome","aiLayoutIsShopPage","aiLayoutShopGridSection","aiStorefrontSays","AI_INSTANCE_REF_PROP","validateAiNodeTree","AI_PAGE_SCROLL_TO_PROP","aiPageLinkTarget","aiStoredScrollTargets","AI_EMAIL_CLIP_BYTES","AI_OUTPUT_BUDGETS","AI_OUTPUT_SURFACE","AI_TEXT_LIMITS","isHeadlineVariant","AI_PALETTE","AI_SX_TOKENS","AI_DOCTRINE_RULES","AI_DOCTRINE_RULE_NUMBERS","Object","keys","map","Number","aiDoctrineViolationText","violation","rule","message","isRecord","value","Array","isArray","walkTree","tree","visits","seen","Set","stack","id","rootId","depth","ancestors","length","node","pop","nodes","has","add","push","children","index","displayName","componentId","elementOf","props","hasAncestor","visit","test","some","unique","values","listNames","ids","names","join","slice","AI_REPEAT_MIN_NODES","AI_REPEAT_MIN_COUNT","AI_REPEAT_ACROSS_PAGES_MIN_NODES","AI_TYPED_LIST_MIN_ITEMS","indexShapes","shapeOf","Map","sizeOf","schema","propsSchema","properties","sort","key","declared","structural","Boolean","enum","type","String","filter","child","set","get","reduce","sum","repeatedByData","repeatedShapes","minNodes","minCount","groupOf","skip","byShape","shape","JSON","stringify","repeated","entries","repeatedIds","flatMap","ancestorsOf","every","ancestor","REPEAT_FRAMES","aiRepeatFrameOrSection","memo","childrenOf","holdsOutline","level","aiHeadingLevel","itemFrame","kinds","size","parentOf","exempt","known","undefined","parent","result","detectRepeatedSubtrees","otherPages","context","reusableComponents","card","first","opens","pictureCard","parentId","find","at","violations","reverse","repeatsCompiled","name","code","nodeIds","elsewhere","other","otherIndex","shared","sharedIds","outermost","aiRepeatedItemCount","most","count","aiBindsRepeatedItems","REGION_ELEMENTS","REGION_WORDS","header","footer","nav","AI_LAYOUT_REGIONS","elements","componentIds","sidebar","main","AI_LAYOUT_REGION_NAMES","LAYOUT_REGION_ALIASES","masthead","navigation","menu","aside","drawer","rail","slot","content","aiLayoutRegionOf","word","read","cleaned","split","replace","toLowerCase","trim","includes","aiTreeLayoutRegions","found","element","region","where","detectLayoutRegions","outputKind","regions","entry","detectInlineForms","loose","unbound","shadowed","bound","COLOR_SX_KEYS","COLOR_IN_VALUE_SX_KEYS","SPACING_SX_KEYS","TYPE_SX_KEYS","COLOR_KEYWORDS","LITERAL_COLOR","LENGTH_WITH_UNIT","paletteTokens","palette","hasLiteralColor","parts","part","sxValues","detectLiteralStyles","colors","lengths","raw","sx","normalizeHex","hex","detectOffBrandEmail","brand","allowed","fonts","font","offBrand","candidates","family","candidate","EMAIL_COLOR_PROPS","emailRgbOf","text","exec","r","g","b","alpha","full","digit","parseInt","fn","isFinite","over","channel","Math","round","emailColorDistance","a","mean","dr","dg","db","sqrt","aiSettleOffBrandEmailColors","input","byPath","path","targets","rgb","settle","named","best","target","settled","emailSettleKeepsContrast","EMAIL_SETTLED_MIN_CONTRAST","emailLuminance","c","emailContrast","light","dark","x","y","written","propOf","groundOf","WHITE","color","ground","touched","background","detectTypedData","sectionOf","byComponent","childId","ref","detectUnfilledInstances","componentProps","unfilled","filled","one","mediaValues","out","roles","propRoles","refId","detectImageSources","hotlinked","missingAlt","alt","decorative","match","detectDocumentStructure","headings","mains","slots","rootElement","slotElement","chosenAway","h1s","heading","page","skipped","previous","WIDTH_SX_KEYS","detectAdHocWidths","fixed","GRID","GRID_CONTAINER_PROPS","GRID_ROW_PROPS","GRID_ROW_DIRECTIONS","GRID_COLUMN_DIRECTION","GRID_ITEM_WRAPPERS","GRID_GAP_SX_KEYS","GRID_DEFAULT_COLUMNS","GRID_QUOTED_MAX_CHARS","writtenValueText","cut","gridColumns","columns","isInteger","gridItemSpan","span","phoneFull","steps","base","xs","breakpoint","gridItemSizeFor","items","across","min","max","md","floor","sm","detectUnresponsiveGrids","shapes","isGrid","isContainer","isSized","writtenProp","unreadContainer","wrapsItems","writtenColumn","direction","setsOutRow","refused","rows","stacks","outside","texts","unsized","suggested","gapped","grandparentId","sized","wrappedItem","holdsSized","isItem","setsContainerProps","within","column","offending","item","gap","spacing","GRID_SIZE_BREAKPOINTS","writtenGridSizeText","pairs","indexOf","aiSettleGridItems","options","mintId","copied","edit","setSize","own","container","settledItems","host","wrapperId","$id","pluginId","aiSettleWrittenGridItems","fromEntries","LINK_COLOR_FAMILIES","LINK_COMPONENTS","isAiLinkElement","PAPER_COMPONENTS","FAMILY_TOKEN","familyOf","bandOf","token","linkWordsFamily","styledAsButton","detectInvisibleLinks","hidden","band","HOME_WORDS","GET_IN_TOUCH_WORDS","aiAsksToGetInTouch","label","unrelatedScreenLinks","home","homeScreenIds","forms","formScreenIds","sent","screenId","linksHome","inNavigation","aiSettleUnrelatedScreenLinks","ownScreenIds","formScreen","parents","next","detectUnrelatedScreenLinks","isFilled","detectLinksWithoutDestination","stored","sections","pageSections","scrollTargetIds","dead","fragments","unknown","kind","via","inForm","wordsOf","listed","toSection","instead","PUBLISH_KEYS","detectPublishIntent","answer","paths","forEach","inner","here","BRACKETED_FACT","aiBracketedFacts","facts","matchAll","fact","FILLER_COPY","JUDGMENT","detectOffVoiceCopy","samples","framing","filler","sample","judged","list","aiTreeCopy","LINE_PROPS","muiTypography","muiListItemText","muiCardHeader","muiAccordionSummary","emailText","LABEL_VARIANTS","DANGLING_WORDS","OPENING_WORDS","CLOSED_LINE","aiDanglingWord","line","lower","before","lineTail","words","detectDanglingWords","LABEL_PROPS","muiButton","muiScreenLink","emailButton","CUT_REPAIR","lineHead","detectCutLines","repairs","idOf","repair","nodeId","limit","shown","PURE_CONTAINERS","EMBED_COMPONENTS","DUPLICATE_SX_MIN_KEYS","DUPLICATE_SX_MIN_NODES","embedVerdict","planned","url","embed","OWNS_ITS_EMPTY_STATE","detectHeavyDocument","wrappers","empty","eager","video","embeds","embedLinks","sxSeen","images","ownProps","boundForm","acceptsChildren","verdict","plannedEmbeds","duplicatedSx","flat","ITEM_NOUNS","muiListItem","muiCard","FRAME_COMPONENTS","WORD_PROPS","muiList","muiInlineText","showsOwn","detectEmptyItems","noun","nouns","EMAIL_COLUMN_PX","MEDIA_IMAGE_PROPS","image","emailImage","collectionEntryAuthor","contentAuthorProfile","servedVariantWidth","slotWidth","widest","width","pixels","parsed","parseFloat","imageRequests","requests","startsWith","assets","mediaId","sizeBytes","bytes","variant","ratio","scoreAiOutput","families","emailHtmlBytes","html","sanitize","TextEncoder","encode","imageBytes","imagesUnmeasured","fontFamilies","METRIC_LABELS","figure","metric","toLocaleString","heaviest","largest","BUDGET_METRICS","detectOverBudget","score","budget","offenders","estimateAiOutputLoad","pageBytes","documentBytes","totalBytes","detectDisagreeingNodes","reached","missing","queue","shift","orphans","detail","REPEAT_KEY","aiSettleDisagreeingNodes","source","changed","setListed","holds","reach","inOrphan","roots","unplaced","kept","HEADING_CUT_MIN_WORDS","HEADING_CUT_MIN_SHARE","SENTENCE_END","CLAUSE_END","headingWithin","keeps","head","pattern","keepMark","aiSettleCutHeadings","textLimits","Infinity","headline","trimmed","aiSettleMechanicalRules","unsetProp","setProp","unsetSx","email","framed","fragment","firstH1","findIndex","start","keepsH1","aiSettleWrittenMechanicalRules","readable","validateAiDoctrineTree","publish","disagreeing","ok","load","validated","error","minted","sourceIds","writtenOf","writtenNode","storedOf","NAME_STOPWORDS","nameTokens","endsWith","aiNamesMatch","left","right","small","large","inventoryKinds","inventory","row","components","layouts","templates","datasets","collections","screens","refKind","plan","sectionPaths","screen","screenIndex","section","sectionIndex","LAYOUT_REGION_NAME","FORM_SECTION_NAME","detectPlanRepeats","capabilities","placesComponent","uses","byName","common","refs","AI_SPLIT_LIST_MIN_SECTIONS","SECTION_LABEL","pluralOf","sectionItemKind","detectPlanSplitLists","run","close","component","placementsOf","creationKey","aiSettlePlanRefs","create","resolve","matches","layout","template","AI_DATASET_SAID_NAME","aiSettlePlanDatasets","dataset","cap","datasetsMax","forForms","said","fields","field","total","record","ranked","dropped","isDropped","writesTo","withoutWritesTo","creation","rest","aiSettlePlanFormDatasets","held","creatable","op","listsOne","aiSettlePlanLayouts","created","unlaid","only","mayCreateLayout","taken","why","duplicateOf","aiSettlePlanLayoutRegionSections","removable","planFormChoices","form","formChoiceKey","bestPlanForm","choices","placed","choice","AI_PLAN_SETTLED_FORM","aiSettlePlanForms","current","use","planFormChoicesText","detectPlanLayoutRegions","noLayoutToName","detectPlanInlineForms","AI_SIMILAR_PAGES_MIN","detectUntemplatedSimilarPages","groups","signature","indexes","detectPlanLiteralColors","REUSE_BEFORE_CREATE_KINDS","detectCreateBeforeReuse","reuse","unexplained","existing","detectPlanUncreatable","undeclaredPlacementKind","placesForm","detectPlanUndeclaredCreations","title","otherwise","reason","detectPlanTypedData","data","typed","bindsData","SLUG","AI_SEO_TITLE_MAX","AI_SEO_DESCRIPTION_MAX","slugKey","slug","detectMissingNavAndSeo","replaceable","clashes","badSlugs","collisions","seo","seoTitle","seoDescription","aiPlanCopy","detectMissedDuplicate","unresolved","nearest","AI_FREE_PAGE_WORST_CASE_CREDITS","firstSection","laterSection","listing","aiFreePageSectionsWithin","creations","credits","pages","freePlanLayouts","creates","needs","freePlanWall","freeTaste","asked","sitePages","freeSitePages","overPages","fits","homeMin","AI_FREE_WALL_SETTLE_MAX_OVER","REACH_SECTION_NAME","freeWallKeeps","aiSettlePlanFreeWall","wall","last","pick","room","splice","detectPlanOverFreeWall","job","beside","keepHome","redo","_","detectPlanUnreadableRegions","unreadable","fieldIndex","detectPlanEmbeds","nowhere","wrongHost","phraseKey","aiPlanEmbedBriefViolations","brief","given","link","unasked","ungiven","validateAiBuildPlan"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-doctrine-validators.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { sanitizeAuthorHtml } from '@aglyn/aglyn/app-utils/author-html'\nimport { isFormInputNode } from '@aglyn/aglyn/app-utils/forms'\nimport {\n formatBytes,\n measureNodeMap,\n nodeMapBytes,\n} from '@aglyn/aglyn/app-utils/measure-node-map'\nimport {\n MEDIA_CDN_VARIANT_WIDTHS,\n parseMediaRef,\n} from '@aglyn/aglyn/app-utils/media-ref'\nimport { ESTIMATED_PAGE_TRANSFER_BYTES } from '@aglyn/aglyn/app-utils/plan-entitlements'\nimport { createIdUrlSafe } from '@aglyn/aglyn/foundation/constants/app'\nimport { FREE_AI_TASTE_CREDITS_PER_MONTH } from '../plan-entitlements'\nimport {\n REUSABLE_INSTANCE_COMPONENT_ID,\n REUSABLE_INSTANCE_PROP_VALUES_KEY,\n} from '@aglyn/aglyn/app-utils/reusable-component-keys'\nimport { parseBreakpointSpan } from '@aglyn/shared-data-enums/breakpoint-span'\nimport { renderEmailHtml } from '@aglyn/shared-util-email/email-render'\nimport {\n AI_BUILD_PLAN_CREATION_NOUNS,\n AI_BUILD_PLAN_EMBED_HOST_NAMES,\n AI_BUILD_PLAN_LIMITS,\n AI_PLAN_ASKS_FOR_VIDEO,\n aiEmbedHostOf,\n aiEmbedVideoKey,\n AI_PLAN_DATASET_ITEM_OP,\n aiPlanCreateFor,\n aiPlanFormDatasetNames,\n aiPlanItemFor,\n aiPlanSlugKey,\n aiPlanUndeclaredRefs,\n isAiPlanNewRef,\n type AiBuildPlan,\n type AiBuildPlanCreateKind,\n type AiBuildPlanEmbed,\n type AiBuildPlanRecord,\n type AiBuildPlanSection,\n type AiPlanUndeclaredRef,\n} from '../model/ai-build-plan'\nimport {\n aiCreationNoun,\n aiPlanCanPlaceForm,\n aiPlanUncreatable,\n aiPlanUncreatableKind,\n type AiPlanCapabilities,\n} from '../model/ai-plan-capabilities'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport {\n aiFreeSiteSectionsWithin,\n aiSiteHomeMinSections,\n aiSitePlanIsHome,\n aiSiteSectionShowsWork,\n} from '../model/ai-site-job'\nimport { aiLayoutIsShopPage, aiLayoutShopGridSection } from '../layout-language/ai-layout-listings'\nimport { aiStorefrontSays } from '../layout-language/ai-layout-storefront'\nimport {\n AI_INSTANCE_REF_PROP,\n validateAiNodeTree,\n type AiNodeTreeContext,\n type AiNodeTreeResult,\n} from './ai-node-tree'\nimport { AI_PAGE_SCROLL_TO_PROP, aiPageLinkTarget, aiStoredScrollTargets } from './ai-page-links'\nimport {\n AI_EMAIL_CLIP_BYTES,\n AI_OUTPUT_BUDGETS,\n AI_OUTPUT_SURFACE,\n AI_TEXT_LIMITS,\n isHeadlineVariant,\n type AiBudgetMetric,\n type AiLoadEstimate,\n type AiOutputKind,\n} from './ai-palette'\nimport { AI_PALETTE, AI_SX_TOKENS } from './ai-palette.generated'\n\n/**\n * The building doctrine's validators (AGL-2935): the rules a generated\n * document is held to, each checked by code rather than asked of a prompt.\n *\n * A generator's system prompt carries the doctrine (`ai-doctrine.ts`), and a\n * model mostly follows it. \"Mostly\" is what these are for. Every tree and\n * every plan passes through them inside `runValidatedGeneration`; a finding\n * is a VIOLATION that names its rule and says, in a sentence a customer can\n * read, what was refused and what to do instead. The runtime re-asks the\n * model once with the findings, and stops for a person when the second\n * answer still breaks one.\n *\n * Trees are checked AFTER `validateAiNodeTree` (AGL-2905) has admitted them,\n * never instead of it: the palette validator decides what may be stored at\n * all, and these decide whether it was built the way a careful author would\n * build it. Plans are checked against the site inventory, which is where\n * \"reuse before create\" becomes checkable.\n *\n * Rule 17 is a MEASUREMENT, in the platform's existing units: the stored\n * node map in the bytes the save counts (`nodeMapBytes`), images at the size\n * the media library recorded, an email's HTML as the send path renders it,\n * and a page's load on top of the page weight the platform already measured.\n * Nothing here invents a second measure of a page.\n */\n\nexport type AiDoctrineRuleNumber =\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n\n/** Each rule's title, in the words the proposal and the docs page use. */\nexport const AI_DOCTRINE_RULES: Readonly<Record<AiDoctrineRuleNumber, string>> = {\n 1: 'Repeats become one reusable component',\n 2: 'Site-wide regions live in the layout',\n 3: 'Forms are built on the Forms page, then placed',\n 4: 'Similar pages share one template',\n 5: 'Colors, spacing and type come from the theme',\n 6: 'Emails use the brand',\n 7: 'Reuse before creating',\n 8: 'Data is bound, not typed',\n 9: 'Images come from the media library, with alt text',\n 10: 'Navigation and SEO travel with a page',\n 11: 'One main landmark and an ordered outline',\n 12: \"Responsive by the theme's breakpoints\",\n 13: 'Drafts only',\n 14: 'Your voice, with no filler copy',\n 15: 'Start from a duplicate of the nearest thing',\n 16: 'The smallest document that does the job',\n 17: 'A measured budget for every output',\n}\n\nexport const AI_DOCTRINE_RULE_NUMBERS = Object.keys(AI_DOCTRINE_RULES).map(\n Number,\n) as AiDoctrineRuleNumber[]\n\nexport interface AiDoctrineViolation {\n /**\n * The rule broken; `null` when the answer could not be read as the output\n * at all, or asks for what its job does not build rather than breaking a\n * building rule.\n */\n rule: AiDoctrineRuleNumber | null\n /** Stable per finding, for specs and logs. */\n code: string\n /** One customer-safe sentence: what was refused and what to do instead. */\n message: string\n /** What the model is told beyond `message`, when the validator's own words say more. */\n detail?: string\n /** Offending nodes, by the ids of the tree that was checked. */\n nodeIds?: string[]\n /** Offending plan entries or answer fields, as `screens[1].sections[2]`. */\n paths?: string[]\n /** Rule 17: the measured figure against its budget. */\n figure?: { metric: AiBudgetMetric; value: number; budget: number }\n}\n\n/** A violation as one line: the rule's number and title, then its sentence. */\nexport function aiDoctrineViolationText(violation: AiDoctrineViolation): string {\n return violation.rule === null\n ? violation.message\n : `Rule ${violation.rule} (${AI_DOCTRINE_RULES[violation.rule]}): ${violation.message}`\n}\n\n/** Who the copy is framed for; agency and enterprise copy holds to the judgment-word rule. */\nexport type AiCopyFraming = 'agency' | 'enterprise' | null\n\n// ── Trees ────────────────────────────────────────────────────────────────\n\nexport interface AiDoctrineNode {\n componentId: string\n props?: Record<string, unknown>\n sx?: Record<string, unknown>\n nodes?: string[]\n}\n\n/** A validated flat node map, as `validateAiNodeTree` returns it. */\nexport interface AiDoctrineTree {\n rootId: string\n nodes: Record<string, AiDoctrineNode>\n}\n\n/** What a library asset records about itself, for the image weight. */\nexport interface AiAssetFacts {\n sizeBytes?: number\n width?: number\n height?: number\n}\n\nexport interface AiDoctrineTreeContext extends AiNodeTreeContext {\n /** The brand an email is held to: palette path → color, and the families. */\n brand?: { colors: Record<string, string>; fonts: string[] } | null\n /** Placed library assets by media id. */\n assets?: Record<string, AiAssetFacts>\n /**\n * The third-party players the confirmed plan lists for this output\n * (AGL-3433): a Video embed is admitted only where one is listed, playing\n * the link the brief gave or none. Absent or empty admits none.\n */\n plannedEmbeds?: readonly Pick<AiBuildPlanEmbed, 'host' | 'url'>[]\n framing?: AiCopyFraming\n /**\n * Whether the workspace keeps reusable components (AGL-3030). `false`\n * draws a repeated block where it repeats. Absent is `true`, the doctrine\n * whole. Forms do not read it: a form is a saved form placed by its id on\n * every plan, counted against `formsPerHost`, or none (AGL-3596).\n */\n reusableComponents?: boolean\n /**\n * A page the layout language compiled (AGL-3660), whose picture cards — a\n * picture over its title and words, one to a cell of a grid — the compiler\n * draws from the site's design. Rule 1 asks no component of those cards;\n * every other repeat on the page is still held to it. The page half of the\n * plan capability of the same name (`AiPlanCapabilities.repeatsCompiled`,\n * AGL-3616), which spares a build's plan a component for a section's items:\n * the plan leaves them to the compiler, and this lets the page it compiles\n * draw them.\n */\n repeatsCompiled?: boolean\n /**\n * The site's home screens, by id (AGL-3056): the screen a link falls back\n * to when the site has none for what it promises. Absent: none is known.\n */\n homeScreenIds?: readonly string[]\n /**\n * The home pages' own titles (AGL-3760): a link home under one of them says\n * where it goes in the site's language, as \"Inicio\" does on a Spanish site.\n */\n homeLabels?: readonly string[]\n /**\n * The site's pages that place its form, by id (AGL-3729): where a link whose\n * words ask a visitor to get in touch (`aiAsksToGetInTouch`) does what it\n * says, even when that page is home. A guided start's café put its\n * pre-order form on Home, and its Menu page's \"Request weekend pickup\"\n * links there. Absent: none is known, and a link home is held to its words.\n */\n formScreenIds?: readonly string[]\n /**\n * The node as the model wrote it, by the id the checked tree gives it\n * (AGL-3078), for a tree that was stored before it is checked: a page\n * section is checked as part of the page, whose props the palette validator\n * has already read, and a value it could not read is absent there. Absent,\n * the tree the check is given is what the model wrote.\n */\n writtenNode?: (id: string) => unknown\n /**\n * The page's sections by their names in its plan, in order, where the tree\n * is a page a plan lays out (AGL-3097). A Button or a Screen Link may then go\n * to one of them, by `scrollTo` naming it or an `href` fragment its name's\n * words make up, which the page step writes as the platform's Scroll to\n * element interaction. Absent: a link goes only where its `screenId` or\n * `href` says.\n */\n pageSections?: readonly string[]\n /**\n * The section roots of the page, by id, where the tree checked is the page as\n * the page step stores it (AGL-3097): a link there that carries a Scroll to\n * element interaction to one of them, built or still to come, goes there.\n * Only a stored page is given them. The palette validator drops every\n * interaction a model writes before anything is stored, and an answer's own\n * are never read.\n */\n scrollTargetIds?: readonly string[]\n}\n\n/** One node of a walk: its id, its depth, and its ancestors' ids from the root down. */\nexport interface Visit {\n id: string\n node: AiDoctrineNode\n depth: number\n ancestors: string[]\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Every reachable node in document order, each once. Exported for a door's\n * own checks (`extend`), which read a tree the way these detectors do.\n */\nexport function walkTree(tree: AiDoctrineTree): Visit[] {\n const visits: Visit[] = []\n const seen = new Set<string>()\n const stack: Array<{ id: string; depth: number; ancestors: string[] }> = [\n { id: tree.rootId, depth: 0, ancestors: [] },\n ]\n while (stack.length) {\n const { id, depth, ancestors } = stack.pop() as (typeof stack)[number]\n const node = tree.nodes[id]\n if (!node || seen.has(id)) continue\n seen.add(id)\n visits.push({ id, node, depth, ancestors })\n const children = node.nodes ?? []\n for (let index = children.length - 1; index >= 0; index -= 1) {\n stack.push({ id: children[index], depth: depth + 1, ancestors: [...ancestors, id] })\n }\n }\n return visits\n}\n\nfunction displayName(componentId: string): string {\n return AI_PALETTE[componentId]?.displayName ?? componentId\n}\n\n/** The HTML element a node was told to render as. */\nfunction elementOf(node: AiDoctrineNode | undefined): string {\n const value = node?.props?.['component'] ?? node?.props?.['element']\n return typeof value === 'string' ? value : ''\n}\n\nfunction hasAncestor(\n tree: AiDoctrineTree,\n visit: Visit,\n test: (node: AiDoctrineNode) => boolean,\n): boolean {\n return visit.ancestors.some((id) => {\n const node = tree.nodes[id]\n return node ? test(node) : false\n })\n}\n\nfunction unique<T>(values: T[]): T[] {\n return [...new Set(values)]\n}\n\nfunction listNames(ids: string[], tree: AiDoctrineTree): string {\n const names = unique(ids.map((id) => displayName(tree.nodes[id]?.componentId ?? '')))\n return names.length <= 1\n ? names.join('')\n : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n}\n\n// Rule 1 and rule 8 read the same index: which subtrees share a shape.\n\n/** Below this, a repeat is a row of buttons, not a block worth a component. */\nexport const AI_REPEAT_MIN_NODES = 3\n/** Rule 1: a block on one page this many times is a component. */\nexport const AI_REPEAT_MIN_COUNT = 3\n/** Rule 1 across pages: a block this large on two pages is a component. */\nexport const AI_REPEAT_ACROSS_PAGES_MIN_NODES = 5\n/** Rule 8: a hand-typed list this long is data. */\nexport const AI_TYPED_LIST_MIN_ITEMS = 8\n\ninterface ShapeIndex {\n visits: Visit[]\n shapeOf: Map<string, string>\n sizeOf: Map<string, number>\n}\n\n/**\n * A subtree's shape: element ids, the prop NAMES it sets, and the values of\n * the props that change structure (enums, switches, numbers) — but never the\n * values of copy, links or media, which is what differs between the twelve\n * cards that should have been one component.\n */\nfunction indexShapes(tree: AiDoctrineTree): ShapeIndex {\n const shapeOf = new Map<string, string>()\n const sizeOf = new Map<string, number>()\n const visits = walkTree(tree)\n for (let index = visits.length - 1; index >= 0; index -= 1) {\n const { id, node } = visits[index]\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n const props = Object.keys(node.props ?? {})\n .sort()\n .map((key) => {\n const declared = schema[key]\n const structural =\n Boolean(declared?.enum) ||\n declared?.type === 'boolean' ||\n declared?.type === 'number' ||\n declared?.type === 'integer'\n return structural ? `${key}=${String(node.props?.[key])}` : key\n })\n .join(',')\n const children = (node.nodes ?? []).filter((child) => shapeOf.has(child))\n shapeOf.set(\n id,\n `${node.componentId}(${props})[${children.map((child) => shapeOf.get(child)).join('|')}]`,\n )\n sizeOf.set(id, 1 + children.reduce((sum, child) => sum + (sizeOf.get(child) ?? 0), 0))\n }\n return { visits, shapeOf, sizeOf }\n}\n\n/** Whether a node sits inside a collection repeater, whose child is authored once and repeated by data. */\nfunction repeatedByData(tree: AiDoctrineTree, visit: Visit): boolean {\n return hasAncestor(tree, visit, (node) => node.componentId === 'collectionEntries')\n}\n\n/**\n * Shapes that repeat at least `minCount` times, reported only where they are\n * the outermost repeat: the header inside each of twelve cards repeats\n * because the card does, and the fix is the card. `groupOf` counts each\n * group's repeats apart; absent, the whole tree is one group.\n */\nfunction repeatedShapes(\n tree: AiDoctrineTree,\n index: ShapeIndex,\n minNodes: number,\n minCount: number,\n groupOf: (visit: Visit) => string = () => tree.rootId,\n skip: (visit: Visit) => boolean = () => false,\n): Array<{ shape: string; ids: string[] }> {\n const byShape = new Map<string, string[]>()\n for (const visit of index.visits) {\n if (visit.id === tree.rootId) continue\n if ((index.sizeOf.get(visit.id) ?? 0) < minNodes) continue\n if (repeatedByData(tree, visit) || skip(visit)) continue\n const shape = JSON.stringify([groupOf(visit), index.shapeOf.get(visit.id)])\n byShape.set(shape, [...(byShape.get(shape) ?? []), visit.id])\n }\n const repeated = [...byShape.entries()].filter(([, ids]) => ids.length >= minCount)\n const repeatedIds = new Set(repeated.flatMap(([, ids]) => ids))\n const ancestorsOf = new Map(index.visits.map((visit) => [visit.id, visit.ancestors]))\n return repeated\n .filter(\n ([, ids]) =>\n !ids.every((id) => (ancestorsOf.get(id) ?? []).some((ancestor) => repeatedIds.has(ancestor))),\n )\n .map(([shape, ids]) => ({ shape, ids }))\n}\n\n/** Elements that frame and space what they hold, as rule 1 reads a frame. */\nconst REPEAT_FRAMES = new Set(['muiBox', 'muiStack', 'muiContainer', 'muiGrid', 'section', 'muiList'])\n\n/**\n * What rule 1 does not call a block (AGL-3660), however like another it is:\n *\n * - a part of the page's OUTLINE — anything holding a heading at h1 or h2.\n * Three sections that each open with an h2 over a row of items share a\n * shape because a page has sections, and a component cannot carry the\n * page's outline: a heading inside one is no heading of the page.\n * - a FRAME OF ITEMS — a Grid container, a List, or a Stack of like\n * elements — and any frame that holds only such frames. What repeats in\n * it is its items, which are judged on their own: two rows of three\n * instances of two different components are not one block.\n *\n * So rule 1 still refuses three like cards, and the same card on two pages;\n * it no longer refuses a page for having more than two sections, or more than\n * two groups.\n */\nfunction aiRepeatFrameOrSection(tree: AiDoctrineTree): (visit: Visit) => boolean {\n const memo = new Map<string, boolean>()\n const childrenOf = (id: string) => (tree.nodes[id]?.nodes ?? []).filter((child) => tree.nodes[child])\n const holdsOutline = (id: string): boolean => {\n const node = tree.nodes[id]\n const level = node ? aiHeadingLevel(node) : null\n return (level !== null && level <= 2) || childrenOf(id).some(holdsOutline)\n }\n const itemFrame = (id: string): boolean => {\n const node = tree.nodes[id]\n if (!node) return false\n if (node.componentId === 'muiGrid' && node.props?.['container'] === true) return true\n if (node.componentId === 'muiList') return true\n const children = childrenOf(id)\n // A Stack of like blocks — cards, rows, panels — and never of lines of text.\n const kinds = new Set(children.map((child) => tree.nodes[child].componentId))\n return (\n node.componentId === 'muiStack' &&\n children.length >= 2 &&\n kinds.size === 1 &&\n children.every((child) => (tree.nodes[child].nodes ?? []).length > 0)\n )\n }\n const parentOf = new Map<string, string>()\n for (const [id, node] of Object.entries(tree.nodes)) for (const child of node?.nodes ?? []) parentOf.set(child, id)\n const exempt = (id: string): boolean => {\n const known = memo.get(id)\n if (known !== undefined) return known\n const node = tree.nodes[id]\n const children = childrenOf(id)\n const parent = parentOf.get(id)\n const result =\n // An item of a frame is an item, whatever heading it carries.\n (holdsOutline(id) && !(parent !== undefined && itemFrame(parent))) ||\n itemFrame(id) ||\n (!!node && REPEAT_FRAMES.has(node.componentId) && children.length > 0 && children.every(exempt))\n memo.set(id, result)\n return result\n }\n return (visit) => exempt(visit.id)\n}\n\n/**\n * Rule 1. A block repeated on one page, or a block this page shares with\n * another page generated beside it, is one component placed as instances.\n *\n * A workspace that keeps no reusable components can place no instance, so\n * there a repeated block is drawn where it repeats, and nothing is refused.\n */\nexport function detectRepeatedSubtrees(\n tree: AiDoctrineTree,\n otherPages: readonly AiDoctrineTree[] = [],\n context: Pick<AiDoctrineTreeContext, 'reusableComponents' | 'repeatsCompiled'> = {},\n): AiDoctrineViolation[] {\n if (context.reusableComponents === false) return []\n const index = indexShapes(tree)\n /**\n * A compiled picture card (AGL-3660): a Stack that opens with its picture,\n * in a cell of a grid — or that cell, holding only the card. A storefront's\n * icon column (AGL-3676), a Stack that opens with its library icon, is the\n * compiler's the same way: no model writes an Icon on a page.\n */\n const card = (id: string | undefined): boolean => {\n const node = id === undefined ? undefined : tree.nodes[id]\n const first = node?.nodes?.[0]\n const opens = first === undefined ? undefined : tree.nodes[first]?.componentId\n return node?.componentId === 'muiStack' && (opens === 'image' || opens === 'icon')\n }\n const pictureCard = (id: string): boolean => {\n const node = tree.nodes[id]\n if (node?.componentId === 'muiGrid' && node.props?.['container'] !== true) return node.nodes?.length === 1 && card(node.nodes[0])\n const parentId = index.visits.find((visit) => visit.id === id)?.ancestors.at(-1)\n return card(id) && parentId !== undefined && tree.nodes[parentId]?.componentId === 'muiGrid'\n }\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES,\n AI_REPEAT_MIN_COUNT,\n // Counted within the band of the page it sits in (AGL-3660), as rule 8\n // counts a typed list: a heading over its words in the About band and in\n // the Services band are two parts of two stories, not one block placed twice.\n (visit) => [...visit.ancestors].reverse().find((id) => tree.nodes[id]?.componentId === 'section') ?? tree.rootId,\n aiRepeatFrameOrSection(tree),\n )\n .filter(({ ids }) => !(context.repeatsCompiled && ids.every(pictureCard)))\n .map(({ ids }) => {\n const name = displayName(tree.nodes[ids[0]].componentId)\n return {\n rule: 1,\n code: 'repeated-subtree',\n message: `The same ${name} block appears ${ids.length} times. Make it one reusable component with props for what changes, and place it ${ids.length} times.`,\n nodeIds: ids,\n }\n })\n if (otherPages.length) {\n const elsewhere = new Set<string>()\n for (const other of otherPages) {\n const otherIndex = indexShapes(other)\n for (const visit of otherIndex.visits) {\n if (visit.id === other.rootId) continue\n if ((otherIndex.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES) {\n elsewhere.add(otherIndex.shapeOf.get(visit.id) as string)\n }\n }\n }\n const shared = index.visits.filter(\n (visit) =>\n visit.id !== tree.rootId &&\n (index.sizeOf.get(visit.id) ?? 0) >= AI_REPEAT_ACROSS_PAGES_MIN_NODES &&\n elsewhere.has(index.shapeOf.get(visit.id) as string),\n )\n const sharedIds = new Set(shared.map((visit) => visit.id))\n const outermost = shared.filter((visit) => !visit.ancestors.some((id) => sharedIds.has(id)))\n for (const visit of outermost) {\n violations.push({\n rule: 1,\n code: 'repeated-across-pages',\n message: `This page and another share the same ${displayName(visit.node.componentId)} block. Make it one reusable component and place it on both.`,\n nodeIds: [visit.id],\n })\n }\n }\n return violations\n}\n\n/**\n * How many copies of one repeated thing a document shows, read as\n * generously as the tree allows (AGL-3024): the largest group of nodes the\n * shape index calls the same shape — the index rule 1 counts repeats with —\n * or, where a node's children outnumber that, its fan-out.\n *\n * GENEROUS ON PURPOSE. The one caller compares this against a count a plan\n * promised and speaks only when the count is SHORT, so every reading that\n * finds more items makes the check quieter, never louder: three cards whose\n * headings a hero's subtitle happens to match read as four and are let\n * through, and four cards laid out as two rows of two read as four either by\n * their shared shape or by the rows' fan-out. What it cannot do is find four\n * items in a document that holds three of everything.\n */\nexport function aiRepeatedItemCount(tree: AiDoctrineTree): number {\n const index = indexShapes(tree)\n const byShape = new Map<string, number>()\n let most = 0\n for (const visit of index.visits) {\n if (visit.id !== tree.rootId) {\n const shape = index.shapeOf.get(visit.id)\n if (shape) {\n const count = (byShape.get(shape) ?? 0) + 1\n byShape.set(shape, count)\n if (count > most) most = count\n }\n }\n const children = (visit.node.nodes ?? []).filter((id) => tree.nodes[id]).length\n if (children > most) most = children\n }\n return most\n}\n\n/** Whether a document draws its repeated items from a collection, which fills them at render. */\nexport function aiBindsRepeatedItems(tree: AiDoctrineTree): boolean {\n return walkTree(tree).some(({ node }) => node.componentId === 'collectionEntries')\n}\n\nconst REGION_ELEMENTS = new Set(['header', 'footer', 'nav'])\nconst REGION_WORDS: Record<string, string> = {\n header: 'header',\n footer: 'footer',\n nav: 'navigation',\n}\n\n/**\n * The regions a layout is built out of, and how each one is found in a tree\n * (AGL-3024): the landmark elements it may be written as, and the palette\n * elements that ARE one wherever they appear.\n *\n * A CLOSED vocabulary, because it is what a plan's promise of a region is\n * checked against: a planner naming a region outside it has promised\n * something no check can find, which the plan rules refuse rather than let\n * pass as built.\n */\nexport const AI_LAYOUT_REGIONS = {\n header: { elements: ['header'], componentIds: ['muiAppBar'] },\n nav: { elements: ['nav'], componentIds: [] },\n sidebar: { elements: ['aside'], componentIds: [] },\n main: { elements: ['main'], componentIds: ['layoutSlot'] },\n footer: { elements: ['footer'], componentIds: [] },\n} as const satisfies Record<string, { elements: readonly string[]; componentIds: readonly string[] }>\n\nexport type AiLayoutRegion = keyof typeof AI_LAYOUT_REGIONS\n\nexport const AI_LAYOUT_REGION_NAMES = Object.keys(AI_LAYOUT_REGIONS) as AiLayoutRegion[]\n\n/** The words a plan may name each region by, beyond the region's own name. */\nconst LAYOUT_REGION_ALIASES: Readonly<Record<string, AiLayoutRegion>> = {\n 'app bar': 'header',\n masthead: 'header',\n 'top bar': 'header',\n navigation: 'nav',\n 'nav bar': 'nav',\n menu: 'nav',\n aside: 'sidebar',\n 'side bar': 'sidebar',\n 'side nav': 'sidebar',\n drawer: 'sidebar',\n rail: 'sidebar',\n slot: 'main',\n 'layout slot': 'main',\n content: 'main',\n}\n\n/**\n * The region a plan's word names, or `null` for a word the vocabulary does\n * not hold.\n *\n * Read the way a recorded plan writes one. A planner names a region as\n * `header`, as `layoutSlot:slot` or as `footer:region (firm name, address)`,\n * so the name is what stands before the first colon, capitals are word\n * breaks, and a trailing \"region\" or \"area\" is filler once the whole name has\n * been tried: \"Sidebar region\", \"side-bar\" and `sidebar:links` are one thing.\n */\nexport function aiLayoutRegionOf(word: string): AiLayoutRegion | null {\n const cleaned = word\n .split(':')[0]\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n const read = (value: string): AiLayoutRegion | null =>\n (AI_LAYOUT_REGION_NAMES as string[]).includes(value)\n ? (value as AiLayoutRegion)\n : (LAYOUT_REGION_ALIASES[value] ?? null)\n if (!cleaned) return null\n return read(cleaned) ?? read(cleaned.replace(/\\s+(?:region|area)$/, ''))\n}\n\n/** Every region a built tree carries, by the elements and palette elements it holds. */\nexport function aiTreeLayoutRegions(tree: AiDoctrineTree): Set<AiLayoutRegion> {\n const found = new Set<AiLayoutRegion>()\n for (const { node } of walkTree(tree)) {\n const element = elementOf(node)\n for (const region of AI_LAYOUT_REGION_NAMES) {\n const where = AI_LAYOUT_REGIONS[region]\n if (\n (element && (where.elements as readonly string[]).includes(element)) ||\n (where.componentIds as readonly string[]).includes(node.componentId)\n ) {\n found.add(region)\n }\n }\n }\n return found\n}\n\n/**\n * Rule 2. A page carries no copy of what every page carries: an app bar, or\n * a header, navigation or footer element near the top of the document. The\n * header of an article inside the page is the article's, not the site's.\n */\nexport function detectLayoutRegions(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind !== 'page' && outputKind !== 'template') return []\n const found: Array<{ id: string; region: string }> = []\n for (const visit of walkTree(tree)) {\n if (visit.id === tree.rootId) continue\n if (visit.node.componentId === 'muiAppBar') {\n found.push({ id: visit.id, region: 'header' })\n continue\n }\n const element = elementOf(visit.node)\n if (\n REGION_ELEMENTS.has(element) &&\n visit.depth <= 3 &&\n !hasAncestor(tree, visit, (node) => elementOf(node) === 'article')\n ) {\n found.push({ id: visit.id, region: REGION_WORDS[element] })\n }\n }\n if (!found.length) return []\n const regions = unique(found.map((entry) => entry.region)).join(' and ')\n return [\n {\n rule: 2,\n code: 'layout-region-in-screen',\n message: `This page carries its own site ${regions}. Headers, navigation and footers live in the site's layout; put the page in the layout instead of copying them onto it.`,\n nodeIds: found.map((entry) => entry.id),\n },\n ]\n}\n\n/**\n * Rule 3. A form on a page is a Form bound by id to a form built on the\n * Forms page — fields, validation, consent and routing kept in one place.\n * Loose fields — a Form Field, or any of MUI's answer elements (an Input,\n * Select, Radio Group, Checkbox or Rating) — an unbound Form, and fields\n * drawn inside a bound Form (which\n * the page never renders: the placed form's own design replaces them) are\n * refused. A form's own design is the one place fields are drawn.\n *\n * On every plan (AGL-3596). A workspace that can save no form once drew an\n * unbound Form holding its fields (AGL-3030): inputs on a page with no saved\n * form behind them, no routing, no consent and nothing in the Forms list —\n * which is what a guided start shipped on its first production run. A page\n * with no saved form to place now places no form, so there is no exception\n * left to read: `reusableComponents` decides repeats only.\n */\nexport function detectInlineForms(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'form' || outputKind === 'email') return []\n const loose: string[] = []\n const unbound: string[] = []\n const shadowed: string[] = []\n for (const visit of walkTree(tree)) {\n if (\n isFormInputNode(visit.node as never) &&\n !hasAncestor(tree, visit, (node) => node.componentId === 'form')\n ) {\n loose.push(visit.id)\n }\n if (visit.node.componentId === 'form') {\n const bound = visit.node.props?.['formId']\n if (typeof bound === 'string' && bound) {\n if ((visit.node.nodes ?? []).length) shadowed.push(visit.id)\n } else {\n unbound.push(visit.id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (loose.length || unbound.length) {\n violations.push({\n rule: 3,\n code: 'inline-form',\n message:\n 'This draws a form inline. Place a saved form from the Forms page by its id, or, where the site has none to place, leave the form off the page.',\n nodeIds: [...unbound, ...loose],\n })\n }\n if (shadowed.length) {\n violations.push({\n rule: 3,\n code: 'fields-inside-bound-form',\n message:\n 'This form is placed by its id, so its fields come from the Forms page. Remove the copies of the fields drawn inside it.',\n nodeIds: shadowed,\n })\n }\n return violations\n}\n\nconst COLOR_SX_KEYS = new Set(['color', 'bgcolor', 'backgroundColor', 'borderColor'])\nconst COLOR_IN_VALUE_SX_KEYS = new Set([\n 'border',\n 'borderTop',\n 'borderRight',\n 'borderBottom',\n 'borderLeft',\n 'boxShadow',\n])\nconst SPACING_SX_KEYS = new Set([\n 'm',\n 'mt',\n 'mr',\n 'mb',\n 'ml',\n 'mx',\n 'my',\n 'margin',\n 'marginTop',\n 'marginRight',\n 'marginBottom',\n 'marginLeft',\n 'p',\n 'pt',\n 'pr',\n 'pb',\n 'pl',\n 'px',\n 'py',\n 'padding',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'gap',\n 'rowGap',\n 'columnGap',\n])\nconst TYPE_SX_KEYS = new Set(['fontSize', 'lineHeight', 'letterSpacing'])\nconst COLOR_KEYWORDS = new Set([\n 'inherit',\n 'transparent',\n 'currentcolor',\n 'initial',\n 'unset',\n 'none',\n])\nconst LITERAL_COLOR =\n /#[0-9a-f]{3,8}\\b|\\b(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\\s*\\(|\\b(?:black|white|red|green|blue|yellow|orange|purple|pink|gray|grey|brown|cyan|magenta|navy|teal|maroon|olive|lime|aqua|silver|gold|indigo|violet|beige|coral|crimson|salmon|tomato|turquoise|khaki|lavender|ivory|azure)\\b/i\nconst LENGTH_WITH_UNIT = /-?\\d*\\.?\\d+\\s*(?:px|rem|em|pt|vh|vw|ch)\\b/i\nconst paletteTokens = new Set<string>(AI_SX_TOKENS.palette)\n\n/** Whether a value names a color by value rather than by theme token. */\nfunction hasLiteralColor(value: unknown): boolean {\n if (typeof value !== 'string') return false\n const parts = value\n .trim()\n .split(/\\s+/)\n .filter((part) => !paletteTokens.has(part) && !COLOR_KEYWORDS.has(part.toLowerCase()))\n return LITERAL_COLOR.test(parts.join(' '))\n}\n\n/** An `sx` value and each of its responsive values. */\nfunction sxValues(value: unknown): unknown[] {\n return isRecord(value) ? Object.values(value) : [value]\n}\n\n/**\n * Rule 5. Every color, spacing, radius and type size is a theme token. A\n * color the theme lacks is a theme change for the theme door to draft, not a\n * value written onto one element.\n */\nexport function detectLiteralStyles(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const colors: string[] = []\n const lengths: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n for (const value of sxValues(raw)) {\n if ((COLOR_SX_KEYS.has(key) || COLOR_IN_VALUE_SX_KEYS.has(key)) && hasLiteralColor(value)) {\n colors.push(id)\n } else if (\n (SPACING_SX_KEYS.has(key) || key === 'borderRadius' || TYPE_SX_KEYS.has(key)) &&\n typeof value === 'string' &&\n LENGTH_WITH_UNIT.test(value)\n ) {\n lengths.push(id)\n } else if (key === 'fontSize' && typeof value === 'number' && value > 0) {\n lengths.push(id)\n }\n }\n }\n const schema = AI_PALETTE[node.componentId]?.propsSchema.properties ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (\n /(?:^|[a-z])(?:color|Color|bgcolor)$/.test(name) &&\n !schema[name]?.enum &&\n hasLiteralColor(value)\n ) {\n colors.push(id)\n }\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (colors.length) {\n violations.push({\n rule: 5,\n code: 'literal-color',\n message:\n \"This sets colors by value. Use the theme's color tokens, and propose a theme change for a color the theme does not have.\",\n nodeIds: unique(colors),\n })\n }\n if (lengths.length) {\n violations.push({\n rule: 5,\n code: 'literal-length',\n message:\n \"This sets spacing, corners or type sizes in fixed units. Use the theme's spacing scale, shape and typography styles.\",\n nodeIds: unique(lengths),\n })\n }\n return violations\n}\n\nfunction normalizeHex(value: string): string {\n const hex = value.trim().toLowerCase()\n return /^#[0-9a-f]{3}$/.test(hex)\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex\n}\n\n/**\n * Rule 6. An email is painted with the brand: its colors are the site's\n * brand colors and its fonts the brand's. A mail client cannot resolve a\n * theme token, so the brand's own values are what an email may name — and\n * with no brand recorded, the blocks' own defaults.\n */\nexport function detectOffBrandEmail(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n brand: AiDoctrineTreeContext['brand'],\n): AiDoctrineViolation[] {\n if (outputKind !== 'email') return []\n const allowed = new Set(Object.values(brand?.colors ?? {}).map(normalizeHex))\n const fonts = new Set((brand?.fonts ?? []).map((font) => font.toLowerCase()))\n const offBrand: string[] = []\n const values: string[] = []\n for (const { id, node } of walkTree(tree)) {\n const candidates: unknown[] = []\n for (const name of ['color', 'backgroundColor']) candidates.push(node.props?.[name])\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (COLOR_SX_KEYS.has(key)) candidates.push(...sxValues(raw))\n if (key === 'fontFamily') {\n for (const family of sxValues(raw)) {\n if (typeof family === 'string' && !fonts.has(family.trim().toLowerCase())) {\n offBrand.push(id)\n values.push(family.trim())\n }\n }\n }\n }\n for (const candidate of candidates) {\n if (typeof candidate !== 'string' || !candidate.trim()) continue\n if (!allowed.has(normalizeHex(candidate))) {\n offBrand.push(id)\n values.push(candidate.trim())\n }\n }\n }\n if (!offBrand.length) return []\n return [\n {\n rule: 6,\n code: 'off-brand-email',\n message: `This email uses ${unique(values).slice(0, 3).join(', ')}, outside the brand. Use the brand's colors and fonts so every email reads as the same sender.`,\n nodeIds: unique(offBrand),\n },\n ]\n}\n\n/** The props an email block is colored by, the ones rule 6 reads. */\nconst EMAIL_COLOR_PROPS = ['color', 'backgroundColor'] as const\n\ninterface Rgb {\n r: number\n g: number\n b: number\n}\n\n/**\n * A color as opaque RGB: hex of 3, 4, 6 or 8 digits, or `rgb()`/`rgba()`. A\n * translucent value is laid over white, the page an email is read on. `null`\n * for anything else, a name or a token included.\n */\nfunction emailRgbOf(value: string): (Rgb & { alpha: number }) | null {\n const text = value.trim().toLowerCase()\n const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.exec(text)?.[1]\n let r: number\n let g: number\n let b: number\n let alpha = 1\n if (hex) {\n const full = hex.length <= 4 ? [...hex].map((digit) => digit + digit).join('') : hex\n r = parseInt(full.slice(0, 2), 16)\n g = parseInt(full.slice(2, 4), 16)\n b = parseInt(full.slice(4, 6), 16)\n if (full.length === 8) alpha = parseInt(full.slice(6, 8), 16) / 255\n } else {\n const fn = /^rgba?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)$/.exec(text)\n if (!fn) return null\n r = Number(fn[1])\n g = Number(fn[2])\n b = Number(fn[3])\n if (fn[4] !== undefined) alpha = Number(fn[4])\n if (![r, g, b, alpha].every(Number.isFinite) || r > 255 || g > 255 || b > 255 || alpha > 1) return null\n }\n const over = (channel: number) => Math.round(channel * alpha + 255 * (1 - alpha))\n return { r: over(r), g: over(g), b: over(b), alpha }\n}\n\n/** How far apart two colors look: the weighted \"redmean\" RGB distance. */\nfunction emailColorDistance(a: Rgb, b: Rgb): number {\n const mean = (a.r + b.r) / 2\n const dr = a.r - b.r\n const dg = a.g - b.g\n const db = a.b - b.b\n return Math.sqrt((2 + mean / 256) * dr * dr + 4 * dg * dg + (2 + (255 - mean) / 256) * db * db)\n}\n\n/**\n * An email's off-brand colors, settled where each has one reading (AGL-3676).\n * Rule 6 holds an email to the brand's own values, and the guided start's\n * welcome email kept writing tints of them — a pale wash of the primary color\n * behind a section — and stopped on rule 6 after its re-ask. Before the tree\n * is checked, each `color` and `backgroundColor` outside the brand is:\n *\n * - a palette path the brand lists, such as `primary.main`: its value;\n * - a color that parses: the NEAREST opaque brand color, so a pale tint\n * becomes the brand's pale surface and a deep one its deep color;\n * - with no brand color recorded at all: dropped, leaving the block's own\n * default, which is what rule 6 asks of an email with no brand.\n *\n * A value that does not parse (a name, a CSS variable) is left for the\n * re-ask, and so is the whole tree when a snapped color would leave words\n * below 3:1 against what they sit on. Nothing is relaxed: the settled tree\n * is the one rule 6 checks.\n * Reads and returns the tree as the model wrote it.\n */\nexport function aiSettleOffBrandEmailColors(\n input: unknown,\n brand: AiDoctrineTreeContext['brand'],\n): unknown {\n if (!isRecord(input) || !isRecord(input['nodes'])) return input\n const entries = Object.entries(brand?.colors ?? {}).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string' && entry[1].trim() !== '',\n )\n const allowed = new Set(entries.map(([, value]) => normalizeHex(value)))\n const byPath = new Map(entries.map(([path, value]) => [path.toLowerCase(), value.trim()]))\n const targets = entries.flatMap(([, value]) => {\n const rgb = emailRgbOf(value)\n return rgb && rgb.alpha === 1 ? [{ value: value.trim(), rgb }] : []\n })\n const settle = (value: string): string | null | undefined => {\n if (!entries.length) return null\n const named = byPath.get(value.trim().toLowerCase())\n if (named) return named\n const rgb = emailRgbOf(value)\n if (!rgb || !targets.length) return undefined\n let best = targets[0]\n for (const target of targets) {\n if (emailColorDistance(rgb, target.rgb) < emailColorDistance(rgb, best.rgb)) best = target\n }\n return best.value\n }\n let nodes: Record<string, unknown> | null = null\n for (const [id, node] of Object.entries(input['nodes'])) {\n if (!isRecord(node) || !isRecord(node['props'])) continue\n let props: Record<string, unknown> | null = null\n for (const name of EMAIL_COLOR_PROPS) {\n const value = node['props'][name]\n if (typeof value !== 'string' || !value.trim() || allowed.has(normalizeHex(value))) continue\n const settled = settle(value)\n if (settled === undefined) continue\n props ??= { ...node['props'] }\n if (settled === null) delete props[name]\n else props[name] = settled\n }\n if (!props) continue\n nodes ??= { ...input['nodes'] }\n nodes[id] = { ...node, props }\n }\n if (!nodes || !targets.length) return nodes ? { ...input, nodes } : input\n // Two colors snapped onto one brand value can leave words the color of what\n // they sit on — a pale green heading on a cream band both become the cream.\n // A settle that leaves any color it touched unreadable is not one reading,\n // so the tree goes back as written and rule 6 asks the model.\n return emailSettleKeepsContrast(input['nodes'], nodes) ? { ...input, nodes } : input\n}\n\n/** The least contrast words keep on what they sit on once settled: WCAG's large-text floor. */\nconst EMAIL_SETTLED_MIN_CONTRAST = 3\n\nfunction emailLuminance({ r, g, b }: Rgb): number {\n const channel = (value: number) => {\n const c = value / 255\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4\n }\n return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b)\n}\n\nfunction emailContrast(a: Rgb, b: Rgb): number {\n const [light, dark] = [emailLuminance(a), emailLuminance(b)].sort((x, y) => y - x)\n return (light + 0.05) / (dark + 0.05)\n}\n\n/**\n * Whether every block whose words or ground the settle changed can still be\n * read: its `color` against its own `backgroundColor` (a button's fill), else\n * the nearest enclosing one, else the white an email is read on. A button\n * with no fill of its own is left out: its fill is the block's default.\n */\nfunction emailSettleKeepsContrast(\n written: Record<string, unknown>,\n settled: Record<string, unknown>,\n): boolean {\n const parentOf = new Map<string, string>()\n for (const [id, node] of Object.entries(settled)) {\n if (!isRecord(node) || !Array.isArray(node['nodes'])) continue\n for (const child of node['nodes']) if (typeof child === 'string') parentOf.set(child, id)\n }\n const propOf = (nodes: Record<string, unknown>, id: string, name: string): unknown => {\n const node = nodes[id]\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n /** The id whose background a node's words sit on, or `null` for the email's white. */\n const groundOf = (id: string): string | null | undefined => {\n if (typeof propOf(settled, id, 'backgroundColor') === 'string') return id\n const node = settled[id]\n if (isRecord(node) && node['componentId'] === 'emailButton') return undefined\n const seen = new Set<string>([id])\n for (let at = parentOf.get(id); at && !seen.has(at); at = parentOf.get(at)) {\n seen.add(at)\n if (typeof propOf(settled, at, 'backgroundColor') === 'string') return at\n }\n return null\n }\n const WHITE: Rgb = { r: 255, g: 255, b: 255 }\n for (const id of Object.keys(settled)) {\n const color = propOf(settled, id, 'color')\n if (typeof color !== 'string') continue\n const ground = groundOf(id)\n if (ground === undefined) continue\n const touched =\n color !== propOf(written, id, 'color') ||\n (ground !== null &&\n propOf(settled, ground, 'backgroundColor') !== propOf(written, ground, 'backgroundColor'))\n if (!touched) continue\n const text = emailRgbOf(color)\n const background = ground === null ? WHITE : emailRgbOf(String(propOf(settled, ground, 'backgroundColor')))\n if (!text || !background) continue\n if (emailContrast(text, background) < EMAIL_SETTLED_MIN_CONTRAST) return false\n }\n return true\n}\n\n/**\n * Rule 8 (tree). A long list typed out item by item is data: bound to a\n * dataset or a content collection it stays current; typed, it is a copy that\n * goes stale. Instances of one component filled in side by side are the same\n * list in a component's clothes, and are counted the same way.\n *\n * A list is counted within the Section it sits in, the unit a plan counts a\n * section's items in (AGL-3061): a page's four practice areas and its four\n * steps are two short lists that happen to share a card, not one long one,\n * and a plan that kept them must not build a page this refuses. The same\n * list split across a section's columns is still one list. A tree with no\n * Section is one group.\n */\nexport function detectTypedData(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const index = indexShapes(tree)\n const sectionOf = (visit: Visit): string =>\n [...visit.ancestors].reverse().find((id) => tree.nodes[id]?.componentId === 'section') ?? tree.rootId\n const violations: AiDoctrineViolation[] = repeatedShapes(\n tree,\n index,\n AI_REPEAT_MIN_NODES - 1,\n AI_TYPED_LIST_MIN_ITEMS,\n sectionOf,\n ).map(({ ids }) => ({\n rule: 8,\n code: 'typed-list',\n message: `${ids.length} ${displayName(tree.nodes[ids[0]].componentId)} items are typed out by hand. Bind the list to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n }))\n for (const visit of index.visits) {\n if (repeatedByData(tree, visit) || visit.node.componentId === 'collectionEntries') continue\n const byComponent = new Map<string, string[]>()\n for (const childId of visit.node.nodes ?? []) {\n const child = tree.nodes[childId]\n const ref = child?.props?.[AI_INSTANCE_REF_PROP]\n if (child?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID || typeof ref !== 'string') continue\n byComponent.set(ref, [...(byComponent.get(ref) ?? []), childId])\n }\n for (const ids of byComponent.values()) {\n if (ids.length < AI_TYPED_LIST_MIN_ITEMS) continue\n violations.push({\n rule: 8,\n code: 'typed-instances',\n message: `${ids.length} copies of one component are filled in by hand. Bind them to a dataset or content collection, or propose a dataset for data the site does not have yet.`,\n nodeIds: ids,\n })\n }\n }\n return violations\n}\n\n/**\n * An instance that fills none of the props its component declares (AGL-3024).\n *\n * Rule 1 says an instance is `\"reusableInstance\"` whose `refId` names the\n * component and whose `propValues` FILL its props, and until now nothing read\n * the second half back. A placed instance with no `propValues` is not empty on\n * the page: it renders the component's own `defaultValue` for every prop, so\n * three of them render three identical cards of placeholder text.\n *\n * MEASURED 2026-09-21 on `attorney-profile-template-v2` (`sak5ei_9Wv`), whose\n * three instances of `practice-area-card` each carried `{\"refId\": …}` and\n * nothing else. It was recorded as the component shipping placeholder content;\n * the component is correct and declares `title`, `description` and `icon` with\n * labels and descriptions. The template placed it three times and filled\n * nothing, so every attorney's page showed the same `[Practice area name]`.\n *\n * Only an instance filling NOTHING is refused. A component may declare a prop\n * whose default is right for most placements, and a partly filled instance is\n * a judgment the doctrine does not have the information to second-guess.\n */\nexport function detectUnfilledInstances(\n tree: AiDoctrineTree,\n context: Pick<AiDoctrineTreeContext, 'componentProps'>,\n): AiDoctrineViolation[] {\n const declared = context.componentProps ?? {}\n const unfilled: string[] = []\n for (const [id, node] of Object.entries(tree.nodes)) {\n if (node?.componentId !== REUSABLE_INSTANCE_COMPONENT_ID) continue\n const ref = node.props?.[AI_INSTANCE_REF_PROP]\n if (typeof ref !== 'string') continue\n const props = declared[ref]\n if (!props || !Object.keys(props).length) continue\n const values = node.props?.['propValues']\n const filled =\n typeof values === 'object' && values !== null && !Array.isArray(values)\n ? Object.keys(values as Record<string, unknown>).filter((name) => name in props)\n : []\n if (!filled.length) unfilled.push(id)\n }\n if (!unfilled.length) return []\n const first = tree.nodes[unfilled[0]]\n const ref = first?.props?.[AI_INSTANCE_REF_PROP] as string\n const names = Object.keys(declared[ref] ?? {})\n const one = unfilled.length === 1\n return [\n {\n rule: 1,\n code: 'instance-props-unfilled',\n message: `${\n one ? 'An instance places' : `${unfilled.length} instances place`\n } a component and fill none of its props, so ${\n one ? 'it shows' : 'they all show'\n } the placeholder text the component falls back to. Fill \"propValues\" with what ${\n one ? 'this one' : 'each one'\n } should say: ${names.join(', ')}.`,\n nodeIds: unfilled,\n },\n ]\n}\n\n/** The media-role props of a node, with the declared image props of an instance. */\nfunction mediaValues(\n node: AiDoctrineNode,\n context: AiNodeTreeContext,\n): Array<{ name: string; value: string }> {\n const out: Array<{ name: string; value: string }> = []\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'media' && typeof value === 'string' && value.trim()) {\n out.push({ name, value: value.trim() })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n if (declared[name] === 'image' && typeof value === 'string' && value.trim()) {\n out.push({ name: `${REUSABLE_INSTANCE_PROP_VALUES_KEY}.${name}`, value: value.trim() })\n }\n }\n }\n return out\n}\n\n/**\n * Rule 9. Images are placed from the media library — an asset, or an empty\n * slot for the author to fill — never hot-linked from another site, and\n * every picture carries alt text (or says it is decorative).\n */\nexport function detectImageSources(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiDoctrineViolation[] {\n const hotlinked: string[] = []\n const missingAlt: string[] = []\n for (const { id, node } of walkTree(tree)) {\n if (mediaValues(node, context).some(({ value }) => /^https?:\\/\\//i.test(value))) {\n hotlinked.push(id)\n }\n if (node.componentId === 'image' || node.componentId === 'emailImage') {\n const alt = node.props?.['alt']\n const decorative = node.props?.['decorative'] === true\n if (!decorative && (typeof alt !== 'string' || !alt.trim())) missingAlt.push(id)\n }\n }\n const violations: AiDoctrineViolation[] = []\n if (hotlinked.length) {\n violations.push({\n rule: 9,\n code: 'hotlinked-image',\n message:\n 'This loads images from another website. Place images from the media library, or leave the slot empty for an upload.',\n nodeIds: hotlinked,\n })\n }\n if (missingAlt.length) {\n violations.push({\n rule: 9,\n code: 'missing-alt',\n message:\n 'An image has no alt text. Describe what each picture shows, or mark a purely decorative one as decorative.',\n nodeIds: missingAlt,\n })\n }\n return violations\n}\n\n/**\n * A heading's level: the element it renders as, else the variant's own.\n * Exported for a door's own checks, which read an outline the way rule 11\n * reads a page's.\n */\nexport function aiHeadingLevel(node: AiDoctrineNode): number | null {\n if (node.componentId !== 'muiTypography') return null\n const element =\n typeof node.props?.['component'] === 'string' ? String(node.props['component']) : ''\n const match = /^h([1-6])$/.exec(element || String(node.props?.['variant'] ?? ''))\n return match ? Number(match[1]) : null\n}\n\n/**\n * Rule 11. One `main` landmark per document, and a heading outline that\n * starts at one `h1` and never skips a level. The platform places the one\n * landmark on the layout's slot, or on a page's root when it has no layout\n * (`stampDocumentLandmark`); a tree that declares two leaves it to pick the\n * wrong one. A component, a form or an email is placed inside pages, so it\n * carries no landmark of its own, and a layout carries no `h1`: every page\n * placed in it brings its own.\n */\nexport function detectDocumentStructure(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const mains = visits.filter((visit) => elementOf(visit.node) === 'main').map((visit) => visit.id)\n const violations: AiDoctrineViolation[] = []\n if (outputKind === 'component' || outputKind === 'email' || outputKind === 'form') {\n if (mains.length) {\n violations.push({\n rule: 11,\n code: 'landmark-in-fragment',\n message: `A ${outputKind} is placed inside pages, so it cannot carry the main landmark. Leave the element unset.`,\n nodeIds: mains,\n })\n }\n } else if (mains.length > 1) {\n violations.push({\n rule: 11,\n code: 'multiple-main',\n message: 'This declares more than one main landmark. A page has exactly one.',\n nodeIds: mains,\n })\n }\n if (outputKind === 'layout') {\n const slots = visits.filter((visit) => visit.node.componentId === 'layoutSlot')\n const rootElement = elementOf(tree.nodes[tree.rootId])\n const slotElement = slots[0] ? elementOf(slots[0].node) : ''\n // The landmark goes on the slot, else on the root — unless an author\n // chose another element for each.\n const chosenAway =\n rootElement !== '' &&\n rootElement !== 'main' &&\n (!slots.length || (slotElement !== '' && slotElement !== 'main'))\n if (slots.length !== 1 || chosenAway) {\n violations.push({\n rule: 11,\n code: 'layout-slot',\n message:\n 'A layout has exactly one Layout Slot, where each page renders, and the slot is the main landmark.',\n nodeIds: slots.map((slot) => slot.id),\n })\n }\n }\n if (outputKind === 'email' || outputKind === 'form') return violations\n\n const headings = visits\n .map((visit) => ({ id: visit.id, level: aiHeadingLevel(visit.node) }))\n .filter((entry): entry is { id: string; level: number } => entry.level !== null)\n const h1s = headings.filter((heading) => heading.level === 1).map((heading) => heading.id)\n const page = outputKind === 'page' || outputKind === 'template'\n if (page && h1s.length !== 1) {\n violations.push({\n rule: 11,\n code: h1s.length ? 'multiple-h1' : 'missing-h1',\n message: h1s.length\n ? `This page has ${h1s.length} top-level headings. A page has one h1; make the others h2.`\n : \"This page has no top-level heading. Give the page's title one h1.\",\n nodeIds: h1s,\n })\n } else if (!page && h1s.length > (outputKind === 'layout' ? 0 : 1)) {\n violations.push({\n rule: 11,\n code: 'multiple-h1',\n message:\n outputKind === 'layout'\n ? 'A layout wraps pages that bring their own h1, so it carries none.'\n : 'A component carries at most one h1.',\n nodeIds: h1s,\n })\n }\n const skipped: string[] = []\n let previous = page ? 0 : (headings[0]?.level ?? 1) - 1\n for (const heading of headings) {\n if (heading.level > previous + 1) skipped.push(heading.id)\n previous = heading.level\n }\n if (skipped.length) {\n violations.push({\n rule: 11,\n code: 'skipped-heading',\n message:\n 'The heading outline skips a level. Step down one level at a time — an h2 before any h3.',\n nodeIds: skipped,\n })\n }\n return violations\n}\n\nconst WIDTH_SX_KEYS = new Set(['width', 'minWidth', 'maxWidth'])\n\n/**\n * Rule 12. Widths follow the theme's breakpoints and the palette's\n * responsive props — a Container's max width, a Grid's span — never a fixed\n * pixel or viewport width that holds at one screen size. An email's column\n * is fixed by the medium, and is exempt.\n */\nexport function detectAdHocWidths(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n): AiDoctrineViolation[] {\n if (outputKind === 'email') return []\n const fixed: string[] = []\n for (const { id, node } of walkTree(tree)) {\n for (const [key, raw] of Object.entries(node.sx ?? {})) {\n if (!WIDTH_SX_KEYS.has(key)) continue\n for (const value of sxValues(raw)) {\n // MUI reads a number up to 1 as a fraction of the parent.\n if (\n (typeof value === 'number' && value > 1) ||\n (typeof value === 'string' && LENGTH_WITH_UNIT.test(value))\n ) {\n fixed.push(id)\n }\n }\n }\n }\n return fixed.length\n ? [\n {\n rule: 12,\n code: 'fixed-width',\n message:\n \"This sets fixed widths. Size elements with the theme's breakpoints — a Container's max width, a Grid span, or a percentage.\",\n nodeIds: unique(fixed),\n },\n ]\n : []\n}\n\nconst GRID = 'muiGrid'\n/** A Grid's props that only a container reads; on an item they do nothing. */\nconst GRID_CONTAINER_PROPS = ['direction', 'wrap', 'spacing', 'rowSpacing', 'columnSpacing', 'columns']\n/** A container's props that set what it holds side by side, which a group that only stacks never needs. */\nconst GRID_ROW_PROPS = ['wrap', 'columns', 'columnSpacing']\n/** The directions the palette keeps for a Grid, which lays out rows. */\nconst GRID_ROW_DIRECTIONS = ['row', 'row-reverse']\n/** A direction a Stack has and a Grid does not; the palette validator drops it from a Grid. */\nconst GRID_COLUMN_DIRECTION = /^column(?:-reverse)?$/i\n/** The elements an answer wraps a container's items in, where they belong in the container itself. */\nconst GRID_ITEM_WRAPPERS = new Set(['muiBox', 'muiStack'])\n/** `sx` keys that space a container's columns outside the widths its items are sized by. */\nconst GRID_GAP_SX_KEYS = ['gap', 'columnGap']\n/** The columns a container divides a row into when it names none. */\nconst GRID_DEFAULT_COLUMNS = 12\n/** The most characters of a written value a re-ask quotes back. */\nconst GRID_QUOTED_MAX_CHARS = 24\n\n/** A value as the model wrote it, as a re-ask quotes it: text in quotes, anything else as JSON, cut short. */\nfunction writtenValueText(value: unknown): string {\n const text = typeof value === 'string' ? value : (JSON.stringify(value) ?? String(value))\n const cut = text.length > GRID_QUOTED_MAX_CHARS ? `${text.slice(0, GRID_QUOTED_MAX_CHARS)}…` : text\n return typeof value === 'string' ? `the text \"${cut}\"` : cut\n}\n\n/** A Grid's columns: its own `columns` when it names a count, else the renderer's twelve. */\nfunction gridColumns(node: AiDoctrineNode): number {\n const columns = Number(node.props?.['columns'])\n return Number.isInteger(columns) && columns > 0 ? columns : GRID_DEFAULT_COLUMNS\n}\n\n/**\n * Whether a Grid item's size is one the renderer reads, full width on a phone,\n * and whether it steps down to a column at a larger width. The size is the\n * stored string the besigner's breakpoint row writes and the Grid renderer\n * parses (`parseBreakpointSpan`): a bare span at every width, or pairs such as\n * `xs:12 md:4`.\n */\nfunction gridItemSpan(size: unknown, columns: number): { phoneFull: boolean; steps: boolean } {\n if (typeof size !== 'string' && typeof size !== 'number') return { phoneFull: false, steps: false }\n const span = parseBreakpointSpan(size)\n if (span.raw !== undefined) return { phoneFull: false, steps: false }\n if (span.base !== undefined) return { phoneFull: span.base === columns, steps: false }\n const values = span.values ?? {}\n return {\n phoneFull: values.xs === columns,\n steps: Object.entries(values).some(([breakpoint, value]) => breakpoint !== 'xs' && value !== columns),\n }\n}\n\n/** The size a container's column is asked for: full width on a phone, a row of up to four from md. */\nfunction gridItemSizeFor(items: number, columns: number): string {\n const across = Math.min(Math.max(items, 2), 4)\n const md = Math.max(1, Math.floor(columns / (items > 4 ? 3 : across)))\n const sm = Math.floor(columns / 2)\n return items >= 4 && sm !== md ? `xs:${columns} sm:${sm} md:${md}` : `xs:${columns} md:${md}`\n}\n\n/**\n * Rule 12, for a Grid (AGL-3055). The palette's Grid is one element in both\n * roles: a CONTAINER lays its direct Grid children out in columns, and an ITEM\n * takes a size. The sizes are fractions of the container's columns, so an\n * item under a Grid that is not a container is sized against nothing, and a\n * row of them stacks one under another at every width; a size that holds at\n * every width keeps a phone's columns as narrow as a desktop's; and an `sx`\n * gap on a container spaces the columns outside the widths the items were\n * sized by, so the last column wraps onto a row of its own. A live About\n * page's practice areas were the first: a Grid with no container holding three\n * items sized \"4\", one column at every width.\n *\n * A Grid that is not a container is told what to do by what it was written as\n * (AGL-3078), because one sentence does not mend every shape: a live About\n * page's section was refused twice for rule 12, with a re-ask that only ever\n * said to make the Grid a container of sized columns.\n *\n * - `grid-not-container`: a row that is not a container. A Grid that holds\n * sized Grid items, sets a prop only a row reads, or holds two or more\n * elements of one shape side by side. The rule's intent: a row of cards is a\n * container of sized items.\n * - `grid-as-stack`: any other Grid that is not a container and sets a prop\n * only a container reads, or holds two or more elements without being an\n * item: a group that only stacks, such as a heading over its text, or one\n * written with a column direction, which a Grid does not have. The re-ask\n * offers a Stack or a Box for the group, or a container of sized items.\n * - `grid-item-outside-container`: a sized Grid item that sits in another\n * element, such as a Box inside its container. A container sizes only the\n * items directly in it, so the re-ask asks to move the item there. A Box or a\n * Stack in a container that holds nothing but sized items is refused through\n * its items, not as a child of the container that is no item.\n * - `grid-container-text`: a Grid whose `container` was written as a value the\n * palette validator cannot read as true or false, such as the text \"True\". The\n * re-ask names the value as the fault.\n * - `grid-item-size`: a container's child that is not a Grid item sized full\n * width on a phone, or a container of several whose items never step down\n * to columns at a larger width.\n * - `grid-gap`: a container spaced by an `sx` gap rather than its spacing.\n *\n * Each re-ask names the Grid or its items by the model's own ids and says what\n * to write, in the size format the renderer reads. `written` is the node as\n * the model wrote it, by an id of `tree`, where that is known: the palette\n * validator reads a `container` it cannot parse, and a column direction, as\n * absent, and only what was written can name them.\n */\nexport function detectUnresponsiveGrids(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n written: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n // Shapes are indexed only once a Grid needs its children compared.\n let shapes: ShapeIndex | null = null\n const shapeOf = (id: string): string | undefined => (shapes ??= indexShapes(tree)).shapeOf.get(id)\n const childrenOf = (id: string): string[] => (tree.nodes[id]?.nodes ?? []).filter((child) => tree.nodes[child])\n const isGrid = (id: string | undefined): boolean => id !== undefined && tree.nodes[id]?.componentId === GRID\n const isContainer = (id: string | undefined): boolean =>\n isGrid(id) && tree.nodes[id as string].props?.['container'] === true\n const isSized = (id: string): boolean => isGrid(id) && tree.nodes[id].props?.['size'] !== undefined\n const writtenProp = (id: string, name: string): unknown => {\n const node = written(id)\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n /** A `container` the model wrote that the palette validator could not read as true or false. */\n const unreadContainer = (id: string): unknown => {\n const value = writtenProp(id, 'container')\n return tree.nodes[id].props?.['container'] === undefined && value !== null ? value : undefined\n }\n /** A Box or a Stack holding nothing but sized Grid items, which belong directly in a container. */\n const wrapsItems = (id: string): boolean => {\n const children = childrenOf(id)\n return GRID_ITEM_WRAPPERS.has(tree.nodes[id].componentId) && children.length > 0 && children.every(isSized)\n }\n /** A direction the model wrote as a column, which the palette validator drops from a Grid. */\n const writtenColumn = (id: string): boolean => {\n const direction = writtenProp(id, 'direction')\n return typeof direction === 'string' && GRID_COLUMN_DIRECTION.test(direction.trim())\n }\n /** A Grid set out as a row: a row direction, a prop only a row reads, or elements of one shape. */\n const setsOutRow = (id: string, children: readonly string[]): boolean =>\n GRID_ROW_DIRECTIONS.includes(String(tree.nodes[id].props?.['direction'])) ||\n GRID_ROW_PROPS.some((name) => tree.nodes[id].props?.[name] !== undefined) ||\n (children.length >= 2 && new Set(children.map(shapeOf)).size === 1)\n\n const refused = new Set<string>()\n const rows: string[] = []\n const stacks: Array<{ id: string; column: boolean }> = []\n const outside: Array<{ id: string; within: string }> = []\n const texts: Array<{ id: string; value: unknown }> = []\n const unsized: string[] = []\n const suggested: string[] = []\n const gapped: Array<{ id: string; spacing: unknown }> = []\n for (const visit of walkTree(tree)) {\n const { id, node } = visit\n if (node.componentId !== GRID) continue\n const children = childrenOf(id)\n const [parentId, grandparentId] = [...visit.ancestors].reverse()\n const parent = parentId === undefined ? undefined : tree.nodes[parentId]\n const sized = node.props?.['size'] !== undefined\n // An item whose container sits one element above it: a Box or a Stack holding only items.\n const wrappedItem = sized && parentId !== undefined && wrapsItems(parentId) && isContainer(grandparentId)\n if (node.props?.['container'] !== true) {\n const holdsSized = children.some(isSized)\n // An item of a container, or of a Grid refused here for not being the container it is written as.\n const isItem =\n parentId !== undefined &&\n isGrid(parentId) &&\n (isContainer(parentId) ||\n childrenOf(parentId).some(isSized) ||\n (refused.has(parentId) && unreadContainer(parentId) !== undefined))\n const setsContainerProps = GRID_CONTAINER_PROPS.some((name) => node.props?.[name] !== undefined)\n if (!holdsSized && !setsContainerProps && (isItem || children.length < 2) && !wrappedItem) continue\n refused.add(id)\n const text = unreadContainer(id)\n if (text !== undefined) texts.push({ id, value: text })\n else if (holdsSized) rows.push(id)\n else if (sized && parent && parent.componentId !== GRID) outside.push({ id, within: parent.componentId })\n else if (writtenColumn(id)) stacks.push({ id, column: true })\n else if (setsOutRow(id, children)) rows.push(id)\n else stacks.push({ id, column: false })\n continue\n }\n if (wrappedItem && parent) outside.push({ id, within: parent.componentId })\n const columns = gridColumns(node)\n // The items a Box or a Stack holds for it are sized against it, and refused where they sit.\n const items = children.flatMap((child) => (wrapsItems(child) ? childrenOf(child) : [child]))\n let steps = false\n const offending: string[] = []\n for (const child of items) {\n const item = tree.nodes[child]\n const span = item.componentId === GRID ? gridItemSpan(item.props?.['size'], columns) : null\n if (!span?.phoneFull) offending.push(child)\n if (span?.steps) steps = true\n }\n if (offending.length) {\n unsized.push(...offending)\n } else if (items.length >= 2 && !steps) {\n unsized.push(...items)\n }\n if (offending.length || (items.length >= 2 && !steps)) {\n suggested.push(gridItemSizeFor(items.length, columns))\n }\n const sx = node.sx ?? {}\n const gap = GRID_GAP_SX_KEYS.find((key) => sx[key] !== undefined)\n if (gap) gapped.push({ id, spacing: sx[gap] })\n }\n const violations: AiDoctrineViolation[] = []\n if (rows.length) {\n violations.push({\n rule: 12,\n code: 'grid-not-container',\n message:\n 'A Grid lays out columns only as a container: this one is not, so what it holds stacks at every width. Set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".',\n nodeIds: unique(rows),\n })\n }\n if (stacks.length) {\n violations.push({\n rule: 12,\n code: 'grid-as-stack',\n message: `${\n stacks[0].column\n ? 'A Grid lays out rows and has no \"column\" direction, so this one only stacks what it holds.'\n : 'A Grid that is not a container lays nothing out, so this one only stacks what it holds.'\n } Use a Stack (or a Box) for a group that only stacks, such as a heading over its text, or make it a container of sized items: set \"container\": true on it, and put each column in a Grid item sized like \"xs:12 md:4\".`,\n nodeIds: unique(stacks.map((entry) => entry.id)),\n })\n }\n if (outside.length) {\n const within = displayName(outside[0].within)\n violations.push({\n rule: 12,\n code: 'grid-item-outside-container',\n message: `A Grid item is sized only by the Grid container it sits directly in, and this one sits in a ${within}, so its size does nothing and it stacks at every width. Move it directly under its Grid container, or, where it has none, put it and the items beside it in one (\"container\": true).`,\n nodeIds: unique(outside.map((entry) => entry.id)),\n })\n }\n if (texts.length) {\n const [first] = texts\n violations.push({\n rule: 12,\n code: 'grid-container-text',\n message: `This Grid's \"container\" is ${writtenValueText(first.value)}, not true, so it is not a container and what it holds stacks at every width. Write \"container\": true${\n typeof first.value === 'string' ? ', with no quotes around true' : ''\n }.`,\n nodeIds: unique(texts.map((entry) => entry.id)),\n })\n }\n if (unsized.length) {\n violations.push({\n rule: 12,\n code: 'grid-item-size',\n message: `Every child of a Grid container is a Grid item whose size is full width on a phone and steps up to columns at a larger width, written as one string. Size these like \"${suggested[0]}\", and wrap any other element in such an item.`,\n nodeIds: unique(unsized),\n })\n }\n if (gapped.length) {\n const [first] = gapped\n const spacing = typeof first.spacing === 'number' ? first.spacing : 2\n violations.push({\n rule: 12,\n code: 'grid-gap',\n message: `A Grid container's items are sized by its \"spacing\", so an sx gap pushes its last column onto a row of its own. Remove the sx gap and set \"spacing\": ${spacing}.`,\n nodeIds: gapped.map((entry) => entry.id),\n })\n }\n return violations\n}\n\n/** The breakpoints a size names, in the order the renderer's string writes them. */\nconst GRID_SIZE_BREAKPOINTS = ['xs', 'sm', 'md', 'lg', 'xl']\n\n/**\n * A size the model wrote as an object of breakpoints (`{ \"xs\": 12, \"md\": 4 }`),\n * which the palette validator drops because a size is stored as one string,\n * written as that string (`xs:12 md:4`). Anything else is not read.\n */\nfunction writtenGridSizeText(size: unknown): string | null {\n if (!isRecord(size)) return null\n const pairs: string[] = []\n for (const [breakpoint, value] of Object.entries(size)) {\n const span = typeof value === 'string' && value.trim() !== '' ? Number(value) : value\n if (!GRID_SIZE_BREAKPOINTS.includes(breakpoint) || typeof span !== 'number' || !Number.isInteger(span)) return null\n pairs.push(`${breakpoint}:${span}`)\n }\n pairs.sort((a, b) => GRID_SIZE_BREAKPOINTS.indexOf(a.split(':')[0]) - GRID_SIZE_BREAKPOINTS.indexOf(b.split(':')[0]))\n return pairs.length ? pairs.join(' ') : null\n}\n\n/**\n * Rule 12's `grid-item-size`, settled before the check reads it where it has\n * one answer (AGL-3596), as `aiSettlePlanRefs` settles a plan. The re-ask for\n * it states the very size to write, and a production Home page was refused and\n * refunded after its re-ask still left a container's items unsized: the model\n * breaks a different rule each run, and a rule whose answer the validator\n * already knows is applied rather than asked for.\n *\n * For every Grid container, its items are read exactly as\n * `detectUnresponsiveGrids` counts them, a Box or a Stack holding nothing but\n * sized Grid items lending its items to the container:\n *\n * - an item whose size is missing, or is not full width on a phone, takes the\n * size the model wrote as an object of breakpoints where that one is full\n * width on a phone, and otherwise the size the re-ask would ask for\n * (`gridItemSizeFor`);\n * - an element that is no Grid, directly in the container, is wrapped in a new\n * Grid item of that size, minted the way the palette validator mints ids;\n * - a container of several items none of which steps down to columns at a\n * larger width takes that size on every item, which is what the re-ask asks;\n * - a `container` written as the text \"true\" in any case or spacing\n * (`grid-container-text`) is true, since it can mean nothing else.\n *\n * A size that is already full width on a phone is kept. Nothing else rule 12\n * names is touched: a Grid that is not a container may be meant as a row or as\n * a stack (`grid-not-container`, `grid-as-stack`), and a sized item inside a\n * Box (`grid-item-outside-container`) is moved only by changing the Box.\n *\n * `written` is the node as the model wrote it, by an id of `tree`, as\n * `detectUnresponsiveGrids` reads it, for a tree the palette validator has\n * read; a tree as the model wrote it is read as it stands, which is how the\n * tree check settles a layout, a template or a component (`aiSettleWrittenGridItems`).\n * A tree with nothing to settle comes back\n * as the same object, so settling is idempotent. A node that is changed is\n * copied, never edited in place.\n */\nexport function aiSettleGridItems<T extends AiDoctrineTree>(\n tree: T,\n options: { written?: (id: string) => unknown; mintId?: () => string } = {},\n): T {\n const written = options.written ?? (() => undefined)\n const mintId = options.mintId ?? createIdUrlSafe\n const nodes: Record<string, AiDoctrineNode> = { ...tree.nodes }\n const copied = new Set<string>()\n const edit = (id: string): AiDoctrineNode & Record<string, unknown> => {\n if (!copied.has(id)) {\n const node = nodes[id]\n nodes[id] = { ...node, props: { ...node.props }, ...(node.nodes ? { nodes: [...node.nodes] } : {}) }\n copied.add(id)\n }\n return nodes[id] as AiDoctrineNode & Record<string, unknown>\n }\n const setSize = (id: string, size: string): void => {\n if (nodes[id].props?.['size'] === size) return\n ;(edit(id).props as Record<string, unknown>)['size'] = size\n }\n const writtenProp = (id: string, name: string): unknown => {\n const node = written(id)\n return isRecord(node) && isRecord(node['props']) ? node['props'][name] : undefined\n }\n const childrenOf = (id: string): string[] => (nodes[id]?.nodes ?? []).filter((child) => nodes[child])\n const isSized = (id: string): boolean => nodes[id]?.componentId === GRID && nodes[id].props?.['size'] !== undefined\n const wrapsItems = (id: string): boolean => {\n const children = childrenOf(id)\n return GRID_ITEM_WRAPPERS.has(nodes[id].componentId) && children.length > 0 && children.every(isSized)\n }\n\n for (const { id } of walkTree(tree)) {\n if (nodes[id].componentId !== GRID) continue\n if (nodes[id].props?.['container'] !== true) {\n // Text the palette validator dropped, or, in a tree as the model wrote it, the prop itself.\n const own = nodes[id].props?.['container']\n const text = own === undefined ? writtenProp(id, 'container') : own\n if (typeof text !== 'string' || text.trim().toLowerCase() !== 'true') continue\n ;(edit(id).props as Record<string, unknown>)['container'] = true\n }\n const container = nodes[id]\n const columns = gridColumns(container)\n const children = childrenOf(id)\n const items = children.flatMap((child) => (wrapsItems(child) ? childrenOf(child) : [child]))\n if (!items.length) continue\n const size = gridItemSizeFor(items.length, columns)\n const settledItems: string[] = []\n for (const item of items) {\n if (nodes[item].componentId !== GRID) {\n // Only a direct child can be no Grid: a wrapper lends only sized Grid items.\n const wrapperId = mintId()\n const host = edit(id)\n host.nodes = (host.nodes ?? []).map((child) => (child === item ? wrapperId : child))\n const shape = container as AiDoctrineNode & Record<string, unknown>\n nodes[wrapperId] = {\n ...('$id' in shape ? { $id: wrapperId } : {}),\n ...('type' in shape ? { type: shape['type'] } : {}),\n componentId: GRID,\n ...('pluginId' in shape ? { pluginId: shape['pluginId'] } : {}),\n ...('parentId' in shape ? { parentId: id } : {}),\n nodes: [item],\n props: { size },\n } as AiDoctrineNode\n copied.add(wrapperId)\n if ('parentId' in (nodes[item] as unknown as Record<string, unknown>)) edit(item)['parentId'] = wrapperId\n settledItems.push(wrapperId)\n continue\n }\n if (!gridItemSpan(nodes[item].props?.['size'], columns).phoneFull) {\n const own = writtenGridSizeText(writtenProp(item, 'size') ?? nodes[item].props?.['size'])\n setSize(item, own !== null && gridItemSpan(own, columns).phoneFull ? own : size)\n }\n settledItems.push(item)\n }\n const steps = settledItems.some((item) => gridItemSpan(nodes[item].props?.['size'], columns).steps)\n if (settledItems.length >= 2 && !steps) for (const item of settledItems) setSize(item, size)\n }\n return copied.size ? ({ ...tree, nodes } as T) : tree\n}\n\n/**\n * `aiSettleGridItems` on a tree as the model wrote it, before the palette\n * validator reads it (AGL-3596): the tree check every kind but a page section\n * goes through stores what the validator makes of its answer, so the answer\n * is settled first. Anything that is no flat node map comes back as it was.\n */\nexport function aiSettleWrittenGridItems(input: unknown): unknown {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return input\n const nodes = Object.fromEntries(Object.entries(input['nodes']).filter(([, node]) => isRecord(node)))\n const tree = { rootId: input['rootId'], nodes: nodes as unknown as Record<string, AiDoctrineNode> }\n const settled = aiSettleGridItems(tree)\n return settled === tree ? input : { ...input, nodes: { ...input['nodes'], ...settled.nodes } }\n}\n\n/** The palette colors a link or a button can take, and a band can be painted in. */\nconst LINK_COLOR_FAMILIES = new Set(['primary', 'secondary', 'success', 'error', 'info', 'warning'])\n/** The elements a page links with; each draws its words in its `color` unless told otherwise. */\nconst LINK_COMPONENTS = new Set(['muiButton', 'muiScreenLink'])\n\n/** Whether an element is one rule 10 holds to a destination: a Button or a Screen Link. */\nexport function isAiLinkElement(componentId: unknown): boolean {\n return typeof componentId === 'string' && LINK_COMPONENTS.has(componentId)\n}\n\n/** Surfaces that paint their own background, whatever band they sit on. */\nconst PAPER_COMPONENTS = new Set(['muiCard', 'muiPaper', 'muiAccordion', 'muiDrawer'])\n/** A palette color token of a link family: `primary.main`, `secondary.dark`. */\nconst FAMILY_TOKEN = /^([a-z]+)\\.(?:main|dark|light)$/\n\n/** The link family a color value names, if it names one. */\nfunction familyOf(value: unknown): string | null {\n const family = typeof value === 'string' ? FAMILY_TOKEN.exec(value.trim())?.[1] : undefined\n return family && LINK_COLOR_FAMILIES.has(family) ? family : null\n}\n\n/**\n * The band a node sits on: the nearest ancestor that paints a background. An\n * `sx` background in a link family's color is a band of that family, and an\n * App Bar is one in its `color`, which is primary when it names none. Any\n * other background, and every paper surface, is not.\n */\nfunction bandOf(tree: AiDoctrineTree, visit: Visit): { family: string; token: string } | null {\n for (const id of [...visit.ancestors].reverse()) {\n const node = tree.nodes[id]\n if (!node) continue\n const background = node.sx?.['bgcolor'] ?? node.sx?.['backgroundColor']\n if (background !== undefined) {\n const token = sxValues(background).find((value) => familyOf(value) !== null)\n return typeof token === 'string' ? { family: familyOf(token) as string, token: token.trim() } : null\n }\n if (node.componentId === 'muiAppBar') {\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n return LINK_COLOR_FAMILIES.has(color) ? { family: color, token: `${color}.main` } : null\n }\n if (PAPER_COMPONENTS.has(node.componentId)) return null\n }\n return null\n}\n\n/**\n * The palette family a link or a button draws its words in: its own `sx`\n * color when it sets one, else its `color` (primary when it names none). A\n * link told to inherit takes the band's own, and a contained button draws its\n * label in the family's contrast text on a fill of its own.\n */\nfunction linkWordsFamily(node: AiDoctrineNode): string | null {\n const own = node.sx?.['color']\n if (own !== undefined) {\n return sxValues(own).map(familyOf).find((family) => family !== null) ?? null\n }\n const color = typeof node.props?.['color'] === 'string' ? node.props['color'] : 'primary'\n if (!LINK_COLOR_FAMILIES.has(color)) return null\n const styledAsButton = node.componentId === 'muiButton' || node.props?.['renderAs'] !== 'link'\n return styledAsButton && node.props?.['variant'] === 'contained' ? null : color\n}\n\n/**\n * Rule 5, for a link on a colored band (AGL-3056). The doctrine asks for\n * palette tokens, and a band in `primary.main` holding a Screen Link that\n * sets no color is two valid tokens: but the link keeps the theme's primary\n * color, so its words are navy on navy. A live About page's footer was the\n * first, a \"Request a Consultation\" link on a primary band. A link or a button\n * whose words are drawn in the family of the band it sits on is refused, with\n * a re-ask to inherit the band's contrast text or to set it.\n */\nexport function detectInvisibleLinks(tree: AiDoctrineTree, outputKind: AiOutputKind): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const hidden: Array<{ id: string; family: string; token: string }> = []\n for (const visit of walkTree(tree)) {\n if (!LINK_COMPONENTS.has(visit.node.componentId)) continue\n const family = linkWordsFamily(visit.node)\n const band = family ? bandOf(tree, visit) : null\n if (band && band.family === family) hidden.push({ id: visit.id, ...band })\n }\n if (!hidden.length) return []\n const [first] = hidden\n return [\n {\n rule: 5,\n code: 'link-color-on-band',\n message: `A link or button on a ${first.token} band draws its words in the theme's ${first.family} color, the band's own, so they cannot be read. Give it \"color\": \"inherit\" under a band whose sx color is ${first.family}.contrastText, or set its own sx color to ${first.family}.contrastText.`,\n nodeIds: unique(hidden.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A link's words that say it goes home. */\nconst HOME_WORDS = /\\bhome(?:\\s?page)?\\b/i\n\n/** A label's words, lowercase, for comparing one label with another. */\nconst labelWords = (label: string) => label.toLowerCase().split(/[^\\p{L}\\p{N}]+/u).filter(Boolean).join(' ')\n\n/** Words that ask a visitor to get in touch, which the site's form answers. */\nconst GET_IN_TOUCH_WORDS =\n /\\b(?:contact|book|booking|call|quote|estimate|appointment|schedule|reserve|reservation|get in touch|request|visit|enquire|inquire|enquiry|inquiry|message|talk|consult|consultation|order|pre-?order|sign up|join|apply|start)\\b/i\n\n/**\n * Whether a link's words ask a visitor to get in touch — contact, book, quote,\n * request, order, pre-order, enquire — which the site's form answers\n * (AGL-3729). The layout language sends such a link to the form.\n */\nexport function aiAsksToGetInTouch(label: string): boolean {\n return GET_IN_TOUCH_WORDS.test(label)\n}\n\n/**\n * The links rule 10 refuses as sent home for nothing (`detectUnrelatedScreenLinks`),\n * in document order. A link whose words ask a visitor to get in touch, sent to\n * a home page that places the site's form, does what it says (AGL-3729).\n */\nfunction unrelatedScreenLinks(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds' | 'homeLabels'>,\n): Array<{ id: string; label: string }> {\n if (outputKind === 'email' || outputKind === 'form') return []\n const home = new Set(context.homeScreenIds ?? [])\n const forms = new Set(context.formScreenIds ?? [])\n const homeLabels = new Set((context.homeLabels ?? []).map(labelWords).filter(Boolean))\n const sent: Array<{ id: string; label: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n const screenId = node.props?.['screenId']\n const linksHome = (typeof screenId === 'string' && home.has(screenId)) || node.props?.['href'] === '/'\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n if (!linksHome || !label || HOME_WORDS.test(label) || homeLabels.has(labelWords(label))) continue\n // Home holds the site's form, and the words ask for what it does (AGL-3729).\n if (typeof screenId === 'string' && forms.has(screenId) && aiAsksToGetInTouch(label)) continue\n // The header and the navigation link home by name and by the site's own brand.\n const inNavigation = hasAncestor(\n tree,\n visit,\n (ancestor) => ancestor.componentId === 'muiAppBar' || ['header', 'nav'].includes(elementOf(ancestor)),\n )\n if (!inNavigation) sent.push({ id: visit.id, label })\n }\n return sent\n}\n\n/**\n * RULE 10'S LINK SENT HOME, REPAIRED IN CODE (AGL-3729).\n *\n * The rule's own advice is \"link the page that does, or leave the link out\",\n * and both halves are something code can do once it knows where the site's\n * form is. A Free guided start's café (beta.243, 2026-10-12) put its contact\n * and pre-order form on Home; its Menu page's \"Request weekend pickup\" was\n * sent to Home, and the page was refused on every answer, since the\n * destination was the compiler's, not the model's. So, before the check reads\n * the tree, each link `detectUnrelatedScreenLinks` would refuse is:\n *\n * - repointed to the page that places the site's form, when its words ask a\n * visitor to get in touch and the site has such a page that is not the page\n * being checked (`formScreenIds`, `ownScreenIds`). The platform reaches a\n * section of another page by no anchor (AGL-2867), so the link names the\n * page; a link to a section of its own page is the Scroll to element\n * interaction, which this never writes;\n * - otherwise left out: the node and everything under it are taken off the\n * page, and out of its parent's children.\n *\n * The root is never taken out. A tree with nothing to repair comes back as\n * the same object; a node that is changed is copied, never edited in place.\n */\nexport function aiSettleUnrelatedScreenLinks<T extends AiDoctrineTree>(\n tree: T,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds' | 'homeLabels'> & {\n /** The page being checked, by every id it goes by: a link never goes to itself. */\n ownScreenIds?: readonly string[]\n } = {},\n): T {\n const sent = unrelatedScreenLinks(tree, outputKind, context)\n if (!sent.length) return tree\n const own = new Set(context.ownScreenIds ?? [])\n const formScreen = (context.formScreenIds ?? []).find((id) => !own.has(id)) ?? null\n const nodes: Record<string, AiDoctrineNode> = { ...tree.nodes }\n const parents = new Map<string, string>()\n for (const visit of walkTree(tree)) {\n const parent = visit.ancestors[visit.ancestors.length - 1]\n if (parent !== undefined) parents.set(visit.id, parent)\n }\n for (const { id, label } of sent) {\n if (!nodes[id]) continue\n if (formScreen && aiAsksToGetInTouch(label)) {\n const props: Record<string, unknown> = { ...(nodes[id].props ?? {}), screenId: formScreen }\n delete props['href']\n nodes[id] = { ...nodes[id], props }\n continue\n }\n const parent = parents.get(id)\n if (parent === undefined || !nodes[parent]) continue\n nodes[parent] = { ...nodes[parent], nodes: (nodes[parent].nodes ?? []).filter((child) => child !== id) }\n const stack = [id]\n while (stack.length) {\n const next = stack.pop() as string\n stack.push(...(nodes[next]?.nodes ?? []))\n delete nodes[next]\n }\n }\n return { ...tree, nodes } as T\n}\n\n/**\n * Rule 10, for a link sent where the site has nothing for it (AGL-3056). A\n * link whose purpose the site has no screen for is left out; it never goes to\n * a screen that does something else. The site inventory cannot say what each\n * screen is for, but it can name the one a model falls back to: a live About\n * page's footer sent \"Request a Consultation\" to the home screen, because the\n * site had no consultation screen. So a Screen Link or a Button, outside the\n * header and the navigation, that links the home screen with words that do\n * not say home is refused, with a re-ask to link the screen that does what it\n * says, or to leave the link out.\n */\nexport function detectUnrelatedScreenLinks(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'homeScreenIds' | 'formScreenIds' | 'homeLabels'> = {},\n): AiDoctrineViolation[] {\n const sent = unrelatedScreenLinks(tree, outputKind, context)\n if (!sent.length) return []\n return [\n {\n rule: 10,\n code: 'link-unrelated-screen',\n message: `\"${sent[0].label}\" links the home page, which does not do what its words say. Link the page that does, or leave the link out when the site has none.`,\n nodeIds: unique(sent.map((entry) => entry.id)),\n },\n ]\n}\n\n/** A prop value with something in it: a destination, or words. */\nfunction isFilled(value: unknown): boolean {\n return typeof value === 'string' && value.trim() !== ''\n}\n\n/**\n * Rule 10, for a link that goes nowhere (AGL-3072). A Button or a Screen Link\n * goes where its `screenId` or its `href` says, and those are the only\n * destinations either element carries: the palette validator keeps a\n * `screenId` the site has, and an `href` that is a path on the site, an\n * `https:` address or a binding the caller admitted. Nothing else can stand\n * in for one. A form is sent by the button the Form draws from its own\n * `submitLabel`, the elements a page places carry no id an anchor could name\n * (AGL-2867), and a generated node sets no interaction. So a link with\n * neither is a dead control: a live About page's hero carried a \"Request a\n * Consultation\" button with no destination. It is refused, with a re-ask\n * naming its words and what it may link.\n *\n * On a page a plan lays out (`context.pageSections`), a link may also go to a\n * section of the same page (AGL-3097). A live hero's re-ask was answered with\n * \"#consultation-form\", an anchor to the form the plan places last, and the\n * page stopped at its first section. A link that names a section, by\n * `scrollTo` or by a fragment that section's name's words make up, goes\n * there, and the page step writes the platform's Scroll to element\n * interaction for it. On a page as stored (`context.scrollTargetIds`), a link\n * carrying that interaction to one of its section roots goes there. Two\n * faults get a sentence of their own:\n *\n * - `link-fragment`: an `href` fragment that names no section. The palette\n * validator drops it, so what the link was written with goes nowhere.\n * - `scroll-target-unknown`: a `scrollTo` naming no section of the page.\n *\n * `written` is the node as the model wrote it and `stored` the node as the\n * check was given it, each by an id of `tree`.\n */\nexport function detectLinksWithoutDestination(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: Pick<AiDoctrineTreeContext, 'pageSections' | 'scrollTargetIds'> = {},\n written: (id: string) => unknown = () => undefined,\n stored: (id: string) => unknown = () => undefined,\n): AiDoctrineViolation[] {\n if (outputKind === 'email' || outputKind === 'form') return []\n const sections = context.pageSections ?? []\n const targets = new Set(context.scrollTargetIds ?? [])\n const dead: Array<{ id: string; label: string; inForm: boolean }> = []\n const fragments: Array<{ id: string; label: string; value: string }> = []\n const unknown: Array<{ id: string; label: string; value: string }> = []\n for (const visit of walkTree(tree)) {\n const { node } = visit\n if (!LINK_COMPONENTS.has(node.componentId)) continue\n if (isFilled(node.props?.['screenId']) || isFilled(node.props?.['href'])) continue\n if (aiStoredScrollTargets(stored(visit.id)).some((target) => targets.has(target))) continue\n const label = typeof node.props?.['children'] === 'string' ? node.props['children'].trim() : ''\n const target = aiPageLinkTarget(written(visit.id), sections)\n if (target?.kind === 'section') continue\n if (target?.kind === 'unknown' && target.via === 'href') {\n fragments.push({ id: visit.id, label, value: target.value })\n } else if (target?.kind === 'unknown' && context.pageSections) {\n unknown.push({ id: visit.id, label, value: target.value })\n } else {\n dead.push({ id: visit.id, label, inForm: hasAncestor(tree, visit, (ancestor) => ancestor.componentId === 'form') })\n }\n }\n const wordsOf = (entry: { id: string; label: string }): string =>\n entry.label ? `\"${entry.label}\"` : `A ${displayName(tree.nodes[entry.id].componentId)}`\n const names = sections.map((name) => `\"${name}\"`)\n const listed = names.length > 1 ? `${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}` : names.join('')\n const toSection = `To take a visitor to a section of this page, set \"${AI_PAGE_SCROLL_TO_PROP}\" to that section's name in the plan: ${listed}.`\n const violations: AiDoctrineViolation[] = []\n if (fragments.length) {\n const [first] = fragments\n violations.push({\n rule: 10,\n code: 'link-fragment',\n message: `${wordsOf(first)} links \"${first.value}\", an anchor, and no element on a page carries an id an anchor could name, so it goes nowhere. ${\n context.pageSections\n ? `${toSection} Otherwise give it the \"screenId\" of a page the site has that does what its words say, or take it out.`\n : 'Give it the \"screenId\" of a page the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives, or take it out.'\n }`,\n nodeIds: unique(fragments.map((entry) => entry.id)),\n })\n }\n if (unknown.length) {\n const [first] = unknown\n violations.push({\n rule: 10,\n code: 'scroll-target-unknown',\n message: `${wordsOf(first)} scrolls to \"${first.value}\", and this page has no section of that name. Set \"${AI_PAGE_SCROLL_TO_PROP}\" to one of its sections' names in the plan: ${listed}, or take the link out.`,\n nodeIds: unique(unknown.map((entry) => entry.id)),\n })\n }\n if (dead.length) {\n const [first] = dead\n const instead = dead.some((entry) => entry.inForm)\n ? ' A Form draws its own send button from its \"submitLabel\", so take out a button drawn inside one and set that label instead.'\n : context.pageSections\n ? ` ${toSection} When none of these fits, take it out.`\n : ' When the site has no page for it, take it out: a form on this page is sent by its own button, and no element can be reached by an anchor.'\n violations.push({\n rule: 10,\n code: 'link-without-destination',\n message: `${wordsOf(first)} goes nowhere. Give it the \"screenId\" of a page the site has that does what its words say, or an \"href\" that is a path on this site or an https: address the brief gives.${instead}`,\n nodeIds: unique(dead.map((entry) => entry.id)),\n })\n }\n return violations\n}\n\n/** Answer fields that say \"publish\", wherever the answer put them. */\nconst PUBLISH_KEYS = /^(?:publish|published|publishNow|publishAt|goLive|isLive|live|makeLive)$/i\n\n/**\n * Rule 13. The AI writes drafts. An answer that asks for anything to be\n * published, or to go live, is refused whatever else it got right; nothing\n * downstream reads such a field, and the refusal is what keeps a future\n * reader from starting to.\n */\nexport function detectPublishIntent(answer: unknown): AiDoctrineViolation[] {\n const paths: string[] = []\n const visit = (value: unknown, path: string, depth: number) => {\n if (depth > 12 || paths.length >= 5) return\n if (Array.isArray(value)) {\n value.forEach((inner, index) => visit(inner, `${path}[${index}]`, depth + 1))\n return\n }\n if (!isRecord(value)) return\n for (const [key, inner] of Object.entries(value)) {\n const here = path ? `${path}.${key}` : key\n // An element's props and styles are page content, not instructions.\n if (key === 'props' || key === 'sx') continue\n if (\n PUBLISH_KEYS.test(key) &&\n inner !== false &&\n inner !== null &&\n inner !== undefined &&\n inner !== ''\n ) {\n paths.push(here)\n } else if (\n key === 'status' &&\n typeof inner === 'string' &&\n /^(?:published|live|public)$/i.test(inner.trim())\n ) {\n paths.push(here)\n } else {\n visit(inner, here, depth + 1)\n }\n }\n }\n visit(answer, '', 0)\n return paths.length\n ? [\n {\n rule: 13,\n code: 'publish-intent',\n message:\n 'The answer asked to publish. Everything the AI builds is a new draft; review it and publish it yourself.',\n paths,\n },\n ]\n : []\n}\n\n/** A fact the brief never gave, marked in square brackets: `[Office phone number]`. */\nconst BRACKETED_FACT = /\\[([^[\\]{}\\n]{1,80})\\]/g\n\n/**\n * The facts in square brackets copy holds (rule 14), each once whatever its\n * case, in the order they first appear, as the copy spells them\n * (AGL-3056): what a member fills in before a draft is published.\n */\nexport function aiBracketedFacts(texts: Iterable<string>): string[] {\n const facts = new Map<string, string>()\n for (const text of texts) {\n for (const match of text.matchAll(BRACKETED_FACT)) {\n const fact = match[1].trim()\n if (fact && !facts.has(fact.toLowerCase())) facts.set(fact.toLowerCase(), `[${fact}]`)\n }\n }\n return [...facts.values()]\n}\n\n/**\n * Filler that stands in for copy. A bracketed marker for a fact the brief\n * never gave — `[phone number]` — is deliberately NOT here: it is the honest\n * alternative to inventing the fact, and refusing it would push the re-ask\n * toward a made-up number.\n */\nconst FILLER_COPY =\n /\\blorem\\b|\\bipsum\\b|\\bdolor sit\\b|\\b(?:your|insert|add) (?:text|copy|content|headline|title|description|tagline) here\\b|\\b(?:placeholder|sample|dummy|filler) (?:text|copy|content)\\b|\\b(?:text|copy|content) goes here\\b/i\nconst JUDGMENT =\n /\\b(?:simply|obviously|no-brainer|cheap|effortless(?:ly)?|dead simple|super easy|just (?:a|one) click)\\b/i\n\nexport interface AiCopySample {\n /** A node id for a tree, a path for a plan. */\n at: string\n text: string\n}\n\n/**\n * Rule 14. Copy in the site's voice: no lorem ipsum or \"your text here\"\n * filler, and — for copy framed for agencies and enterprises — no words that\n * judge the reader's work as simple or cheap.\n */\nexport function detectOffVoiceCopy(\n samples: readonly AiCopySample[],\n framing: AiCopyFraming = null,\n): AiDoctrineViolation[] {\n const filler = samples.filter((sample) => FILLER_COPY.test(sample.text))\n const judged =\n framing === 'agency' || framing === 'enterprise'\n ? samples.filter((sample) => JUDGMENT.test(sample.text))\n : []\n const at = (list: readonly AiCopySample[]) => {\n const ids = unique(list.map((sample) => sample.at))\n const paths = ids.filter((id) => /[.[\\]]/.test(id))\n const nodeIds = ids.filter((id) => !/[.[\\]]/.test(id))\n return { ...(nodeIds.length ? { nodeIds } : {}), ...(paths.length ? { paths } : {}) }\n }\n const violations: AiDoctrineViolation[] = []\n if (filler.length) {\n violations.push({\n rule: 14,\n code: 'filler-copy',\n message:\n \"This leaves filler copy. Write the real words in the site's voice, from what the brief and the site already say.\",\n ...at(filler),\n })\n }\n if (judged.length) {\n violations.push({\n rule: 14,\n code: 'judgment-words',\n message:\n 'This copy calls the work simple or cheap, which reads as a judgment to an agency or enterprise audience. Say what it does instead.',\n ...at(judged),\n })\n }\n return violations\n}\n\n/** Every piece of copy a tree carries, with the node it sits on. */\nexport function aiTreeCopy(\n tree: AiDoctrineTree,\n context: AiNodeTreeContext = {},\n): AiCopySample[] {\n const samples: AiCopySample[] = []\n for (const { id, node } of walkTree(tree)) {\n const roles = AI_PALETTE[node.componentId]?.propRoles ?? {}\n for (const [name, value] of Object.entries(node.props ?? {})) {\n if (roles[name] === 'text' && typeof value === 'string' && value.trim()) {\n samples.push({ at: id, text: value })\n }\n }\n const refId = node.props?.[AI_INSTANCE_REF_PROP]\n const values = node.props?.[REUSABLE_INSTANCE_PROP_VALUES_KEY]\n if (typeof refId === 'string' && isRecord(values)) {\n const declared = context.componentProps?.[refId] ?? {}\n for (const [name, value] of Object.entries(values)) {\n const type = declared[name] ?? 'text'\n if ((type === 'text' || type === 'richText') && typeof value === 'string') {\n samples.push({ at: id, text: value })\n }\n }\n }\n }\n return samples\n}\n\n/**\n * The props a heading, a subhead or a body text shows as a line a reader\n * reads, by element. A button's or a link's label, a form field's label, a\n * run of inline text inside a sentence and every accessible name are not\n * lines, and how they end is not held.\n */\nconst LINE_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiTypography: ['children'],\n muiListItemText: ['primary', 'secondary'],\n muiCardHeader: ['title', 'subheader'],\n muiAccordionSummary: ['children'],\n emailText: ['children'],\n}\n\n/** Text styles that label rather than say: a caption, an overline, a micro label. */\nconst LABEL_VARIANTS = new Set(['caption', 'overline', 'micro'])\n\n/**\n * Words no finished line ends on: an article, or a conjunction that joins two\n * parts. \"a\" counts only in lowercase, since \"Plan A\" ends on a name.\n */\nconst DANGLING_WORDS = new Set(['an', 'the', 'and', 'or', 'but', 'nor', '&'])\n\n/**\n * Words that open a phrase. A title may end on one it strands, as \"What we\n * help with\" does, but a line that ends on one right after a comma or a dash\n * opened a phrase it never wrote: \"…that matter most, with\".\n */\nconst OPENING_WORDS = new Set([\n 'about',\n 'across',\n 'after',\n 'against',\n 'along',\n 'among',\n 'as',\n 'at',\n 'because',\n 'before',\n 'between',\n 'by',\n 'for',\n 'from',\n 'if',\n 'in',\n 'into',\n 'like',\n 'of',\n 'on',\n 'onto',\n 'since',\n 'so',\n 'than',\n 'that',\n 'through',\n 'to',\n 'toward',\n 'towards',\n 'unless',\n 'until',\n 'upon',\n 'via',\n 'when',\n 'where',\n 'whereas',\n 'while',\n 'with',\n 'within',\n 'without',\n])\n\n/** A line that closes itself: a sentence's end, a closing quote or bracket, or a colon that introduces what follows. */\nconst CLOSED_LINE = /[.!?…:;\"'”’»)\\]]$/\n\n/**\n * The word a line ends on when that word leaves it unfinished (AGL-3072), or\n * `null`. A line that closes itself, ends on a binding or a bracketed fact the\n * member fills, or ends on any other word, is finished as far as a check can\n * tell. Exported for the specs that hold the closed list.\n */\nexport function aiDanglingWord(line: string): string | null {\n const text = line.trim()\n if (!text || CLOSED_LINE.test(text)) return null\n const word = /(?:^|[^A-Za-z&'’])([A-Za-z]+|&)$/.exec(text)?.[1]\n if (!word) return null\n const lower = word.toLowerCase()\n if (word === 'a' || DANGLING_WORDS.has(lower)) return word\n // A comma, a semicolon or a dash breaks the line before the word; the hyphen\n // of \"Drop-in\" or \"Add-on\" joins one word and breaks nothing.\n const before = text.slice(0, text.length - word.length)\n return OPENING_WORDS.has(lower) && /(?:[,;—–]|\\s-)\\s*$/.test(before) ? word : null\n}\n\n/** The last words of a line, as a re-ask quotes them. */\nfunction lineTail(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 6 ? `…${words.slice(-6).join(' ')}` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut short (AGL-3072). Copy in the site's voice is\n * finished copy: a heading, a subhead or a body text that ends on an article\n * or a joining conjunction, or on a word that opens a phrase right after a\n * comma, with no closing punctuation, reads as a sentence cut off mid-thought.\n * A live About page's hero subhead ended \"…that matter most, with\". A closed\n * list of words, on the lines a reader reads, keeps it deterministic: a\n * label, a button, a caption and a bracketed fact are never held to it.\n */\nexport function detectDanglingWords(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const found: Array<{ id: string; line: string; word: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const props = LINE_PROPS[node.componentId]\n if (!props) continue\n if (node.componentId === 'muiTypography' && LABEL_VARIANTS.has(String(node.props?.['variant'] ?? ''))) continue\n if (node.componentId === 'emailText' && node.props?.['variant'] === 'caption') continue\n for (const name of props) {\n const line = node.props?.[name]\n const word = typeof line === 'string' ? aiDanglingWord(line) : null\n if (word) found.push({ id, line: line as string, word })\n }\n }\n if (!found.length) return []\n const [first] = found\n return [\n {\n rule: 14,\n code: 'dangling-word',\n message: `\"${lineTail(first.line)}\" has no closing punctuation, and its last word, \"${first.word}\", leaves the sentence unfinished. Finish the sentence, or end the line before \"${first.word}\".`,\n nodeIds: unique(found.map((entry) => entry.id)),\n },\n ]\n}\n\n/** The labels a button or a link shows, beside the lines: cut, they read as broken too. */\nconst LABEL_PROPS: Readonly<Record<string, readonly string[]>> = {\n muiButton: ['children'],\n muiScreenLink: ['children'],\n emailButton: ['children'],\n}\n\n/** The line the palette validator writes when it cuts a prop at its ceiling. */\nconst CUT_REPAIR = /^(.+)\\.([A-Za-z0-9_]+) was over (\\d+) characters; truncated$/\n\n/** The first words of a line, as a re-ask quotes them. */\nfunction lineHead(line: string): string {\n const words = line.trim().split(/\\s+/)\n return words.length > 8 ? `${words.slice(0, 8).join(' ')}…` : words.join(' ')\n}\n\n/**\n * Rule 14, for a line cut at its ceiling (AGL-3076). The palette validator\n * holds copy to a ceiling for its role and cuts what runs past it, and says so\n * only in its repairs. A cut line is unfinished wherever the cut falls, after\n * a word or inside one, and a heading style's ceiling of\n * `AI_TEXT_LIMITS.headline` characters is one the catalog never shows a model:\n * a live About page's hero subhead, a Typography in the h5 style, was cut at\n * 120 characters to \"…that matter most, with\". So a heading, a subhead, a body\n * line, or a button's or a link's label the validator cut is refused, with a\n * re-ask naming the ceiling.\n *\n * `repairs` are the palette validator's, naming nodes by the ids of the tree\n * it was given, `written`; `idOf` turns such an id into the id the violation\n * names.\n */\nexport function detectCutLines(\n repairs: readonly string[],\n written: Readonly<Record<string, unknown>>,\n idOf: (id: string) => string = (id) => id,\n): AiDoctrineViolation[] {\n const cut: Array<{ id: string; line: string; limit: number; heading: boolean }> = []\n for (const repair of repairs) {\n const match = CUT_REPAIR.exec(repair)\n if (!match) continue\n const [, nodeId, name, limit] = match\n const node = written[nodeId]\n if (!isRecord(node) || typeof node['componentId'] !== 'string') continue\n const props = isRecord(node['props']) ? node['props'] : {}\n const shown = LINE_PROPS[node['componentId']] ?? LABEL_PROPS[node['componentId']] ?? []\n const line = props[name]\n if (!shown.includes(name) || typeof line !== 'string') continue\n cut.push({\n id: idOf(nodeId),\n line,\n limit: Number(limit),\n heading: node['componentId'] === 'muiTypography' && isHeadlineVariant(props['variant']),\n })\n }\n if (!cut.length) return []\n const [first] = cut\n const message = first.heading\n ? `A line in a heading style holds at most ${first.limit} characters, and \"${lineHead(first.line)}\" runs past them, so it was cut off where they end. Write it whole within ${first.limit} characters, or give a longer line a subtitle or body style.`\n : `\"${lineHead(first.line)}\" runs past the ${first.limit} characters its element holds, so it was cut off where they end. Write it whole within ${first.limit} characters.`\n return [{ rule: 14, code: 'copy-cut-at-ceiling', message, nodeIds: unique(cut.map((entry) => entry.id)) }]\n}\n\nconst PURE_CONTAINERS = new Set(['muiBox', 'muiStack', 'muiContainer', 'muiGrid', 'section'])\nconst EMBED_COMPONENTS = new Set(['videoEmbed', 'custom-html'])\nconst DUPLICATE_SX_MIN_KEYS = 2\nconst DUPLICATE_SX_MIN_NODES = 4\n\n/**\n * Whether a third-party player is one the confirmed plan lists (AGL-3433). A\n * Video embed is admitted where the plan lists a player, playing the video\n * the brief gave or none yet, which the site owner pastes. Raw HTML never is.\n */\nfunction embedVerdict(\n node: AiDoctrineNode,\n planned: readonly Pick<AiBuildPlanEmbed, 'host' | 'url'>[],\n): 'planned' | 'unplanned' | 'unplanned-link' {\n if (node.componentId !== 'videoEmbed' || !planned.length) return 'unplanned'\n const url = typeof node.props?.['url'] === 'string' ? node.props['url'].trim() : ''\n if (!url) return 'planned'\n const key = aiEmbedVideoKey(url)\n return key && planned.some((embed) => embed.url && aiEmbedVideoKey(embed.url) === key)\n ? 'planned'\n : 'unplanned-link'\n}\n\n/**\n * Containers whose empty state is something they draw themselves, so an empty\n * one is a placement and not a gap (AGL-3716): the Music player, placed with\n * no tracks, asks its owner to add their own; a model never fills it.\n */\nconst OWNS_ITS_EMPTY_STATE: ReadonlySet<string> = new Set(['musicPlayer'])\n\n/**\n * Rule 16. The flattest tree that renders the design: no container that\n * wraps one other container and adds nothing, no empty containers, no inline\n * style repeated where a token or a component prop would carry it, no font\n * beyond the theme's, images lazy below the first, video by poster rather\n * than autoplay, no third-party player the confirmed plan does not list, and\n * none playing a video the brief did not give.\n */\nexport function detectHeavyDocument(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const visits = walkTree(tree)\n const wrappers: string[] = []\n const empty: string[] = []\n const fonts: string[] = []\n const eager: string[] = []\n const video: string[] = []\n const embeds: string[] = []\n const embedLinks: string[] = []\n const sxSeen = new Map<string, string[]>()\n let images = 0\n for (const { id, node } of visits) {\n const entry = AI_PALETTE[node.componentId]\n const children = (node.nodes ?? []).filter((child) => tree.nodes[child])\n const ownProps = Object.entries(node.props ?? {}).filter(\n ([name, value]) => !(name === 'component' && value === 'div'),\n )\n if (\n id !== tree.rootId &&\n PURE_CONTAINERS.has(node.componentId) &&\n children.length === 1 &&\n PURE_CONTAINERS.has(tree.nodes[children[0]].componentId) &&\n !ownProps.length &&\n !Object.keys(node.sx ?? {}).length\n ) {\n wrappers.push(id)\n }\n const boundForm = node.componentId === 'form' && typeof node.props?.['formId'] === 'string'\n if (entry?.acceptsChildren && !children.length && !boundForm && !OWNS_ITS_EMPTY_STATE.has(node.componentId)) {\n empty.push(id)\n }\n if (outputKind !== 'email' && node.sx?.['fontFamily'] !== undefined) fonts.push(id)\n if (node.componentId === 'image') {\n images += 1\n if (images > 1 && node.props?.['loading'] === 'eager') eager.push(id)\n }\n if (\n node.componentId === 'video' &&\n (node.props?.['autoPlay'] === true ||\n node.props?.['preload'] === 'auto' ||\n (typeof node.props?.['src'] === 'string' && node.props['src'] && !node.props?.['poster']))\n ) {\n video.push(id)\n }\n if (EMBED_COMPONENTS.has(node.componentId)) {\n const verdict = embedVerdict(node, context.plannedEmbeds ?? [])\n if (verdict === 'unplanned') embeds.push(id)\n if (verdict === 'unplanned-link') embedLinks.push(id)\n }\n const sx = node.sx ?? {}\n if (Object.keys(sx).length >= DUPLICATE_SX_MIN_KEYS) {\n const key = JSON.stringify(Object.keys(sx).sort().map((name) => [name, sx[name]]))\n sxSeen.set(key, [...(sxSeen.get(key) ?? []), id])\n }\n }\n const duplicatedSx = [...sxSeen.values()]\n .filter((ids) => ids.length >= DUPLICATE_SX_MIN_NODES)\n .flat()\n const violations: AiDoctrineViolation[] = []\n const add = (code: string, ids: string[], message: string) => {\n if (ids.length) violations.push({ rule: 16, code, message, nodeIds: ids })\n }\n add(\n 'wrapper-in-wrapper',\n wrappers,\n 'A container wraps a single container and adds nothing. Remove the outer one.',\n )\n add('empty-container', empty, 'An element meant to hold content is empty. Remove it, or fill it.')\n add(\n 'duplicated-inline-style',\n duplicatedSx,\n 'The same inline style repeats across elements. Carry it in a theme token or a component prop, once.',\n )\n add('extra-font', fonts, \"This names a font the theme does not load. Use the theme's typography.\")\n add(\n 'eager-image',\n eager,\n 'An image below the first loads eagerly. Leave loading unset so images further down the page load when they are reached.',\n )\n add(\n 'autoplay-video',\n video,\n 'A video loads its file before anyone plays it. Give it a poster, and let it play on click.',\n )\n add(\n 'third-party-embed',\n embeds,\n \"This embeds a third-party player, which loads its host's code on every visit, and the confirmed plan lists none here. Remove it; a film from the media library plays in a Video (video).\",\n )\n add(\n 'embed-link-unplanned',\n embedLinks,\n 'This player plays a video the brief did not give. Use the link the plan lists, or leave the link empty for the site owner to paste.',\n )\n return violations\n}\n\n/** The items a list or a row of cards repeats, as a re-ask names them. */\nconst ITEM_NOUNS: Readonly<Record<string, string>> = { muiListItem: 'list item', muiCard: 'card' }\n\n/** Elements that frame or space what they hold and show nothing of their own. */\nconst FRAME_COMPONENTS = new Set([\n 'div',\n 'section',\n 'muiBox',\n 'muiStack',\n 'muiContainer',\n 'muiGrid',\n 'muiPaper',\n 'muiCard',\n 'muiCardContent',\n 'muiCardActions',\n 'muiListItem',\n 'muiAccordion',\n 'muiAccordionDetails',\n])\n\n/** Elements that show only their words, by the props that hold them. */\nconst WORD_PROPS: Readonly<Record<string, readonly string[]>> = {\n ...LINE_PROPS,\n muiList: ['subheader'],\n muiInlineText: ['children'],\n muiButton: ['children'],\n muiScreenLink: ['children'],\n}\n\n/** Whether a node shows anything of its own: its words, or whatever an element that is neither a frame nor words draws. */\nfunction showsOwn(node: AiDoctrineNode): boolean {\n const words = WORD_PROPS[node.componentId]\n if (words) return words.some((name) => isFilled(node.props?.[name]))\n return !FRAME_COMPONENTS.has(node.componentId)\n}\n\n/**\n * Rule 16, for an item with nothing in it (AGL-3072). A list item or a card\n * that holds elements, none of which shows a word, a picture or anything\n * else, is an empty row or an empty box on the page: a live About page's list\n * of estate planning services ended on a List Item whose List Item Text had\n * no words. An item that holds no element at all is `empty-container`'s, and\n * is not reported twice.\n */\nexport function detectEmptyItems(tree: AiDoctrineTree): AiDoctrineViolation[] {\n const empty: Array<{ id: string; noun: string }> = []\n for (const { id, node } of walkTree(tree)) {\n const noun = ITEM_NOUNS[node.componentId]\n if (!noun || !(node.nodes ?? []).some((child) => tree.nodes[child])) continue\n if (!walkTree({ rootId: id, nodes: tree.nodes }).some((inner) => showsOwn(inner.node))) {\n empty.push({ id, noun })\n }\n }\n if (!empty.length) return []\n const nouns = unique(empty.map((entry) => entry.noun))\n const message =\n nouns.length > 1\n ? 'A list item and a card hold nothing to read or see. Give each its words, or take it out.'\n : nouns[0] === 'list item'\n ? 'A list item holds no words, so its row shows empty. Write the words of its List Item Text, or take the item out.'\n : 'A card holds nothing to read or see. Give it its words, or take the card out.'\n return [{ rule: 16, code: 'empty-item', message, nodeIds: empty.map((entry) => entry.id) }]\n}\n\n// ── Rule 17: the budget, measured ────────────────────────────────────────\n\nexport interface AiOutputScore {\n nodes: number\n /** The stored node map, in the save's own bytes. */\n bytes: number\n /** What the placed library images request, from their recorded sizes. */\n imageBytes: number\n /** Placed images the media library could not size: hot-linked, or no facts supplied. */\n imagesUnmeasured: number\n embeds: number\n fontFamilies: number\n /** An email's rendered HTML; `null` for every other output. */\n emailHtmlBytes: number | null\n}\n\nconst EMAIL_COLUMN_PX = 600\nconst MEDIA_IMAGE_PROPS: Record<string, readonly string[]> = {\n image: ['src'],\n emailImage: ['src'],\n video: ['poster'],\n collectionEntryAuthor: ['image'],\n contentAuthorProfile: ['image'],\n}\n\n/** The variant a slot of this width is served. */\nfunction servedVariantWidth(slotWidth: number | null): number {\n const widest = MEDIA_CDN_VARIANT_WIDTHS[MEDIA_CDN_VARIANT_WIDTHS.length - 1]\n if (!slotWidth) return widest\n return MEDIA_CDN_VARIANT_WIDTHS.find((width) => width >= slotWidth) ?? widest\n}\n\nfunction pixels(value: unknown): number | null {\n const parsed = typeof value === 'number' ? value : Number.parseFloat(String(value ?? ''))\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null\n}\n\nfunction imageRequests(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): Array<{ id: string; bytes: number | null }> {\n const requests: Array<{ id: string; bytes: number | null }> = []\n for (const { id, node } of walkTree(tree)) {\n const named = MEDIA_IMAGE_PROPS[node.componentId] ?? []\n const values = mediaValues(node, context).filter(\n ({ name }) =>\n named.includes(name) || name.startsWith(`${REUSABLE_INSTANCE_PROP_VALUES_KEY}.`),\n )\n for (const { value } of values) {\n const ref = parseMediaRef(value)\n const facts = ref ? context.assets?.[ref.mediaId] : undefined\n if (!facts?.sizeBytes) {\n requests.push({ id, bytes: null })\n continue\n }\n const slot = pixels(node.props?.['width'])\n const variant = servedVariantWidth(\n outputKind === 'email' ? Math.min(slot ?? EMAIL_COLUMN_PX, EMAIL_COLUMN_PX) : slot,\n )\n // A variant is the original scaled down, so its bytes scale with its\n // area; a variant wider than the original is the original.\n const ratio = facts.width ? Math.min(1, variant / facts.width) : 1\n requests.push({ id, bytes: Math.round(facts.sizeBytes * ratio * ratio) })\n }\n }\n return requests\n}\n\n/** The rule-17 measurements of one validated tree. */\nexport function scoreAiOutput(\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n): AiOutputScore {\n const visits = walkTree(tree)\n const images = imageRequests(tree, outputKind, context)\n const families = new Set<string>()\n for (const { node } of visits) {\n for (const family of sxValues(node.sx?.['fontFamily'])) {\n if (typeof family === 'string' && family.trim()) families.add(family.trim().toLowerCase())\n }\n }\n let emailHtmlBytes: number | null = null\n if (outputKind === 'email') {\n const { html } = renderEmailHtml({\n nodes: tree.nodes as Parameters<typeof renderEmailHtml>[0]['nodes'],\n rootId: tree.rootId,\n sanitize: (value: string) => sanitizeAuthorHtml(value),\n })\n emailHtmlBytes = new TextEncoder().encode(html).length\n }\n return {\n nodes: visits.length,\n bytes: nodeMapBytes(tree.nodes),\n imageBytes: images.reduce((sum, image) => sum + (image.bytes ?? 0), 0),\n imagesUnmeasured: images.filter((image) => image.bytes === null).length,\n embeds: visits.filter(({ node }) => EMBED_COMPONENTS.has(node.componentId)).length,\n fontFamilies: families.size,\n emailHtmlBytes,\n }\n}\n\nconst METRIC_LABELS: Record<AiBudgetMetric, string> = {\n nodes: 'elements',\n bytes: 'stored size',\n imageBytes: 'image weight',\n embeds: 'third-party embeds',\n fontFamilies: 'extra font families',\n emailHtmlBytes: `rendered size (mail clients clip past ${formatBytes(AI_EMAIL_CLIP_BYTES)})`,\n}\n\nfunction figure(metric: AiBudgetMetric, value: number): string {\n return metric === 'nodes' || metric === 'embeds' || metric === 'fontFamilies'\n ? value.toLocaleString('en-US')\n : formatBytes(value)\n}\n\n/** The parts of a tree that weigh most under one metric, heaviest first. */\nfunction heaviest(\n metric: AiBudgetMetric,\n tree: AiDoctrineTree,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext,\n): string[] {\n switch (metric) {\n case 'bytes':\n case 'emailHtmlBytes':\n return measureNodeMap(tree.nodes).largest.map((entry) => entry.id)\n case 'nodes': {\n const index = indexShapes(tree)\n return index.visits\n .filter((visit) => visit.depth >= 1 && visit.depth <= 2)\n .sort((a, b) => (index.sizeOf.get(b.id) ?? 0) - (index.sizeOf.get(a.id) ?? 0))\n .slice(0, 3)\n .map((visit) => visit.id)\n }\n case 'imageBytes':\n return imageRequests(tree, outputKind, context)\n .filter((image) => image.bytes !== null)\n .sort((a, b) => (b.bytes ?? 0) - (a.bytes ?? 0))\n .slice(0, 3)\n .map((image) => image.id)\n case 'embeds':\n return walkTree(tree)\n .filter(({ node }) => EMBED_COMPONENTS.has(node.componentId))\n .map((visit) => visit.id)\n case 'fontFamilies':\n return walkTree(tree)\n .filter(({ node }) => node.sx?.['fontFamily'] !== undefined)\n .map((visit) => visit.id)\n }\n}\n\nconst BUDGET_METRICS: readonly AiBudgetMetric[] = [\n 'nodes',\n 'bytes',\n 'imageBytes',\n 'embeds',\n 'fontFamilies',\n 'emailHtmlBytes',\n]\n\n/**\n * Rule 17. An output over its kind's budget is refused with the figure, the\n * budget and the heaviest parts named, so the re-ask knows where to cut.\n */\nexport function detectOverBudget(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n tree: AiDoctrineTree,\n context: AiDoctrineTreeContext = {},\n): AiDoctrineViolation[] {\n const budget = AI_OUTPUT_BUDGETS[outputKind]\n const violations: AiDoctrineViolation[] = []\n for (const metric of BUDGET_METRICS) {\n const value = score[metric]\n const limit = budget[metric]\n if (value === null || limit === undefined || value <= limit) continue\n const offenders = heaviest(metric, tree, outputKind, context)\n const parts = offenders.length ? ` The heaviest parts: ${listNames(offenders, tree)}.` : ''\n violations.push({\n rule: 17,\n code: `over-budget-${metric}`,\n message: `This ${outputKind} measures ${figure(metric, value)} of ${METRIC_LABELS[metric]} against a budget of ${figure(metric, limit)}.${parts}`,\n nodeIds: offenders,\n figure: { metric, value, budget: limit },\n })\n }\n return violations\n}\n\n/**\n * What a first visit to a generated output is estimated to transfer.\n *\n * The page half is a MEASUREMENT the platform already holds, not a guess:\n * `ESTIMATED_PAGE_TRANSFER_BYTES` is the first-party weight a published page\n * measured at settle, which `check:page-view-rate` holds against the\n * tenant page budget and the bandwidth meter is priced from. The tenant's\n * real-user vitals (`web-vitals-rum.ts`) report to analytics per visit and\n * are not readable for a draft nobody has visited, so they are not a second\n * source here. On top of that weight go this output's own stored document\n * and the images it places. A component or a layout reports what it adds to\n * a page; an email is not a page load and has none.\n */\nexport function estimateAiOutputLoad(\n score: AiOutputScore,\n outputKind: AiOutputKind,\n): AiLoadEstimate | null {\n if (outputKind === 'email') return null\n const pageBytes =\n outputKind === 'page' || outputKind === 'template' ? ESTIMATED_PAGE_TRANSFER_BYTES : 0\n return {\n pageBytes,\n documentBytes: score.bytes,\n imageBytes: score.imageBytes,\n imagesUnmeasured: score.imagesUnmeasured,\n embeds: score.embeds,\n totalBytes: Math.round(pageBytes + score.bytes + score.imageBytes),\n }\n}\n\n/**\n * A NODE MAP THAT DOES NOT AGREE WITH ITSELF (AGL-3143).\n *\n * A flat node map is two halves that have to match: what each node lists\n * under `nodes`, and what the map holds. A model writing one section in one\n * pass gets them out of step in two ways, and neither reaches it as\n * something it can act on.\n *\n * An element written but listed by nobody is dropped on the way in, so the\n * container that should have held it reads as empty and the answer comes\n * back \"an element meant to hold content is empty — remove it, or fill it\".\n * The content is already written; it is one line away from being placed, and\n * the re-ask does not say so. A live page build was told exactly that of a\n * card grid whose repeated card it had written and not placed; it answered by\n * naming four children and writing one.\n *\n * Which is the other half: a name listed under `nodes` that the map never\n * holds. That one is refused, but by the sanitizer under the palette\n * validator, as `Missing node \"card2\"` — which the door turns into \"the\n * answer could not be used as a section\", with no rule, no node and nothing\n * to change. It cost that page its last attempt and the build stopped three\n * sections in, so the page's form — the thing being measured — was never\n * reached at all.\n *\n * Both are read off the tree AS THE MODEL WROTE IT, before the palette\n * validator drops anything, so a re-ask can quote the node at fault.\n */\nexport function detectDisagreeingNodes(input: unknown): AiDoctrineViolation[] {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return []\n const rootId = input['rootId']\n const nodes = input['nodes']\n if (!isRecord(nodes[rootId])) return []\n const childrenOf = (id: string): string[] => {\n const node = nodes[id]\n const listed = isRecord(node) ? node['nodes'] : undefined\n return Array.isArray(listed) ? listed.filter((child): child is string => typeof child === 'string') : []\n }\n const reached = new Set<string>([rootId])\n const missing = new Map<string, string[]>()\n const queue = [rootId]\n while (queue.length) {\n const id = queue.shift() as string\n for (const child of childrenOf(id)) {\n if (!isRecord(nodes[child])) {\n missing.set(id, [...(missing.get(id) ?? []), child])\n continue\n }\n if (reached.has(child)) continue\n reached.add(child)\n queue.push(child)\n }\n }\n const orphans = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n const violations: AiDoctrineViolation[] = []\n if (missing.size) {\n const named = unique([...missing.values()].flat())\n violations.push({\n rule: null,\n code: 'missing-child',\n message:\n 'This holds elements that were never written, so the answer could not be read. Write each one, or take its name out of the list of what this holds.',\n detail: `Listed under \"nodes\" and missing from the answer: ${named.map((id) => `\"${id}\"`).join(', ')}.`,\n nodeIds: [...missing.keys()],\n })\n }\n if (orphans.length) {\n violations.push({\n rule: 16,\n code: 'orphan-node',\n message:\n 'This element was written, but nothing holds it, so none of it reaches the page. List it under the element it belongs in, or take it out.',\n nodeIds: orphans,\n })\n }\n return violations\n}\n\n/** The key a repeated item is written under (`AI_REPEAT_KEY` in `ai-repeated-items.ts`, which imports this file). */\nconst REPEAT_KEY = 'repeat'\n\n/**\n * A node map that does not agree with itself, settled where it has one\n * reading (AGL-3596), before `detectDisagreeingNodes` reads it. A guided\n * start's Home page stopped on each of these after its re-ask, and each is\n * one line the model left out, not a choice it made.\n *\n * - A name listed under `nodes` that the map never holds is taken out of the\n * list: there is nothing written to place there.\n * - An element written and listed by nobody goes where the model said it\n * goes, when its own `parentId` names an element the tree reaches that can\n * hold it. Failing that, a single such element goes in the single element\n * the tree reaches that can hold elements and holds none, which is the shape\n * of a row whose item was written beside it. Failing both, it is dropped,\n * with everything under it: nothing on the page holds it, and none of it\n * would ever be shown.\n * - A repeated item (`repeat`) is the exception: dropping it would lose every\n * card it draws, so one that cannot be placed is left for the re-ask.\n *\n * Reads and returns the tree as the model wrote it; an input with nothing to\n * settle comes back as the same object.\n */\nexport function aiSettleDisagreeingNodes(input: unknown): unknown {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return input\n const rootId = input['rootId']\n const source = input['nodes']\n if (!isRecord(source[rootId])) return input\n const nodes: Record<string, unknown> = { ...source }\n let changed = false\n const listed = (id: string): unknown[] => {\n const node = nodes[id]\n return isRecord(node) && Array.isArray(node['nodes']) ? node['nodes'] : []\n }\n const setListed = (id: string, children: unknown[]): void => {\n nodes[id] = { ...(nodes[id] as Record<string, unknown>), nodes: children }\n changed = true\n }\n const holds = (id: string): boolean => {\n const node = nodes[id]\n return isRecord(node) && typeof node['componentId'] === 'string' && AI_PALETTE[node['componentId']]?.acceptsChildren === true\n }\n const reach = (): Set<string> => {\n const reached = new Set<string>([rootId])\n const queue = [rootId]\n while (queue.length) {\n for (const child of listed(queue.shift() as string)) {\n if (typeof child !== 'string' || reached.has(child) || !isRecord(nodes[child])) continue\n reached.add(child)\n queue.push(child)\n }\n }\n return reached\n }\n\n // Names that were never written come out of the lists that name them.\n for (const id of Object.keys(nodes)) {\n const children = listed(id)\n const written = children.filter((child) => typeof child !== 'string' || isRecord(nodes[child]))\n if (written.length !== children.length) setListed(id, written)\n }\n\n let reached = reach()\n const orphans = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n if (orphans.length) {\n const inOrphan = new Set(orphans.flatMap((id) => listed(id)))\n const roots = orphans.filter((id) => !inOrphan.has(id))\n const empty = [...reached].filter((id) => id !== rootId && holds(id) && listed(id).length === 0)\n for (const id of roots) {\n const named = (nodes[id] as Record<string, unknown>)['parentId']\n const parent =\n typeof named === 'string' && reached.has(named) && holds(named)\n ? named\n : roots.length === 1 && empty.length === 1\n ? empty[0]\n : null\n if (parent) setListed(parent, [...listed(parent), id])\n }\n reached = reach()\n const unplaced = Object.keys(nodes).filter((id) => !reached.has(id) && isRecord(nodes[id]))\n // A repeated item, and what it holds, is kept for the re-ask to place.\n const kept = new Set<string>()\n const queue = unplaced.filter((id) => (nodes[id] as Record<string, unknown>)[REPEAT_KEY] !== undefined)\n while (queue.length) {\n const id = queue.shift() as string\n if (kept.has(id) || !isRecord(nodes[id])) continue\n kept.add(id)\n for (const child of listed(id)) if (typeof child === 'string') queue.push(child)\n }\n for (const id of unplaced) {\n if (kept.has(id)) continue\n delete nodes[id]\n changed = true\n }\n }\n return changed ? { ...input, nodes } : input\n}\n\n\n/** The fewest words a heading cut at a boundary keeps, so a cut never leaves a stub. */\nconst HEADING_CUT_MIN_WORDS = 3\n/** The least share of the ceiling a heading cut at a boundary keeps. */\nconst HEADING_CUT_MIN_SHARE = 0.3\n/** Where a sentence ends: its stop is kept. */\nconst SENTENCE_END = /[.!?](?=\\s)/g\n/** Where a clause ends: the mark is dropped. */\nconst CLAUSE_END = /\\s*(?:[,;:]|\\s[—–-])\\s/g\n\n/**\n * The longest whole part of a heading that fits `limit`: up to the last\n * sentence that ends within it, else the last clause, or `null` where neither\n * does, or where what is left is a stub.\n */\nfunction headingWithin(line: string, limit: number): string | null {\n const keeps = (head: string): boolean =>\n head.split(/\\s+/).length >= HEADING_CUT_MIN_WORDS && head.length >= limit * HEADING_CUT_MIN_SHARE\n for (const [pattern, keepMark] of [\n [SENTENCE_END, true],\n [CLAUSE_END, false],\n ] as const) {\n let best: string | null = null\n for (const match of line.matchAll(pattern)) {\n const head = line.slice(0, (match.index ?? 0) + (keepMark ? match[0].length : 0)).trim()\n if (head.length > limit) break\n best = head\n }\n if (best !== null && keeps(best)) return best\n }\n return null\n}\n\n/**\n * A heading written past the headline ceiling, settled where it has one\n * reading (AGL-3596). The palette validator cuts such a line where the\n * ceiling falls, mid-word, and the check refuses the cut (rule 14,\n * `copy-cut-at-ceiling`); live guided starts' heroes stopped on it after\n * their re-ask. A heading whose first sentence or clause ends within the\n * ceiling is a whole line already, so it is kept to that, its later words\n * dropped: \"Free inspections after a storm, with photos of every shingle we\n * replace and a written…\" becomes \"Free inspections after a storm\". A heading\n * with no such boundary, or whose part within is a stub, is left for the\n * re-ask. Reads and returns the tree as the model wrote it.\n */\nexport function aiSettleCutHeadings(input: unknown): unknown {\n if (!isRecord(input) || !isRecord(input['nodes'])) return input\n const limit = Math.min(AI_PALETTE['muiTypography']?.textLimits?.['children'] ?? Infinity, AI_TEXT_LIMITS.headline)\n let nodes: Record<string, unknown> | null = null\n for (const [id, node] of Object.entries(input['nodes'])) {\n if (!isRecord(node) || node['componentId'] !== 'muiTypography' || !isRecord(node['props'])) continue\n const line = node['props']['children']\n if (!isHeadlineVariant(node['props']['variant']) || typeof line !== 'string') continue\n const trimmed = line.trim()\n if (trimmed.length <= limit || trimmed.includes('{{')) continue\n const head = headingWithin(trimmed, limit)\n if (head === null) continue\n nodes ??= { ...input['nodes'] }\n nodes[id] = { ...node, props: { ...node['props'], children: head } }\n }\n return nodes ? { ...input, nodes } : input\n}\n\n// ── Mechanical rules, settled in code (AGL-3660) ─────────────────────────\n\n/**\n * THE RULES A CHECK WOULD REFUSE FOR AN ATTRIBUTE, SETTLED IN CODE (AGL-3660).\n *\n * A finding whose fix is one attribute, one level or one key, with nothing to\n * decide about what the page says, is applied before the check reads the\n * tree, as `aiSettleGridItems` sizes a container's items. A live Free guided\n * start's Portfolio page (2026-10-10) was refused for rule 16's `eager-image`:\n * the pictures step loaded every photo of the opening section eagerly, the\n * last pass reads the stored page and asks no model, and Try again could only\n * refuse the same page for the same reason. None of these is a choice a model\n * makes better than the code that knows the answer:\n *\n * - `eager-image` (16): only the tree's first image may load eagerly; every\n * later one has `loading` unset, so the renderer loads it when reached;\n * - `autoplay-video` (16), its attribute half: `autoPlay` and `preload: auto`\n * are taken off. A film with no poster still needs a picture, and is left;\n * - `extra-font` (16): an `sx` font family outside an email is taken off, so\n * the element reads the theme's typography;\n * - `multiple-h1` and `skipped-heading` (11): every top-level heading after a\n * page's first renders as an h2 (a layout's all do, a component's after its\n * first), and a heading after it that skips a level renders one below the\n * heading before it. Only the element changes (`component`): the variant,\n * and so the look, is kept. A heading before a page's h1, and a page with no\n * h1, are the model's to mend;\n * - `multiple-main` and `landmark-in-fragment` (11): a `main` landmark after\n * the first, and any in a component, a form or an email, is unset;\n * - `grid-gap` (12): a Grid container's `sx` gap is taken off and becomes its\n * `spacing` where it sets none, a number gap as itself, anything else 2,\n * which is what the re-ask asks for;\n * - `link-color-on-band` (5): a link or a button whose words are drawn in its\n * band's own family is given that family's contrast text as its `sx` color,\n * which is what the re-ask asks for.\n *\n * A tree with nothing to settle comes back as the same object, so settling is\n * idempotent; a node that is changed is copied, never edited in place.\n */\nexport function aiSettleMechanicalRules<T extends AiDoctrineTree>(tree: T, outputKind: AiOutputKind): T {\n if (!tree.nodes[tree.rootId]) return tree\n const nodes: Record<string, AiDoctrineNode> = { ...tree.nodes }\n const copied = new Set<string>()\n const edit = (id: string): AiDoctrineNode => {\n if (!copied.has(id)) {\n const node = nodes[id]\n nodes[id] = {\n ...node,\n ...(node.props ? { props: { ...node.props } } : {}),\n ...(node.sx ? { sx: { ...node.sx } } : {}),\n }\n copied.add(id)\n }\n return nodes[id]\n }\n const unsetProp = (id: string, name: string): void => {\n if (nodes[id].props?.[name] === undefined) return\n delete (edit(id).props as Record<string, unknown>)[name]\n }\n const setProp = (id: string, name: string, value: unknown): void => {\n if (nodes[id].props?.[name] === value) return\n const node = edit(id)\n node.props = { ...(node.props ?? {}), [name]: value }\n }\n const unsetSx = (id: string, name: string): void => {\n if (nodes[id].sx?.[name] === undefined) return\n delete (edit(id).sx as Record<string, unknown>)[name]\n }\n const visits = walkTree(tree)\n const email = outputKind === 'email'\n const framed = !email && outputKind !== 'form'\n const fragment = outputKind === 'component' || email || outputKind === 'form'\n\n let images = 0\n let mains = 0\n for (const { id, node } of visits) {\n // Rule 16: one eager image, the first; the rest load when they are reached.\n if (node.componentId === 'image') {\n images += 1\n if (images > 1 && node.props?.['loading'] === 'eager') unsetProp(id, 'loading')\n }\n // Rule 16: a film loads nothing before it is played.\n if (node.componentId === 'video') {\n if (node.props?.['autoPlay'] === true) unsetProp(id, 'autoPlay')\n if (node.props?.['preload'] === 'auto') unsetProp(id, 'preload')\n }\n // Rule 16: the theme's typography, outside an email.\n if (!email && node.sx?.['fontFamily'] !== undefined) unsetSx(id, 'fontFamily')\n // Rule 11: one main landmark, and none in what is placed inside pages.\n if (elementOf(node) === 'main') {\n mains += 1\n if (fragment || mains > 1) {\n if (node.props?.['component'] === 'main') unsetProp(id, 'component')\n if (node.props?.['element'] === 'main') unsetProp(id, 'element')\n }\n }\n // Rule 12: a container is spaced by its `spacing`, never an sx gap.\n if (framed && node.componentId === GRID && node.props?.['container'] === true) {\n const gap = GRID_GAP_SX_KEYS.find((key) => node.sx?.[key] !== undefined)\n if (gap) {\n const value = node.sx?.[gap]\n for (const key of GRID_GAP_SX_KEYS) unsetSx(id, key)\n if (node.props?.['spacing'] === undefined) setProp(id, 'spacing', typeof value === 'number' ? value : 2)\n }\n }\n }\n\n // Rule 11: the heading outline, in document order.\n if (framed) {\n const headings = visits\n .map((visit) => ({ id: visit.id, level: aiHeadingLevel(nodes[visit.id]) }))\n .filter((entry): entry is { id: string; level: number } => entry.level !== null)\n const page = outputKind === 'page' || outputKind === 'template'\n const firstH1 = headings.findIndex((heading) => heading.level === 1)\n // A page's outline is settled from its h1 on; a layout's and a component's from their first heading.\n const start = page ? firstH1 : 0\n let previous: number | null = page ? 0 : null\n for (let index = Math.max(start, 0); start >= 0 && index < headings.length; index += 1) {\n const heading = headings[index]\n // A page keeps its first h1, a component its first, and a layout none.\n const keepsH1 = outputKind !== 'layout' && index === firstH1\n let level = heading.level === 1 && !keepsH1 ? 2 : heading.level\n previous ??= level - 1\n if (level > previous + 1) level = previous + 1\n if (level !== heading.level) setProp(heading.id, 'component', `h${level}`)\n previous = level\n }\n }\n\n // Rule 5: a link's words in its band's contrast text, read on the tree as settled so far.\n if (framed) {\n const settled: AiDoctrineTree = { rootId: tree.rootId, nodes }\n for (const visit of walkTree(settled)) {\n if (!LINK_COMPONENTS.has(visit.node.componentId)) continue\n const family = linkWordsFamily(visit.node)\n const band = family ? bandOf(settled, visit) : null\n if (!band || band.family !== family) continue\n const node = edit(visit.id)\n node.sx = { ...(node.sx ?? {}), color: `${family}.contrastText` }\n }\n }\n return copied.size ? ({ ...tree, nodes } as T) : tree\n}\n\n/**\n * `aiSettleMechanicalRules` on a tree as the model wrote it, before the\n * palette validator reads it (AGL-3660), as `aiSettleWrittenGridItems` settles\n * its items. Anything that is no flat node map comes back as it was, and a\n * node whose shape is not a palette node's is read as nothing and left as written.\n */\nexport function aiSettleWrittenMechanicalRules(input: unknown, outputKind: AiOutputKind): unknown {\n if (!isRecord(input) || typeof input['rootId'] !== 'string' || !isRecord(input['nodes'])) return input\n const readable = Object.entries(input['nodes']).filter(\n ([, node]) =>\n isRecord(node) &&\n typeof node['componentId'] === 'string' &&\n (node['props'] === undefined || isRecord(node['props'])) &&\n (node['sx'] === undefined || isRecord(node['sx'])) &&\n (node['nodes'] === undefined ||\n (Array.isArray(node['nodes']) && node['nodes'].every((child) => typeof child === 'string'))),\n )\n const tree = {\n rootId: input['rootId'],\n nodes: Object.fromEntries(readable) as unknown as Record<string, AiDoctrineNode>,\n }\n const settled = aiSettleMechanicalRules(tree, outputKind)\n return settled === tree ? input : { ...input, nodes: { ...input['nodes'], ...settled.nodes } }\n}\n\nexport interface AiDoctrineTreeReport {\n ok: boolean\n /** The palette validator's result: the tree to store, its repairs and its id map. */\n tree: Extract<AiNodeTreeResult, { ok: true }> | null\n violations: AiDoctrineViolation[]\n score: AiOutputScore | null\n load: AiLoadEstimate | null\n}\n\n/**\n * The whole check on one emitted tree: the palette validator first, then\n * every tree rule, then the budget. `otherPages` are the trees generated\n * beside this one, for the across-pages half of rule 1.\n */\nexport function validateAiDoctrineTree(\n input: unknown,\n outputKind: AiOutputKind,\n context: AiDoctrineTreeContext = {},\n otherPages: readonly AiDoctrineTree[] = [],\n): AiDoctrineTreeReport {\n const publish = detectPublishIntent(input)\n // Asked of the answer as written, because the palette validator drops an\n // element nobody lists and refuses a name nobody wrote in words no re-ask\n // can act on (AGL-3143).\n const disagreeing = detectDisagreeingNodes(input)\n if (disagreeing.length) {\n return { ok: false, tree: null, violations: [...disagreeing, ...publish], score: null, load: null }\n }\n const validated = validateAiNodeTree(input, AI_OUTPUT_SURFACE[outputKind], context)\n if (validated.ok === false) {\n return {\n ok: false,\n tree: null,\n violations: [\n {\n rule: null,\n code: `tree-${validated.code}`,\n message: `The answer could not be used as a ${outputKind}.`,\n detail: validated.error,\n },\n ...publish,\n ],\n score: null,\n load: null,\n }\n }\n const tree: AiDoctrineTree = {\n rootId: validated.rootId,\n nodes: validated.nodes as unknown as Record<string, AiDoctrineNode>,\n }\n // The validator's repairs name the nodes as they were written; every finding names the minted ids.\n const minted = new Map(Object.entries(validated.sourceIds).map(([id, source]) => [source, id]))\n const written = isRecord(input) && isRecord(input['nodes']) ? input['nodes'] : {}\n // What the model wrote of a node, by its minted id: the answer this check was\n // given, or what the caller says was written of a tree it stored first.\n const writtenOf = (id: string): unknown => {\n const source = validated.sourceIds[id] ?? id\n return context.writtenNode ? context.writtenNode(source) : written[source]\n }\n // A node as this check was given it, by its minted id: for a page as stored, what the page carries.\n const storedOf = (id: string): unknown => written[validated.sourceIds[id] ?? id]\n const violations = [\n ...publish,\n // A form's fields share a shape because a field IS one shape — a Form\n // Control over a Form Label and an answer — and a form places no\n // instances, so rule 1 has nothing to ask of one.\n ...(outputKind === 'form' ? [] : detectRepeatedSubtrees(tree, otherPages, context)),\n ...detectLayoutRegions(tree, outputKind),\n ...detectInlineForms(tree, outputKind),\n ...detectLiteralStyles(tree, outputKind),\n ...detectInvisibleLinks(tree, outputKind),\n ...detectOffBrandEmail(tree, outputKind, context.brand),\n ...detectTypedData(tree),\n ...detectUnfilledInstances(tree, context),\n ...detectImageSources(tree, context),\n ...detectUnrelatedScreenLinks(tree, outputKind, context),\n ...detectLinksWithoutDestination(tree, outputKind, context, writtenOf, storedOf),\n ...detectDocumentStructure(tree, outputKind),\n ...detectAdHocWidths(tree, outputKind),\n ...detectUnresponsiveGrids(tree, outputKind, writtenOf),\n ...detectOffVoiceCopy(aiTreeCopy(tree, context), context.framing),\n ...detectCutLines(validated.repairs, written, (id) => minted.get(id) ?? id),\n ...detectDanglingWords(tree),\n ...detectHeavyDocument(tree, outputKind, context),\n ...detectEmptyItems(tree),\n ]\n const score = scoreAiOutput(tree, outputKind, context)\n violations.push(...detectOverBudget(score, outputKind, tree, context))\n return {\n ok: violations.length === 0,\n tree: validated,\n violations,\n score,\n load: estimateAiOutputLoad(score, outputKind),\n }\n}\n\n// ── Plans ────────────────────────────────────────────────────────────────\n\ntype RecordKind =\n | 'component'\n | 'layout'\n | 'template'\n | 'form'\n | 'dataset'\n | 'collection'\n | 'screen'\n\nconst NAME_STOPWORDS = new Set([\n 'a',\n 'an',\n 'and',\n 'the',\n 'of',\n 'for',\n 'to',\n 'our',\n 'your',\n 'my',\n 'us',\n 'we',\n 'page',\n 'pages',\n 'section',\n 'new',\n 'site',\n 'block',\n 'main',\n])\n\nfunction nameTokens(value: string): string[] {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .split(' ')\n .filter(Boolean)\n .map((word) =>\n word.length > 3 && word.endsWith('s') && !word.endsWith('ss') ? word.slice(0, -1) : word,\n )\n .filter((word) => !NAME_STOPWORDS.has(word))\n}\n\n/**\n * Whether two names name the same thing: the same words once filler is\n * dropped, or every word of a name of two or more words inside the other.\n */\nexport function aiNamesMatch(left: string, right: string): boolean {\n const a = new Set(nameTokens(left))\n const b = new Set(nameTokens(right))\n if (!a.size || !b.size) return false\n const [small, large] = a.size <= b.size ? [a, b] : [b, a]\n return (\n [...small].every((word) => large.has(word)) &&\n (small.size === large.size || small.size >= 2)\n )\n}\n\nfunction inventoryKinds(inventory: AiSiteInventory | null): Map<string, RecordKind> {\n const kinds = new Map<string, RecordKind>()\n if (!inventory) return kinds\n const add = (rows: Array<{ id: string }>, kind: RecordKind) => {\n for (const row of rows) kinds.set(row.id, kind)\n }\n add(inventory.components, 'component')\n add(inventory.layouts, 'layout')\n add(inventory.templates, 'template')\n add(inventory.forms, 'form')\n add(inventory.datasets, 'dataset')\n add(inventory.collections, 'collection')\n add(inventory.screens, 'screen')\n return kinds\n}\n\n/** What a plan reference resolves to: an inventory record's kind, or a creation's. */\nfunction refKind(\n ref: string | null,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): RecordKind | AiBuildPlanCreateKind | null {\n if (!ref) return null\n if (isAiPlanNewRef(ref)) return aiPlanCreateFor(plan, ref)?.kind ?? null\n return kinds.get(ref) ?? null\n}\n\nfunction sectionPaths(plan: AiBuildPlan) {\n return plan.screens.flatMap((screen, screenIndex) =>\n screen.sections.map((section, sectionIndex) => ({\n screen,\n screenIndex,\n section,\n path: `screens[${screenIndex}].sections[${sectionIndex}]`,\n })),\n )\n}\n\nconst LAYOUT_REGION_NAME =\n /\\b(?:site header|header|nav(?:igation)?|nav ?bar|footer|announcement(?: bar)?|cookie(?: notice| banner| consent)?|top ?bar)\\b/i\nconst FORM_SECTION_NAME =\n /\\bform\\b|\\bsign[- ]?up\\b|\\bsubscribe\\b|\\bnewsletter\\b|\\bcontact us\\b|\\b(?:get|request) a quote\\b|\\bregist(?:er|ration)\\b|\\b(?:en|in)quiry\\b/i\n\n/**\n * Rule 1 (plan): repeated items place a component, and a section two screens\n * share is one. A workspace that keeps no reusable components draws them in\n * their sections instead (AGL-3030), and nothing is refused.\n *\n * A job whose pages the layout language compiles (`repeatsCompiled`, a\n * build) is not asked for a component for a section's repeated items: the\n * compiler draws them in the section, compact where the plan places none, so\n * the page answers rule 1 itself (AGL-3660). Held to the first half anyway,\n * the canonical build request was refused twice for an About page's three\n * values (AGL-3616). A section two pages share is still one component.\n */\nexport function detectPlanRepeats(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (capabilities?.reusableComponents === false) return []\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const placesComponent = (uses: string[]) =>\n uses.some((ref) => refKind(ref, plan, kinds) === 'component')\n const bound = (uses: string[]) =>\n uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))\n const repeated = capabilities?.repeatsCompiled\n ? []\n : sectionPaths(plan).filter(\n ({ section }) =>\n section.items >= AI_REPEAT_MIN_COUNT && !placesComponent(section.uses) && !bound(section.uses),\n )\n if (repeated.length) {\n violations.push({\n rule: 1,\n code: 'plan-repeated-items',\n message:\n 'A section repeats items without a component. Plan one reusable component for the item, reuse one the site has, or bind the items to data.',\n paths: repeated.map((entry) => entry.path),\n })\n }\n const byName = new Map<string, ReturnType<typeof sectionPaths>>()\n for (const entry of sectionPaths(plan)) {\n const key = nameTokens(entry.section.name).join(' ')\n if (!key || LAYOUT_REGION_NAME.test(entry.section.name)) continue\n byName.set(key, [...(byName.get(key) ?? []), entry])\n }\n for (const entries of byName.values()) {\n const screens = new Set(entries.map((entry) => entry.screenIndex))\n if (screens.size < 2) continue\n const shared = entries\n .map((entry) => entry.section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component'))\n .reduce((common, refs) => common.filter((ref) => refs.includes(ref)))\n if (shared.length) continue\n violations.push({\n rule: 1,\n code: 'plan-section-across-screens',\n message: `The \"${entries[0].section.name}\" section is planned on ${screens.size} pages. Plan it as one reusable component and place it on each.`,\n paths: entries.map((entry) => entry.path),\n })\n }\n return violations\n}\n\n/** The fewest sections of one item, side by side and of one kind, that are one list split apart. */\nexport const AI_SPLIT_LIST_MIN_SECTIONS = 2\n\n/** A section name's label: what comes before a colon or a spaced dash, as \"practice area\" in \"practice area: family law\". */\nconst SECTION_LABEL = /^(.+?)\\s*(?::|\\s[-–—])\\s*\\S/\n\n/** A name for many of what a name names one of. */\nfunction pluralOf(name: string): string {\n const words = name.trim()\n if (/s$/i.test(words)) return words\n return /[^aeiou]y$/i.test(words) ? `${words.slice(0, -1)}ies` : `${words}s`\n}\n\n/**\n * What kind of item a section of one item shows, for telling a list split\n * into sections apart from sections that each show one different thing: the\n * components it places, else the label its name gives the item. `null` when\n * neither says, or when the section binds its item to data.\n */\nfunction sectionItemKind(\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n inventory: AiSiteInventory | null,\n): { key: string; name: string; components: string[] } | null {\n if (section.uses.some((ref) => ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))))) return null\n const label = SECTION_LABEL.exec(section.name)?.[1]?.trim() ?? ''\n const components = section.uses.filter((ref) => refKind(ref, plan, kinds) === 'component')\n if (components.length) {\n const [first] = components\n const named = isAiPlanNewRef(first)\n ? aiPlanCreateFor(plan, first)?.name\n : inventory?.components.find((row) => row.id === first)?.name\n return {\n key: `component:${components.map((ref) => ref.toLowerCase()).sort().join('|')}`,\n name: pluralOf(label || named || first),\n components,\n }\n }\n const words = nameTokens(label).join(' ')\n return words ? { key: `label:${words}`, name: pluralOf(label), components: [] } : null\n}\n\n/**\n * Rule 1 (plan): a list is one section whose items repeat (AGL-3071). A\n * section's `items` counts what it repeats, so two or more sections side by\n * side that each show one item of the same kind — the same component, or a\n * name that labels the same kind of item — are one list split apart. A live\n * Free About page planned \"the four areas we practice\" as four sections of one\n * item: none was drawn from the one written-once item a repeated section is\n * built from, and the four came out in three different shapes. The re-ask\n * names the sections and gives the one section to plan instead. Where the\n * workspace keeps reusable components, a list long enough for rule 1 places\n * one for its item, so the section it gives places one too.\n *\n * Sections of several items are never joined: two lists that share a card\n * are two lists, and rule 8 counts each within its own section (AGL-3061).\n */\nexport function detectPlanSplitLists(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n plan.screens.forEach((screen, screenIndex) => {\n let run: Array<{ index: number; kind: NonNullable<ReturnType<typeof sectionItemKind>> }> = []\n const close = () => {\n if (run.length >= AI_SPLIT_LIST_MIN_SECTIONS) {\n const names = run.map(({ index }) => `\"${screen.sections[index].name}\"`)\n const listed = `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n const [{ kind }] = run\n // Rule 1 asks a list this long on a workspace that keeps components to place one for its item.\n const component =\n !kind.components.length &&\n capabilities?.reusableComponents !== false &&\n !capabilities?.repeatsCompiled &&\n run.length >= AI_REPEAT_MIN_COUNT\n const section = { name: kind.name, uses: component ? ['new:<name>'] : kind.components, items: run.length }\n const instead = component\n ? `, placing one reusable component for the item: reuse one the site has by its id, or declare one in create and place it as new:<name>, as in ${JSON.stringify(section)}.`\n : `: ${JSON.stringify(section)}.`\n violations.push({\n rule: 1,\n code: 'plan-split-list',\n message: `The sections ${listed} each show one item of the same kind, so they are one list split apart. Plan them as one section whose ${run.length} items repeat${instead}`,\n paths: run.map(({ index }) => `screens[${screenIndex}].sections[${index}]`),\n })\n }\n run = []\n }\n screen.sections.forEach((section, index) => {\n const kind = section.items === 1 ? sectionItemKind(section, plan, kinds, inventory) : null\n if (!kind || (run.length && run[0].kind.key !== kind.key)) close()\n if (kind) run.push({ index, kind })\n })\n close()\n })\n return violations\n}\n\n/** Where the plan's sections place a record of one kind, as `screens[0].sections[1].uses[0]`. */\nfunction placementsOf(\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n kind: RecordKind,\n): string[] {\n return sectionPaths(plan).flatMap(({ section, path }) =>\n section.uses.flatMap((ref, index) =>\n refKind(ref, plan, kinds) === kind ? [`${path}.uses[${index}]`] : [],\n ),\n )\n}\n\n/** A creation's name as a reference may spell it: letters and digits only. */\nfunction creationKey(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '')\n}\n\n/**\n * A `new:` reference that spells a creation differently — `new:cake-order-form`\n * for \"Cake order form\" (a live bakery plan, 2026-10-07) — is pointed at that\n * creation before the rules read the plan, when exactly one creation matches\n * it with case, spaces and punctuation ignored. Two that match, or none, are\n * left for the rules to ask about.\n *\n * So is a creation named without its prefix — `Contact form` in a section's\n * uses for the \"Contact form\" the plan creates — where the name is no record\n * the site has (AGL-3660). A re-asked plan told to place its form \"by id\"\n * can answer with the form's bare name, which is no reference at all.\n */\nexport function aiSettlePlanRefs(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null = null,\n): AiBuildPlan {\n if (!plan.create.length) return plan\n const kinds = inventoryKinds(inventory)\n const resolve = (ref: string | null): string | null => {\n if (!ref || kinds.has(ref) || aiPlanCreateFor(plan, ref)) return ref\n const key = creationKey(isAiPlanNewRef(ref) ? ref.slice('new:'.length) : ref)\n if (!key) return ref\n const matches = plan.create.filter((entry) => creationKey(entry.name) === key)\n return matches.length === 1 ? `new:${matches[0].name}` : ref\n }\n let changed = false\n const settle = (ref: string | null): string | null => {\n const next = resolve(ref)\n if (next !== ref) changed = true\n return next\n }\n const screens = plan.screens.map((screen) => ({\n ...screen,\n layout: settle(screen.layout),\n template: settle(screen.template),\n sections: screen.sections.map((section) => ({\n ...section,\n uses: section.uses.map((ref) => settle(ref) ?? ref),\n })),\n }))\n return changed ? { ...plan, screens } : plan\n}\n\n/**\n * What customers say, which no dataset of the site's holds: a review, a\n * testimonial, a rating, a quote (AGL-3616). A job never writes them for the\n * people who did not, so a dataset of them is one nothing can seed.\n */\nexport const AI_DATASET_SAID_NAME = /\\b(reviews?|testimonials?|ratings?|quotes?|stars?|endorsements?)\\b/i\n\n/**\n * A plan that creates more datasets than this job may make is settled in\n * code, never re-asked (AGL-3616). The live eval of 2026-10-10 refused a\n * dental practice's plan four times over for a fourth dataset, and a food\n * bank's re-ask for one broke a layout rule its first answer had kept.\n *\n * A dataset of what customers say (`AI_DATASET_SAID_NAME`, in its name or a\n * field) is let go first, whatever the cap: both of those plans made one of\n * testimonials, which nothing may seed.\n *\n * The datasets kept are the most useful: the ones the most sections list,\n * a record template counting double, plan order breaking ties. Each one let\n * go leaves the plan whole — its `new:` reference comes off every section,\n * a record template of it becomes a page of its own, and a section that\n * listed it shows fewer items than rule 8 binds, so its items are written\n * out on the page. Where the job may create no dataset at all, rule 7 still\n * asks, as it does for any creation.\n */\nexport function aiSettlePlanDatasets(plan: AiBuildPlan, capabilities: AiPlanCapabilities | null = null): AiBuildPlan {\n const entry = capabilities?.create.dataset\n if (!entry?.allowed) return plan\n const cap = Math.min(capabilities?.datasetsMax ?? Infinity, entry.left ?? Infinity)\n const datasets = plan.create.filter((one) => one.kind === 'dataset')\n // A dataset a form writes to holds what visitors send (AGL-3616): its\n // fields may well be a rating or a quote request, and nothing seeds it.\n const forForms = aiPlanFormDatasetNames(plan)\n const said = (one: (typeof datasets)[number]) =>\n !forForms.has(one.name.trim().toLowerCase()) &&\n (AI_DATASET_SAID_NAME.test(one.name) || one.fields.some((field) => AI_DATASET_SAID_NAME.test(field)))\n if (!datasets.some(said) && (!Number.isFinite(cap) || datasets.length <= cap)) return plan\n const named = (ref: string | null | undefined, name: string) =>\n !!ref && isAiPlanNewRef(ref) && ref.slice('new:'.length).trim().toLowerCase() === name.trim().toLowerCase()\n // A form's dataset counts as much as a record template: the form the\n // person asked for is built around it.\n const score = (name: string) =>\n (forForms.has(name.trim().toLowerCase()) ? 2 : 0) +\n plan.screens.reduce(\n (total, screen) =>\n total +\n (named(screen.record?.dataset, name) ? 2 : 0) +\n screen.sections.filter((section) => section.uses.some((ref) => named(ref, name))).length,\n 0,\n )\n const ranked = datasets\n .filter((one) => !said(one))\n .map((one, index) => ({ name: one.name, index, score: score(one.name) }))\n .sort((a, b) => b.score - a.score || a.index - b.index)\n const kept = new Set(ranked.slice(0, Math.max(0, cap)).map((one) => one.name.trim().toLowerCase()))\n const dropped = new Set(datasets.map((one) => one.name.trim().toLowerCase()).filter((name) => !kept.has(name)))\n const isDropped = (ref: string | null | undefined) => [...dropped].some((name) => named(ref, name))\n return {\n ...plan,\n create: plan.create\n .filter((one) => one.kind !== 'dataset' || !dropped.has(one.name.trim().toLowerCase()))\n // A form whose dataset was let go sends its submissions to the Inbox only.\n .map((one) => (one.kind === 'form' && isDropped(one.writesTo) ? withoutWritesTo(one) : one)),\n screens: plan.screens.map((screen) => ({\n ...screen,\n record: screen.record && isDropped(screen.record.dataset) ? null : screen.record,\n sections: screen.sections.map((section) =>\n section.uses.some(isDropped)\n ? {\n ...section,\n uses: section.uses.filter((ref) => !isDropped(ref)),\n items: Math.min(section.items, AI_TYPED_LIST_MIN_ITEMS - 1),\n }\n : section,\n ),\n })),\n }\n}\n\n/** A creation with no `writesTo`, as a plan that never said one reads. */\nfunction withoutWritesTo<T extends { writesTo?: string | null }>(creation: T): T {\n const rest = { ...creation }\n delete rest.writesTo\n return rest\n}\n\n/**\n * A form's dataset, settled in code before the rules read the plan\n * (AGL-3616, Zach 2026-10-10: Aglyn AI's forms write to its datasets).\n *\n * - A `writesTo` that names nothing the form can write to comes off: a\n * `new:` of no dataset this plan creates, an id the inventory does not\n * hold, or a dataset this job may not create. The form is then the\n * form it always was, its submissions in the Inbox. A dataset the\n * inventory holds, named by its name rather than its id, is given its id.\n * - A dataset this plan creates for a form holds the people who send it:\n * no page lists it and none is its record template, so its `new:` comes\n * off every section and record that named it, and a section that listed\n * it shows fewer items than rule 8 binds.\n */\nexport function aiSettlePlanFormDatasets(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n if (!plan.create.some((one) => one.kind === 'form' && one.writesTo)) return plan\n const held = inventory?.datasets ?? []\n const creatable = !capabilities || capabilities.create.dataset.allowed\n let changed = false\n const create = plan.create.map((one) => {\n if (one.kind !== 'form' || !one.writesTo) return one\n const ref = one.writesTo.trim()\n if (isAiPlanNewRef(ref)) {\n if (creatable && aiPlanCreateFor(plan, ref)?.kind === 'dataset') return one\n // A build's dataset item, which the data plugin's operation makes.\n if (aiPlanItemFor(plan, ref)?.op === AI_PLAN_DATASET_ITEM_OP) return one\n } else {\n if (held.some((row) => row.id === ref)) return one\n const byName = held.find((row) => aiNamesMatch(row.name, ref))\n if (byName) {\n changed = true\n return { ...one, writesTo: byName.id }\n }\n }\n changed = true\n return withoutWritesTo(one)\n })\n const settled = { ...plan, create }\n const forForms = aiPlanFormDatasetNames(settled)\n const listsOne = (ref: string | null | undefined) =>\n isAiPlanNewRef(ref) && forForms.has(ref.slice('new:'.length).trim().toLowerCase())\n const screens = plan.screens.map((screen) => {\n const record = screen.record && listsOne(screen.record.dataset) ? null : screen.record\n const sections = screen.sections.map((section) =>\n section.uses.some(listsOne)\n ? {\n ...section,\n uses: section.uses.filter((ref) => !listsOne(ref)),\n items: Math.min(section.items, AI_TYPED_LIST_MIN_ITEMS - 1),\n }\n : section,\n )\n if (record === screen.record && sections.every((section, index) => section === screen.sections[index])) return screen\n changed = true\n return { ...screen, record, sections }\n })\n return changed ? { ...settled, screens } : plan\n}\n\n/**\n * A page that names no layout, on a site where only one layout can frame it,\n * is put in that layout before the rules read the plan (2026-10-07). The\n * model sometimes leaves one page's layout empty — a live run's bookkeeper\n * plan did, beside a layout it created — and rule 2 refused the whole plan\n * for a choice with one answer. That answer exists only on a site with no\n * layout whose plan creates exactly one, which is every guided start. Where\n * the site has a layout of its own, a page that names none may mean another,\n * so the rule still asks.\n */\nexport function aiSettlePlanLayouts(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n if (!inventory || inventory.layouts.length > 0 || !plan.screens.length) return plan\n const kinds = inventoryKinds(inventory)\n const created = plan.create.filter((entry) => entry.kind === 'layout')\n const unlaid = plan.screens.filter((screen) => refKind(screen.layout, plan, kinds) !== 'layout')\n if (!unlaid.length) return plan\n if (created.length === 1) {\n const only = `new:${created[0].name}`\n return {\n ...plan,\n screens: plan.screens.map((screen) =>\n refKind(screen.layout, plan, kinds) === 'layout' ? screen : { ...screen, layout: only },\n ),\n }\n }\n // No layout planned at all on a site with none (a live dental plan named\n // \"default\" for both pages, twice): the site's one shared header and footer\n // is planned for it, with every region a layout is built of, and every page\n // goes in it. Only where this job may create a layout.\n const mayCreateLayout = !capabilities || capabilities.create.layout.allowed\n if (created.length > 0 || !mayCreateLayout) return plan\n const taken = new Set(plan.create.map((entry) => entry.name.toLowerCase()))\n const name = taken.has('site layout') ? 'Site header and footer' : 'Site layout'\n return {\n ...plan,\n create: [\n {\n kind: 'layout',\n name,\n why: 'Every page shares one header, navigation and footer.',\n duplicateOf: null,\n fields: ['header', 'nav', 'main', 'footer'],\n },\n ...plan.create,\n ],\n screens: plan.screens.map((screen) => ({ ...screen, layout: `new:${name}` })),\n }\n}\n\n/**\n * A page section that is a layout region — a header, navigation or footer,\n * read by the name rule 2's `plan-layout-region-section` reads — is taken off\n * the page before the rules read the plan (AGL-3750). The region is already\n * the layout's, so the rule's own answer, \"take the section off the page\", is\n * the only one: a live Free start of 2026-10-12 (a bakery that sells cakes to\n * order) planned a Header and a Footer on its pages three times and stopped.\n *\n * Only a section that places nothing, or nothing but a layout (which rule 2\n * refuses placing as well), is taken off: one that places a form or a\n * component may be a band misnamed, so the rule still asks. A page whose\n * every section is a region keeps them all, and is re-asked as before, since\n * a page of no sections has no answer here. A home this leaves under its\n * fewest sections, or a Free plan still past its wall, is the existing\n * checks' to settle or refuse.\n */\nexport function aiSettlePlanLayoutRegionSections(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiBuildPlan {\n const kinds = inventoryKinds(inventory)\n const removable = (section: AiBuildPlan['screens'][number]['sections'][number]) =>\n LAYOUT_REGION_NAME.test(section.name) &&\n section.uses.every((ref) => refKind(ref, plan, kinds) === 'layout')\n let changed = false\n const screens = plan.screens.map((screen) => {\n const kept = screen.sections.filter((section) => !removable(section))\n if (kept.length === screen.sections.length || !kept.length) return screen\n changed = true\n return { ...screen, sections: kept }\n })\n return changed ? { ...plan, screens } : plan\n}\n\n/**\n * A section that shows the work — a gallery, a portfolio, selected works, by\n * the name `aiSiteSectionShowsWork` reads — planned with fewer pieces than\n * the job's `galleryMinItems` is raised to it before the rules read the plan\n * (AGL-3754). The site start's `plan-empty-gallery` refusal names one answer,\n * \"plan it with three to six items\", and the fewest is the one that keeps\n * the plan's own count closest: a section's items move no section cap, Free\n * wall or credit figure, which count sections and pages.\n *\n * A section the rule reads as one item of a list split into sections is\n * left for rule 1's re-ask to join, as the Free wall's trim leaves it: raised\n * here, it would hide the split. A job that sets no `galleryMinItems` (every\n * job but a site start) is returned unchanged.\n */\nexport function aiSettlePlanGalleries(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n const least = capabilities?.galleryMinItems ?? 0\n const thin = (section: AiBuildPlanSection) => aiSiteSectionShowsWork(section.name) && section.items < least\n if (!plan.screens.some((screen) => screen.sections.some(thin))) return plan\n const split = new Set(detectPlanSplitLists(plan, inventory, capabilities).flatMap((violation) => violation.paths ?? []))\n let changed = false\n const screens = plan.screens.map((screen, screenIndex) => {\n if (!screen.sections.some(thin)) return screen\n return {\n ...screen,\n sections: screen.sections.map((section, sectionIndex) => {\n if (!thin(section) || split.has(`screens[${screenIndex}].sections[${sectionIndex}]`)) return section\n changed = true\n return { ...section, items: least }\n }),\n }\n })\n return changed ? { ...plan, screens } : plan\n}\n\n/** A saved form a plan section could place: one the plan creates, or one the site has. */\ninterface AiPlanFormChoice {\n /** As a section's uses names it: `new:<name>` or the inventory id. */\n ref: string\n name: string\n created: boolean\n}\n\n/** Every saved form a plan could place, the plan's own creations first. */\nfunction planFormChoices(plan: AiBuildPlan, inventory: AiSiteInventory | null): AiPlanFormChoice[] {\n return [\n ...plan.create\n .filter((entry) => entry.kind === 'form')\n .map((entry) => ({ ref: `new:${entry.name}`, name: entry.name, created: true })),\n ...(inventory?.forms ?? []).map((form) => ({ ref: form.id, name: form.name, created: false })),\n ]\n}\n\n/** The form a plan's own words would name for a section's reference, so placements count alike. */\nfunction formChoiceKey(ref: string, plan: AiBuildPlan): string {\n const created = isAiPlanNewRef(ref) ? aiPlanCreateFor(plan, ref) : undefined\n return created ? `new:${created.name}` : ref\n}\n\n/**\n * The form a section that collects answers places: the one whose name shares\n * the most words with the section's (\"Commission inquiry\" → \"Commission\n * inquiry form\"), then the one the plan already places most, then the plan's\n * own creation over a form the site has. `null` when there is none.\n */\nfunction bestPlanForm(\n section: AiBuildPlanSection,\n choices: readonly AiPlanFormChoice[],\n placed: ReadonlyMap<string, number>,\n): AiPlanFormChoice | null {\n const words = new Set(nameTokens(section.name).filter((word) => word !== 'form'))\n const score = (choice: AiPlanFormChoice) =>\n nameTokens(choice.name).filter((word) => word !== 'form' && words.has(word)).length\n const ranked = [...choices].sort(\n (a, b) =>\n score(b) - score(a) ||\n (placed.get(b.ref) ?? 0) - (placed.get(a.ref) ?? 0) ||\n Number(b.created) - Number(a.created),\n )\n return ranked[0] ?? null\n}\n\n/** The contact form a plan is given when a section collects answers and the plan makes no form. */\nexport const AI_PLAN_SETTLED_FORM = {\n name: 'Contact form',\n why: 'Visitors need a way to reach the owner, and the site has no saved form for it.',\n fields: ['name', 'email', 'message'],\n} as const\n\n/**\n * A section that collects answers and places no saved form is given one\n * before the rules read the plan (AGL-3660), rather than failing the build.\n * A production guided start for a ceramic artist's portfolio (2026-10-09,\n * five pages, 94 credits refunded) planned a section that asks for\n * commissions on its work page without placing the contact form the plan\n * made for its Contact page; the answer and its re-ask both did, and rule 3\n * failed the whole site for one section.\n *\n * The section places, in order of preference:\n * 1. the form whose name best matches it, among those the plan creates and\n * the site has, preferring one the plan already places — so a guided\n * start, which makes one form, places that same form again rather than a\n * second one;\n * 2. where there is no form at all and this job may create one, a form the\n * plan now creates: named for the `new:` reference the section already\n * holds when it names a form it never declared, the contact form\n * otherwise.\n *\n * Nothing is taken out of the plan: the section keeps its name, its other\n * uses and its items. Where the site has no form and the job may create none,\n * rule 3 asks for nothing (AGL-3596), and neither does this. A section whose\n * uses are already full is left for the rule to ask about.\n */\nexport function aiSettlePlanForms(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n if (!aiPlanCanPlaceForm(inventory, capabilities)) return plan\n const kinds = inventoryKinds(inventory)\n const unbound = (current: AiBuildPlan) =>\n sectionPaths(current).filter(\n ({ section }) =>\n FORM_SECTION_NAME.test(section.name) &&\n section.uses.length < AI_BUILD_PLAN_LIMITS.uses &&\n !section.uses.some((ref) => refKind(ref, current, kinds) === 'form'),\n )\n const first = unbound(plan)\n if (!first.length) return plan\n let next = plan\n if (!planFormChoices(next, inventory).length) {\n if (capabilities && !capabilities.create.form.allowed) return plan\n // A form the section already names and the plan never declared is the form it meant.\n const named = first\n .flatMap(({ section }) => section.uses)\n .find((ref) => isAiPlanNewRef(ref) && !aiPlanCreateFor(next, ref) && !aiPlanItemFor(next, ref))\n const taken = new Set(next.create.map((entry) => entry.name.toLowerCase()))\n const name = named\n ? named.slice('new:'.length).trim()\n : taken.has(AI_PLAN_SETTLED_FORM.name.toLowerCase())\n ? 'Get in touch form'\n : AI_PLAN_SETTLED_FORM.name\n next = {\n ...next,\n create: [\n ...next.create,\n {\n kind: 'form',\n name,\n why: AI_PLAN_SETTLED_FORM.why,\n duplicateOf: null,\n fields: [...AI_PLAN_SETTLED_FORM.fields],\n },\n ],\n }\n }\n const choices = planFormChoices(next, inventory)\n const placed = new Map<string, number>()\n for (const { section } of sectionPaths(next)) {\n for (const ref of section.uses) {\n if (refKind(ref, next, kinds) !== 'form') continue\n const key = formChoiceKey(ref, next)\n placed.set(key, (placed.get(key) ?? 0) + 1)\n }\n }\n const settle = new Map<string, string>()\n for (const { section, path } of unbound(next)) {\n const form = bestPlanForm(section, choices, placed)\n if (form) settle.set(path, form.ref)\n }\n if (!settle.size) return next\n return {\n ...next,\n screens: next.screens.map((screen, screenIndex) => ({\n ...screen,\n sections: screen.sections.map((section, sectionIndex) => {\n const ref = settle.get(`screens[${screenIndex}].sections[${sectionIndex}]`)\n if (!ref) return section\n // The undeclared reference the form was named for now names it; any other stays.\n const uses = section.uses.some((use) => formChoiceKey(use, next) === ref) ? section.uses : [...section.uses, ref]\n return { ...section, uses }\n }),\n })),\n }\n}\n\n/** The forms a section that collects answers can place, as the re-ask names them. */\nfunction planFormChoicesText(plan: AiBuildPlan, inventory: AiSiteInventory | null): string {\n const choices = planFormChoices(plan, inventory)\n if (!choices.length) return 'Plan one in create as a form, and put new:<its name> in the section\\'s uses.'\n return `Put one of these in the section's uses: ${choices\n .map((choice) => (choice.created ? choice.ref : `${choice.ref} (${choice.name})`))\n .join(', ')}.`\n}\n\n/**\n * Rule 2 (plan): every screen declares a layout, no section is a copy of a\n * layout region, and no section places a layout, which frames a whole screen\n * (AGL-3040). A site with no layout, where this job may not create one\n * (AGL-3030), has nothing to declare: its screens name none, and a screen\n * that names none is not refused there. A screen whose layout is a `new:`\n * reference the plan never creates is refused here, and only here.\n */\nexport function detectPlanLayoutRegions(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const mayCreateLayout = !capabilities || capabilities.create.layout.allowed\n const noLayoutToName = !mayCreateLayout && !(inventory?.layouts.length ?? 0)\n const unlaid = plan.screens\n .map((screen, index) => ({ screen, index }))\n .filter(\n ({ screen }) =>\n refKind(screen.layout, plan, kinds) !== 'layout' &&\n !(noLayoutToName && screen.layout === null),\n )\n if (unlaid.length) {\n violations.push({\n rule: 2,\n code: 'plan-screen-without-layout',\n message: noLayoutToName\n ? 'A page names a layout the site does not have, and this job may not create one. Leave the layout empty.'\n : mayCreateLayout\n ? \"A page names no layout the site has or the plan creates. Put every page in the site's layout, or plan one.\"\n : 'A page names no layout the site has, and this job may not create one. Put every page in a layout the site has.',\n paths: unlaid.map(({ index }) => `screens[${index}].layout`),\n })\n }\n const regions = sectionPaths(plan).filter(({ section }) =>\n LAYOUT_REGION_NAME.test(section.name),\n )\n if (regions.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-region-section',\n message:\n 'A page plans its own header, navigation or footer. Those live in the layout; take the section off the page.',\n paths: regions.map((entry) => entry.path),\n })\n }\n const placed = placementsOf(plan, kinds, 'layout')\n if (placed.length) {\n violations.push({\n rule: 2,\n code: 'plan-layout-in-section',\n message:\n \"A section places a layout. A layout frames a whole page and is never placed inside one: name it as the page's layout, and take it out of the section's uses.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/**\n * Rule 3 (plan): a section that collects answers places a saved form — one\n * the site has, or one the plan creates on the Forms page. Where neither is\n * possible (the site has no form and this job may create none), the page\n * places no form, and a section named for one is not refused: there is\n * nothing it could place (AGL-3596). It is never drawn inline instead.\n */\nexport function detectPlanInlineForms(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n if (!aiPlanCanPlaceForm(inventory, capabilities)) return []\n const kinds = inventoryKinds(inventory)\n const unbound = sectionPaths(plan).filter(\n ({ section }) =>\n FORM_SECTION_NAME.test(section.name) &&\n !section.uses.some((ref) => refKind(ref, plan, kinds) === 'form'),\n )\n return unbound.length\n ? [\n {\n rule: 3,\n code: 'plan-form-not-placed',\n message:\n 'A section collects answers without a form. Reuse a form from the Forms page, or plan one there, and place it by id.',\n detail: planFormChoicesText(plan, inventory),\n paths: unbound.map((entry) => entry.path),\n },\n ]\n : []\n}\n\n/** Pages sharing one shape this many times are a template applied. */\nexport const AI_SIMILAR_PAGES_MIN = 3\n\n/**\n * Rule 4 (plan): three or more screens with the same sections share one\n * template, and a template is what a screen applies, never what one of its\n * sections places (AGL-3040).\n *\n * A record-bound screen (AGL-3475) is the other answer: one page that the\n * data plugin serves once per record of a dataset. It stands for its pages\n * rather than copying them, so it joins no group, and it is held to naming a\n * dataset the site has or the plan creates, and a base no other record page\n * of the plan takes — the save route refuses a second template of one\n * dataset or one base, so a plan that promises either promises a binding the\n * member cannot save.\n */\nexport function detectUntemplatedSimilarPages(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const groups = new Map<string, number[]>()\n plan.screens.forEach((screen, index) => {\n if (screen.record || screen.sections.length < 2) return\n const signature = screen.sections\n .map((section) => nameTokens(section.name).join(' '))\n .join('|')\n groups.set(signature, [...(groups.get(signature) ?? []), index])\n })\n const violations: AiDoctrineViolation[] = []\n for (const indexes of groups.values()) {\n if (indexes.length < AI_SIMILAR_PAGES_MIN) continue\n const templates = new Set(indexes.map((index) => plan.screens[index].template))\n if (templates.size === 1 && !templates.has(null)) continue\n violations.push({\n rule: 4,\n code: 'plan-similar-pages',\n message: `${indexes.length} pages share one shape. Plan one template and apply it ${indexes.length} times with each page's copy, or bind it to a collection; when the pages are records of a dataset, plan one page bound to it by \"record\" instead.`,\n paths: indexes.map((index) => `screens[${index}].template`),\n })\n }\n const bound = plan.screens\n .map((screen, index) => ({ record: screen.record, index }))\n .filter((entry): entry is { record: AiBuildPlanRecord; index: number } => Boolean(entry.record))\n const unknown = bound.filter(({ record }) => refKind(record.dataset, plan, kinds) !== 'dataset')\n if (unknown.length) {\n violations.push({\n rule: 4,\n code: 'plan-record-dataset',\n message:\n 'A record page names no dataset the site has or the plan creates. Name one from the site inventory, or plan the dataset and name it as new:<name>.',\n paths: unknown.map(({ index }) => `screens[${index}].record.dataset`),\n })\n }\n const shared = bound.filter(({ record, index }) =>\n bound.some(\n (other) =>\n other.index !== index &&\n (other.record.base === record.base || other.record.dataset === record.dataset),\n ),\n )\n if (shared.length) {\n violations.push({\n rule: 4,\n code: 'plan-record-shared',\n message:\n 'Two record pages share a dataset or a base. A dataset has one record template on a site, and each base serves one: keep one page, or give each its own dataset and base.',\n paths: shared.map(({ index }) => `screens[${index}].record`),\n })\n }\n const placed = placementsOf(plan, kinds, 'template')\n if (placed.length) {\n violations.push({\n rule: 4,\n code: 'plan-template-in-section',\n message:\n \"A section places a template. A template is applied to a whole page and is never placed inside one: take it out of the section's uses, and name it as the page's template only when the whole page is built from it.\",\n paths: placed,\n })\n }\n return violations\n}\n\n/** Rule 5 (plan): a color value belongs only in a theme change. */\nexport function detectPlanLiteralColors(plan: AiBuildPlan): AiDoctrineViolation[] {\n const paths: string[] = []\n plan.create.forEach((entry, index) => {\n if (entry.kind === 'theme-change') return\n if (hasLiteralColor(entry.why) || entry.fields.some(hasLiteralColor)) {\n paths.push(`create[${index}]`)\n }\n })\n for (const { section, path } of sectionPaths(plan)) {\n if (hasLiteralColor(section.name)) paths.push(path)\n }\n return paths.length\n ? [\n {\n rule: 5,\n code: 'plan-literal-color',\n message:\n 'The plan writes a color by value outside a theme change. Name theme tokens, and plan a theme change for a color the theme lacks.',\n paths,\n },\n ]\n : []\n}\n\nconst REUSE_BEFORE_CREATE_KINDS: ReadonlySet<AiBuildPlanCreateKind> = new Set([\n 'component',\n 'layout',\n 'form',\n 'dataset',\n])\n\n/** Rule 7 (plan): reuse names real records, and a creation is an exception that says why. */\nexport function detectCreateBeforeReuse(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unknown = plan.reuse\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => entry.kind !== 'theme' && kinds.get(entry.id) !== entry.kind)\n if (unknown.length) {\n violations.push({\n rule: 7,\n code: 'plan-reuse-unknown',\n message:\n 'The plan reuses something the site does not have. Reuse only what the site inventory lists.',\n paths: unknown.map(({ index }) => `reuse[${index}]`),\n })\n }\n const unexplained = plan.create\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => !entry.why.trim())\n if (unexplained.length) {\n violations.push({\n rule: 7,\n code: 'plan-create-without-why',\n message: 'The plan creates something without saying why nothing the site has will do.',\n paths: unexplained.map(({ index }) => `create[${index}].why`),\n })\n }\n const rows: Record<string, Array<{ id: string; name: string }>> = {\n component: inventory?.components ?? [],\n layout: inventory?.layouts ?? [],\n form: inventory?.forms ?? [],\n dataset: inventory?.datasets ?? [],\n }\n plan.create.forEach((entry, index) => {\n if (!REUSE_BEFORE_CREATE_KINDS.has(entry.kind) || entry.duplicateOf) return\n const existing = rows[entry.kind].find((row) => aiNamesMatch(row.name, entry.name))\n if (!existing) return\n violations.push({\n rule: 7,\n code: 'plan-duplicates-existing',\n message: `The site already has a ${entry.kind} named \"${existing.name}\". Reuse it, or propose extending it, instead of creating \"${entry.name}\".`,\n paths: [`create[${index}]`],\n })\n })\n return violations\n}\n\n/**\n * Rule 7 (plan): a plan creates only what the request says this job may\n * create on this site (AGL-3030) — what the workspace's plan includes, what\n * the site has room for, and what the job builds itself. One violation a\n * creation, each saying why and what to do instead.\n */\nexport function detectPlanUncreatable(\n plan: AiBuildPlan,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n if (!capabilities) return []\n return aiPlanUncreatable(plan, capabilities).map((entry) => ({\n rule: 7,\n code: 'plan-create-not-allowed',\n message: entry.message,\n paths: [entry.path],\n }))\n}\n\n/**\n * What a section most likely meant by a creation it places and the plan never\n * declares, so the refusal can name the way out: a form where the reference\n * or its section reads as one and the section places no form yet, otherwise\n * a component. Only the message reads it; the reference is refused whatever\n * it was meant to be.\n */\nfunction undeclaredPlacementKind(\n name: string,\n section: AiBuildPlanSection,\n plan: AiBuildPlan,\n kinds: Map<string, RecordKind>,\n): 'form' | 'component' {\n if (FORM_SECTION_NAME.test(name)) return 'form'\n const placesForm = section.uses.some((ref) => refKind(ref, plan, kinds) === 'form')\n return FORM_SECTION_NAME.test(section.name) && !placesForm ? 'form' : 'component'\n}\n\n/**\n * Rule 7 (plan): what a plan places, it reuses or it creates (AGL-3040). The\n * doctrine has a plan refer to what it creates as new:<name>, so a reference\n * that names no entry of the create list is a creation nothing builds. A page\n * kept with one stops at its first pass, sending the member to make that\n * creation by hand, which a workspace that cannot make it never can. Each is\n * refused with the one re-ask, once a name however often it is placed, and\n * says what to do on THIS workspace: declare the creation where the job may\n * make one more of that kind, and otherwise build the page without it, drawn\n * on the page or placed from what the site has. A screen's layout is rule\n * 2's (`plan-screen-without-layout`), and is not reported twice.\n */\nexport function detectPlanUndeclaredCreations(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const byName = new Map<string, AiPlanUndeclaredRef[]>()\n for (const ref of aiPlanUndeclaredRefs(plan)) {\n if (ref.field === 'layout') continue\n const key = ref.name.toLowerCase()\n byName.set(key, [...(byName.get(key) ?? []), ref])\n }\n return [...byName.values()].map((refs): AiDoctrineViolation => {\n const [first] = refs\n const screen = plan.screens[first.screenIndex]\n const section = first.field === 'uses' ? screen.sections[first.sectionIndex] : null\n const kind: AiBuildPlanCreateKind = section\n ? undeclaredPlacementKind(first.name, section, plan, kinds)\n : 'template'\n const refused = capabilities ? aiPlanUncreatableKind(plan, kind, capabilities) : null\n const where = section\n ? `${section.name ? `The \"${section.name}\" section` : 'A section'} places a creation named \"${first.name}\", but the plan never creates it`\n : `${screen.title ? `The page \"${screen.title}\"` : 'A page'} applies a template named \"${first.name}\", but the plan never creates it`\n let message: string\n if (!refused) {\n const otherwise = section\n ? `place ${aiCreationNoun(kind)} the site already has by its id`\n : \"leave the page's template empty\"\n message = `${where}. Declare it in create as ${aiCreationNoun(kind)}, with why nothing the site has will do, or ${otherwise}.`\n } else if (section) {\n message = `${where}, and ${refused.reason}. ${refused.instead} Take it out of the section's uses.`\n } else {\n message = `${where}, and ${refused.reason}. Leave the page's template empty, or apply a template the site already has.`\n }\n return { rule: 7, code: 'plan-creation-undeclared', message, paths: refs.map((ref) => ref.path) }\n })\n}\n\n/**\n * Rule 8 (plan): long lists are bound, and a list the site already holds is\n * bound to it. Where this job may not create a dataset (AGL-3030), the way\n * out the refusal names is a shorter list rather than a dataset it would\n * only refuse next.\n */\nexport function detectPlanTypedData(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const data = [...(inventory?.datasets ?? []), ...(inventory?.collections ?? [])]\n const typed: string[] = []\n const unbound: Array<{ path: string; name: string }> = []\n for (const { section, path } of sectionPaths(plan)) {\n const bindsData = section.uses.some((ref) =>\n ['dataset', 'collection'].includes(String(refKind(ref, plan, kinds))),\n )\n if (bindsData) continue\n if (section.items >= AI_TYPED_LIST_MIN_ITEMS) typed.push(path)\n const match = data.find((row) => aiNamesMatch(row.name, section.name))\n if (match) unbound.push({ path, name: match.name })\n }\n if (typed.length) {\n violations.push({\n rule: 8,\n code: 'plan-typed-list',\n message:\n capabilities && !capabilities.create.dataset.allowed\n ? `A section plans a long list of typed-out items. Bind it to a dataset or collection the site has, or plan fewer than ${AI_TYPED_LIST_MIN_ITEMS} items.`\n : 'A section plans a long list of typed-out items. Bind it to a dataset or collection, or plan a dataset for data the site does not have yet.',\n paths: typed,\n })\n }\n if (unbound.length) {\n violations.push({\n rule: 8,\n code: 'plan-existing-data-unbound',\n message: `The site already holds \"${unbound[0].name}\" as data. Bind the section to it instead of copying it into the page.`,\n paths: unbound.map((entry) => entry.path),\n })\n }\n return violations\n}\n\nconst SLUG = /^\\/?[a-z0-9]+(?:-[a-z0-9]+)*(?:\\/[a-z0-9]+(?:-[a-z0-9]+)*)*\\/?$|^\\/$/\nexport const AI_SEO_TITLE_MAX = 70\nexport const AI_SEO_DESCRIPTION_MAX = 170\n\nfunction slugKey(slug: string): string {\n return slug.trim().toLowerCase().replace(/^\\/+|\\/+$/g, '')\n}\n\n/** Rule 10 (plan): every screen has a free, well-formed slug, an SEO title and description. */\nexport function detectMissingNavAndSeo(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const violations: AiDoctrineViolation[] = []\n // The starter home a planned home page replaces (AGL-3594) keeps no\n // address from the plan: publishing the page planned at `/` retires it.\n const taken = new Map(\n (inventory?.screens ?? [])\n .filter((screen) => !screen.replaceable)\n .map((screen) => [slugKey(screen.slug), screen.name]),\n )\n const clashes = new Set<string>()\n const seen = new Set<string>()\n const badSlugs: string[] = []\n const collisions: string[] = []\n const seo: string[] = []\n plan.screens.forEach((screen, index) => {\n const key = slugKey(screen.slug)\n if (!screen.slug.trim() || !SLUG.test(screen.slug.trim())) {\n badSlugs.push(`screens[${index}].slug`)\n } else if (seen.has(key) || taken.has(key)) {\n collisions.push(`screens[${index}].slug`)\n clashes.add(`/${key}`)\n }\n seen.add(key)\n if (!screen.seoTitle || screen.seoTitle.length > AI_SEO_TITLE_MAX) {\n seo.push(`screens[${index}].seoTitle`)\n }\n if (!screen.seoDescription || screen.seoDescription.length > AI_SEO_DESCRIPTION_MAX) {\n seo.push(`screens[${index}].seoDescription`)\n }\n })\n if (badSlugs.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug',\n message:\n 'A page has no usable address. Give each one a slug of lowercase words joined by hyphens.',\n paths: badSlugs,\n })\n }\n if (collisions.length) {\n violations.push({\n rule: 10,\n code: 'plan-slug-taken',\n // Names the addresses, so the one re-ask can move the page off them.\n message: `A page reuses an address the site or the plan already uses (${[...clashes].join(', ')}). Give each page its own slug.`,\n paths: collisions,\n })\n }\n if (seo.length) {\n violations.push({\n rule: 10,\n code: 'plan-seo',\n message: `A page is missing its search title or description, or runs past ${AI_SEO_TITLE_MAX} and ${AI_SEO_DESCRIPTION_MAX} characters. Write both for every page.`,\n paths: seo,\n })\n }\n return violations\n}\n\n/** Every piece of copy a plan carries, with its path. */\nexport function aiPlanCopy(plan: AiBuildPlan): AiCopySample[] {\n const samples: AiCopySample[] = []\n plan.screens.forEach((screen, index) => {\n samples.push({ at: `screens[${index}].title`, text: screen.title })\n samples.push({ at: `screens[${index}].seoTitle`, text: screen.seoTitle })\n samples.push({ at: `screens[${index}].seoDescription`, text: screen.seoDescription })\n })\n plan.create.forEach((entry, index) => {\n samples.push({ at: `create[${index}].name`, text: entry.name })\n })\n return samples\n}\n\n/** Rule 15 (plan): a screen or template like one the site has starts as its duplicate. */\nexport function detectMissedDuplicate(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n): AiDoctrineViolation[] {\n const kinds = inventoryKinds(inventory)\n const violations: AiDoctrineViolation[] = []\n const unresolved: string[] = []\n plan.screens.forEach((screen, index) => {\n if (screen.duplicateOf) {\n if (kinds.get(screen.duplicateOf) !== 'screen') {\n unresolved.push(`screens[${index}].duplicateOf`)\n }\n return\n }\n // A starter home is replaced, not duplicated (AGL-3594).\n const nearest = (inventory?.screens ?? []).find(\n (existing) =>\n !existing.template && !existing.replaceable && aiNamesMatch(existing.name, screen.title),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has \"${nearest.name}\". Start the new page from a duplicate of it, which keeps its bindings and SEO, and edit that.`,\n paths: [`screens[${index}].duplicateOf`],\n })\n }\n })\n plan.create.forEach((entry, index) => {\n if (entry.duplicateOf) {\n const kind = kinds.get(entry.duplicateOf)\n if (!kind || (kind !== entry.kind && !(entry.kind === 'template' && kind === 'screen'))) {\n unresolved.push(`create[${index}].duplicateOf`)\n }\n return\n }\n if (entry.kind !== 'template') return\n const nearest = (inventory?.templates ?? []).find((existing) =>\n aiNamesMatch(existing.name, entry.name),\n )\n if (nearest) {\n violations.push({\n rule: 15,\n code: 'plan-missed-duplicate',\n message: `The site already has the \"${nearest.name}\" template. Start from a duplicate of it and edit that.`,\n paths: [`create[${index}].duplicateOf`],\n })\n }\n })\n if (unresolved.length) {\n violations.push({\n rule: 15,\n code: 'plan-duplicate-unknown',\n message:\n 'The plan duplicates something the site does not have. Duplicate only what the site inventory lists.',\n paths: unresolved,\n })\n }\n return violations\n}\n\n/** What each exchange of a Free page job comes to at its worst, in credits. */\nexport interface AiFreePageWorstCase {\n /** The page plan. */\n plan: number\n /** The one layout a Free plan includes, built first on a site with none (AGL-3031). */\n layout: number\n /** The first section pass, which writes the cached prefix. */\n firstSection: number\n /** Each later section pass, which reads it. */\n laterSection: number\n /** A page's listing. */\n listing: number\n}\n\n/**\n * The Free taste's wall at its worst (AGL-3030, AGL-3070): each exchange of a\n * Free page job in credits, every answer at its ceiling, as\n * `jobs/ai-job-free-page.spec.ts` derives them from the page plan and the\n * layout generation measured live and the requests as they stand. The spec\n * fails when a figure it derives moves and this does not, so the section cap\n * below cannot drift from the proof.\n */\nexport const AI_FREE_PAGE_WORST_CASE_CREDITS: Readonly<AiFreePageWorstCase> = {\n plan: 83,\n layout: 64,\n firstSection: 44,\n laterSection: 20,\n listing: 3,\n}\n\n/**\n * The most sections a Free job fits in `FREE_AI_TASTE_CREDITS_PER_MONTH` at\n * its worst: the plan, the layouts it builds first, a listing for each page\n * and the first section's pass, then as many later passes as the rest pays\n * for; none when that is already past the wall. A component or a form is never\n * a Free creation, since rule 7 refuses both on a workspace that keeps no\n * reusable components, so the wall's proof measures neither.\n */\nexport function aiFreePageSectionsWithin(\n creations: { layouts: number; pages?: number },\n credits: Readonly<AiFreePageWorstCase> = AI_FREE_PAGE_WORST_CASE_CREDITS,\n): number {\n const before =\n credits.plan + creations.layouts * credits.layout + (creations.pages ?? 1) * credits.listing + credits.firstSection\n if (before > FREE_AI_TASTE_CREDITS_PER_MONTH) return 0\n return 1 + Math.floor((FREE_AI_TASTE_CREDITS_PER_MONTH - before) / credits.laterSection)\n}\n\n/**\n * The layouts a Free plan's job builds before its sections: the ones it\n * creates that the workspace may make, and on a site with no layout where it\n * may make one, the one rule 2 asks the plan to create.\n */\nfunction freePlanLayouts(plan: AiBuildPlan, inventory: AiSiteInventory | null, capabilities: AiPlanCapabilities): number {\n const refused = aiPlanUncreatable(plan, capabilities).filter((entry) => entry.kind === 'layout').length\n const creates = plan.create.filter((entry) => entry.kind === 'layout').length - refused\n const needs = !(inventory?.layouts.length ?? 0) && capabilities.create.layout.allowed ? 1 : 0\n return Math.max(creates, needs)\n}\n\n/** What the Free wall holds a plan to: its sections, the sections it fits, and the home's fewest. */\ninterface AiFreePlanWall {\n /** The sections the plan asks for, across its pages. */\n asked: number\n /** The sections the wall fits beside what the job builds first. */\n fits: number\n layouts: number\n pages: number\n /** A site start's page cap (AGL-3594); undefined on a page job. */\n sitePages: number | undefined\n /** Whether a site start plans more pages than its cap, which the wall refuses before it counts sections. */\n overPages: boolean\n /** The fewest sections a site start's home at / keeps on this wall (AGL-3660); 0 where it keeps no minimum. */\n homeMin: number\n}\n\n/** The Free wall a plan is held to, or null where the job is not on the Free taste. */\nfunction freePlanWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null,\n): AiFreePlanWall | null {\n if (!capabilities?.freeTaste) return null\n const asked = plan.screens.reduce((sum, screen) => sum + screen.sections.length, 0)\n const layouts = freePlanLayouts(plan, inventory, capabilities)\n const pages = Math.max(plan.screens.length, 1)\n // A Free site scaffold (AGL-3594) is held to its page cap first, and then to\n // what a SITE plan's worst case leaves for sections, with room for a retry.\n const sitePages = capabilities.freeSitePages\n const overPages = sitePages !== undefined && plan.screens.length > sitePages\n // A site start's saved form is a step of its own (AGL-3596), counted on the wall since AGL-3660.\n const forms =\n plan.create.filter((entry) => entry.kind === 'form').length -\n aiPlanUncreatable(plan, capabilities).filter((entry) => entry.kind === 'form').length\n const fits =\n sitePages !== undefined\n ? aiFreeSiteSectionsWithin({ layouts, pages, forms: Math.max(0, forms) }, FREE_AI_TASTE_CREDITS_PER_MONTH)\n : aiFreePageSectionsWithin({ layouts, pages })\n // A site start's home keeps its full five (AGL-3660): told only \"plan at\n // most 8\", the live yoga start of 2026-10-08 cut a home of 6 to 4 and kept\n // its other page, so the redo names where the sections come from.\n const homeMin =\n sitePages !== undefined && plan.screens.some(aiSitePlanIsHome)\n ? aiSiteHomeMinSections({ pages, across: fits })\n : 0\n return { asked, fits, layouts, pages, sitePages, overPages, homeMin }\n}\n\n/**\n * The most sections past the Free wall a plan is trimmed by rather than\n * re-asked (AGL-3737). The live candle-shop start of 2026-10-12 planned 9\n * sections against a wall of 8 on all three answers, each with a home of 7:\n * the model reaching for the budget the site redo names (\"plan 7 to 8\") and\n * landing one band past it, which no re-ask cured. Within two, the plan's\n * shape is right and only a band or two the brief needs least is extra, so\n * taking those from the end loses nothing the plan depends on. Further over,\n * the shape itself is off — a list planned as sections, a page the wall\n * cannot pay for — and cutting more would drop content the model meant, so\n * that plan is still re-asked.\n */\nexport const AI_FREE_WALL_SETTLE_MAX_OVER = 2\n\n/** A section through which a visitor reaches the owner: contact, a visit, a booking. */\nconst REACH_SECTION_NAME =\n /\\b(?:contact|get in touch|visit(?: us)?|find us|locations?|hours|book(?:ing)?|reserve|reservations?)\\b/i\n\n/**\n * Whether the Free wall's trim keeps a section of a page (AGL-3737): the\n * page's opening, any section that places something (a dataset it lists, a\n * form, a component — dropping it would leave a creation unplaced), one that\n * collects answers or says how to reach the owner, and a storefront's\n * listing parts — the bestsellers, the collections, the sign-up, and a Shop\n * page's product grid.\n */\nfunction freeWallKeeps(screen: AiBuildPlan['screens'][number], index: number): boolean {\n const section = screen.sections[index]\n if (index === 0 || section.uses.length > 0) return true\n if (FORM_SECTION_NAME.test(section.name) || REACH_SECTION_NAME.test(section.name)) return true\n if (\n aiStorefrontSays('featured', section.name) ||\n aiStorefrontSays('collections', section.name) ||\n aiStorefrontSays('signup', section.name)\n ) {\n return true\n }\n return aiLayoutIsShopPage(screen) && aiLayoutShopGridSection(screen.sections) === index\n}\n\n/**\n * A Free plan a section or two past the wall is trimmed to fit before the\n * rules read the plan (AGL-3737), rather than re-asked: which sections go has\n * one answer, so the re-ask only costs the member a stopped start. The live\n * candle-shop start of 2026-10-12 asked for a home of 7 and a second page of\n * 2 against a wall of 8, three answers running, and stopped needing input.\n *\n * One section goes at a time, the last of its page that `freeWallKeeps`\n * does not hold, from the page furthest past its share: the home at / past\n * its fewest (`aiSiteHomeMinSections`, five on a site start whose wall pays\n * for a full home), any other page past two; on a tie, the longer page, then\n * the home. No home goes under its fewest and no page under one section. The\n * shares are what a site start is told to plan (a home of five or six, the\n * other page two or three): the candle shop's 7 + 2 becomes 6 + 2, never\n * 7 + 1, and the recorded yoga answer's 6 + 4 becomes 5 + 3, the shape its\n * own redo chose.\n *\n * A plan more than `AI_FREE_WALL_SETTLE_MAX_OVER` past the wall, a site\n * start past its page cap, a plan with a list split into sections, and a\n * plan the trim cannot fit without a section it keeps are returned\n * unchanged, for the wall to re-ask.\n */\nexport function aiSettlePlanFreeWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null = null,\n): AiBuildPlan {\n const wall = freePlanWall(plan, inventory, capabilities)\n if (!wall || wall.overPages) return plan\n const over = wall.asked - wall.fits\n if (over <= 0 || over > AI_FREE_WALL_SETTLE_MAX_OVER) return plan\n // A list split into sections is joined by its re-ask, which frees the room;\n // a trim would cut one of its items and hide the split from the rule.\n if (detectPlanSplitLists(plan, inventory, capabilities).length) return plan\n const kept = plan.screens.map((screen) => screen.sections.map((section, index) => ({ section, index })))\n const home = plan.screens.findIndex(aiSitePlanIsHome)\n const floor = (screenIndex: number) => (screenIndex === home ? Math.max(wall.homeMin, 1) : 1)\n const target = (screenIndex: number) => (screenIndex === home ? Math.max(wall.homeMin, 1) : 2)\n // The last section of a page the trim may take, or -1.\n const last = (screenIndex: number) => {\n const entries = kept[screenIndex]\n if (entries.length <= floor(screenIndex)) return -1\n for (let at = entries.length - 1; at > 0; at -= 1) {\n if (!freeWallKeeps(plan.screens[screenIndex], entries[at].index)) return at\n }\n return -1\n }\n for (let left = over; left > 0; left -= 1) {\n let pick = -1\n for (let index = 0; index < kept.length; index += 1) {\n if (last(index) === -1) continue\n const room = kept[index].length - target(index)\n const best = pick === -1 ? null : kept[pick].length - target(pick)\n if (\n best === null ||\n room > best ||\n (room === best && (kept[index].length > kept[pick].length || (kept[index].length === kept[pick].length && index === home)))\n ) {\n pick = index\n }\n }\n if (pick === -1) return plan\n kept[pick].splice(last(pick), 1)\n }\n return {\n ...plan,\n screens: plan.screens.map((screen, index) =>\n kept[index].length === screen.sections.length\n ? screen\n : { ...screen, sections: kept[index].map((entry) => entry.section) },\n ),\n }\n}\n\n/**\n * The Free wall (plan): a plan asks for no more sections than the Free taste\n * pays for at its worst beside what the job builds first (AGL-3070). A live\n * Free plan asked for eight sections beside its layout, where the wall's worst\n * case pays for six, and fit only because every exchange ran under its\n * ceiling; one that does not runs out of credits with its page half built. The\n * cap only lowers what a plan may ask for, from the same figures the wall is\n * proven with, so no plan the proof admits is refused. It is no building rule,\n * so it names none.\n */\nexport function detectPlanOverFreeWall(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n capabilities: AiPlanCapabilities | null,\n): AiDoctrineViolation[] {\n const wall = freePlanWall(plan, inventory, capabilities)\n if (!wall) return []\n const { asked, layouts, pages, sitePages, fits, homeMin } = wall\n if (sitePages !== undefined && wall.overPages) {\n return [\n {\n rule: null,\n code: 'plan-over-free-wall',\n message: `This plan builds ${plan.screens.length} pages, and a Free workspace's site start builds at most ${sitePages}. Plan the home page and the one page the brief most needs.`,\n paths: ['screens'],\n },\n ]\n }\n if (asked <= fits) return []\n const job = pages > 1 ? `a Free plan of ${pages} pages` : 'a Free page'\n const beside = layouts ? ` that creates ${layouts > 1 ? `${layouts} layouts` : 'its layout'}` : ''\n const keepHome = homeMin\n ? ` Keep the home page at / at ${homeMin} or more sections, and take the rest from the other ${pages > 2 ? 'pages' : 'page'}.`\n : ''\n // A site start's redo keeps the plan full (AGL-3660): the wall's sections\n // are its budget to use, and a redo told only \"at most\" cuts far under it.\n const redo =\n sitePages !== undefined && fits >= 2\n ? `Plan ${fits - 1} to ${fits}: the ${fits} are the budget to use, not a ceiling to stay under. Draw a list's repeated items in one section, and take out only the sections the brief needs least.`\n : `Plan at most ${fits}: draw a list's repeated items in one section, and leave out a section the brief does not ask for.`\n return [\n {\n rule: null,\n code: 'plan-over-free-wall',\n message: `This plan asks for ${asked} sections, and ${job}${beside} fits ${fits} in the ${FREE_AI_TASTE_CREDITS_PER_MONTH} AI credits a Free workspace has a month. ${redo}${keepHome}`,\n paths: plan.screens.map((_, index) => `screens[${index}].sections`),\n },\n ]\n}\n\n/**\n * Rule 2 (plan): a layout the plan creates lists the regions it has, and\n * every one is a region this platform builds (AGL-3024).\n *\n * A layout has no properties, so its `fields` are its REGIONS — the promise\n * the build is later held to. A word the vocabulary does not hold is refused\n * HERE, on the plan, where the re-ask costs a sentence: a promise nothing can\n * look for would otherwise reach the build as a commitment no check can\n * settle, and a build that cannot settle its own plan stops for a person\n * instead of reporting itself done.\n */\nexport function detectPlanUnreadableRegions(plan: AiBuildPlan): AiDoctrineViolation[] {\n const unreadable: Array<{ word: string; path: string }> = []\n plan.create.forEach((entry, index) => {\n if (entry.kind !== 'layout') return\n entry.fields.forEach((field, fieldIndex) => {\n if (!aiLayoutRegionOf(field)) {\n unreadable.push({ word: field, path: `create[${index}].fields[${fieldIndex}]` })\n }\n })\n })\n if (!unreadable.length) return []\n const one = unreadable.length === 1\n return [\n {\n rule: 2,\n code: 'plan-layout-region-unknown',\n message: `A layout lists ${unreadable\n .map((entry) => `\"${entry.word}\"`)\n .join(', ')} among its regions, and a layout is built out of ${AI_LAYOUT_REGION_NAMES.join(\n ', ',\n )}. Name ${one ? 'it' : 'them'} with one of those, or leave ${one ? 'it' : 'them'} off the layout.`,\n paths: unreadable.map((entry) => entry.path),\n },\n ]\n}\n\n/**\n * Rule 16 (plan): a third-party player is planned where it can play\n * (AGL-3433). A screen of the plan or a component it creates carries at most\n * its kind's budget. A template renders for every record it serves and a\n * layout around every page, so neither carries one, and a form, an email or a\n * dataset has nowhere to. A link the plan gives is one its host plays.\n */\nexport function detectPlanEmbeds(plan: AiBuildPlan): AiDoctrineViolation[] {\n const nowhere: string[] = []\n const elsewhere: Array<{ kind: AiBuildPlanCreateKind; path: string }> = []\n const wrongHost: string[] = []\n const placed = new Map<string, { label: string; kind: 'page' | 'component'; paths: string[] }>()\n ;(plan.embeds ?? []).forEach((embed, index) => {\n const path = `embeds[${index}]`\n if (embed.url !== null && aiEmbedHostOf(embed.url) !== embed.host) wrongHost.push(`${path}.url`)\n let target: { key: string; label: string; kind: 'page' | 'component' } | null = null\n if (isAiPlanNewRef(embed.where)) {\n const creation = aiPlanCreateFor(plan, embed.where)\n if (creation && creation.kind !== 'component') {\n elsewhere.push({ kind: creation.kind, path: `${path}.where` })\n return\n }\n if (creation) target = { key: embed.where.trim().toLowerCase(), label: creation.name, kind: 'component' }\n } else {\n const screen = plan.screens.find((row) => aiPlanSlugKey(row.slug) === aiPlanSlugKey(embed.where))\n if (screen) target = { key: aiPlanSlugKey(screen.slug), label: screen.slug, kind: 'page' }\n }\n if (!target) {\n nowhere.push(`${path}.where`)\n return\n }\n const entry = placed.get(target.key) ?? { label: target.label, kind: target.kind, paths: [] }\n entry.paths.push(path)\n placed.set(target.key, entry)\n })\n const violations: AiDoctrineViolation[] = []\n if (nowhere.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-nowhere',\n message:\n 'A player is planned where the plan builds nothing. Name a screen of the plan by its slug, or new:<name> of a component it creates.',\n paths: nowhere,\n })\n }\n if (elsewhere.length) {\n const nouns = [...new Set(elsewhere.map((entry) => AI_BUILD_PLAN_CREATION_NOUNS[entry.kind].noun))]\n violations.push({\n rule: 16,\n code: 'plan-embed-refused',\n message: `Only a page or a component carries a third-party player, and this plan puts one on a ${nouns.join(\n ' and a ',\n )}. A template or a layout would load the player's code on every page it serves. Place it on a page or a component, or leave it off.`,\n paths: elsewhere.map((entry) => entry.path),\n })\n }\n for (const entry of placed.values()) {\n const limit = AI_OUTPUT_BUDGETS[entry.kind].embeds\n if (entry.paths.length <= limit) continue\n violations.push({\n rule: 16,\n code: 'plan-embed-over-budget',\n message: `${entry.label} is planned ${entry.paths.length} players, and a ${entry.kind} carries at most ${limit}. Keep the one the brief asks for most.`,\n paths: entry.paths,\n })\n }\n if (wrongHost.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-link-host',\n message: `A planned player's link is not a video link of its host, ${Object.values(\n AI_BUILD_PLAN_EMBED_HOST_NAMES,\n ).join(' or ')}. Give the brief's own link for that host, or null.`,\n paths: wrongHost,\n })\n }\n return violations\n}\n\n/** Text as two copies of one phrase compare: lowercase, no quotes, one space. */\nfunction phraseKey(text: string): string {\n return text\n .toLowerCase()\n .replace(/[“”\"‘’'`]/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\n/**\n * Rule 16 (plan, against the brief): a player is planned only where the brief\n * asks for one (AGL-3433). The plan quotes the brief's words, and those words\n * are found in the brief and ask for a video; a link it gives is one the brief\n * gives. The plan step holds this, being the one door that reads the brief\n * beside the plan.\n */\nexport function aiPlanEmbedBriefViolations(plan: AiBuildPlan, brief: string): AiDoctrineViolation[] {\n const said = phraseKey(brief)\n const given = new Set(\n (brief.match(/https:\\/\\/\\S+/g) ?? [])\n .map((link) => aiEmbedVideoKey(link.replace(/[).,;!?]+$/, '')))\n .filter((key): key is string => key !== null),\n )\n const unasked: string[] = []\n const ungiven: string[] = []\n ;(plan.embeds ?? []).forEach((embed, index) => {\n const asked = phraseKey(embed.asked)\n if (!asked || !said.includes(asked) || !AI_PLAN_ASKS_FOR_VIDEO.test(asked)) {\n unasked.push(`embeds[${index}].asked`)\n }\n if (embed.url !== null) {\n const key = aiEmbedVideoKey(embed.url)\n if (!key || !given.has(key)) ungiven.push(`embeds[${index}].url`)\n }\n })\n const violations: AiDoctrineViolation[] = []\n if (unasked.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-not-asked',\n message:\n 'A player is planned that the brief does not ask for: its words are not words of the brief asking for a video. Take it off the plan; a film from the media library plays in a Video.',\n paths: unasked,\n })\n }\n if (ungiven.length) {\n violations.push({\n rule: 16,\n code: 'plan-embed-link-not-given',\n message:\n \"A planned player's link is not one the brief gives. Give the brief's own link, or null for the site owner to paste.\",\n paths: ungiven,\n })\n }\n return violations\n}\n\n/**\n * Every plan rule, against the site inventory the plan was made from and,\n * where the job read them, what it may create there (AGL-3030). `null`\n * capabilities restrict nothing: the doctrine applies whole.\n */\nexport function validateAiBuildPlan(\n plan: AiBuildPlan,\n inventory: AiSiteInventory | null,\n framing: AiCopyFraming = null,\n capabilities: AiPlanCapabilities | null = null,\n): AiDoctrineViolation[] {\n return [\n ...detectPlanRepeats(plan, inventory, capabilities),\n ...detectPlanSplitLists(plan, inventory, capabilities),\n ...detectPlanOverFreeWall(plan, inventory, capabilities),\n ...detectPlanLayoutRegions(plan, inventory, capabilities),\n ...detectPlanUnreadableRegions(plan),\n ...detectPlanInlineForms(plan, inventory, capabilities),\n ...detectUntemplatedSimilarPages(plan, inventory),\n ...detectPlanLiteralColors(plan),\n ...detectPlanEmbeds(plan),\n ...detectCreateBeforeReuse(plan, inventory),\n ...detectPlanUncreatable(plan, capabilities),\n ...detectPlanUndeclaredCreations(plan, inventory, capabilities),\n ...detectPlanTypedData(plan, inventory, capabilities),\n ...detectMissingNavAndSeo(plan, inventory),\n ...detectOffVoiceCopy(aiPlanCopy(plan), framing),\n ...detectMissedDuplicate(plan, inventory),\n ]\n}\n"],"names":["sanitizeAuthorHtml","isFormInputNode","formatBytes","measureNodeMap","nodeMapBytes","MEDIA_CDN_VARIANT_WIDTHS","parseMediaRef","ESTIMATED_PAGE_TRANSFER_BYTES","createIdUrlSafe","FREE_AI_TASTE_CREDITS_PER_MONTH","REUSABLE_INSTANCE_COMPONENT_ID","REUSABLE_INSTANCE_PROP_VALUES_KEY","parseBreakpointSpan","renderEmailHtml","AI_BUILD_PLAN_CREATION_NOUNS","AI_BUILD_PLAN_EMBED_HOST_NAMES","AI_BUILD_PLAN_LIMITS","AI_PLAN_ASKS_FOR_VIDEO","aiEmbedHostOf","aiEmbedVideoKey","AI_PLAN_DATASET_ITEM_OP","aiPlanCreateFor","aiPlanFormDatasetNames","aiPlanItemFor","aiPlanSlugKey","aiPlanUndeclaredRefs","isAiPlanNewRef","aiCreationNoun","aiPlanCanPlaceForm","aiPlanUncreatable","aiPlanUncreatableKind","aiFreeSiteSectionsWithin","aiSiteHomeMinSections","aiSitePlanIsHome","aiSiteSectionShowsWork","aiLayoutIsShopPage","aiLayoutShopGridSection","aiStorefrontSays","AI_INSTANCE_REF_PROP","validateAiNodeTree","AI_PAGE_SCROLL_TO_PROP","aiPageLinkTarget","aiStoredScrollTargets","AI_EMAIL_CLIP_BYTES","AI_OUTPUT_BUDGETS","AI_OUTPUT_SURFACE","AI_TEXT_LIMITS","isHeadlineVariant","AI_PALETTE","AI_SX_TOKENS","AI_DOCTRINE_RULES","AI_DOCTRINE_RULE_NUMBERS","Object","keys","map","Number","aiDoctrineViolationText","violation","rule","message","isRecord","value","Array","isArray","walkTree","tree","visits","seen","Set","stack","id","rootId","depth","ancestors","length","node","pop","nodes","has","add","push","children","index","displayName","componentId","elementOf","props","hasAncestor","visit","test","some","unique","values","listNames","ids","names","join","slice","AI_REPEAT_MIN_NODES","AI_REPEAT_MIN_COUNT","AI_REPEAT_ACROSS_PAGES_MIN_NODES","AI_TYPED_LIST_MIN_ITEMS","indexShapes","shapeOf","Map","sizeOf","schema","propsSchema","properties","sort","key","declared","structural","Boolean","enum","type","String","filter","child","set","get","reduce","sum","repeatedByData","repeatedShapes","minNodes","minCount","groupOf","skip","byShape","shape","JSON","stringify","repeated","entries","repeatedIds","flatMap","ancestorsOf","every","ancestor","REPEAT_FRAMES","aiRepeatFrameOrSection","memo","childrenOf","holdsOutline","level","aiHeadingLevel","itemFrame","kinds","size","parentOf","exempt","known","undefined","parent","result","detectRepeatedSubtrees","otherPages","context","reusableComponents","card","first","opens","pictureCard","parentId","find","at","violations","reverse","repeatsCompiled","name","code","nodeIds","elsewhere","other","otherIndex","shared","sharedIds","outermost","aiRepeatedItemCount","most","count","aiBindsRepeatedItems","REGION_ELEMENTS","REGION_WORDS","header","footer","nav","AI_LAYOUT_REGIONS","elements","componentIds","sidebar","main","AI_LAYOUT_REGION_NAMES","LAYOUT_REGION_ALIASES","masthead","navigation","menu","aside","drawer","rail","slot","content","aiLayoutRegionOf","word","read","cleaned","split","replace","toLowerCase","trim","includes","aiTreeLayoutRegions","found","element","region","where","detectLayoutRegions","outputKind","regions","entry","detectInlineForms","loose","unbound","shadowed","bound","COLOR_SX_KEYS","COLOR_IN_VALUE_SX_KEYS","SPACING_SX_KEYS","TYPE_SX_KEYS","COLOR_KEYWORDS","LITERAL_COLOR","LENGTH_WITH_UNIT","paletteTokens","palette","hasLiteralColor","parts","part","sxValues","detectLiteralStyles","colors","lengths","raw","sx","normalizeHex","hex","detectOffBrandEmail","brand","allowed","fonts","font","offBrand","candidates","family","candidate","EMAIL_COLOR_PROPS","emailRgbOf","text","exec","r","g","b","alpha","full","digit","parseInt","fn","isFinite","over","channel","Math","round","emailColorDistance","a","mean","dr","dg","db","sqrt","aiSettleOffBrandEmailColors","input","byPath","path","targets","rgb","settle","named","best","target","settled","emailSettleKeepsContrast","EMAIL_SETTLED_MIN_CONTRAST","emailLuminance","c","emailContrast","light","dark","x","y","written","propOf","groundOf","WHITE","color","ground","touched","background","detectTypedData","sectionOf","byComponent","childId","ref","detectUnfilledInstances","componentProps","unfilled","filled","one","mediaValues","out","roles","propRoles","refId","detectImageSources","hotlinked","missingAlt","alt","decorative","match","detectDocumentStructure","headings","mains","slots","rootElement","slotElement","chosenAway","h1s","heading","page","skipped","previous","WIDTH_SX_KEYS","detectAdHocWidths","fixed","GRID","GRID_CONTAINER_PROPS","GRID_ROW_PROPS","GRID_ROW_DIRECTIONS","GRID_COLUMN_DIRECTION","GRID_ITEM_WRAPPERS","GRID_GAP_SX_KEYS","GRID_DEFAULT_COLUMNS","GRID_QUOTED_MAX_CHARS","writtenValueText","cut","gridColumns","columns","isInteger","gridItemSpan","span","phoneFull","steps","base","xs","breakpoint","gridItemSizeFor","items","across","min","max","md","floor","sm","detectUnresponsiveGrids","shapes","isGrid","isContainer","isSized","writtenProp","unreadContainer","wrapsItems","writtenColumn","direction","setsOutRow","refused","rows","stacks","outside","texts","unsized","suggested","gapped","grandparentId","sized","wrappedItem","holdsSized","isItem","setsContainerProps","within","column","offending","item","gap","spacing","GRID_SIZE_BREAKPOINTS","writtenGridSizeText","pairs","indexOf","aiSettleGridItems","options","mintId","copied","edit","setSize","own","container","settledItems","host","wrapperId","$id","pluginId","aiSettleWrittenGridItems","fromEntries","LINK_COLOR_FAMILIES","LINK_COMPONENTS","isAiLinkElement","PAPER_COMPONENTS","FAMILY_TOKEN","familyOf","bandOf","token","linkWordsFamily","styledAsButton","detectInvisibleLinks","hidden","band","HOME_WORDS","labelWords","label","GET_IN_TOUCH_WORDS","aiAsksToGetInTouch","unrelatedScreenLinks","home","homeScreenIds","forms","formScreenIds","homeLabels","sent","screenId","linksHome","inNavigation","aiSettleUnrelatedScreenLinks","ownScreenIds","formScreen","parents","next","detectUnrelatedScreenLinks","isFilled","detectLinksWithoutDestination","stored","sections","pageSections","scrollTargetIds","dead","fragments","unknown","kind","via","inForm","wordsOf","listed","toSection","instead","PUBLISH_KEYS","detectPublishIntent","answer","paths","forEach","inner","here","BRACKETED_FACT","aiBracketedFacts","facts","matchAll","fact","FILLER_COPY","JUDGMENT","detectOffVoiceCopy","samples","framing","filler","sample","judged","list","aiTreeCopy","LINE_PROPS","muiTypography","muiListItemText","muiCardHeader","muiAccordionSummary","emailText","LABEL_VARIANTS","DANGLING_WORDS","OPENING_WORDS","CLOSED_LINE","aiDanglingWord","line","lower","before","lineTail","words","detectDanglingWords","LABEL_PROPS","muiButton","muiScreenLink","emailButton","CUT_REPAIR","lineHead","detectCutLines","repairs","idOf","repair","nodeId","limit","shown","PURE_CONTAINERS","EMBED_COMPONENTS","DUPLICATE_SX_MIN_KEYS","DUPLICATE_SX_MIN_NODES","embedVerdict","planned","url","embed","OWNS_ITS_EMPTY_STATE","detectHeavyDocument","wrappers","empty","eager","video","embeds","embedLinks","sxSeen","images","ownProps","boundForm","acceptsChildren","verdict","plannedEmbeds","duplicatedSx","flat","ITEM_NOUNS","muiListItem","muiCard","FRAME_COMPONENTS","WORD_PROPS","muiList","muiInlineText","showsOwn","detectEmptyItems","noun","nouns","EMAIL_COLUMN_PX","MEDIA_IMAGE_PROPS","image","emailImage","collectionEntryAuthor","contentAuthorProfile","servedVariantWidth","slotWidth","widest","width","pixels","parsed","parseFloat","imageRequests","requests","startsWith","assets","mediaId","sizeBytes","bytes","variant","ratio","scoreAiOutput","families","emailHtmlBytes","html","sanitize","TextEncoder","encode","imageBytes","imagesUnmeasured","fontFamilies","METRIC_LABELS","figure","metric","toLocaleString","heaviest","largest","BUDGET_METRICS","detectOverBudget","score","budget","offenders","estimateAiOutputLoad","pageBytes","documentBytes","totalBytes","detectDisagreeingNodes","reached","missing","queue","shift","orphans","detail","REPEAT_KEY","aiSettleDisagreeingNodes","source","changed","setListed","holds","reach","inOrphan","roots","unplaced","kept","HEADING_CUT_MIN_WORDS","HEADING_CUT_MIN_SHARE","SENTENCE_END","CLAUSE_END","headingWithin","keeps","head","pattern","keepMark","aiSettleCutHeadings","textLimits","Infinity","headline","trimmed","aiSettleMechanicalRules","unsetProp","setProp","unsetSx","email","framed","fragment","firstH1","findIndex","start","keepsH1","aiSettleWrittenMechanicalRules","readable","validateAiDoctrineTree","publish","disagreeing","ok","load","validated","error","minted","sourceIds","writtenOf","writtenNode","storedOf","NAME_STOPWORDS","nameTokens","endsWith","aiNamesMatch","left","right","small","large","inventoryKinds","inventory","row","components","layouts","templates","datasets","collections","screens","refKind","plan","sectionPaths","screen","screenIndex","section","sectionIndex","LAYOUT_REGION_NAME","FORM_SECTION_NAME","detectPlanRepeats","capabilities","placesComponent","uses","byName","common","refs","AI_SPLIT_LIST_MIN_SECTIONS","SECTION_LABEL","pluralOf","sectionItemKind","detectPlanSplitLists","run","close","component","placementsOf","creationKey","aiSettlePlanRefs","create","resolve","matches","layout","template","AI_DATASET_SAID_NAME","aiSettlePlanDatasets","dataset","cap","datasetsMax","forForms","said","fields","field","total","record","ranked","dropped","isDropped","writesTo","withoutWritesTo","creation","rest","aiSettlePlanFormDatasets","held","creatable","op","listsOne","aiSettlePlanLayouts","created","unlaid","only","mayCreateLayout","taken","why","duplicateOf","aiSettlePlanLayoutRegionSections","removable","aiSettlePlanGalleries","least","galleryMinItems","thin","planFormChoices","form","formChoiceKey","bestPlanForm","choices","placed","choice","AI_PLAN_SETTLED_FORM","aiSettlePlanForms","current","use","planFormChoicesText","detectPlanLayoutRegions","noLayoutToName","detectPlanInlineForms","AI_SIMILAR_PAGES_MIN","detectUntemplatedSimilarPages","groups","signature","indexes","detectPlanLiteralColors","REUSE_BEFORE_CREATE_KINDS","detectCreateBeforeReuse","reuse","unexplained","existing","detectPlanUncreatable","undeclaredPlacementKind","placesForm","detectPlanUndeclaredCreations","title","otherwise","reason","detectPlanTypedData","data","typed","bindsData","SLUG","AI_SEO_TITLE_MAX","AI_SEO_DESCRIPTION_MAX","slugKey","slug","detectMissingNavAndSeo","replaceable","clashes","badSlugs","collisions","seo","seoTitle","seoDescription","aiPlanCopy","detectMissedDuplicate","unresolved","nearest","AI_FREE_PAGE_WORST_CASE_CREDITS","firstSection","laterSection","listing","aiFreePageSectionsWithin","creations","credits","pages","freePlanLayouts","creates","needs","freePlanWall","freeTaste","asked","sitePages","freeSitePages","overPages","fits","homeMin","AI_FREE_WALL_SETTLE_MAX_OVER","REACH_SECTION_NAME","freeWallKeeps","aiSettlePlanFreeWall","wall","last","pick","room","splice","detectPlanOverFreeWall","job","beside","keepHome","redo","_","detectPlanUnreadableRegions","unreadable","fieldIndex","detectPlanEmbeds","nowhere","wrongHost","phraseKey","aiPlanEmbedBriefViolations","brief","given","link","unasked","ungiven","validateAiBuildPlan"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,kBAAkB,QAAQ,qCAAoC;AACvE,SAASC,eAAe,QAAQ,+BAA8B;AAC9D,SACEC,WAAW,EACXC,cAAc,EACdC,YAAY,QACP,0CAAyC;AAChD,SACEC,wBAAwB,EACxBC,aAAa,QACR,mCAAkC;AACzC,SAASC,6BAA6B,QAAQ,2CAA0C;AACxF,SAASC,eAAe,QAAQ,wCAAuC;AACvE,SAASC,+BAA+B,QAAQ,0BAAsB;AACtE,SACEC,8BAA8B,EAC9BC,iCAAiC,QAC5B,iDAAgD;AACvD,SAASC,mBAAmB,QAAQ,2CAA0C;AAC9E,SAASC,eAAe,QAAQ,wCAAuC;AACvE,SACEC,4BAA4B,EAC5BC,8BAA8B,EAC9BC,oBAAoB,EACpBC,sBAAsB,EACtBC,aAAa,EACbC,eAAe,EACfC,uBAAuB,EACvBC,eAAe,EACfC,sBAAsB,EACtBC,aAAa,EACbC,aAAa,EACbC,oBAAoB,EACpBC,cAAc,QAOT,4BAAwB;AAC/B,SACEC,cAAc,EACdC,kBAAkB,EAClBC,iBAAiB,EACjBC,qBAAqB,QAEhB,mCAA+B;AAEtC,SACEC,wBAAwB,EACxBC,qBAAqB,EACrBC,gBAAgB,EAChBC,sBAAsB,QACjB,0BAAsB;AAC7B,SAASC,kBAAkB,EAAEC,uBAAuB,QAAQ,2CAAuC;AACnG,SAASC,gBAAgB,QAAQ,6CAAyC;AAC1E,SACEC,oBAAoB,EACpBC,kBAAkB,QAGb,oBAAgB;AACvB,SAASC,sBAAsB,EAAEC,gBAAgB,EAAEC,qBAAqB,QAAQ,qBAAiB;AACjG,SACEC,mBAAmB,EACnBC,iBAAiB,EACjBC,iBAAiB,EACjBC,cAAc,EACdC,iBAAiB,QAIZ,kBAAc;AACrB,SAASC,UAAU,EAAEC,YAAY,QAAQ,4BAAwB;AA8CjE,wEAAwE,GACxE,OAAO,MAAMC,oBAAoE;IAC/E,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;AACN,EAAC;AAED,OAAO,MAAMC,2BAA2BC,OAAOC,IAAI,CAACH,mBAAmBI,GAAG,CACxEC,QACyB;AAuB3B,6EAA6E,GAC7E,OAAO,SAASC,wBAAwBC,SAA8B;IACpE,OAAOA,UAAUC,IAAI,KAAK,OACtBD,UAAUE,OAAO,GACjB,CAAC,KAAK,EAAEF,UAAUC,IAAI,CAAC,EAAE,EAAER,iBAAiB,CAACO,UAAUC,IAAI,CAAC,CAAC,GAAG,EAAED,UAAUE,OAAO,EAAE;AAC3F;AA+GA,SAASC,SAASC,KAAc;IAC9B,OAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,OAAO,CAACF;AACvE;AAEA;;;CAGC,GACD,OAAO,SAASG,SAASC,IAAoB;IAC3C,MAAMC,SAAkB,EAAE;IAC1B,MAAMC,OAAO,IAAIC;IACjB,MAAMC,QAAmE;QACvE;YAAEC,IAAIL,KAAKM,MAAM;YAAEC,OAAO;YAAGC,WAAW,EAAE;QAAC;KAC5C;IACD,MAAOJ,MAAMK,MAAM,CAAE;YAMFC;QALjB,MAAM,EAAEL,EAAE,EAAEE,KAAK,EAAEC,SAAS,EAAE,GAAGJ,MAAMO,GAAG;QAC1C,MAAMD,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,IAAI,CAACK,QAAQR,KAAKW,GAAG,CAACR,KAAK;QAC3BH,KAAKY,GAAG,CAACT;QACTJ,OAAOc,IAAI,CAAC;YAAEV;YAAIK;YAAMH;YAAOC;QAAU;QACzC,MAAMQ,YAAWN,cAAAA,KAAKE,KAAK,YAAVF,cAAc,EAAE;QACjC,IAAK,IAAIO,QAAQD,SAASP,MAAM,GAAG,GAAGQ,SAAS,GAAGA,SAAS,EAAG;YAC5Db,MAAMW,IAAI,CAAC;gBAAEV,IAAIW,QAAQ,CAACC,MAAM;gBAAEV,OAAOA,QAAQ;gBAAGC,WAAW;uBAAIA;oBAAWH;iBAAG;YAAC;QACpF;IACF;IACA,OAAOJ;AACT;AAEA,SAASiB,YAAYC,WAAmB;;QAC/BpC;IAAP,gBAAOA,0BAAAA,UAAU,CAACoC,YAAY,qBAAvBpC,wBAAyBmC,WAAW,mBAAIC;AACjD;AAEA,mDAAmD,GACnD,SAASC,UAAUV,IAAgC;;QACnCA,aAA8BA;IAA5C,MAAMd,gBAAQc,yBAAAA,cAAAA,KAAMW,KAAK,qBAAXX,WAAa,CAAC,YAAY,mBAAIA,yBAAAA,eAAAA,KAAMW,KAAK,qBAAXX,YAAa,CAAC,UAAU;IACpE,OAAO,OAAOd,UAAU,WAAWA,QAAQ;AAC7C;AAEA,SAAS0B,YACPtB,IAAoB,EACpBuB,KAAY,EACZC,IAAuC;IAEvC,OAAOD,MAAMf,SAAS,CAACiB,IAAI,CAAC,CAACpB;QAC3B,MAAMK,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,OAAOK,OAAOc,KAAKd,QAAQ;IAC7B;AACF;AAEA,SAASgB,OAAUC,MAAW;IAC5B,OAAO;WAAI,IAAIxB,IAAIwB;KAAQ;AAC7B;AAEA,SAASC,UAAUC,GAAa,EAAE7B,IAAoB;IACpD,MAAM8B,QAAQJ,OAAOG,IAAIxC,GAAG,CAAC,CAACgB;;YAAmBL;eAAZkB,qBAAYlB,iBAAAA,KAAKY,KAAK,CAACP,GAAG,qBAAdL,eAAgBmB,WAAW,mBAAI;;IAChF,OAAOW,MAAMrB,MAAM,IAAI,IACnBqB,MAAMC,IAAI,CAAC,MACX,GAAGD,MAAME,KAAK,CAAC,GAAG,CAAC,GAAGD,IAAI,CAAC,MAAM,KAAK,EAAED,KAAK,CAACA,MAAMrB,MAAM,GAAG,EAAE,EAAE;AACvE;AAEA,uEAAuE;AAEvE,6EAA6E,GAC7E,OAAO,MAAMwB,sBAAsB,EAAC;AACpC,gEAAgE,GAChE,OAAO,MAAMC,sBAAsB,EAAC;AACpC,yEAAyE,GACzE,OAAO,MAAMC,mCAAmC,EAAC;AACjD,iDAAiD,GACjD,OAAO,MAAMC,0BAA0B,EAAC;AAQxC;;;;;CAKC,GACD,SAASC,YAAYrC,IAAoB;IACvC,MAAMsC,UAAU,IAAIC;IACpB,MAAMC,SAAS,IAAID;IACnB,MAAMtC,SAASF,SAASC;IACxB,IAAK,IAAIiB,QAAQhB,OAAOQ,MAAM,GAAG,GAAGQ,SAAS,GAAGA,SAAS,EAAG;kBAGhCP,aAYRA;YAbH3B;QADf,MAAM,EAAEsB,EAAE,EAAEK,IAAI,EAAE,GAAGT,MAAM,CAACgB,MAAM;QAClC,MAAMwB,kBAAS1D,+BAAAA,UAAU,CAAC2B,KAAKS,WAAW,CAAC,qBAA5BpC,6BAA8B2D,WAAW,CAACC,UAAU,mBAAI,CAAC;QACxE,MAAMtB,QAAQlC,OAAOC,IAAI,EAACsB,cAAAA,KAAKW,KAAK,YAAVX,cAAc,CAAC,GACtCkC,IAAI,GACJvD,GAAG,CAAC,CAACwD;gBAOiCnC;YANrC,MAAMoC,WAAWL,MAAM,CAACI,IAAI;YAC5B,MAAME,aACJC,QAAQF,4BAAAA,SAAUG,IAAI,KACtBH,CAAAA,4BAAAA,SAAUI,IAAI,MAAK,aACnBJ,CAAAA,4BAAAA,SAAUI,IAAI,MAAK,YACnBJ,CAAAA,4BAAAA,SAAUI,IAAI,MAAK;YACrB,OAAOH,aAAa,GAAGF,IAAI,CAAC,EAAEM,QAAOzC,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAACmC,IAAI,GAAG,GAAGA;QAC9D,GACCd,IAAI,CAAC;QACR,MAAMf,WAAW,EAACN,cAAAA,KAAKE,KAAK,YAAVF,cAAc,EAAE,EAAE0C,MAAM,CAAC,CAACC,QAAUf,QAAQzB,GAAG,CAACwC;QAClEf,QAAQgB,GAAG,CACTjD,IACA,GAAGK,KAAKS,WAAW,CAAC,CAAC,EAAEE,MAAM,EAAE,EAAEL,SAAS3B,GAAG,CAAC,CAACgE,QAAUf,QAAQiB,GAAG,CAACF,QAAQtB,IAAI,CAAC,KAAK,CAAC,CAAC;QAE3FS,OAAOc,GAAG,CAACjD,IAAI,IAAIW,SAASwC,MAAM,CAAC,CAACC,KAAKJ;gBAAiBb;mBAAPiB,QAAOjB,cAAAA,OAAOe,GAAG,CAACF,kBAAXb,cAAqB;WAAI;IACrF;IACA,OAAO;QAAEvC;QAAQqC;QAASE;IAAO;AACnC;AAEA,yGAAyG,GACzG,SAASkB,eAAe1D,IAAoB,EAAEuB,KAAY;IACxD,OAAOD,YAAYtB,MAAMuB,OAAO,CAACb,OAASA,KAAKS,WAAW,KAAK;AACjE;AAEA;;;;;CAKC,GACD,SAASwC,eACP3D,IAAoB,EACpBiB,KAAiB,EACjB2C,QAAgB,EAChBC,QAAgB,EAChBC,UAAoC,IAAM9D,KAAKM,MAAM,EACrDyD,OAAkC,IAAM,KAAK;IAE7C,MAAMC,UAAU,IAAIzB;IACpB,KAAK,MAAMhB,SAASN,MAAMhB,MAAM,CAAE;YAE3BgB,mBAGmB+C;QAJxB,IAAIzC,MAAMlB,EAAE,KAAKL,KAAKM,MAAM,EAAE;QAC9B,IAAI,EAACW,oBAAAA,MAAMuB,MAAM,CAACe,GAAG,CAAChC,MAAMlB,EAAE,aAAzBY,oBAA8B,KAAK2C,UAAU;QAClD,IAAIF,eAAe1D,MAAMuB,UAAUwC,KAAKxC,QAAQ;QAChD,MAAM0C,QAAQC,KAAKC,SAAS,CAAC;YAACL,QAAQvC;YAAQN,MAAMqB,OAAO,CAACiB,GAAG,CAAChC,MAAMlB,EAAE;SAAE;QAC1E2D,QAAQV,GAAG,CAACW,OAAO;gBAAKD,eAAAA,QAAQT,GAAG,CAACU,kBAAZD,eAAsB,EAAE;YAAGzC,MAAMlB,EAAE;SAAC;IAC9D;IACA,MAAM+D,WAAW;WAAIJ,QAAQK,OAAO;KAAG,CAACjB,MAAM,CAAC,CAAC,GAAGvB,IAAI,GAAKA,IAAIpB,MAAM,IAAIoD;IAC1E,MAAMS,cAAc,IAAInE,IAAIiE,SAASG,OAAO,CAAC,CAAC,GAAG1C,IAAI,GAAKA;IAC1D,MAAM2C,cAAc,IAAIjC,IAAItB,MAAMhB,MAAM,CAACZ,GAAG,CAAC,CAACkC,QAAU;YAACA,MAAMlB,EAAE;YAAEkB,MAAMf,SAAS;SAAC;IACnF,OAAO4D,SACJhB,MAAM,CACL,CAAC,GAAGvB,IAAI,GACN,CAACA,IAAI4C,KAAK,CAAC,CAACpE;gBAAQmE;mBAAD,EAACA,mBAAAA,YAAYjB,GAAG,CAAClD,eAAhBmE,mBAAuB,EAAE,EAAE/C,IAAI,CAAC,CAACiD,WAAaJ,YAAYzD,GAAG,CAAC6D;YAErFrF,GAAG,CAAC,CAAC,CAAC4E,OAAOpC,IAAI,GAAM,CAAA;YAAEoC;YAAOpC;QAAI,CAAA;AACzC;AAEA,2EAA2E,GAC3E,MAAM8C,gBAAgB,IAAIxE,IAAI;IAAC;IAAU;IAAY;IAAgB;IAAW;IAAW;CAAU;AAErG;;;;;;;;;;;;;;;CAeC,GACD,SAASyE,uBAAuB5E,IAAoB;;IAClD,MAAM6E,OAAO,IAAItC;IACjB,MAAMuC,aAAa,CAACzE;;YAAgBL;eAAD,UAACA,iBAAAA,KAAKY,KAAK,CAACP,GAAG,qBAAdL,eAAgBY,KAAK,mBAAI,EAAE,EAAEwC,MAAM,CAAC,CAACC,QAAUrD,KAAKY,KAAK,CAACyC,MAAM;;IACpG,MAAM0B,eAAe,CAAC1E;QACpB,MAAMK,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,MAAM2E,QAAQtE,OAAOuE,eAAevE,QAAQ;QAC5C,OAAO,AAACsE,UAAU,QAAQA,SAAS,KAAMF,WAAWzE,IAAIoB,IAAI,CAACsD;IAC/D;IACA,MAAMG,YAAY,CAAC7E;YAGqBK;QAFtC,MAAMA,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,IAAI,CAACK,MAAM,OAAO;QAClB,IAAIA,KAAKS,WAAW,KAAK,aAAaT,EAAAA,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,YAAY,MAAK,MAAM,OAAO;QACjF,IAAIA,KAAKS,WAAW,KAAK,WAAW,OAAO;QAC3C,MAAMH,WAAW8D,WAAWzE;QAC5B,6EAA6E;QAC7E,MAAM8E,QAAQ,IAAIhF,IAAIa,SAAS3B,GAAG,CAAC,CAACgE,QAAUrD,KAAKY,KAAK,CAACyC,MAAM,CAAClC,WAAW;QAC3E,OACET,KAAKS,WAAW,KAAK,cACrBH,SAASP,MAAM,IAAI,KACnB0E,MAAMC,IAAI,KAAK,KACfpE,SAASyD,KAAK,CAAC,CAACpB;gBAAWrD;mBAAD,EAACA,0BAAAA,KAAKY,KAAK,CAACyC,MAAM,CAACzC,KAAK,YAAvBZ,0BAA2B,EAAE,EAAES,MAAM,GAAG;;IAEvE;IACA,MAAM4E,WAAW,IAAI9C;IACrB,KAAK,MAAM,CAAClC,IAAIK,KAAK,IAAIvB,OAAOkF,OAAO,CAACrE,KAAKY,KAAK,EAAG,KAAK,MAAMyC,iBAAS3C,wBAAAA,KAAME,KAAK,mBAAI,EAAE,CAAEyE,SAAS/B,GAAG,CAACD,OAAOhD;IAChH,MAAMiF,SAAS,CAACjF;QACd,MAAMkF,QAAQV,KAAKtB,GAAG,CAAClD;QACvB,IAAIkF,UAAUC,WAAW,OAAOD;QAChC,MAAM7E,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,MAAMW,WAAW8D,WAAWzE;QAC5B,MAAMoF,SAASJ,SAAS9B,GAAG,CAAClD;QAC5B,MAAMqF,SAEJ,AADA,8DAA8D;QAC7DX,aAAa1E,OAAO,CAAEoF,CAAAA,WAAWD,aAAaN,UAAUO,OAAM,KAC/DP,UAAU7E,OACT,CAAC,CAACK,QAAQiE,cAAc9D,GAAG,CAACH,KAAKS,WAAW,KAAKH,SAASP,MAAM,GAAG,KAAKO,SAASyD,KAAK,CAACa;QAC1FT,KAAKvB,GAAG,CAACjD,IAAIqF;QACb,OAAOA;IACT;IACA,OAAO,CAACnE,QAAU+D,OAAO/D,MAAMlB,EAAE;AACnC;AAEA;;;;;;CAMC,GACD,OAAO,SAASsF,uBACd3F,IAAoB,EACpB4F,aAAwC,EAAE,EAC1CC,UAAiF,CAAC,CAAC;IAEnF,IAAIA,QAAQC,kBAAkB,KAAK,OAAO,OAAO,EAAE;IACnD,MAAM7E,QAAQoB,YAAYrC;IAC1B;;;;;GAKC,GACD,MAAM+F,OAAO,CAAC1F;YAEEK,aACkCV;QAFhD,MAAMU,OAAOL,OAAOmF,YAAYA,YAAYxF,KAAKY,KAAK,CAACP,GAAG;QAC1D,MAAM2F,QAAQtF,yBAAAA,cAAAA,KAAME,KAAK,qBAAXF,WAAa,CAAC,EAAE;QAC9B,MAAMuF,QAAQD,UAAUR,YAAYA,aAAYxF,oBAAAA,KAAKY,KAAK,CAACoF,MAAM,qBAAjBhG,kBAAmBmB,WAAW;QAC9E,OAAOT,CAAAA,wBAAAA,KAAMS,WAAW,MAAK,cAAe8E,CAAAA,UAAU,WAAWA,UAAU,MAAK;IAClF;IACA,MAAMC,cAAc,CAAC7F;YAEoBK,aAA2CA,aACjEO,oBAC4BjB;QAH7C,MAAMU,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,IAAIK,CAAAA,wBAAAA,KAAMS,WAAW,MAAK,aAAaT,EAAAA,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,YAAY,MAAK,MAAM,OAAOA,EAAAA,cAAAA,KAAKE,KAAK,qBAAVF,YAAYD,MAAM,MAAK,KAAKsF,KAAKrF,KAAKE,KAAK,CAAC,EAAE;QAChI,MAAMuF,YAAWlF,qBAAAA,MAAMhB,MAAM,CAACmG,IAAI,CAAC,CAAC7E,QAAUA,MAAMlB,EAAE,KAAKA,wBAA1CY,mBAA+CT,SAAS,CAAC6F,EAAE,CAAC,CAAC;QAC9E,OAAON,KAAK1F,OAAO8F,aAAaX,aAAaxF,EAAAA,uBAAAA,KAAKY,KAAK,CAACuF,SAAS,qBAApBnG,qBAAsBmB,WAAW,MAAK;IACrF;IACA,MAAMmF,aAAoC3C,eACxC3D,MACAiB,OACAgB,qBACAC,qBACA,uEAAuE;IACvE,yEAAyE;IACzE,8EAA8E;IAC9E,CAACX;YAAU;gBAAA,gBAAA;eAAIA,MAAMf,SAAS;SAAC,CAAC+F,OAAO,GAAGH,IAAI,CAAC,CAAC/F;gBAAOL;mBAAAA,EAAAA,iBAAAA,KAAKY,KAAK,CAACP,GAAG,qBAAdL,eAAgBmB,WAAW,MAAK;sBAA5E,gBAA0FnB,KAAKM,MAAM;OAChHsE,uBAAuB5E,OAEtBoD,MAAM,CAAC,CAAC,EAAEvB,GAAG,EAAE,GAAK,CAAEgE,CAAAA,QAAQW,eAAe,IAAI3E,IAAI4C,KAAK,CAACyB,YAAW,GACtE7G,GAAG,CAAC,CAAC,EAAEwC,GAAG,EAAE;QACb,MAAM4E,OAAOvF,YAAYlB,KAAKY,KAAK,CAACiB,GAAG,CAAC,EAAE,CAAC,CAACV,WAAW;QACvD,OAAO;YACL1B,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,SAAS,EAAE+G,KAAK,eAAe,EAAE5E,IAAIpB,MAAM,CAAC,iFAAiF,EAAEoB,IAAIpB,MAAM,CAAC,OAAO,CAAC;YAC5JkG,SAAS9E;QACX;IACF;IACA,IAAI+D,WAAWnF,MAAM,EAAE;QACrB,MAAMmG,YAAY,IAAIzG;QACtB,KAAK,MAAM0G,SAASjB,WAAY;YAC9B,MAAMkB,aAAazE,YAAYwE;YAC/B,KAAK,MAAMtF,SAASuF,WAAW7G,MAAM,CAAE;oBAEhC6G;gBADL,IAAIvF,MAAMlB,EAAE,KAAKwG,MAAMvG,MAAM,EAAE;gBAC/B,IAAI,EAACwG,yBAAAA,WAAWtE,MAAM,CAACe,GAAG,CAAChC,MAAMlB,EAAE,aAA9ByG,yBAAmC,MAAM3E,kCAAkC;oBAC9EyE,UAAU9F,GAAG,CAACgG,WAAWxE,OAAO,CAACiB,GAAG,CAAChC,MAAMlB,EAAE;gBAC/C;YACF;QACF;QACA,MAAM0G,SAAS9F,MAAMhB,MAAM,CAACmD,MAAM,CAChC,CAAC7B;gBAEEN;mBADDM,MAAMlB,EAAE,KAAKL,KAAKM,MAAM,IACxB,EAACW,oBAAAA,MAAMuB,MAAM,CAACe,GAAG,CAAChC,MAAMlB,EAAE,aAAzBY,oBAA8B,MAAMkB,oCACrCyE,UAAU/F,GAAG,CAACI,MAAMqB,OAAO,CAACiB,GAAG,CAAChC,MAAMlB,EAAE;;QAE5C,MAAM2G,YAAY,IAAI7G,IAAI4G,OAAO1H,GAAG,CAAC,CAACkC,QAAUA,MAAMlB,EAAE;QACxD,MAAM4G,YAAYF,OAAO3D,MAAM,CAAC,CAAC7B,QAAU,CAACA,MAAMf,SAAS,CAACiB,IAAI,CAAC,CAACpB,KAAO2G,UAAUnG,GAAG,CAACR;QACvF,KAAK,MAAMkB,SAAS0F,UAAW;YAC7BX,WAAWvF,IAAI,CAAC;gBACdtB,MAAM;gBACNiH,MAAM;gBACNhH,SAAS,CAAC,qCAAqC,EAAEwB,YAAYK,MAAMb,IAAI,CAACS,WAAW,EAAE,4DAA4D,CAAC;gBAClJwF,SAAS;oBAACpF,MAAMlB,EAAE;iBAAC;YACrB;QACF;IACF;IACA,OAAOiG;AACT;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASY,oBAAoBlH,IAAoB;IACtD,MAAMiB,QAAQoB,YAAYrC;IAC1B,MAAMgE,UAAU,IAAIzB;IACpB,IAAI4E,OAAO;IACX,KAAK,MAAM5F,SAASN,MAAMhB,MAAM,CAAE;YASdsB;QARlB,IAAIA,MAAMlB,EAAE,KAAKL,KAAKM,MAAM,EAAE;YAC5B,MAAM2D,QAAQhD,MAAMqB,OAAO,CAACiB,GAAG,CAAChC,MAAMlB,EAAE;YACxC,IAAI4D,OAAO;oBACMD;gBAAf,MAAMoD,QAAQ,EAACpD,eAAAA,QAAQT,GAAG,CAACU,kBAAZD,eAAsB,KAAK;gBAC1CA,QAAQV,GAAG,CAACW,OAAOmD;gBACnB,IAAIA,QAAQD,MAAMA,OAAOC;YAC3B;QACF;QACA,MAAMpG,WAAW,EAACO,oBAAAA,MAAMb,IAAI,CAACE,KAAK,YAAhBW,oBAAoB,EAAE,EAAE6B,MAAM,CAAC,CAAC/C,KAAOL,KAAKY,KAAK,CAACP,GAAG,EAAEI,MAAM;QAC/E,IAAIO,WAAWmG,MAAMA,OAAOnG;IAC9B;IACA,OAAOmG;AACT;AAEA,+FAA+F,GAC/F,OAAO,SAASE,qBAAqBrH,IAAoB;IACvD,OAAOD,SAASC,MAAMyB,IAAI,CAAC,CAAC,EAAEf,IAAI,EAAE,GAAKA,KAAKS,WAAW,KAAK;AAChE;AAEA,MAAMmG,kBAAkB,IAAInH,IAAI;IAAC;IAAU;IAAU;CAAM;AAC3D,MAAMoH,eAAuC;IAC3CC,QAAQ;IACRC,QAAQ;IACRC,KAAK;AACP;AAEA;;;;;;;;;CASC,GACD,OAAO,MAAMC,oBAAoB;IAC/BH,QAAQ;QAAEI,UAAU;YAAC;SAAS;QAAEC,cAAc;YAAC;SAAY;IAAC;IAC5DH,KAAK;QAAEE,UAAU;YAAC;SAAM;QAAEC,cAAc,EAAE;IAAC;IAC3CC,SAAS;QAAEF,UAAU;YAAC;SAAQ;QAAEC,cAAc,EAAE;IAAC;IACjDE,MAAM;QAAEH,UAAU;YAAC;SAAO;QAAEC,cAAc;YAAC;SAAa;IAAC;IACzDJ,QAAQ;QAAEG,UAAU;YAAC;SAAS;QAAEC,cAAc,EAAE;IAAC;AACnD,EAAqG;AAIrG,OAAO,MAAMG,yBAAyB7I,OAAOC,IAAI,CAACuI,mBAAsC;AAExF,4EAA4E,GAC5E,MAAMM,wBAAkE;IACtE,WAAW;IACXC,UAAU;IACV,WAAW;IACXC,YAAY;IACZ,WAAW;IACXC,MAAM;IACNC,OAAO;IACP,YAAY;IACZ,YAAY;IACZC,QAAQ;IACRC,MAAM;IACNC,MAAM;IACN,eAAe;IACfC,SAAS;AACX;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASC,iBAAiBC,IAAY;QAYpCC;IAXP,MAAMC,UAAUF,KACbG,KAAK,CAAC,IAAI,CAAC,EAAE,CACbC,OAAO,CAAC,sBAAsB,SAC9BC,WAAW,GACXD,OAAO,CAAC,eAAe,KACvBE,IAAI;IACP,MAAML,OAAO,CAAChJ;YAGPqI;eAFL,AAACD,uBAAoCkB,QAAQ,CAACtJ,SACzCA,SACAqI,+BAAAA,qBAAqB,CAACrI,MAAM,YAA5BqI,+BAAgC;;IACvC,IAAI,CAACY,SAAS,OAAO;IACrB,QAAOD,QAAAA,KAAKC,oBAALD,QAAiBA,KAAKC,QAAQE,OAAO,CAAC,uBAAuB;AACtE;AAEA,sFAAsF,GACtF,OAAO,SAASI,oBAAoBnJ,IAAoB;IACtD,MAAMoJ,QAAQ,IAAIjJ;IAClB,KAAK,MAAM,EAAEO,IAAI,EAAE,IAAIX,SAASC,MAAO;QACrC,MAAMqJ,UAAUjI,UAAUV;QAC1B,KAAK,MAAM4I,UAAUtB,uBAAwB;YAC3C,MAAMuB,QAAQ5B,iBAAiB,CAAC2B,OAAO;YACvC,IACE,AAACD,WAAW,AAACE,MAAM3B,QAAQ,CAAuBsB,QAAQ,CAACG,YAC3D,AAACE,MAAM1B,YAAY,CAAuBqB,QAAQ,CAACxI,KAAKS,WAAW,GACnE;gBACAiI,MAAMtI,GAAG,CAACwI;YACZ;QACF;IACF;IACA,OAAOF;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASI,oBACdxJ,IAAoB,EACpByJ,UAAwB;IAExB,IAAIA,eAAe,UAAUA,eAAe,YAAY,OAAO,EAAE;IACjE,MAAML,QAA+C,EAAE;IACvD,KAAK,MAAM7H,SAASxB,SAASC,MAAO;QAClC,IAAIuB,MAAMlB,EAAE,KAAKL,KAAKM,MAAM,EAAE;QAC9B,IAAIiB,MAAMb,IAAI,CAACS,WAAW,KAAK,aAAa;YAC1CiI,MAAMrI,IAAI,CAAC;gBAAEV,IAAIkB,MAAMlB,EAAE;gBAAEiJ,QAAQ;YAAS;YAC5C;QACF;QACA,MAAMD,UAAUjI,UAAUG,MAAMb,IAAI;QACpC,IACE4G,gBAAgBzG,GAAG,CAACwI,YACpB9H,MAAMhB,KAAK,IAAI,KACf,CAACe,YAAYtB,MAAMuB,OAAO,CAACb,OAASU,UAAUV,UAAU,YACxD;YACA0I,MAAMrI,IAAI,CAAC;gBAAEV,IAAIkB,MAAMlB,EAAE;gBAAEiJ,QAAQ/B,YAAY,CAAC8B,QAAQ;YAAC;QAC3D;IACF;IACA,IAAI,CAACD,MAAM3I,MAAM,EAAE,OAAO,EAAE;IAC5B,MAAMiJ,UAAUhI,OAAO0H,MAAM/J,GAAG,CAAC,CAACsK,QAAUA,MAAML,MAAM,GAAGvH,IAAI,CAAC;IAChE,OAAO;QACL;YACEtC,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,+BAA+B,EAAEgK,QAAQ,wHAAwH,CAAC;YAC5K/C,SAASyC,MAAM/J,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QACxC;KACD;AACH;AAEA;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASuJ,kBACd5J,IAAoB,EACpByJ,UAAwB;IAExB,IAAIA,eAAe,UAAUA,eAAe,SAAS,OAAO,EAAE;IAC9D,MAAMI,QAAkB,EAAE;IAC1B,MAAMC,UAAoB,EAAE;IAC5B,MAAMC,WAAqB,EAAE;IAC7B,KAAK,MAAMxI,SAASxB,SAASC,MAAO;QAClC,IACEhE,gBAAgBuF,MAAMb,IAAI,KAC1B,CAACY,YAAYtB,MAAMuB,OAAO,CAACb,OAASA,KAAKS,WAAW,KAAK,SACzD;YACA0I,MAAM9I,IAAI,CAACQ,MAAMlB,EAAE;QACrB;QACA,IAAIkB,MAAMb,IAAI,CAACS,WAAW,KAAK,QAAQ;gBACvBI;YAAd,MAAMyI,SAAQzI,oBAAAA,MAAMb,IAAI,CAACW,KAAK,qBAAhBE,iBAAkB,CAAC,SAAS;YAC1C,IAAI,OAAOyI,UAAU,YAAYA,OAAO;oBACjCzI;gBAAL,IAAI,EAACA,oBAAAA,MAAMb,IAAI,CAACE,KAAK,YAAhBW,oBAAoB,EAAE,EAAEd,MAAM,EAAEsJ,SAAShJ,IAAI,CAACQ,MAAMlB,EAAE;YAC7D,OAAO;gBACLyJ,QAAQ/I,IAAI,CAACQ,MAAMlB,EAAE;YACvB;QACF;IACF;IACA,MAAMiG,aAAoC,EAAE;IAC5C,IAAIuD,MAAMpJ,MAAM,IAAIqJ,QAAQrJ,MAAM,EAAE;QAClC6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAAS;mBAAImD;mBAAYD;aAAM;QACjC;IACF;IACA,IAAIE,SAAStJ,MAAM,EAAE;QACnB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASoD;QACX;IACF;IACA,OAAOzD;AACT;AAEA,MAAM2D,gBAAgB,IAAI9J,IAAI;IAAC;IAAS;IAAW;IAAmB;CAAc;AACpF,MAAM+J,yBAAyB,IAAI/J,IAAI;IACrC;IACA;IACA;IACA;IACA;IACA;CACD;AACD,MAAMgK,kBAAkB,IAAIhK,IAAI;IAC9B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AACD,MAAMiK,eAAe,IAAIjK,IAAI;IAAC;IAAY;IAAc;CAAgB;AACxE,MAAMkK,iBAAiB,IAAIlK,IAAI;IAC7B;IACA;IACA;IACA;IACA;IACA;CACD;AACD,MAAMmK,gBACJ;AACF,MAAMC,mBAAmB;AACzB,MAAMC,gBAAgB,IAAIrK,IAAYnB,aAAayL,OAAO;AAE1D,uEAAuE,GACvE,SAASC,gBAAgB9K,KAAc;IACrC,IAAI,OAAOA,UAAU,UAAU,OAAO;IACtC,MAAM+K,QAAQ/K,MACXqJ,IAAI,GACJH,KAAK,CAAC,OACN1F,MAAM,CAAC,CAACwH,OAAS,CAACJ,cAAc3J,GAAG,CAAC+J,SAAS,CAACP,eAAexJ,GAAG,CAAC+J,KAAK5B,WAAW;IACpF,OAAOsB,cAAc9I,IAAI,CAACmJ,MAAM5I,IAAI,CAAC;AACvC;AAEA,qDAAqD,GACrD,SAAS8I,SAASjL,KAAc;IAC9B,OAAOD,SAASC,SAAST,OAAOwC,MAAM,CAAC/B,SAAS;QAACA;KAAM;AACzD;AAEA;;;;CAIC,GACD,OAAO,SAASkL,oBACd9K,IAAoB,EACpByJ,UAAwB;IAExB,IAAIA,eAAe,SAAS,OAAO,EAAE;IACrC,MAAMsB,SAAmB,EAAE;IAC3B,MAAMC,UAAoB,EAAE;IAC5B,KAAK,MAAM,EAAE3K,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;YACDU,gBAgBGA;YAD5B3B;QAff,KAAK,MAAM,CAAC8D,KAAKoI,IAAI,IAAI9L,OAAOkF,OAAO,EAAC3D,WAAAA,KAAKwK,EAAE,YAAPxK,WAAW,CAAC,GAAI;YACtD,KAAK,MAAMd,SAASiL,SAASI,KAAM;gBACjC,IAAI,AAAChB,CAAAA,cAAcpJ,GAAG,CAACgC,QAAQqH,uBAAuBrJ,GAAG,CAACgC,IAAG,KAAM6H,gBAAgB9K,QAAQ;oBACzFmL,OAAOhK,IAAI,CAACV;gBACd,OAAO,IACL,AAAC8J,CAAAA,gBAAgBtJ,GAAG,CAACgC,QAAQA,QAAQ,kBAAkBuH,aAAavJ,GAAG,CAACgC,IAAG,KAC3E,OAAOjD,UAAU,YACjB2K,iBAAiB/I,IAAI,CAAC5B,QACtB;oBACAoL,QAAQjK,IAAI,CAACV;gBACf,OAAO,IAAIwC,QAAQ,cAAc,OAAOjD,UAAU,YAAYA,QAAQ,GAAG;oBACvEoL,QAAQjK,IAAI,CAACV;gBACf;YACF;QACF;QACA,MAAMoC,kBAAS1D,+BAAAA,UAAU,CAAC2B,KAAKS,WAAW,CAAC,qBAA5BpC,6BAA8B2D,WAAW,CAACC,UAAU,mBAAI,CAAC;QACxE,KAAK,MAAM,CAAC8D,MAAM7G,MAAM,IAAIT,OAAOkF,OAAO,EAAC3D,cAAAA,KAAKW,KAAK,YAAVX,cAAc,CAAC,GAAI;gBAGzD+B;YAFH,IACE,sCAAsCjB,IAAI,CAACiF,SAC3C,GAAChE,eAAAA,MAAM,CAACgE,KAAK,qBAAZhE,aAAcQ,IAAI,KACnByH,gBAAgB9K,QAChB;gBACAmL,OAAOhK,IAAI,CAACV;YACd;QACF;IACF;IACA,MAAMiG,aAAoC,EAAE;IAC5C,IAAIyE,OAAOtK,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASjF,OAAOqJ;QAClB;IACF;IACA,IAAIC,QAAQvK,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASjF,OAAOsJ;QAClB;IACF;IACA,OAAO1E;AACT;AAEA,SAAS6E,aAAavL,KAAa;IACjC,MAAMwL,MAAMxL,MAAMqJ,IAAI,GAAGD,WAAW;IACpC,OAAO,iBAAiBxH,IAAI,CAAC4J,OACzB,CAAC,CAAC,EAAEA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAE,GAAGA,GAAG,CAAC,EAAE,EAAE,GACzDA;AACN;AAEA;;;;;CAKC,GACD,OAAO,SAASC,oBACdrL,IAAoB,EACpByJ,UAAwB,EACxB6B,KAAqC;;IAErC,IAAI7B,eAAe,SAAS,OAAO,EAAE;IACrC,MAAM8B,UAAU,IAAIpL,IAAIhB,OAAOwC,MAAM,SAAC2J,yBAAAA,MAAOP,MAAM,mBAAI,CAAC,GAAG1L,GAAG,CAAC8L;IAC/D,MAAMK,QAAQ,IAAIrL,IAAI,UAACmL,yBAAAA,MAAOE,KAAK,oBAAI,EAAE,EAAEnM,GAAG,CAAC,CAACoM,OAASA,KAAKzC,WAAW;IACzE,MAAM0C,WAAqB,EAAE;IAC7B,MAAM/J,SAAmB,EAAE;IAC3B,KAAK,MAAM,EAAEtB,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;YAGDU;YADyBA;QADjE,MAAMiL,aAAwB,EAAE;QAChC,KAAK,MAAMlF,QAAQ;YAAC;YAAS;SAAkB,CAAEkF,WAAW5K,IAAI,EAACL,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC+F,KAAK;QACnF,KAAK,MAAM,CAAC5D,KAAKoI,IAAI,IAAI9L,OAAOkF,OAAO,EAAC3D,WAAAA,KAAKwK,EAAE,YAAPxK,WAAW,CAAC,GAAI;YACtD,IAAIuJ,cAAcpJ,GAAG,CAACgC,MAAM8I,WAAW5K,IAAI,IAAI8J,SAASI;YACxD,IAAIpI,QAAQ,cAAc;gBACxB,KAAK,MAAM+I,UAAUf,SAASI,KAAM;oBAClC,IAAI,OAAOW,WAAW,YAAY,CAACJ,MAAM3K,GAAG,CAAC+K,OAAO3C,IAAI,GAAGD,WAAW,KAAK;wBACzE0C,SAAS3K,IAAI,CAACV;wBACdsB,OAAOZ,IAAI,CAAC6K,OAAO3C,IAAI;oBACzB;gBACF;YACF;QACF;QACA,KAAK,MAAM4C,aAAaF,WAAY;YAClC,IAAI,OAAOE,cAAc,YAAY,CAACA,UAAU5C,IAAI,IAAI;YACxD,IAAI,CAACsC,QAAQ1K,GAAG,CAACsK,aAAaU,aAAa;gBACzCH,SAAS3K,IAAI,CAACV;gBACdsB,OAAOZ,IAAI,CAAC8K,UAAU5C,IAAI;YAC5B;QACF;IACF;IACA,IAAI,CAACyC,SAASjL,MAAM,EAAE,OAAO,EAAE;IAC/B,OAAO;QACL;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,gBAAgB,EAAEgC,OAAOC,QAAQK,KAAK,CAAC,GAAG,GAAGD,IAAI,CAAC,MAAM,8FAA8F,CAAC;YACjK4E,SAASjF,OAAOgK;QAClB;KACD;AACH;AAEA,mEAAmE,GACnE,MAAMI,oBAAoB;IAAC;IAAS;CAAkB;AAQtD;;;;CAIC,GACD,SAASC,WAAWnM,KAAa;QAEnB;IADZ,MAAMoM,OAAOpM,MAAMqJ,IAAI,GAAGD,WAAW;IACrC,MAAMoC,OAAM,QAAA,6CAA6Ca,IAAI,CAACD,0BAAlD,KAAyD,CAAC,EAAE;IACxE,IAAIE;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC,QAAQ;IACZ,IAAIjB,KAAK;QACP,MAAMkB,OAAOlB,IAAI3K,MAAM,IAAI,IAAI;eAAI2K;SAAI,CAAC/L,GAAG,CAAC,CAACkN,QAAUA,QAAQA,OAAOxK,IAAI,CAAC,MAAMqJ;QACjFc,IAAIM,SAASF,KAAKtK,KAAK,CAAC,GAAG,IAAI;QAC/BmK,IAAIK,SAASF,KAAKtK,KAAK,CAAC,GAAG,IAAI;QAC/BoK,IAAII,SAASF,KAAKtK,KAAK,CAAC,GAAG,IAAI;QAC/B,IAAIsK,KAAK7L,MAAM,KAAK,GAAG4L,QAAQG,SAASF,KAAKtK,KAAK,CAAC,GAAG,IAAI,MAAM;IAClE,OAAO;QACL,MAAMyK,KAAK,8EAA8ER,IAAI,CAACD;QAC9F,IAAI,CAACS,IAAI,OAAO;QAChBP,IAAI5M,OAAOmN,EAAE,CAAC,EAAE;QAChBN,IAAI7M,OAAOmN,EAAE,CAAC,EAAE;QAChBL,IAAI9M,OAAOmN,EAAE,CAAC,EAAE;QAChB,IAAIA,EAAE,CAAC,EAAE,KAAKjH,WAAW6G,QAAQ/M,OAAOmN,EAAE,CAAC,EAAE;QAC7C,IAAI,CAAC;YAACP;YAAGC;YAAGC;YAAGC;SAAM,CAAC5H,KAAK,CAACnF,OAAOoN,QAAQ,KAAKR,IAAI,OAAOC,IAAI,OAAOC,IAAI,OAAOC,QAAQ,GAAG,OAAO;IACrG;IACA,MAAMM,OAAO,CAACC,UAAoBC,KAAKC,KAAK,CAACF,UAAUP,QAAQ,MAAO,CAAA,IAAIA,KAAI;IAC9E,OAAO;QAAEH,GAAGS,KAAKT;QAAIC,GAAGQ,KAAKR;QAAIC,GAAGO,KAAKP;QAAIC;IAAM;AACrD;AAEA,wEAAwE,GACxE,SAASU,mBAAmBC,CAAM,EAAEZ,CAAM;IACxC,MAAMa,OAAO,AAACD,CAAAA,EAAEd,CAAC,GAAGE,EAAEF,CAAC,AAADA,IAAK;IAC3B,MAAMgB,KAAKF,EAAEd,CAAC,GAAGE,EAAEF,CAAC;IACpB,MAAMiB,KAAKH,EAAEb,CAAC,GAAGC,EAAED,CAAC;IACpB,MAAMiB,KAAKJ,EAAEZ,CAAC,GAAGA,EAAEA,CAAC;IACpB,OAAOS,KAAKQ,IAAI,CAAC,AAAC,CAAA,IAAIJ,OAAO,GAAE,IAAKC,KAAKA,KAAK,IAAIC,KAAKA,KAAK,AAAC,CAAA,IAAI,AAAC,CAAA,MAAMF,IAAG,IAAK,GAAE,IAAKG,KAAKA;AAC9F;AAEA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASE,4BACdC,KAAc,EACdjC,KAAqC;;IAErC,IAAI,CAAC3L,SAAS4N,UAAU,CAAC5N,SAAS4N,KAAK,CAAC,QAAQ,GAAG,OAAOA;IAC1D,MAAMlJ,UAAUlF,OAAOkF,OAAO,SAACiH,yBAAAA,MAAOP,MAAM,mBAAI,CAAC,GAAG3H,MAAM,CACxD,CAACuG,QAAqC,OAAOA,KAAK,CAAC,EAAE,KAAK,YAAYA,KAAK,CAAC,EAAE,CAACV,IAAI,OAAO;IAE5F,MAAMsC,UAAU,IAAIpL,IAAIkE,QAAQhF,GAAG,CAAC,CAAC,GAAGO,MAAM,GAAKuL,aAAavL;IAChE,MAAM4N,SAAS,IAAIjL,IAAI8B,QAAQhF,GAAG,CAAC,CAAC,CAACoO,MAAM7N,MAAM,GAAK;YAAC6N,KAAKzE,WAAW;YAAIpJ,MAAMqJ,IAAI;SAAG;IACxF,MAAMyE,UAAUrJ,QAAQE,OAAO,CAAC,CAAC,GAAG3E,MAAM;QACxC,MAAM+N,MAAM5B,WAAWnM;QACvB,OAAO+N,OAAOA,IAAItB,KAAK,KAAK,IAAI;YAAC;gBAAEzM,OAAOA,MAAMqJ,IAAI;gBAAI0E;YAAI;SAAE,GAAG,EAAE;IACrE;IACA,MAAMC,SAAS,CAAChO;QACd,IAAI,CAACyE,QAAQ5D,MAAM,EAAE,OAAO;QAC5B,MAAMoN,QAAQL,OAAOjK,GAAG,CAAC3D,MAAMqJ,IAAI,GAAGD,WAAW;QACjD,IAAI6E,OAAO,OAAOA;QAClB,MAAMF,MAAM5B,WAAWnM;QACvB,IAAI,CAAC+N,OAAO,CAACD,QAAQjN,MAAM,EAAE,OAAO+E;QACpC,IAAIsI,OAAOJ,OAAO,CAAC,EAAE;QACrB,KAAK,MAAMK,UAAUL,QAAS;YAC5B,IAAIX,mBAAmBY,KAAKI,OAAOJ,GAAG,IAAIZ,mBAAmBY,KAAKG,KAAKH,GAAG,GAAGG,OAAOC;QACtF;QACA,OAAOD,KAAKlO,KAAK;IACnB;IACA,IAAIgB,QAAwC;IAC5C,KAAK,MAAM,CAACP,IAAIK,KAAK,IAAIvB,OAAOkF,OAAO,CAACkJ,KAAK,CAAC,QAAQ,EAAG;QACvD,IAAI,CAAC5N,SAASe,SAAS,CAACf,SAASe,IAAI,CAAC,QAAQ,GAAG;QACjD,IAAIW,QAAwC;QAC5C,KAAK,MAAMoF,QAAQqF,kBAAmB;YACpC,MAAMlM,QAAQc,IAAI,CAAC,QAAQ,CAAC+F,KAAK;YACjC,IAAI,OAAO7G,UAAU,YAAY,CAACA,MAAMqJ,IAAI,MAAMsC,QAAQ1K,GAAG,CAACsK,aAAavL,SAAS;YACpF,MAAMoO,UAAUJ,OAAOhO;YACvB,IAAIoO,YAAYxI,WAAW;YAC3BnE,gBAAAA,QAAAA,QAAU,aAAKX,IAAI,CAAC,QAAQ;YAC5B,IAAIsN,YAAY,MAAM,OAAO3M,KAAK,CAACoF,KAAK;iBACnCpF,KAAK,CAACoF,KAAK,GAAGuH;QACrB;QACA,IAAI,CAAC3M,OAAO;QACZT,gBAAAA,QAAAA,QAAU,aAAK2M,KAAK,CAAC,QAAQ;QAC7B3M,KAAK,CAACP,GAAG,GAAG,aAAKK;YAAMW;;IACzB;IACA,IAAI,CAACT,SAAS,CAAC8M,QAAQjN,MAAM,EAAE,OAAOG,QAAQ,aAAK2M;QAAO3M;SAAU2M;IACpE,4EAA4E;IAC5E,4EAA4E;IAC5E,2EAA2E;IAC3E,8DAA8D;IAC9D,OAAOU,yBAAyBV,KAAK,CAAC,QAAQ,EAAE3M,SAAS,aAAK2M;QAAO3M;SAAU2M;AACjF;AAEA,6FAA6F,GAC7F,MAAMW,6BAA6B;AAEnC,SAASC,eAAe,EAAEjC,CAAC,EAAEC,CAAC,EAAEC,CAAC,EAAO;IACtC,MAAMQ,UAAU,CAAChN;QACf,MAAMwO,IAAIxO,QAAQ;QAClB,OAAOwO,KAAK,UAAUA,IAAI,QAAQ,AAAC,CAAA,AAACA,CAAAA,IAAI,KAAI,IAAK,KAAI,KAAM;IAC7D;IACA,OAAO,SAASxB,QAAQV,KAAK,SAASU,QAAQT,KAAK,SAASS,QAAQR;AACtE;AAEA,SAASiC,cAAcrB,CAAM,EAAEZ,CAAM;IACnC,MAAM,CAACkC,OAAOC,KAAK,GAAG;QAACJ,eAAenB;QAAImB,eAAe/B;KAAG,CAACxJ,IAAI,CAAC,CAAC4L,GAAGC,IAAMA,IAAID;IAChF,OAAO,AAACF,CAAAA,QAAQ,IAAG,IAAMC,CAAAA,OAAO,IAAG;AACrC;AAEA;;;;;CAKC,GACD,SAASN,yBACPS,OAAgC,EAChCV,OAAgC;IAEhC,MAAM3I,WAAW,IAAI9C;IACrB,KAAK,MAAM,CAAClC,IAAIK,KAAK,IAAIvB,OAAOkF,OAAO,CAAC2J,SAAU;QAChD,IAAI,CAACrO,SAASe,SAAS,CAACb,MAAMC,OAAO,CAACY,IAAI,CAAC,QAAQ,GAAG;QACtD,KAAK,MAAM2C,SAAS3C,IAAI,CAAC,QAAQ,CAAE,IAAI,OAAO2C,UAAU,UAAUgC,SAAS/B,GAAG,CAACD,OAAOhD;IACxF;IACA,MAAMsO,SAAS,CAAC/N,OAAgCP,IAAYoG;QAC1D,MAAM/F,OAAOE,KAAK,CAACP,GAAG;QACtB,OAAOV,SAASe,SAASf,SAASe,IAAI,CAAC,QAAQ,IAAIA,IAAI,CAAC,QAAQ,CAAC+F,KAAK,GAAGjB;IAC3E;IACA,oFAAoF,GACpF,MAAMoJ,WAAW,CAACvO;QAChB,IAAI,OAAOsO,OAAOX,SAAS3N,IAAI,uBAAuB,UAAU,OAAOA;QACvE,MAAMK,OAAOsN,OAAO,CAAC3N,GAAG;QACxB,IAAIV,SAASe,SAASA,IAAI,CAAC,cAAc,KAAK,eAAe,OAAO8E;QACpE,MAAMtF,OAAO,IAAIC,IAAY;YAACE;SAAG;QACjC,IAAK,IAAIgG,KAAKhB,SAAS9B,GAAG,CAAClD,KAAKgG,MAAM,CAACnG,KAAKW,GAAG,CAACwF,KAAKA,KAAKhB,SAAS9B,GAAG,CAAC8C,IAAK;YAC1EnG,KAAKY,GAAG,CAACuF;YACT,IAAI,OAAOsI,OAAOX,SAAS3H,IAAI,uBAAuB,UAAU,OAAOA;QACzE;QACA,OAAO;IACT;IACA,MAAMwI,QAAa;QAAE3C,GAAG;QAAKC,GAAG;QAAKC,GAAG;IAAI;IAC5C,KAAK,MAAM/L,MAAMlB,OAAOC,IAAI,CAAC4O,SAAU;QACrC,MAAMc,QAAQH,OAAOX,SAAS3N,IAAI;QAClC,IAAI,OAAOyO,UAAU,UAAU;QAC/B,MAAMC,SAASH,SAASvO;QACxB,IAAI0O,WAAWvJ,WAAW;QAC1B,MAAMwJ,UACJF,UAAUH,OAAOD,SAASrO,IAAI,YAC7B0O,WAAW,QACVJ,OAAOX,SAASe,QAAQ,uBAAuBJ,OAAOD,SAASK,QAAQ;QAC3E,IAAI,CAACC,SAAS;QACd,MAAMhD,OAAOD,WAAW+C;QACxB,MAAMG,aAAaF,WAAW,OAAOF,QAAQ9C,WAAW5I,OAAOwL,OAAOX,SAASe,QAAQ;QACvF,IAAI,CAAC/C,QAAQ,CAACiD,YAAY;QAC1B,IAAIZ,cAAcrC,MAAMiD,cAAcf,4BAA4B,OAAO;IAC3E;IACA,OAAO;AACT;AAEA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASgB,gBAAgBlP,IAAoB;IAClD,MAAMiB,QAAQoB,YAAYrC;IAC1B,MAAMmP,YAAY,CAAC5N;YACjB;gBAAA,gBAAA;eAAIA,MAAMf,SAAS;SAAC,CAAC+F,OAAO,GAAGH,IAAI,CAAC,CAAC/F;gBAAOL;mBAAAA,EAAAA,iBAAAA,KAAKY,KAAK,CAACP,GAAG,qBAAdL,eAAgBmB,WAAW,MAAK;sBAA5E,gBAA0FnB,KAAKM,MAAM;;IACvG,MAAMgG,aAAoC3C,eACxC3D,MACAiB,OACAgB,sBAAsB,GACtBG,yBACA+M,WACA9P,GAAG,CAAC,CAAC,EAAEwC,GAAG,EAAE,GAAM,CAAA;YAClBpC,MAAM;YACNiH,MAAM;YACNhH,SAAS,GAAGmC,IAAIpB,MAAM,CAAC,CAAC,EAAES,YAAYlB,KAAKY,KAAK,CAACiB,GAAG,CAAC,EAAE,CAAC,CAACV,WAAW,EAAE,yIAAyI,CAAC;YAChNwF,SAAS9E;QACX,CAAA;IACA,KAAK,MAAMN,SAASN,MAAMhB,MAAM,CAAE;YAGVsB;QAFtB,IAAImC,eAAe1D,MAAMuB,UAAUA,MAAMb,IAAI,CAACS,WAAW,KAAK,qBAAqB;QACnF,MAAMiO,cAAc,IAAI7M;QACxB,KAAK,MAAM8M,YAAW9N,oBAAAA,MAAMb,IAAI,CAACE,KAAK,YAAhBW,oBAAoB,EAAE,CAAE;gBAIlB6N;gBAFd/L;YADZ,MAAMA,QAAQrD,KAAKY,KAAK,CAACyO,QAAQ;YACjC,MAAMC,MAAMjM,0BAAAA,eAAAA,MAAOhC,KAAK,qBAAZgC,YAAc,CAAChF,qBAAqB;YAChD,IAAIgF,CAAAA,yBAAAA,MAAOlC,WAAW,MAAK1E,kCAAkC,OAAO6S,QAAQ,UAAU;YACtFF,YAAY9L,GAAG,CAACgM,KAAK;oBAAKF,mBAAAA,YAAY7L,GAAG,CAAC+L,gBAAhBF,mBAAwB,EAAE;gBAAGC;aAAQ;QACjE;QACA,KAAK,MAAMxN,OAAOuN,YAAYzN,MAAM,GAAI;YACtC,IAAIE,IAAIpB,MAAM,GAAG2B,yBAAyB;YAC1CkE,WAAWvF,IAAI,CAAC;gBACdtB,MAAM;gBACNiH,MAAM;gBACNhH,SAAS,GAAGmC,IAAIpB,MAAM,CAAC,uJAAuJ,CAAC;gBAC/KkG,SAAS9E;YACX;QACF;IACF;IACA,OAAOyE;AACT;AAEA;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,SAASiJ,wBACdvP,IAAoB,EACpB6F,OAAsD;QAErCA,yBAkBS/C;QADdkD;IAjBZ,MAAMlD,YAAW+C,0BAAAA,QAAQ2J,cAAc,YAAtB3J,0BAA0B,CAAC;IAC5C,MAAM4J,WAAqB,EAAE;IAC7B,KAAK,MAAM,CAACpP,IAAIK,KAAK,IAAIvB,OAAOkF,OAAO,CAACrE,KAAKY,KAAK,EAAG;YAEvCF,aAIGA;QALf,IAAIA,CAAAA,wBAAAA,KAAMS,WAAW,MAAK1E,gCAAgC;QAC1D,MAAM6S,OAAM5O,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAACrC,qBAAqB;QAC9C,IAAI,OAAOiR,QAAQ,UAAU;QAC7B,MAAMjO,QAAQyB,QAAQ,CAACwM,IAAI;QAC3B,IAAI,CAACjO,SAAS,CAAClC,OAAOC,IAAI,CAACiC,OAAOZ,MAAM,EAAE;QAC1C,MAAMkB,UAASjB,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,aAAa;QACzC,MAAMgP,SACJ,OAAO/N,WAAW,YAAYA,WAAW,QAAQ,CAAC9B,MAAMC,OAAO,CAAC6B,UAC5DxC,OAAOC,IAAI,CAACuC,QAAmCyB,MAAM,CAAC,CAACqD,OAASA,QAAQpF,SACxE,EAAE;QACR,IAAI,CAACqO,OAAOjP,MAAM,EAAEgP,SAAS1O,IAAI,CAACV;IACpC;IACA,IAAI,CAACoP,SAAShP,MAAM,EAAE,OAAO,EAAE;IAC/B,MAAMuF,QAAQhG,KAAKY,KAAK,CAAC6O,QAAQ,CAAC,EAAE,CAAC;IACrC,MAAMH,MAAMtJ,0BAAAA,eAAAA,MAAO3E,KAAK,qBAAZ2E,YAAc,CAAC3H,qBAAqB;IAChD,MAAMyD,QAAQ3C,OAAOC,IAAI,EAAC0D,gBAAAA,QAAQ,CAACwM,IAAI,YAAbxM,gBAAiB,CAAC;IAC5C,MAAM6M,MAAMF,SAAShP,MAAM,KAAK;IAChC,OAAO;QACL;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GACPiQ,MAAM,uBAAuB,GAAGF,SAAShP,MAAM,CAAC,gBAAgB,CAAC,CAClE,4CAA4C,EAC3CkP,MAAM,aAAa,gBACpB,+EAA+E,EAC9EA,MAAM,aAAa,WACpB,aAAa,EAAE7N,MAAMC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnC4E,SAAS8I;QACX;KACD;AACH;AAEA,kFAAkF,GAClF,SAASG,YACPlP,IAAoB,EACpBmF,OAA0B;cAIiBnF;QAD7B3B,8BAMA2B,cACCA;IARf,MAAMmP,MAA8C,EAAE;IACtD,MAAMC,iBAAQ/Q,+BAAAA,UAAU,CAAC2B,KAAKS,WAAW,CAAC,qBAA5BpC,6BAA8BgR,SAAS,mBAAI,CAAC;IAC1D,KAAK,MAAM,CAACtJ,MAAM7G,MAAM,IAAIT,OAAOkF,OAAO,EAAC3D,cAAAA,KAAKW,KAAK,YAAVX,cAAc,CAAC,GAAI;QAC5D,IAAIoP,KAAK,CAACrJ,KAAK,KAAK,WAAW,OAAO7G,UAAU,YAAYA,MAAMqJ,IAAI,IAAI;YACxE4G,IAAI9O,IAAI,CAAC;gBAAE0F;gBAAM7G,OAAOA,MAAMqJ,IAAI;YAAG;QACvC;IACF;IACA,MAAM+G,SAAQtP,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAACrC,qBAAqB;IAChD,MAAMsD,UAASjB,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAChE,kCAAkC;IAC9D,IAAI,OAAOsT,UAAU,YAAYrQ,SAASgC,SAAS;;YAChCkE;QAAjB,MAAM/C,qBAAW+C,0BAAAA,QAAQ2J,cAAc,qBAAtB3J,uBAAwB,CAACmK,MAAM,oBAAI,CAAC;QACrD,KAAK,MAAM,CAACvJ,MAAM7G,MAAM,IAAIT,OAAOkF,OAAO,CAAC1C,QAAS;YAClD,IAAImB,QAAQ,CAAC2D,KAAK,KAAK,WAAW,OAAO7G,UAAU,YAAYA,MAAMqJ,IAAI,IAAI;gBAC3E4G,IAAI9O,IAAI,CAAC;oBAAE0F,MAAM,GAAG/J,kCAAkC,CAAC,EAAE+J,MAAM;oBAAE7G,OAAOA,MAAMqJ,IAAI;gBAAG;YACvF;QACF;IACF;IACA,OAAO4G;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASI,mBACdjQ,IAAoB,EACpB6F,UAA6B,CAAC,CAAC;IAE/B,MAAMqK,YAAsB,EAAE;IAC9B,MAAMC,aAAuB,EAAE;IAC/B,KAAK,MAAM,EAAE9P,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;QACzC,IAAI4P,YAAYlP,MAAMmF,SAASpE,IAAI,CAAC,CAAC,EAAE7B,KAAK,EAAE,GAAK,gBAAgB4B,IAAI,CAAC5B,SAAS;YAC/EsQ,UAAUnP,IAAI,CAACV;QACjB;QACA,IAAIK,KAAKS,WAAW,KAAK,WAAWT,KAAKS,WAAW,KAAK,cAAc;gBACzDT,aACOA;YADnB,MAAM0P,OAAM1P,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,MAAM;YAC/B,MAAM2P,aAAa3P,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,aAAa,MAAK;YAClD,IAAI,CAAC2P,cAAe,CAAA,OAAOD,QAAQ,YAAY,CAACA,IAAInH,IAAI,EAAC,GAAIkH,WAAWpP,IAAI,CAACV;QAC/E;IACF;IACA,MAAMiG,aAAoC,EAAE;IAC5C,IAAI4J,UAAUzP,MAAM,EAAE;QACpB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASuJ;QACX;IACF;IACA,IAAIC,WAAW1P,MAAM,EAAE;QACrB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASwJ;QACX;IACF;IACA,OAAO7J;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASrB,eAAevE,IAAoB;;QAGxCA,aACyCA;IAHlD,IAAIA,KAAKS,WAAW,KAAK,iBAAiB,OAAO;IACjD,MAAMkI,UACJ,SAAO3I,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,YAAY,MAAK,WAAWyC,OAAOzC,KAAKW,KAAK,CAAC,YAAY,IAAI;IACpF,MAAMiP,QAAQ,aAAarE,IAAI,CAAC5C,WAAWlG,gBAAOzC,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,mBAAI;IAC7E,OAAO4P,QAAQhR,OAAOgR,KAAK,CAAC,EAAE,IAAI;AACpC;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASC,wBACdvQ,IAAoB,EACpByJ,UAAwB;;QAsEG+G;IApE3B,MAAMvQ,SAASF,SAASC;IACxB,MAAMyQ,QAAQxQ,OAAOmD,MAAM,CAAC,CAAC7B,QAAUH,UAAUG,MAAMb,IAAI,MAAM,QAAQrB,GAAG,CAAC,CAACkC,QAAUA,MAAMlB,EAAE;IAChG,MAAMiG,aAAoC,EAAE;IAC5C,IAAImD,eAAe,eAAeA,eAAe,WAAWA,eAAe,QAAQ;QACjF,IAAIgH,MAAMhQ,MAAM,EAAE;YAChB6F,WAAWvF,IAAI,CAAC;gBACdtB,MAAM;gBACNiH,MAAM;gBACNhH,SAAS,CAAC,EAAE,EAAE+J,WAAW,uFAAuF,CAAC;gBACjH9C,SAAS8J;YACX;QACF;IACF,OAAO,IAAIA,MAAMhQ,MAAM,GAAG,GAAG;QAC3B6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS;YACTiH,SAAS8J;QACX;IACF;IACA,IAAIhH,eAAe,UAAU;QAC3B,MAAMiH,QAAQzQ,OAAOmD,MAAM,CAAC,CAAC7B,QAAUA,MAAMb,IAAI,CAACS,WAAW,KAAK;QAClE,MAAMwP,cAAcvP,UAAUpB,KAAKY,KAAK,CAACZ,KAAKM,MAAM,CAAC;QACrD,MAAMsQ,cAAcF,KAAK,CAAC,EAAE,GAAGtP,UAAUsP,KAAK,CAAC,EAAE,CAAChQ,IAAI,IAAI;QAC1D,qEAAqE;QACrE,kCAAkC;QAClC,MAAMmQ,aACJF,gBAAgB,MAChBA,gBAAgB,UACf,CAAA,CAACD,MAAMjQ,MAAM,IAAKmQ,gBAAgB,MAAMA,gBAAgB,MAAM;QACjE,IAAIF,MAAMjQ,MAAM,KAAK,KAAKoQ,YAAY;YACpCvK,WAAWvF,IAAI,CAAC;gBACdtB,MAAM;gBACNiH,MAAM;gBACNhH,SACE;gBACFiH,SAAS+J,MAAMrR,GAAG,CAAC,CAACmJ,OAASA,KAAKnI,EAAE;YACtC;QACF;IACF;IACA,IAAIoJ,eAAe,WAAWA,eAAe,QAAQ,OAAOnD;IAE5D,MAAMkK,WAAWvQ,OACdZ,GAAG,CAAC,CAACkC,QAAW,CAAA;YAAElB,IAAIkB,MAAMlB,EAAE;YAAE2E,OAAOC,eAAe1D,MAAMb,IAAI;QAAE,CAAA,GAClE0C,MAAM,CAAC,CAACuG,QAAkDA,MAAM3E,KAAK,KAAK;IAC7E,MAAM8L,MAAMN,SAASpN,MAAM,CAAC,CAAC2N,UAAYA,QAAQ/L,KAAK,KAAK,GAAG3F,GAAG,CAAC,CAAC0R,UAAYA,QAAQ1Q,EAAE;IACzF,MAAM2Q,OAAOvH,eAAe,UAAUA,eAAe;IACrD,IAAIuH,QAAQF,IAAIrQ,MAAM,KAAK,GAAG;QAC5B6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAMoK,IAAIrQ,MAAM,GAAG,gBAAgB;YACnCf,SAASoR,IAAIrQ,MAAM,GACf,CAAC,cAAc,EAAEqQ,IAAIrQ,MAAM,CAAC,2DAA2D,CAAC,GACxF;YACJkG,SAASmK;QACX;IACF,OAAO,IAAI,CAACE,QAAQF,IAAIrQ,MAAM,GAAIgJ,CAAAA,eAAe,WAAW,IAAI,CAAA,GAAI;QAClEnD,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE+J,eAAe,WACX,sEACA;YACN9C,SAASmK;QACX;IACF;IACA,MAAMG,UAAoB,EAAE;IAC5B,IAAIC,WAAWF,OAAO,IAAI,UAACR,aAAAA,QAAQ,CAAC,EAAE,qBAAXA,WAAaxL,KAAK,mBAAI,KAAK;IACtD,KAAK,MAAM+L,WAAWP,SAAU;QAC9B,IAAIO,QAAQ/L,KAAK,GAAGkM,WAAW,GAAGD,QAAQlQ,IAAI,CAACgQ,QAAQ1Q,EAAE;QACzD6Q,WAAWH,QAAQ/L,KAAK;IAC1B;IACA,IAAIiM,QAAQxQ,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASsK;QACX;IACF;IACA,OAAO3K;AACT;AAEA,MAAM6K,gBAAgB,IAAIhR,IAAI;IAAC;IAAS;IAAY;CAAW;AAE/D;;;;;CAKC,GACD,OAAO,SAASiR,kBACdpR,IAAoB,EACpByJ,UAAwB;IAExB,IAAIA,eAAe,SAAS,OAAO,EAAE;IACrC,MAAM4H,QAAkB,EAAE;IAC1B,KAAK,MAAM,EAAEhR,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;YACDU;QAAxC,KAAK,MAAM,CAACmC,KAAKoI,IAAI,IAAI9L,OAAOkF,OAAO,EAAC3D,WAAAA,KAAKwK,EAAE,YAAPxK,WAAW,CAAC,GAAI;YACtD,IAAI,CAACyQ,cAActQ,GAAG,CAACgC,MAAM;YAC7B,KAAK,MAAMjD,SAASiL,SAASI,KAAM;gBACjC,0DAA0D;gBAC1D,IACE,AAAC,OAAOrL,UAAU,YAAYA,QAAQ,KACrC,OAAOA,UAAU,YAAY2K,iBAAiB/I,IAAI,CAAC5B,QACpD;oBACAyR,MAAMtQ,IAAI,CAACV;gBACb;YACF;QACF;IACF;IACA,OAAOgR,MAAM5Q,MAAM,GACf;QACE;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASjF,OAAO2P;QAClB;KACD,GACD,EAAE;AACR;AAEA,MAAMC,OAAO;AACb,4EAA4E,GAC5E,MAAMC,uBAAuB;IAAC;IAAa;IAAQ;IAAW;IAAc;IAAiB;CAAU;AACvG,yGAAyG,GACzG,MAAMC,iBAAiB;IAAC;IAAQ;IAAW;CAAgB;AAC3D,sEAAsE,GACtE,MAAMC,sBAAsB;IAAC;IAAO;CAAc;AAClD,6FAA6F,GAC7F,MAAMC,wBAAwB;AAC9B,oGAAoG,GACpG,MAAMC,qBAAqB,IAAIxR,IAAI;IAAC;IAAU;CAAW;AACzD,0FAA0F,GAC1F,MAAMyR,mBAAmB;IAAC;IAAO;CAAY;AAC7C,mEAAmE,GACnE,MAAMC,uBAAuB;AAC7B,iEAAiE,GACjE,MAAMC,wBAAwB;AAE9B,4GAA4G,GAC5G,SAASC,iBAAiBnS,KAAc;QACYsE;IAAlD,MAAM8H,OAAO,OAAOpM,UAAU,WAAWA,SAASsE,kBAAAA,KAAKC,SAAS,CAACvE,kBAAfsE,kBAAyBf,OAAOvD;IAClF,MAAMoS,MAAMhG,KAAKvL,MAAM,GAAGqR,wBAAwB,GAAG9F,KAAKhK,KAAK,CAAC,GAAG8P,uBAAuB,CAAC,CAAC,GAAG9F;IAC/F,OAAO,OAAOpM,UAAU,WAAW,CAAC,UAAU,EAAEoS,IAAI,CAAC,CAAC,GAAGA;AAC3D;AAEA,2FAA2F,GAC3F,SAASC,YAAYvR,IAAoB;QAChBA;IAAvB,MAAMwR,UAAU5S,QAAOoB,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,UAAU;IAC9C,OAAOpB,OAAO6S,SAAS,CAACD,YAAYA,UAAU,IAAIA,UAAUL;AAC9D;AAEA;;;;;;CAMC,GACD,SAASO,aAAahN,IAAa,EAAE8M,OAAe;QAKnCG;IAJf,IAAI,OAAOjN,SAAS,YAAY,OAAOA,SAAS,UAAU,OAAO;QAAEkN,WAAW;QAAOC,OAAO;IAAM;IAClG,MAAMF,OAAO1V,oBAAoByI;IACjC,IAAIiN,KAAKpH,GAAG,KAAKzF,WAAW,OAAO;QAAE8M,WAAW;QAAOC,OAAO;IAAM;IACpE,IAAIF,KAAKG,IAAI,KAAKhN,WAAW,OAAO;QAAE8M,WAAWD,KAAKG,IAAI,KAAKN;QAASK,OAAO;IAAM;IACrF,MAAM5Q,UAAS0Q,eAAAA,KAAK1Q,MAAM,YAAX0Q,eAAe,CAAC;IAC/B,OAAO;QACLC,WAAW3Q,OAAO8Q,EAAE,KAAKP;QACzBK,OAAOpT,OAAOkF,OAAO,CAAC1C,QAAQF,IAAI,CAAC,CAAC,CAACiR,YAAY9S,MAAM,GAAK8S,eAAe,QAAQ9S,UAAUsS;IAC/F;AACF;AAEA,oGAAoG,GACpG,SAASS,gBAAgBC,KAAa,EAAEV,OAAe;IACrD,MAAMW,SAAShG,KAAKiG,GAAG,CAACjG,KAAKkG,GAAG,CAACH,OAAO,IAAI;IAC5C,MAAMI,KAAKnG,KAAKkG,GAAG,CAAC,GAAGlG,KAAKoG,KAAK,CAACf,UAAWU,CAAAA,QAAQ,IAAI,IAAIC,MAAK;IAClE,MAAMK,KAAKrG,KAAKoG,KAAK,CAACf,UAAU;IAChC,OAAOU,SAAS,KAAKM,OAAOF,KAAK,CAAC,GAAG,EAAEd,QAAQ,IAAI,EAAEgB,GAAG,IAAI,EAAEF,IAAI,GAAG,CAAC,GAAG,EAAEd,QAAQ,IAAI,EAAEc,IAAI;AAC/F;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CC,GACD,OAAO,SAASG,wBACdnT,IAAoB,EACpByJ,UAAwB,EACxBiF,UAAmC,IAAMlJ,SAAS;IAElD,IAAIiE,eAAe,WAAWA,eAAe,QAAQ,OAAO,EAAE;IAC9D,mEAAmE;IACnE,IAAI2J,SAA4B;IAChC,MAAM9Q,UAAU,CAACjC,KAAmC,CAAC+S,iBAAAA,SAAAA,SAAW/Q,YAAYrC,OAAOsC,OAAO,CAACiB,GAAG,CAAClD;IAC/F,MAAMyE,aAAa,CAACzE;;YAA0BL;eAAD,UAACA,iBAAAA,KAAKY,KAAK,CAACP,GAAG,qBAAdL,eAAgBY,KAAK,mBAAI,EAAE,EAAEwC,MAAM,CAAC,CAACC,QAAUrD,KAAKY,KAAK,CAACyC,MAAM;;IAC9G,MAAMgQ,SAAS,CAAChT;YAAwDL;eAApBK,OAAOmF,aAAaxF,EAAAA,iBAAAA,KAAKY,KAAK,CAACP,GAAG,qBAAdL,eAAgBmB,WAAW,MAAKmQ;;IACxG,MAAMgC,cAAc,CAACjT;YACLL;eAAdqT,OAAOhT,OAAOL,EAAAA,uBAAAA,KAAKY,KAAK,CAACP,GAAa,CAACgB,KAAK,qBAA9BrB,oBAAgC,CAAC,YAAY,MAAK;;IAClE,MAAMuT,UAAU,CAAClT;YAAsCL;eAAdqT,OAAOhT,OAAOL,EAAAA,uBAAAA,KAAKY,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAApBrB,oBAAsB,CAAC,OAAO,MAAKwF;;IAC1F,MAAMgO,cAAc,CAACnT,IAAYoG;QAC/B,MAAM/F,OAAOgO,QAAQrO;QACrB,OAAOV,SAASe,SAASf,SAASe,IAAI,CAAC,QAAQ,IAAIA,IAAI,CAAC,QAAQ,CAAC+F,KAAK,GAAGjB;IAC3E;IACA,8FAA8F,GAC9F,MAAMiO,kBAAkB,CAACpT;YAEhBL;QADP,MAAMJ,QAAQ4T,YAAYnT,IAAI;QAC9B,OAAOL,EAAAA,uBAAAA,KAAKY,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAApBrB,oBAAsB,CAAC,YAAY,MAAKwF,aAAa5F,UAAU,OAAOA,QAAQ4F;IACvF;IACA,iGAAiG,GACjG,MAAMkO,aAAa,CAACrT;QAClB,MAAMW,WAAW8D,WAAWzE;QAC5B,OAAOsR,mBAAmB9Q,GAAG,CAACb,KAAKY,KAAK,CAACP,GAAG,CAACc,WAAW,KAAKH,SAASP,MAAM,GAAG,KAAKO,SAASyD,KAAK,CAAC8O;IACrG;IACA,4FAA4F,GAC5F,MAAMI,gBAAgB,CAACtT;QACrB,MAAMuT,YAAYJ,YAAYnT,IAAI;QAClC,OAAO,OAAOuT,cAAc,YAAYlC,sBAAsBlQ,IAAI,CAACoS,UAAU3K,IAAI;IACnF;IACA,iGAAiG,GACjG,MAAM4K,aAAa,CAACxT,IAAYW;YACMhB;eAApCyR,oBAAoBvI,QAAQ,CAAC/F,QAAOnD,uBAAAA,KAAKY,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAApBrB,oBAAsB,CAAC,YAAY,MACvEwR,eAAe/P,IAAI,CAAC,CAACgF;gBAASzG;mBAAAA,EAAAA,uBAAAA,KAAKY,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAApBrB,oBAAsB,CAACyG,KAAK,MAAKjB;cAC9DxE,SAASP,MAAM,IAAI,KAAK,IAAIN,IAAIa,SAAS3B,GAAG,CAACiD,UAAU8C,IAAI,KAAK;;IAEnE,MAAM0O,UAAU,IAAI3T;IACpB,MAAM4T,OAAiB,EAAE;IACzB,MAAMC,SAAiD,EAAE;IACzD,MAAMC,UAAiD,EAAE;IACzD,MAAMC,QAA+C,EAAE;IACvD,MAAMC,UAAoB,EAAE;IAC5B,MAAMC,YAAsB,EAAE;IAC9B,MAAMC,SAAkD,EAAE;IAC1D,KAAK,MAAM9S,SAASxB,SAASC,MAAO;YAkDvBU;YA5CGA,aAGVA;QARJ,MAAM,EAAEL,EAAE,EAAEK,IAAI,EAAE,GAAGa;QACrB,IAAIb,KAAKS,WAAW,KAAKmQ,MAAM;QAC/B,MAAMtQ,WAAW8D,WAAWzE;QAC5B,MAAM,CAAC8F,UAAUmO,cAAc,GAAG;eAAI/S,MAAMf,SAAS;SAAC,CAAC+F,OAAO;QAC9D,MAAMd,SAASU,aAAaX,YAAYA,YAAYxF,KAAKY,KAAK,CAACuF,SAAS;QACxE,MAAMoO,QAAQ7T,EAAAA,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,OAAO,MAAK8E;QACvC,0FAA0F;QAC1F,MAAMgP,cAAcD,SAASpO,aAAaX,aAAakO,WAAWvN,aAAamN,YAAYgB;QAC3F,IAAI5T,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,YAAY,MAAK,MAAM;YACtC,MAAM+T,aAAazT,SAASS,IAAI,CAAC8R;YACjC,kGAAkG;YAClG,MAAMmB,SACJvO,aAAaX,aACb6N,OAAOlN,aACNmN,CAAAA,YAAYnN,aACXrB,WAAWqB,UAAU1E,IAAI,CAAC8R,YACzBO,QAAQjT,GAAG,CAACsF,aAAasN,gBAAgBtN,cAAcX,SAAS;YACrE,MAAMmP,qBAAqBpD,qBAAqB9P,IAAI,CAAC,CAACgF;oBAAS/F;uBAAAA,EAAAA,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC+F,KAAK,MAAKjB;;YACtF,IAAI,CAACiP,cAAc,CAACE,sBAAuBD,CAAAA,UAAU1T,SAASP,MAAM,GAAG,CAAA,KAAM,CAAC+T,aAAa;YAC3FV,QAAQhT,GAAG,CAACT;YACZ,MAAM2L,OAAOyH,gBAAgBpT;YAC7B,IAAI2L,SAASxG,WAAW0O,MAAMnT,IAAI,CAAC;gBAAEV;gBAAIT,OAAOoM;YAAK;iBAChD,IAAIyI,YAAYV,KAAKhT,IAAI,CAACV;iBAC1B,IAAIkU,SAAS9O,UAAUA,OAAOtE,WAAW,KAAKmQ,MAAM2C,QAAQlT,IAAI,CAAC;gBAAEV;gBAAIuU,QAAQnP,OAAOtE,WAAW;YAAC;iBAClG,IAAIwS,cAActT,KAAK2T,OAAOjT,IAAI,CAAC;gBAAEV;gBAAIwU,QAAQ;YAAK;iBACtD,IAAIhB,WAAWxT,IAAIW,WAAW+S,KAAKhT,IAAI,CAACV;iBACxC2T,OAAOjT,IAAI,CAAC;gBAAEV;gBAAIwU,QAAQ;YAAM;YACrC;QACF;QACA,IAAIL,eAAe/O,QAAQwO,QAAQlT,IAAI,CAAC;YAAEV;YAAIuU,QAAQnP,OAAOtE,WAAW;QAAC;QACzE,MAAM+Q,UAAUD,YAAYvR;QAC5B,4FAA4F;QAC5F,MAAMkS,QAAQ5R,SAASuD,OAAO,CAAC,CAAClB,QAAWqQ,WAAWrQ,SAASyB,WAAWzB,SAAS;gBAACA;aAAM;QAC1F,IAAIkP,QAAQ;QACZ,MAAMuC,YAAsB,EAAE;QAC9B,KAAK,MAAMzR,SAASuP,MAAO;gBAE6BmC;YADtD,MAAMA,OAAO/U,KAAKY,KAAK,CAACyC,MAAM;YAC9B,MAAMgP,OAAO0C,KAAK5T,WAAW,KAAKmQ,OAAOc,cAAa2C,cAAAA,KAAK1T,KAAK,qBAAV0T,WAAY,CAAC,OAAO,EAAE7C,WAAW;YACvF,IAAI,EAACG,wBAAAA,KAAMC,SAAS,GAAEwC,UAAU/T,IAAI,CAACsC;YACrC,IAAIgP,wBAAAA,KAAME,KAAK,EAAEA,QAAQ;QAC3B;QACA,IAAIuC,UAAUrU,MAAM,EAAE;YACpB0T,QAAQpT,IAAI,IAAI+T;QAClB,OAAO,IAAIlC,MAAMnS,MAAM,IAAI,KAAK,CAAC8R,OAAO;YACtC4B,QAAQpT,IAAI,IAAI6R;QAClB;QACA,IAAIkC,UAAUrU,MAAM,IAAKmS,MAAMnS,MAAM,IAAI,KAAK,CAAC8R,OAAQ;YACrD6B,UAAUrT,IAAI,CAAC4R,gBAAgBC,MAAMnS,MAAM,EAAEyR;QAC/C;QACA,MAAMhH,MAAKxK,WAAAA,KAAKwK,EAAE,YAAPxK,WAAW,CAAC;QACvB,MAAMsU,MAAMpD,iBAAiBxL,IAAI,CAAC,CAACvD,MAAQqI,EAAE,CAACrI,IAAI,KAAK2C;QACvD,IAAIwP,KAAKX,OAAOtT,IAAI,CAAC;YAAEV;YAAI4U,SAAS/J,EAAE,CAAC8J,IAAI;QAAC;IAC9C;IACA,MAAM1O,aAAoC,EAAE;IAC5C,IAAIyN,KAAKtT,MAAM,EAAE;QACf6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASjF,OAAOqS;QAClB;IACF;IACA,IAAIC,OAAOvT,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GACPsU,MAAM,CAAC,EAAE,CAACa,MAAM,GACZ,+FACA,0FACL,sNAAsN,CAAC;YACxNlO,SAASjF,OAAOsS,OAAO3U,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAChD;IACF;IACA,IAAI4T,QAAQxT,MAAM,EAAE;QAClB,MAAMmU,SAAS1T,YAAY+S,OAAO,CAAC,EAAE,CAACW,MAAM;QAC5CtO,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,4FAA4F,EAAEkV,OAAO,qLAAqL,CAAC;YACrSjO,SAASjF,OAAOuS,QAAQ5U,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QACjD;IACF;IACA,IAAI6T,MAAMzT,MAAM,EAAE;QAChB,MAAM,CAACuF,MAAM,GAAGkO;QAChB5N,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,2BAA2B,EAAEqS,iBAAiB/L,MAAMpG,KAAK,EAAE,qGAAqG,EACxK,OAAOoG,MAAMpG,KAAK,KAAK,WAAW,iCAAiC,GACpE,CAAC,CAAC;YACH+G,SAASjF,OAAOwS,MAAM7U,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAC/C;IACF;IACA,IAAI8T,QAAQ1T,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,sKAAsK,EAAE0U,SAAS,CAAC,EAAE,CAAC,8CAA8C,CAAC;YAC9OzN,SAASjF,OAAOyS;QAClB;IACF;IACA,IAAIE,OAAO5T,MAAM,EAAE;QACjB,MAAM,CAACuF,MAAM,GAAGqO;QAChB,MAAMY,UAAU,OAAOjP,MAAMiP,OAAO,KAAK,WAAWjP,MAAMiP,OAAO,GAAG;QACpE3O,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,qJAAqJ,EAAEuV,QAAQ,CAAC,CAAC;YAC3KtO,SAAS0N,OAAOhV,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QACzC;IACF;IACA,OAAOiG;AACT;AAEA,kFAAkF,GAClF,MAAM4O,wBAAwB;IAAC;IAAM;IAAM;IAAM;IAAM;CAAK;AAE5D;;;;CAIC,GACD,SAASC,oBAAoB/P,IAAa;IACxC,IAAI,CAACzF,SAASyF,OAAO,OAAO;IAC5B,MAAMgQ,QAAkB,EAAE;IAC1B,KAAK,MAAM,CAAC1C,YAAY9S,MAAM,IAAIT,OAAOkF,OAAO,CAACe,MAAO;QACtD,MAAMiN,OAAO,OAAOzS,UAAU,YAAYA,MAAMqJ,IAAI,OAAO,KAAK3J,OAAOM,SAASA;QAChF,IAAI,CAACsV,sBAAsBhM,QAAQ,CAACwJ,eAAe,OAAOL,SAAS,YAAY,CAAC/S,OAAO6S,SAAS,CAACE,OAAO,OAAO;QAC/G+C,MAAMrU,IAAI,CAAC,GAAG2R,WAAW,CAAC,EAAEL,MAAM;IACpC;IACA+C,MAAMxS,IAAI,CAAC,CAACoK,GAAGZ,IAAM8I,sBAAsBG,OAAO,CAACrI,EAAElE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAIoM,sBAAsBG,OAAO,CAACjJ,EAAEtD,KAAK,CAAC,IAAI,CAAC,EAAE;IACnH,OAAOsM,MAAM3U,MAAM,GAAG2U,MAAMrT,IAAI,CAAC,OAAO;AAC1C;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCC,GACD,OAAO,SAASuT,kBACdtV,IAAO,EACPuV,UAAwE,CAAC,CAAC;QAE1DA,kBACDA;IADf,MAAM7G,WAAU6G,mBAAAA,QAAQ7G,OAAO,YAAf6G,mBAAoB,IAAM/P;IAC1C,MAAMgQ,UAASD,kBAAAA,QAAQC,MAAM,YAAdD,kBAAkBhZ;IACjC,MAAMqE,QAAwC,aAAKZ,KAAKY,KAAK;IAC7D,MAAM6U,SAAS,IAAItV;IACnB,MAAMuV,OAAO,CAACrV;QACZ,IAAI,CAACoV,OAAO5U,GAAG,CAACR,KAAK;YACnB,MAAMK,OAAOE,KAAK,CAACP,GAAG;YACtBO,KAAK,CAACP,GAAG,GAAG,aAAKK;gBAAMW,OAAO,aAAKX,KAAKW,KAAK;eAAQX,KAAKE,KAAK,GAAG;gBAAEA,OAAO;uBAAIF,KAAKE,KAAK;iBAAC;YAAC,IAAI,CAAC;YAChG6U,OAAO3U,GAAG,CAACT;QACb;QACA,OAAOO,KAAK,CAACP,GAAG;IAClB;IACA,MAAMsV,UAAU,CAACtV,IAAY+E;YACvBxE;QAAJ,IAAIA,EAAAA,kBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAAfT,eAAiB,CAAC,OAAO,MAAKwE,MAAM;QACtCsQ,KAAKrV,IAAIgB,KAAK,AAA4B,CAAC,OAAO,GAAG+D;IACzD;IACA,MAAMoO,cAAc,CAACnT,IAAYoG;QAC/B,MAAM/F,OAAOgO,QAAQrO;QACrB,OAAOV,SAASe,SAASf,SAASe,IAAI,CAAC,QAAQ,IAAIA,IAAI,CAAC,QAAQ,CAAC+F,KAAK,GAAGjB;IAC3E;IACA,MAAMV,aAAa,CAACzE;;YAA0BO;eAAD,UAACA,YAAAA,KAAK,CAACP,GAAG,qBAATO,UAAWA,KAAK,mBAAI,EAAE,EAAEwC,MAAM,CAAC,CAACC,QAAUzC,KAAK,CAACyC,MAAM;;IACpG,MAAMkQ,UAAU,CAAClT;YAAwBO,WAAmCA;eAAnCA,EAAAA,YAAAA,KAAK,CAACP,GAAG,qBAATO,UAAWO,WAAW,MAAKmQ,QAAQ1Q,EAAAA,kBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAAfT,eAAiB,CAAC,OAAO,MAAK4E;;IAC1G,MAAMkO,aAAa,CAACrT;QAClB,MAAMW,WAAW8D,WAAWzE;QAC5B,OAAOsR,mBAAmB9Q,GAAG,CAACD,KAAK,CAACP,GAAG,CAACc,WAAW,KAAKH,SAASP,MAAM,GAAG,KAAKO,SAASyD,KAAK,CAAC8O;IAChG;IAEA,KAAK,MAAM,EAAElT,EAAE,EAAE,IAAIN,SAASC,MAAO;YAE/BY;QADJ,IAAIA,KAAK,CAACP,GAAG,CAACc,WAAW,KAAKmQ,MAAM;QACpC,IAAI1Q,EAAAA,kBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAAfT,eAAiB,CAAC,YAAY,MAAK,MAAM;gBAE/BA;YADZ,4FAA4F;YAC5F,MAAMgV,OAAMhV,mBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAAfT,gBAAiB,CAAC,YAAY;YAC1C,MAAMoL,OAAO4J,QAAQpQ,YAAYgO,YAAYnT,IAAI,eAAeuV;YAChE,IAAI,OAAO5J,SAAS,YAAYA,KAAK/C,IAAI,GAAGD,WAAW,OAAO,QAAQ;YACpE0M,KAAKrV,IAAIgB,KAAK,AAA4B,CAAC,YAAY,GAAG;QAC9D;QACA,MAAMwU,YAAYjV,KAAK,CAACP,GAAG;QAC3B,MAAM6R,UAAUD,YAAY4D;QAC5B,MAAM7U,WAAW8D,WAAWzE;QAC5B,MAAMuS,QAAQ5R,SAASuD,OAAO,CAAC,CAAClB,QAAWqQ,WAAWrQ,SAASyB,WAAWzB,SAAS;gBAACA;aAAM;QAC1F,IAAI,CAACuP,MAAMnS,MAAM,EAAE;QACnB,MAAM2E,OAAOuN,gBAAgBC,MAAMnS,MAAM,EAAEyR;QAC3C,MAAM4D,eAAyB,EAAE;QACjC,KAAK,MAAMf,QAAQnC,MAAO;gBAqBNhS;YApBlB,IAAIA,KAAK,CAACmU,KAAK,CAAC5T,WAAW,KAAKmQ,MAAM;oBAItByE;gBAHd,6EAA6E;gBAC7E,MAAMC,YAAYR;gBAClB,MAAMO,OAAOL,KAAKrV;gBAClB0V,KAAKnV,KAAK,GAAG,EAACmV,cAAAA,KAAKnV,KAAK,YAAVmV,cAAc,EAAE,EAAE1W,GAAG,CAAC,CAACgE,QAAWA,UAAU0R,OAAOiB,YAAY3S;gBAC7E,MAAMY,QAAQ4R;gBACdjV,KAAK,CAACoV,UAAU,GAAG,aACb,SAAS/R,QAAQ;oBAAEgS,KAAKD;gBAAU,IAAI,CAAC,GACvC,UAAU/R,QAAQ;oBAAEf,MAAMe,KAAK,CAAC,OAAO;gBAAC,IAAI,CAAC;oBACjD9C,aAAamQ;mBACT,cAAcrN,QAAQ;oBAAEiS,UAAUjS,KAAK,CAAC,WAAW;gBAAC,IAAI,CAAC,GACzD,cAAcA,QAAQ;oBAAEkC,UAAU9F;gBAAG,IAAI,CAAC;oBAC9CO,OAAO;wBAACmU;qBAAK;oBACb1T,OAAO;wBAAE+D;oBAAK;;gBAEhBqQ,OAAO3U,GAAG,CAACkV;gBACX,IAAI,cAAepV,KAAK,CAACmU,KAAK,EAAyCW,KAAKX,KAAK,CAAC,WAAW,GAAGiB;gBAChGF,aAAa/U,IAAI,CAACiV;gBAClB;YACF;YACA,IAAI,CAAC5D,cAAaxR,oBAAAA,KAAK,CAACmU,KAAK,CAAC1T,KAAK,qBAAjBT,iBAAmB,CAAC,OAAO,EAAEsR,SAASI,SAAS,EAAE;oBACjCkB;oBAA6B5S;gBAA7D,MAAMgV,MAAMT,qBAAoB3B,eAAAA,YAAYuB,MAAM,mBAAlBvB,gBAA6B5S,qBAAAA,KAAK,CAACmU,KAAK,CAAC1T,KAAK,qBAAjBT,kBAAmB,CAAC,OAAO;gBACxF+U,QAAQZ,MAAMa,QAAQ,QAAQxD,aAAawD,KAAK1D,SAASI,SAAS,GAAGsD,MAAMxQ;YAC7E;YACA0Q,aAAa/U,IAAI,CAACgU;QACpB;QACA,MAAMxC,QAAQuD,aAAarU,IAAI,CAAC,CAACsT;gBAAsBnU;mBAAbwR,cAAaxR,oBAAAA,KAAK,CAACmU,KAAK,CAAC1T,KAAK,qBAAjBT,iBAAmB,CAAC,OAAO,EAAEsR,SAASK,KAAK;;QAClG,IAAIuD,aAAarV,MAAM,IAAI,KAAK,CAAC8R,OAAO,KAAK,MAAMwC,QAAQe,aAAcH,QAAQZ,MAAM3P;IACzF;IACA,OAAOqQ,OAAOrQ,IAAI,GAAI,aAAKpF;QAAMY;SAAgBZ;AACnD;AAEA;;;;;CAKC,GACD,OAAO,SAASmW,yBAAyB5I,KAAc;IACrD,IAAI,CAAC5N,SAAS4N,UAAU,OAAOA,KAAK,CAAC,SAAS,KAAK,YAAY,CAAC5N,SAAS4N,KAAK,CAAC,QAAQ,GAAG,OAAOA;IACjG,MAAM3M,QAAQzB,OAAOiX,WAAW,CAACjX,OAAOkF,OAAO,CAACkJ,KAAK,CAAC,QAAQ,EAAEnK,MAAM,CAAC,CAAC,GAAG1C,KAAK,GAAKf,SAASe;IAC9F,MAAMV,OAAO;QAAEM,QAAQiN,KAAK,CAAC,SAAS;QAAE3M,OAAOA;IAAmD;IAClG,MAAMoN,UAAUsH,kBAAkBtV;IAClC,OAAOgO,YAAYhO,OAAOuN,QAAQ,aAAKA;QAAO3M,OAAO,aAAK2M,KAAK,CAAC,QAAQ,EAAKS,QAAQpN,KAAK;;AAC5F;AAEA,kFAAkF,GAClF,MAAMyV,sBAAsB,IAAIlW,IAAI;IAAC;IAAW;IAAa;IAAW;IAAS;IAAQ;CAAU;AACnG,+FAA+F,GAC/F,MAAMmW,kBAAkB,IAAInW,IAAI;IAAC;IAAa;CAAgB;AAE9D,yFAAyF,GACzF,OAAO,SAASoW,gBAAgBpV,WAAoB;IAClD,OAAO,OAAOA,gBAAgB,YAAYmV,gBAAgBzV,GAAG,CAACM;AAChE;AAEA,yEAAyE,GACzE,MAAMqV,mBAAmB,IAAIrW,IAAI;IAAC;IAAW;IAAY;IAAgB;CAAY;AACrF,8EAA8E,GAC9E,MAAMsW,eAAe;AAErB,0DAA0D,GAC1D,SAASC,SAAS9W,KAAc;QACa6W;IAA3C,MAAM7K,SAAS,OAAOhM,UAAU,YAAW6W,qBAAAA,aAAaxK,IAAI,CAACrM,MAAMqJ,IAAI,wBAA5BwN,kBAAiC,CAAC,EAAE,GAAGjR;IAClF,OAAOoG,UAAUyK,oBAAoBxV,GAAG,CAAC+K,UAAUA,SAAS;AAC9D;AAEA;;;;;CAKC,GACD,SAAS+K,OAAO3W,IAAoB,EAAEuB,KAAY;IAChD,KAAK,MAAMlB,MAAM;WAAIkB,MAAMf,SAAS;KAAC,CAAC+F,OAAO,GAAI;;YAG5B7F,UAAwBA;QAF3C,MAAMA,OAAOV,KAAKY,KAAK,CAACP,GAAG;QAC3B,IAAI,CAACK,MAAM;QACX,MAAMuO,sBAAavO,WAAAA,KAAKwK,EAAE,qBAAPxK,QAAS,CAAC,UAAU,oBAAIA,YAAAA,KAAKwK,EAAE,qBAAPxK,SAAS,CAAC,kBAAkB;QACvE,IAAIuO,eAAezJ,WAAW;YAC5B,MAAMoR,QAAQ/L,SAASoE,YAAY7I,IAAI,CAAC,CAACxG,QAAU8W,SAAS9W,WAAW;YACvE,OAAO,OAAOgX,UAAU,WAAW;gBAAEhL,QAAQ8K,SAASE;gBAAkBA,OAAOA,MAAM3N,IAAI;YAAG,IAAI;QAClG;QACA,IAAIvI,KAAKS,WAAW,KAAK,aAAa;gBACfT;YAArB,MAAMoO,QAAQ,SAAOpO,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,QAAQ,MAAK,WAAWA,KAAKW,KAAK,CAAC,QAAQ,GAAG;YAChF,OAAOgV,oBAAoBxV,GAAG,CAACiO,SAAS;gBAAElD,QAAQkD;gBAAO8H,OAAO,GAAG9H,MAAM,KAAK,CAAC;YAAC,IAAI;QACtF;QACA,IAAI0H,iBAAiB3V,GAAG,CAACH,KAAKS,WAAW,GAAG,OAAO;IACrD;IACA,OAAO;AACT;AAEA;;;;;CAKC,GACD,SAAS0V,gBAAgBnW,IAAoB;QAC/BA,UAISA,aAEsCA,cAClCA;IAPzB,MAAMkV,OAAMlV,WAAAA,KAAKwK,EAAE,qBAAPxK,QAAS,CAAC,QAAQ;IAC9B,IAAIkV,QAAQpQ,WAAW;YACdqF;QAAP,QAAOA,qBAAAA,SAAS+K,KAAKvW,GAAG,CAACqX,UAAUtQ,IAAI,CAAC,CAACwF,SAAWA,WAAW,iBAAxDf,qBAAiE;IAC1E;IACA,MAAMiE,QAAQ,SAAOpO,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,QAAQ,MAAK,WAAWA,KAAKW,KAAK,CAAC,QAAQ,GAAG;IAChF,IAAI,CAACgV,oBAAoBxV,GAAG,CAACiO,QAAQ,OAAO;IAC5C,MAAMgI,iBAAiBpW,KAAKS,WAAW,KAAK,eAAeT,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,WAAW,MAAK;IACxF,OAAOoW,kBAAkBpW,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,cAAc,OAAOoO;AAC5E;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASiI,qBAAqB/W,IAAoB,EAAEyJ,UAAwB;IACjF,IAAIA,eAAe,WAAWA,eAAe,QAAQ,OAAO,EAAE;IAC9D,MAAMuN,SAA+D,EAAE;IACvE,KAAK,MAAMzV,SAASxB,SAASC,MAAO;QAClC,IAAI,CAACsW,gBAAgBzV,GAAG,CAACU,MAAMb,IAAI,CAACS,WAAW,GAAG;QAClD,MAAMyK,SAASiL,gBAAgBtV,MAAMb,IAAI;QACzC,MAAMuW,OAAOrL,SAAS+K,OAAO3W,MAAMuB,SAAS;QAC5C,IAAI0V,QAAQA,KAAKrL,MAAM,KAAKA,QAAQoL,OAAOjW,IAAI,CAAC;YAAEV,IAAIkB,MAAMlB,EAAE;WAAK4W;IACrE;IACA,IAAI,CAACD,OAAOvW,MAAM,EAAE,OAAO,EAAE;IAC7B,MAAM,CAACuF,MAAM,GAAGgR;IAChB,OAAO;QACL;YACEvX,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,sBAAsB,EAAEsG,MAAM4Q,KAAK,CAAC,qCAAqC,EAAE5Q,MAAM4F,MAAM,CAAC,0GAA0G,EAAE5F,MAAM4F,MAAM,CAAC,0CAA0C,EAAE5F,MAAM4F,MAAM,CAAC,cAAc,CAAC;YACnSjF,SAASjF,OAAOsV,OAAO3X,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAChD;KACD;AACH;AAEA,0CAA0C,GAC1C,MAAM6W,aAAa;AAEnB,sEAAsE,GACtE,MAAMC,aAAa,CAACC,QAAkBA,MAAMpO,WAAW,GAAGF,KAAK,CAAC,8maAAmB1F,MAAM,CAACJ,SAASjB,IAAI,CAAC;AAExG,6EAA6E,GAC7E,MAAMsV,qBACJ;AAEF;;;;CAIC,GACD,OAAO,SAASC,mBAAmBF,KAAa;IAC9C,OAAOC,mBAAmB7V,IAAI,CAAC4V;AACjC;AAEA;;;;CAIC,GACD,SAASG,qBACPvX,IAAoB,EACpByJ,UAAwB,EACxB5D,OAAsF;QAGjEA,wBACCA,wBACMA;IAH5B,IAAI4D,eAAe,WAAWA,eAAe,QAAQ,OAAO,EAAE;IAC9D,MAAM+N,OAAO,IAAIrX,KAAI0F,yBAAAA,QAAQ4R,aAAa,YAArB5R,yBAAyB,EAAE;IAChD,MAAM6R,QAAQ,IAAIvX,KAAI0F,yBAAAA,QAAQ8R,aAAa,YAArB9R,yBAAyB,EAAE;IACjD,MAAM+R,aAAa,IAAIzX,IAAI,EAAC0F,sBAAAA,QAAQ+R,UAAU,YAAlB/R,sBAAsB,EAAE,EAAExG,GAAG,CAAC8X,YAAY/T,MAAM,CAACJ;IAC7E,MAAM6U,OAA6C,EAAE;IACrD,KAAK,MAAMtW,SAASxB,SAASC,MAAO;YAGjBU,aACyDA,cACrDA;QAJrB,MAAM,EAAEA,IAAI,EAAE,GAAGa;QACjB,IAAI,CAAC+U,gBAAgBzV,GAAG,CAACH,KAAKS,WAAW,GAAG;QAC5C,MAAM2W,YAAWpX,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,WAAW;QACzC,MAAMqX,YAAY,AAAC,OAAOD,aAAa,YAAYN,KAAK3W,GAAG,CAACiX,aAAcpX,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,OAAO,MAAK;QACnG,MAAM0W,QAAQ,SAAO1W,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,WAAW,MAAK,WAAWA,KAAKW,KAAK,CAAC,WAAW,CAAC4H,IAAI,KAAK;QAC7F,IAAI,CAAC8O,aAAa,CAACX,SAASF,WAAW1V,IAAI,CAAC4V,UAAUQ,WAAW/W,GAAG,CAACsW,WAAWC,SAAS;QACzF,6EAA6E;QAC7E,IAAI,OAAOU,aAAa,YAAYJ,MAAM7W,GAAG,CAACiX,aAAaR,mBAAmBF,QAAQ;QACtF,+EAA+E;QAC/E,MAAMY,eAAe1W,YACnBtB,MACAuB,OACA,CAACmD,WAAaA,SAASvD,WAAW,KAAK,eAAe;gBAAC;gBAAU;aAAM,CAAC+H,QAAQ,CAAC9H,UAAUsD;QAE7F,IAAI,CAACsT,cAAcH,KAAK9W,IAAI,CAAC;YAAEV,IAAIkB,MAAMlB,EAAE;YAAE+W;QAAM;IACrD;IACA,OAAOS;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;;CAsBC,GACD,OAAO,SAASI,6BACdjY,IAAO,EACPyJ,UAAwB,EACxB5D,UAGI,CAAC,CAAC;QAIcA,uBACD,OAACA;IAHpB,MAAMgS,OAAON,qBAAqBvX,MAAMyJ,YAAY5D;IACpD,IAAI,CAACgS,KAAKpX,MAAM,EAAE,OAAOT;IACzB,MAAM4V,MAAM,IAAIzV,KAAI0F,wBAAAA,QAAQqS,YAAY,YAApBrS,wBAAwB,EAAE;IAC9C,MAAMsS,cAAa,QAAA,EAACtS,yBAAAA,QAAQ8R,aAAa,YAArB9R,yBAAyB,EAAE,EAAEO,IAAI,CAAC,CAAC/F,KAAO,CAACuV,IAAI/U,GAAG,CAACR,gBAApD,QAA4D;IAC/E,MAAMO,QAAwC,aAAKZ,KAAKY,KAAK;IAC7D,MAAMwX,UAAU,IAAI7V;IACpB,KAAK,MAAMhB,SAASxB,SAASC,MAAO;QAClC,MAAMyF,SAASlE,MAAMf,SAAS,CAACe,MAAMf,SAAS,CAACC,MAAM,GAAG,EAAE;QAC1D,IAAIgF,WAAWD,WAAW4S,QAAQ9U,GAAG,CAAC/B,MAAMlB,EAAE,EAAEoF;IAClD;IACA,KAAK,MAAM,EAAEpF,EAAE,EAAE+W,KAAK,EAAE,IAAIS,KAAM;YAUYjX;QAT5C,IAAI,CAACA,KAAK,CAACP,GAAG,EAAE;QAChB,IAAI8X,cAAcb,mBAAmBF,QAAQ;gBACExW;YAA7C,MAAMS,QAAiC,cAAMT,kBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,YAAfT,kBAAmB,CAAC;gBAAIkX,UAAUK;;YAC/E,OAAO9W,KAAK,CAAC,OAAO;YACpBT,KAAK,CAACP,GAAG,GAAG,aAAKO,KAAK,CAACP,GAAG;gBAAEgB;;YAC5B;QACF;QACA,MAAMoE,SAAS2S,QAAQ7U,GAAG,CAAClD;QAC3B,IAAIoF,WAAWD,aAAa,CAAC5E,KAAK,CAAC6E,OAAO,EAAE;QAC5C7E,KAAK,CAAC6E,OAAO,GAAG,aAAK7E,KAAK,CAAC6E,OAAO;YAAE7E,OAAO,EAACA,sBAAAA,KAAK,CAAC6E,OAAO,CAAC7E,KAAK,YAAnBA,sBAAuB,EAAE,EAAEwC,MAAM,CAAC,CAACC,QAAUA,UAAUhD;;QACnG,MAAMD,QAAQ;YAACC;SAAG;QAClB,MAAOD,MAAMK,MAAM,CAAE;;gBAEJG;YADf,MAAMyX,OAAOjY,MAAMO,GAAG;YACtBP,MAAMW,IAAI,aAAKH,cAAAA,KAAK,CAACyX,KAAK,qBAAXzX,YAAaA,KAAK,mBAAI,EAAE;YACvC,OAAOA,KAAK,CAACyX,KAAK;QACpB;IACF;IACA,OAAO,aAAKrY;QAAMY;;AACpB;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAAS0X,2BACdtY,IAAoB,EACpByJ,UAAwB,EACxB5D,UAAyF,CAAC,CAAC;IAE3F,MAAMgS,OAAON,qBAAqBvX,MAAMyJ,YAAY5D;IACpD,IAAI,CAACgS,KAAKpX,MAAM,EAAE,OAAO,EAAE;IAC3B,OAAO;QACL;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,CAAC,EAAEmY,IAAI,CAAC,EAAE,CAACT,KAAK,CAAC,mIAAmI,CAAC;YAC/JzQ,SAASjF,OAAOmW,KAAKxY,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAC9C;KACD;AACH;AAEA,gEAAgE,GAChE,SAASkY,SAAS3Y,KAAc;IAC9B,OAAO,OAAOA,UAAU,YAAYA,MAAMqJ,IAAI,OAAO;AACvD;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BC,GACD,OAAO,SAASuP,8BACdxY,IAAoB,EACpByJ,UAAwB,EACxB5D,UAA2E,CAAC,CAAC,EAC7E6I,UAAmC,IAAMlJ,SAAS,EAClDiT,SAAkC,IAAMjT,SAAS;QAGhCK,uBACOA;IAFxB,IAAI4D,eAAe,WAAWA,eAAe,QAAQ,OAAO,EAAE;IAC9D,MAAMiP,YAAW7S,wBAAAA,QAAQ8S,YAAY,YAApB9S,wBAAwB,EAAE;IAC3C,MAAM6H,UAAU,IAAIvN,KAAI0F,2BAAAA,QAAQ+S,eAAe,YAAvB/S,2BAA2B,EAAE;IACrD,MAAMgT,OAA8D,EAAE;IACtE,MAAMC,YAAiE,EAAE;IACzE,MAAMC,UAA+D,EAAE;IACvE,KAAK,MAAMxX,SAASxB,SAASC,MAAO;YAGrBU,aAAsCA,cAE9BA;QAJrB,MAAM,EAAEA,IAAI,EAAE,GAAGa;QACjB,IAAI,CAAC+U,gBAAgBzV,GAAG,CAACH,KAAKS,WAAW,GAAG;QAC5C,IAAIoX,UAAS7X,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,WAAW,KAAK6X,UAAS7X,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,OAAO,GAAG;QAC1E,IAAIjC,sBAAsBga,OAAOlX,MAAMlB,EAAE,GAAGoB,IAAI,CAAC,CAACsM,SAAWL,QAAQ7M,GAAG,CAACkN,UAAU;QACnF,MAAMqJ,QAAQ,SAAO1W,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,WAAW,MAAK,WAAWA,KAAKW,KAAK,CAAC,WAAW,CAAC4H,IAAI,KAAK;QAC7F,MAAM8E,SAASvP,iBAAiBkQ,QAAQnN,MAAMlB,EAAE,GAAGqY;QACnD,IAAI3K,CAAAA,0BAAAA,OAAQiL,IAAI,MAAK,WAAW;QAChC,IAAIjL,CAAAA,0BAAAA,OAAQiL,IAAI,MAAK,aAAajL,OAAOkL,GAAG,KAAK,QAAQ;YACvDH,UAAU/X,IAAI,CAAC;gBAAEV,IAAIkB,MAAMlB,EAAE;gBAAE+W;gBAAOxX,OAAOmO,OAAOnO,KAAK;YAAC;QAC5D,OAAO,IAAImO,CAAAA,0BAAAA,OAAQiL,IAAI,MAAK,aAAanT,QAAQ8S,YAAY,EAAE;YAC7DI,QAAQhY,IAAI,CAAC;gBAAEV,IAAIkB,MAAMlB,EAAE;gBAAE+W;gBAAOxX,OAAOmO,OAAOnO,KAAK;YAAC;QAC1D,OAAO;YACLiZ,KAAK9X,IAAI,CAAC;gBAAEV,IAAIkB,MAAMlB,EAAE;gBAAE+W;gBAAO8B,QAAQ5X,YAAYtB,MAAMuB,OAAO,CAACmD,WAAaA,SAASvD,WAAW,KAAK;YAAQ;QACnH;IACF;IACA,MAAMgY,UAAU,CAACxP,QACfA,MAAMyN,KAAK,GAAG,CAAC,CAAC,EAAEzN,MAAMyN,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAElW,YAAYlB,KAAKY,KAAK,CAAC+I,MAAMtJ,EAAE,CAAC,CAACc,WAAW,GAAG;IACzF,MAAMW,QAAQ4W,SAASrZ,GAAG,CAAC,CAACoH,OAAS,CAAC,CAAC,EAAEA,KAAK,CAAC,CAAC;IAChD,MAAM2S,SAAStX,MAAMrB,MAAM,GAAG,IAAI,GAAGqB,MAAME,KAAK,CAAC,GAAG,CAAC,GAAGD,IAAI,CAAC,MAAM,IAAI,EAAED,KAAK,CAACA,MAAMrB,MAAM,GAAG,EAAE,EAAE,GAAGqB,MAAMC,IAAI,CAAC;IAChH,MAAMsX,YAAY,CAAC,kDAAkD,EAAE9a,uBAAuB,sCAAsC,EAAE6a,OAAO,CAAC,CAAC;IAC/I,MAAM9S,aAAoC,EAAE;IAC5C,IAAIwS,UAAUrY,MAAM,EAAE;QACpB,MAAM,CAACuF,MAAM,GAAG8S;QAChBxS,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GAAGyZ,QAAQnT,OAAO,QAAQ,EAAEA,MAAMpG,KAAK,CAAC,+FAA+F,EAC9IiG,QAAQ8S,YAAY,GAChB,GAAGU,UAAU,sGAAsG,CAAC,GACpH,8KACJ;YACF1S,SAASjF,OAAOoX,UAAUzZ,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QACnD;IACF;IACA,IAAI0Y,QAAQtY,MAAM,EAAE;QAClB,MAAM,CAACuF,MAAM,GAAG+S;QAChBzS,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GAAGyZ,QAAQnT,OAAO,aAAa,EAAEA,MAAMpG,KAAK,CAAC,mDAAmD,EAAErB,uBAAuB,6CAA6C,EAAE6a,OAAO,uBAAuB,CAAC;YAChNzS,SAASjF,OAAOqX,QAAQ1Z,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QACjD;IACF;IACA,IAAIwY,KAAKpY,MAAM,EAAE;QACf,MAAM,CAACuF,MAAM,GAAG6S;QAChB,MAAMS,UAAUT,KAAKpX,IAAI,CAAC,CAACkI,QAAUA,MAAMuP,MAAM,IAC7C,gIACArT,QAAQ8S,YAAY,GAClB,CAAC,CAAC,EAAEU,UAAU,sCAAsC,CAAC,GACrD;QACN/S,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GAAGyZ,QAAQnT,OAAO,yKAAyK,EAAEsT,SAAS;YAC/M3S,SAASjF,OAAOmX,KAAKxZ,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAC9C;IACF;IACA,OAAOiG;AACT;AAEA,oEAAoE,GACpE,MAAMiT,eAAe;AAErB;;;;;CAKC,GACD,OAAO,SAASC,oBAAoBC,MAAe;IACjD,MAAMC,QAAkB,EAAE;IAC1B,MAAMnY,QAAQ,CAAC3B,OAAgB6N,MAAclN;QAC3C,IAAIA,QAAQ,MAAMmZ,MAAMjZ,MAAM,IAAI,GAAG;QACrC,IAAIZ,MAAMC,OAAO,CAACF,QAAQ;YACxBA,MAAM+Z,OAAO,CAAC,CAACC,OAAO3Y,QAAUM,MAAMqY,OAAO,GAAGnM,KAAK,CAAC,EAAExM,MAAM,CAAC,CAAC,EAAEV,QAAQ;YAC1E;QACF;QACA,IAAI,CAACZ,SAASC,QAAQ;QACtB,KAAK,MAAM,CAACiD,KAAK+W,MAAM,IAAIza,OAAOkF,OAAO,CAACzE,OAAQ;YAChD,MAAMia,OAAOpM,OAAO,GAAGA,KAAK,CAAC,EAAE5K,KAAK,GAAGA;YACvC,oEAAoE;YACpE,IAAIA,QAAQ,WAAWA,QAAQ,MAAM;YACrC,IACE0W,aAAa/X,IAAI,CAACqB,QAClB+W,UAAU,SACVA,UAAU,QACVA,UAAUpU,aACVoU,UAAU,IACV;gBACAF,MAAM3Y,IAAI,CAAC8Y;YACb,OAAO,IACLhX,QAAQ,YACR,OAAO+W,UAAU,YACjB,+BAA+BpY,IAAI,CAACoY,MAAM3Q,IAAI,KAC9C;gBACAyQ,MAAM3Y,IAAI,CAAC8Y;YACb,OAAO;gBACLtY,MAAMqY,OAAOC,MAAMtZ,QAAQ;YAC7B;QACF;IACF;IACAgB,MAAMkY,QAAQ,IAAI;IAClB,OAAOC,MAAMjZ,MAAM,GACf;QACE;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga;QACF;KACD,GACD,EAAE;AACR;AAEA,qFAAqF,GACrF,MAAMI,iBAAiB;AAEvB;;;;CAIC,GACD,OAAO,SAASC,iBAAiB7F,KAAuB;IACtD,MAAM8F,QAAQ,IAAIzX;IAClB,KAAK,MAAMyJ,QAAQkI,MAAO;QACxB,KAAK,MAAM5D,SAAStE,KAAKiO,QAAQ,CAACH,gBAAiB;YACjD,MAAMI,OAAO5J,KAAK,CAAC,EAAE,CAACrH,IAAI;YAC1B,IAAIiR,QAAQ,CAACF,MAAMnZ,GAAG,CAACqZ,KAAKlR,WAAW,KAAKgR,MAAM1W,GAAG,CAAC4W,KAAKlR,WAAW,IAAI,CAAC,CAAC,EAAEkR,KAAK,CAAC,CAAC;QACvF;IACF;IACA,OAAO;WAAIF,MAAMrY,MAAM;KAAG;AAC5B;AAEA;;;;;CAKC,GACD,MAAMwY,cACJ;AACF,MAAMC,WACJ;AAQF;;;;CAIC,GACD,OAAO,SAASC,mBACdC,OAAgC,EAChCC,UAAyB,IAAI;IAE7B,MAAMC,SAASF,QAAQlX,MAAM,CAAC,CAACqX,SAAWN,YAAY3Y,IAAI,CAACiZ,OAAOzO,IAAI;IACtE,MAAM0O,SACJH,YAAY,YAAYA,YAAY,eAChCD,QAAQlX,MAAM,CAAC,CAACqX,SAAWL,SAAS5Y,IAAI,CAACiZ,OAAOzO,IAAI,KACpD,EAAE;IACR,MAAM3F,KAAK,CAACsU;QACV,MAAM9Y,MAAMH,OAAOiZ,KAAKtb,GAAG,CAAC,CAACob,SAAWA,OAAOpU,EAAE;QACjD,MAAMqT,QAAQ7X,IAAIuB,MAAM,CAAC,CAAC/C,KAAO,SAASmB,IAAI,CAACnB;QAC/C,MAAMsG,UAAU9E,IAAIuB,MAAM,CAAC,CAAC/C,KAAO,CAAC,SAASmB,IAAI,CAACnB;QAClD,OAAO,aAAMsG,QAAQlG,MAAM,GAAG;YAAEkG;QAAQ,IAAI,CAAC,GAAQ+S,MAAMjZ,MAAM,GAAG;YAAEiZ;QAAM,IAAI,CAAC;IACnF;IACA,MAAMpT,aAAoC,EAAE;IAC5C,IAAIkU,OAAO/Z,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;WACC2G,GAAGmU;IAEV;IACA,IAAIE,OAAOja,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;WACC2G,GAAGqU;IAEV;IACA,OAAOpU;AACT;AAEA,kEAAkE,GAClE,OAAO,SAASsU,WACd5a,IAAoB,EACpB6F,UAA6B,CAAC,CAAC;IAE/B,MAAMyU,UAA0B,EAAE;IAClC,KAAK,MAAM,EAAEja,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;kBAEEU;YAD7B3B,8BAMA2B,cACCA;QAPf,MAAMoP,iBAAQ/Q,+BAAAA,UAAU,CAAC2B,KAAKS,WAAW,CAAC,qBAA5BpC,6BAA8BgR,SAAS,mBAAI,CAAC;QAC1D,KAAK,MAAM,CAACtJ,MAAM7G,MAAM,IAAIT,OAAOkF,OAAO,EAAC3D,cAAAA,KAAKW,KAAK,YAAVX,cAAc,CAAC,GAAI;YAC5D,IAAIoP,KAAK,CAACrJ,KAAK,KAAK,UAAU,OAAO7G,UAAU,YAAYA,MAAMqJ,IAAI,IAAI;gBACvEqR,QAAQvZ,IAAI,CAAC;oBAAEsF,IAAIhG;oBAAI2L,MAAMpM;gBAAM;YACrC;QACF;QACA,MAAMoQ,SAAQtP,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAACrC,qBAAqB;QAChD,MAAMsD,UAASjB,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAChE,kCAAkC;QAC9D,IAAI,OAAOsT,UAAU,YAAYrQ,SAASgC,SAAS;;gBAChCkE;YAAjB,MAAM/C,qBAAW+C,0BAAAA,QAAQ2J,cAAc,qBAAtB3J,uBAAwB,CAACmK,MAAM,oBAAI,CAAC;YACrD,KAAK,MAAM,CAACvJ,MAAM7G,MAAM,IAAIT,OAAOkF,OAAO,CAAC1C,QAAS;oBACrCmB;gBAAb,MAAMI,QAAOJ,iBAAAA,QAAQ,CAAC2D,KAAK,YAAd3D,iBAAkB;gBAC/B,IAAI,AAACI,CAAAA,SAAS,UAAUA,SAAS,UAAS,KAAM,OAAOtD,UAAU,UAAU;oBACzE0a,QAAQvZ,IAAI,CAAC;wBAAEsF,IAAIhG;wBAAI2L,MAAMpM;oBAAM;gBACrC;YACF;QACF;IACF;IACA,OAAO0a;AACT;AAEA;;;;;CAKC,GACD,MAAMO,aAA0D;IAC9DC,eAAe;QAAC;KAAW;IAC3BC,iBAAiB;QAAC;QAAW;KAAY;IACzCC,eAAe;QAAC;QAAS;KAAY;IACrCC,qBAAqB;QAAC;KAAW;IACjCC,WAAW;QAAC;KAAW;AACzB;AAEA,mFAAmF,GACnF,MAAMC,iBAAiB,IAAIhb,IAAI;IAAC;IAAW;IAAY;CAAQ;AAE/D;;;CAGC,GACD,MAAMib,iBAAiB,IAAIjb,IAAI;IAAC;IAAM;IAAO;IAAO;IAAM;IAAO;IAAO;CAAI;AAE5E;;;;CAIC,GACD,MAAMkb,gBAAgB,IAAIlb,IAAI;IAC5B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,sHAAsH,GACtH,MAAMmb,cAAc;AAEpB;;;;;CAKC,GACD,OAAO,SAASC,eAAeC,IAAY;QAG5B;IAFb,MAAMxP,OAAOwP,KAAKvS,IAAI;IACtB,IAAI,CAAC+C,QAAQsP,YAAY9Z,IAAI,CAACwK,OAAO,OAAO;IAC5C,MAAMrD,QAAO,QAAA,mCAAmCsD,IAAI,CAACD,0BAAxC,KAA+C,CAAC,EAAE;IAC/D,IAAI,CAACrD,MAAM,OAAO;IAClB,MAAM8S,QAAQ9S,KAAKK,WAAW;IAC9B,IAAIL,SAAS,OAAOyS,eAAeva,GAAG,CAAC4a,QAAQ,OAAO9S;IACtD,6EAA6E;IAC7E,8DAA8D;IAC9D,MAAM+S,SAAS1P,KAAKhK,KAAK,CAAC,GAAGgK,KAAKvL,MAAM,GAAGkI,KAAKlI,MAAM;IACtD,OAAO4a,cAAcxa,GAAG,CAAC4a,UAAU,qBAAqBja,IAAI,CAACka,UAAU/S,OAAO;AAChF;AAEA,uDAAuD,GACvD,SAASgT,SAASH,IAAY;IAC5B,MAAMI,QAAQJ,KAAKvS,IAAI,GAAGH,KAAK,CAAC;IAChC,OAAO8S,MAAMnb,MAAM,GAAG,IAAI,CAAC,CAAC,EAAEmb,MAAM5Z,KAAK,CAAC,CAAC,GAAGD,IAAI,CAAC,MAAM,GAAG6Z,MAAM7Z,IAAI,CAAC;AACzE;AAEA;;;;;;;;CAQC,GACD,OAAO,SAAS8Z,oBAAoB7b,IAAoB;IACtD,MAAMoJ,QAA2D,EAAE;IACnE,KAAK,MAAM,EAAE/I,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;;YAG6BU,aAC9BA;QAHxC,MAAMW,QAAQwZ,UAAU,CAACna,KAAKS,WAAW,CAAC;QAC1C,IAAI,CAACE,OAAO;QACZ,IAAIX,KAAKS,WAAW,KAAK,mBAAmBga,eAAeta,GAAG,CAACsC,gBAAOzC,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,UAAU,mBAAI,MAAM;QACvG,IAAIA,KAAKS,WAAW,KAAK,eAAeT,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,WAAW;QAC/E,KAAK,MAAM+F,QAAQpF,MAAO;gBACXX;YAAb,MAAM8a,QAAO9a,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC+F,KAAK;YAC/B,MAAMkC,OAAO,OAAO6S,SAAS,WAAWD,eAAeC,QAAQ;YAC/D,IAAI7S,MAAMS,MAAMrI,IAAI,CAAC;gBAAEV;gBAAImb,MAAMA;gBAAgB7S;YAAK;QACxD;IACF;IACA,IAAI,CAACS,MAAM3I,MAAM,EAAE,OAAO,EAAE;IAC5B,MAAM,CAACuF,MAAM,GAAGoD;IAChB,OAAO;QACL;YACE3J,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,CAAC,EAAEic,SAAS3V,MAAMwV,IAAI,EAAE,kDAAkD,EAAExV,MAAM2C,IAAI,CAAC,gFAAgF,EAAE3C,MAAM2C,IAAI,CAAC,EAAE,CAAC;YACjMhC,SAASjF,OAAO0H,MAAM/J,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAC/C;KACD;AACH;AAEA,yFAAyF,GACzF,MAAMyb,cAA2D;IAC/DC,WAAW;QAAC;KAAW;IACvBC,eAAe;QAAC;KAAW;IAC3BC,aAAa;QAAC;KAAW;AAC3B;AAEA,8EAA8E,GAC9E,MAAMC,aAAa;AAEnB,wDAAwD,GACxD,SAASC,SAASX,IAAY;IAC5B,MAAMI,QAAQJ,KAAKvS,IAAI,GAAGH,KAAK,CAAC;IAChC,OAAO8S,MAAMnb,MAAM,GAAG,IAAI,GAAGmb,MAAM5Z,KAAK,CAAC,GAAG,GAAGD,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG6Z,MAAM7Z,IAAI,CAAC;AAC3E;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASqa,eACdC,OAA0B,EAC1B3N,OAA0C,EAC1C4N,OAA+B,CAACjc,KAAOA,EAAE;IAEzC,MAAM2R,MAA4E,EAAE;IACpF,KAAK,MAAMuK,UAAUF,QAAS;YAOdxB,MAAAA;QANd,MAAMvK,QAAQ4L,WAAWjQ,IAAI,CAACsQ;QAC9B,IAAI,CAACjM,OAAO;QACZ,MAAM,GAAGkM,QAAQ/V,MAAMgW,MAAM,GAAGnM;QAChC,MAAM5P,OAAOgO,OAAO,CAAC8N,OAAO;QAC5B,IAAI,CAAC7c,SAASe,SAAS,OAAOA,IAAI,CAAC,cAAc,KAAK,UAAU;QAChE,MAAMW,QAAQ1B,SAASe,IAAI,CAAC,QAAQ,IAAIA,IAAI,CAAC,QAAQ,GAAG,CAAC;QACzD,MAAMgc,SAAQ7B,QAAAA,+BAAAA,UAAU,CAACna,IAAI,CAAC,cAAc,CAAC,YAA/Bma,+BAAmCiB,WAAW,CAACpb,IAAI,CAAC,cAAc,CAAC,YAAnEma,OAAuE,EAAE;QACvF,MAAMW,OAAOna,KAAK,CAACoF,KAAK;QACxB,IAAI,CAACiW,MAAMxT,QAAQ,CAACzC,SAAS,OAAO+U,SAAS,UAAU;QACvDxJ,IAAIjR,IAAI,CAAC;YACPV,IAAIic,KAAKE;YACThB;YACAiB,OAAOnd,OAAOmd;YACd1L,SAASrQ,IAAI,CAAC,cAAc,KAAK,mBAAmB5B,kBAAkBuC,KAAK,CAAC,UAAU;QACxF;IACF;IACA,IAAI,CAAC2Q,IAAIvR,MAAM,EAAE,OAAO,EAAE;IAC1B,MAAM,CAACuF,MAAM,GAAGgM;IAChB,MAAMtS,UAAUsG,MAAM+K,OAAO,GACzB,CAAC,wCAAwC,EAAE/K,MAAMyW,KAAK,CAAC,kBAAkB,EAAEN,SAASnW,MAAMwV,IAAI,EAAE,0EAA0E,EAAExV,MAAMyW,KAAK,CAAC,4DAA4D,CAAC,GACrP,CAAC,CAAC,EAAEN,SAASnW,MAAMwV,IAAI,EAAE,gBAAgB,EAAExV,MAAMyW,KAAK,CAAC,uFAAuF,EAAEzW,MAAMyW,KAAK,CAAC,YAAY,CAAC;IAC7K,OAAO;QAAC;YAAEhd,MAAM;YAAIiH,MAAM;YAAuBhH;YAASiH,SAASjF,OAAOsQ,IAAI3S,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAAG;KAAE;AAC5G;AAEA,MAAMsc,kBAAkB,IAAIxc,IAAI;IAAC;IAAU;IAAY;IAAgB;IAAW;CAAU;AAC5F,MAAMyc,mBAAmB,IAAIzc,IAAI;IAAC;IAAc;CAAc;AAC9D,MAAM0c,wBAAwB;AAC9B,MAAMC,yBAAyB;AAE/B;;;;CAIC,GACD,SAASC,aACPrc,IAAoB,EACpBsc,OAA0D;QAGvCtc;IADnB,IAAIA,KAAKS,WAAW,KAAK,gBAAgB,CAAC6b,QAAQvc,MAAM,EAAE,OAAO;IACjE,MAAMwc,MAAM,SAAOvc,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,MAAM,MAAK,WAAWA,KAAKW,KAAK,CAAC,MAAM,CAAC4H,IAAI,KAAK;IACjF,IAAI,CAACgU,KAAK,OAAO;IACjB,MAAMpa,MAAM3F,gBAAgB+f;IAC5B,OAAOpa,OAAOma,QAAQvb,IAAI,CAAC,CAACyb,QAAUA,MAAMD,GAAG,IAAI/f,gBAAgBggB,MAAMD,GAAG,MAAMpa,OAC9E,YACA;AACN;AAEA;;;;CAIC,GACD,MAAMsa,uBAA4C,IAAIhd,IAAI;IAAC;CAAc;AAEzE;;;;;;;CAOC,GACD,OAAO,SAASid,oBACdpd,IAAoB,EACpByJ,UAAwB,EACxB5D,UAAiC,CAAC,CAAC;IAEnC,MAAM5F,SAASF,SAASC;IACxB,MAAMqd,WAAqB,EAAE;IAC7B,MAAMC,QAAkB,EAAE;IAC1B,MAAM9R,QAAkB,EAAE;IAC1B,MAAM+R,QAAkB,EAAE;IAC1B,MAAMC,QAAkB,EAAE;IAC1B,MAAMC,SAAmB,EAAE;IAC3B,MAAMC,aAAuB,EAAE;IAC/B,MAAMC,SAAS,IAAIpb;IACnB,IAAIqb,SAAS;IACb,KAAK,MAAM,EAAEvd,EAAE,EAAEK,IAAI,EAAE,IAAIT,OAAQ;YAEfS,aACcA,aASjBA,UA0BJA;YAtB6CA,cAI1BA,WAO3BA,cACCA,cACQA,cAA0DA;QA5BtE,MAAMiJ,QAAQ5K,UAAU,CAAC2B,KAAKS,WAAW,CAAC;QAC1C,MAAMH,WAAW,EAACN,cAAAA,KAAKE,KAAK,YAAVF,cAAc,EAAE,EAAE0C,MAAM,CAAC,CAACC,QAAUrD,KAAKY,KAAK,CAACyC,MAAM;QACvE,MAAMwa,WAAW1e,OAAOkF,OAAO,EAAC3D,cAAAA,KAAKW,KAAK,YAAVX,cAAc,CAAC,GAAG0C,MAAM,CACtD,CAAC,CAACqD,MAAM7G,MAAM,GAAK,CAAE6G,CAAAA,SAAS,eAAe7G,UAAU,KAAI;QAE7D,IACES,OAAOL,KAAKM,MAAM,IAClBqc,gBAAgB9b,GAAG,CAACH,KAAKS,WAAW,KACpCH,SAASP,MAAM,KAAK,KACpBkc,gBAAgB9b,GAAG,CAACb,KAAKY,KAAK,CAACI,QAAQ,CAAC,EAAE,CAAC,CAACG,WAAW,KACvD,CAAC0c,SAASpd,MAAM,IAChB,CAACtB,OAAOC,IAAI,EAACsB,WAAAA,KAAKwK,EAAE,YAAPxK,WAAW,CAAC,GAAGD,MAAM,EAClC;YACA4c,SAAStc,IAAI,CAACV;QAChB;QACA,MAAMyd,YAAYpd,KAAKS,WAAW,KAAK,UAAU,SAAOT,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,SAAS,MAAK;QACnF,IAAIiJ,CAAAA,yBAAAA,MAAOoU,eAAe,KAAI,CAAC/c,SAASP,MAAM,IAAI,CAACqd,aAAa,CAACX,qBAAqBtc,GAAG,CAACH,KAAKS,WAAW,GAAG;YAC3Gmc,MAAMvc,IAAI,CAACV;QACb;QACA,IAAIoJ,eAAe,WAAW/I,EAAAA,YAAAA,KAAKwK,EAAE,qBAAPxK,SAAS,CAAC,aAAa,MAAK8E,WAAWgG,MAAMzK,IAAI,CAACV;QAChF,IAAIK,KAAKS,WAAW,KAAK,SAAS;gBAEdT;YADlBkd,UAAU;YACV,IAAIA,SAAS,KAAKld,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,SAAS6c,MAAMxc,IAAI,CAACV;QACpE;QACA,IACEK,KAAKS,WAAW,KAAK,WACpBT,CAAAA,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,WAAW,MAAK,QAC5BA,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,UAC3B,SAAOA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,MAAM,MAAK,YAAYA,KAAKW,KAAK,CAAC,MAAM,IAAI,GAACX,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,SAAS,CAAA,GAC1F;YACA8c,MAAMzc,IAAI,CAACV;QACb;QACA,IAAIuc,iBAAiB/b,GAAG,CAACH,KAAKS,WAAW,GAAG;gBACP0E;YAAnC,MAAMmY,UAAUjB,aAAarc,OAAMmF,yBAAAA,QAAQoY,aAAa,YAArBpY,yBAAyB,EAAE;YAC9D,IAAImY,YAAY,aAAaP,OAAO1c,IAAI,CAACV;YACzC,IAAI2d,YAAY,kBAAkBN,WAAW3c,IAAI,CAACV;QACpD;QACA,MAAM6K,MAAKxK,YAAAA,KAAKwK,EAAE,YAAPxK,YAAW,CAAC;QACvB,IAAIvB,OAAOC,IAAI,CAAC8L,IAAIzK,MAAM,IAAIoc,uBAAuB;gBAE9Bc;YADrB,MAAM9a,MAAMqB,KAAKC,SAAS,CAAChF,OAAOC,IAAI,CAAC8L,IAAItI,IAAI,GAAGvD,GAAG,CAAC,CAACoH,OAAS;oBAACA;oBAAMyE,EAAE,CAACzE,KAAK;iBAAC;YAChFkX,OAAOra,GAAG,CAACT,KAAK;oBAAK8a,cAAAA,OAAOpa,GAAG,CAACV,gBAAX8a,cAAmB,EAAE;gBAAGtd;aAAG;QAClD;IACF;IACA,MAAM6d,eAAe;WAAIP,OAAOhc,MAAM;KAAG,CACtCyB,MAAM,CAAC,CAACvB,MAAQA,IAAIpB,MAAM,IAAIqc,wBAC9BqB,IAAI;IACP,MAAM7X,aAAoC,EAAE;IAC5C,MAAMxF,MAAM,CAAC4F,MAAc7E,KAAenC;QACxC,IAAImC,IAAIpB,MAAM,EAAE6F,WAAWvF,IAAI,CAAC;YAAEtB,MAAM;YAAIiH;YAAMhH;YAASiH,SAAS9E;QAAI;IAC1E;IACAf,IACE,sBACAuc,UACA;IAEFvc,IAAI,mBAAmBwc,OAAO;IAC9Bxc,IACE,2BACAod,cACA;IAEFpd,IAAI,cAAc0K,OAAO;IACzB1K,IACE,eACAyc,OACA;IAEFzc,IACE,kBACA0c,OACA;IAEF1c,IACE,qBACA2c,QACA;IAEF3c,IACE,wBACA4c,YACA;IAEF,OAAOpX;AACT;AAEA,wEAAwE,GACxE,MAAM8X,aAA+C;IAAEC,aAAa;IAAaC,SAAS;AAAO;AAEjG,+EAA+E,GAC/E,MAAMC,mBAAmB,IAAIpe,IAAI;IAC/B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,sEAAsE,GACtE,MAAMqe,aAA0D,aAC3D3D;IACH4D,SAAS;QAAC;KAAY;IACtBC,eAAe;QAAC;KAAW;IAC3B3C,WAAW;QAAC;KAAW;IACvBC,eAAe;QAAC;KAAW;;AAG7B,yHAAyH,GACzH,SAAS2C,SAASje,IAAoB;IACpC,MAAMkb,QAAQ4C,UAAU,CAAC9d,KAAKS,WAAW,CAAC;IAC1C,IAAIya,OAAO,OAAOA,MAAMna,IAAI,CAAC,CAACgF;YAAkB/F;eAAT6X,UAAS7X,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC+F,KAAK;;IAClE,OAAO,CAAC8X,iBAAiB1d,GAAG,CAACH,KAAKS,WAAW;AAC/C;AAEA;;;;;;;CAOC,GACD,OAAO,SAASyd,iBAAiB5e,IAAoB;IACnD,MAAMsd,QAA6C,EAAE;IACrD,KAAK,MAAM,EAAEjd,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;YAE1BU;QADf,MAAMme,OAAOT,UAAU,CAAC1d,KAAKS,WAAW,CAAC;QACzC,IAAI,CAAC0d,QAAQ,CAAC,EAACne,cAAAA,KAAKE,KAAK,YAAVF,cAAc,EAAE,EAAEe,IAAI,CAAC,CAAC4B,QAAUrD,KAAKY,KAAK,CAACyC,MAAM,GAAG;QACrE,IAAI,CAACtD,SAAS;YAAEO,QAAQD;YAAIO,OAAOZ,KAAKY,KAAK;QAAC,GAAGa,IAAI,CAAC,CAACmY,QAAU+E,SAAS/E,MAAMlZ,IAAI,IAAI;YACtF4c,MAAMvc,IAAI,CAAC;gBAAEV;gBAAIwe;YAAK;QACxB;IACF;IACA,IAAI,CAACvB,MAAM7c,MAAM,EAAE,OAAO,EAAE;IAC5B,MAAMqe,QAAQpd,OAAO4b,MAAMje,GAAG,CAAC,CAACsK,QAAUA,MAAMkV,IAAI;IACpD,MAAMnf,UACJof,MAAMre,MAAM,GAAG,IACX,6FACAqe,KAAK,CAAC,EAAE,KAAK,cACX,qHACA;IACR,OAAO;QAAC;YAAErf,MAAM;YAAIiH,MAAM;YAAchH;YAASiH,SAAS2W,MAAMje,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QAAE;KAAE;AAC7F;AAkBA,MAAM0e,kBAAkB;AACxB,MAAMC,oBAAuD;IAC3DC,OAAO;QAAC;KAAM;IACdC,YAAY;QAAC;KAAM;IACnB1B,OAAO;QAAC;KAAS;IACjB2B,uBAAuB;QAAC;KAAQ;IAChCC,sBAAsB;QAAC;KAAQ;AACjC;AAEA,gDAAgD,GAChD,SAASC,mBAAmBC,SAAwB;QAG3CljB;IAFP,MAAMmjB,SAASnjB,wBAAwB,CAACA,yBAAyBqE,MAAM,GAAG,EAAE;IAC5E,IAAI,CAAC6e,WAAW,OAAOC;IACvB,QAAOnjB,iCAAAA,yBAAyBgK,IAAI,CAAC,CAACoZ,QAAUA,SAASF,sBAAlDljB,iCAAgEmjB;AACzE;AAEA,SAASE,OAAO7f,KAAc;IAC5B,MAAM8f,SAAS,OAAO9f,UAAU,WAAWA,QAAQN,OAAOqgB,UAAU,CAACxc,OAAOvD,gBAAAA,QAAS;IACrF,OAAON,OAAOoN,QAAQ,CAACgT,WAAWA,SAAS,IAAIA,SAAS;AAC1D;AAEA,SAASE,cACP5f,IAAoB,EACpByJ,UAAwB,EACxB5D,OAA8B;IAE9B,MAAMga,WAAwD,EAAE;IAChE,KAAK,MAAM,EAAExf,EAAE,EAAEK,IAAI,EAAE,IAAIX,SAASC,MAAO;YAC3Bgf;QAAd,MAAMnR,SAAQmR,sCAAAA,iBAAiB,CAACte,KAAKS,WAAW,CAAC,YAAnC6d,sCAAuC,EAAE;QACvD,MAAMrd,SAASiO,YAAYlP,MAAMmF,SAASzC,MAAM,CAC9C,CAAC,EAAEqD,IAAI,EAAE,GACPoH,MAAM3E,QAAQ,CAACzC,SAASA,KAAKqZ,UAAU,CAAC,GAAGpjB,kCAAkC,CAAC,CAAC;QAEnF,KAAK,MAAM,EAAEkD,KAAK,EAAE,IAAI+B,OAAQ;gBAEVkE,iBAKAnF;YANpB,MAAM4O,MAAMjT,cAAcuD;YAC1B,MAAMoa,QAAQ1K,OAAMzJ,kBAAAA,QAAQka,MAAM,qBAAdla,eAAgB,CAACyJ,IAAI0Q,OAAO,CAAC,GAAGxa;YACpD,IAAI,EAACwU,yBAAAA,MAAOiG,SAAS,GAAE;gBACrBJ,SAAS9e,IAAI,CAAC;oBAAEV;oBAAI6f,OAAO;gBAAK;gBAChC;YACF;YACA,MAAM1X,OAAOiX,QAAO/e,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,QAAQ;YACzC,MAAMyf,UAAUd,mBACd5V,eAAe,UAAUoD,KAAKiG,GAAG,CAACtK,eAAAA,OAAQuW,iBAAiBA,mBAAmBvW;YAEhF,qEAAqE;YACrE,2DAA2D;YAC3D,MAAM4X,QAAQpG,MAAMwF,KAAK,GAAG3S,KAAKiG,GAAG,CAAC,GAAGqN,UAAUnG,MAAMwF,KAAK,IAAI;YACjEK,SAAS9e,IAAI,CAAC;gBAAEV;gBAAI6f,OAAOrT,KAAKC,KAAK,CAACkN,MAAMiG,SAAS,GAAGG,QAAQA;YAAO;QACzE;IACF;IACA,OAAOP;AACT;AAEA,oDAAoD,GACpD,OAAO,SAASQ,cACdrgB,IAAoB,EACpByJ,UAAwB,EACxB5D,UAAiC,CAAC,CAAC;IAEnC,MAAM5F,SAASF,SAASC;IACxB,MAAM4d,SAASgC,cAAc5f,MAAMyJ,YAAY5D;IAC/C,MAAMya,WAAW,IAAIngB;IACrB,KAAK,MAAM,EAAEO,IAAI,EAAE,IAAIT,OAAQ;YACCS;QAA9B,KAAK,MAAMkL,UAAUf,UAASnK,WAAAA,KAAKwK,EAAE,qBAAPxK,QAAS,CAAC,aAAa,EAAG;YACtD,IAAI,OAAOkL,WAAW,YAAYA,OAAO3C,IAAI,IAAIqX,SAASxf,GAAG,CAAC8K,OAAO3C,IAAI,GAAGD,WAAW;QACzF;IACF;IACA,IAAIuX,iBAAgC;IACpC,IAAI9W,eAAe,SAAS;QAC1B,MAAM,EAAE+W,IAAI,EAAE,GAAG5jB,gBAAgB;YAC/BgE,OAAOZ,KAAKY,KAAK;YACjBN,QAAQN,KAAKM,MAAM;YACnBmgB,UAAU,CAAC7gB,QAAkB7D,mBAAmB6D;QAClD;QACA2gB,iBAAiB,IAAIG,cAAcC,MAAM,CAACH,MAAM/f,MAAM;IACxD;IACA,OAAO;QACLG,OAAOX,OAAOQ,MAAM;QACpByf,OAAO/jB,aAAa6D,KAAKY,KAAK;QAC9BggB,YAAYhD,OAAOpa,MAAM,CAAC,CAACC,KAAKwb;gBAAiBA;mBAAPxb,QAAOwb,eAAAA,MAAMiB,KAAK,YAAXjB,eAAe;WAAI;QACpE4B,kBAAkBjD,OAAOxa,MAAM,CAAC,CAAC6b,QAAUA,MAAMiB,KAAK,KAAK,MAAMzf,MAAM;QACvEgd,QAAQxd,OAAOmD,MAAM,CAAC,CAAC,EAAE1C,IAAI,EAAE,GAAKkc,iBAAiB/b,GAAG,CAACH,KAAKS,WAAW,GAAGV,MAAM;QAClFqgB,cAAcR,SAASlb,IAAI;QAC3Bmb;IACF;AACF;AAEA,MAAMQ,gBAAgD;IACpDngB,OAAO;IACPsf,OAAO;IACPU,YAAY;IACZnD,QAAQ;IACRqD,cAAc;IACdP,gBAAgB,CAAC,sCAAsC,EAAEtkB,YAAYyC,qBAAqB,CAAC,CAAC;AAC9F;AAEA,SAASsiB,OAAOC,MAAsB,EAAErhB,KAAa;IACnD,OAAOqhB,WAAW,WAAWA,WAAW,YAAYA,WAAW,iBAC3DrhB,MAAMshB,cAAc,CAAC,WACrBjlB,YAAY2D;AAClB;AAEA,0EAA0E,GAC1E,SAASuhB,SACPF,MAAsB,EACtBjhB,IAAoB,EACpByJ,UAAwB,EACxB5D,OAA8B;IAE9B,OAAQob;QACN,KAAK;QACL,KAAK;YACH,OAAO/kB,eAAe8D,KAAKY,KAAK,EAAEwgB,OAAO,CAAC/hB,GAAG,CAAC,CAACsK,QAAUA,MAAMtJ,EAAE;QACnE,KAAK;YAAS;gBACZ,MAAMY,QAAQoB,YAAYrC;gBAC1B,OAAOiB,MAAMhB,MAAM,CAChBmD,MAAM,CAAC,CAAC7B,QAAUA,MAAMhB,KAAK,IAAI,KAAKgB,MAAMhB,KAAK,IAAI,GACrDqC,IAAI,CAAC,CAACoK,GAAGZ;wBAAOnL,mBAAgCA;2BAAjC,EAACA,oBAAAA,MAAMuB,MAAM,CAACe,GAAG,CAAC6I,EAAE/L,EAAE,aAArBY,oBAA0B,OAAMA,qBAAAA,MAAMuB,MAAM,CAACe,GAAG,CAACyJ,EAAE3M,EAAE,aAArBY,qBAA0B;mBAC1Ee,KAAK,CAAC,GAAG,GACT3C,GAAG,CAAC,CAACkC,QAAUA,MAAMlB,EAAE;YAC5B;QACA,KAAK;YACH,OAAOuf,cAAc5f,MAAMyJ,YAAY5D,SACpCzC,MAAM,CAAC,CAAC6b,QAAUA,MAAMiB,KAAK,KAAK,MAClCtd,IAAI,CAAC,CAACoK,GAAGZ;oBAAOA,UAAiBY;uBAAlB,EAACZ,WAAAA,EAAE8T,KAAK,YAAP9T,WAAW,OAAMY,WAAAA,EAAEkT,KAAK,YAAPlT,WAAW;eAC5ChL,KAAK,CAAC,GAAG,GACT3C,GAAG,CAAC,CAAC4f,QAAUA,MAAM5e,EAAE;QAC5B,KAAK;YACH,OAAON,SAASC,MACboD,MAAM,CAAC,CAAC,EAAE1C,IAAI,EAAE,GAAKkc,iBAAiB/b,GAAG,CAACH,KAAKS,WAAW,GAC1D9B,GAAG,CAAC,CAACkC,QAAUA,MAAMlB,EAAE;QAC5B,KAAK;YACH,OAAON,SAASC,MACboD,MAAM,CAAC,CAAC,EAAE1C,IAAI,EAAE;oBAAKA;uBAAAA,EAAAA,WAAAA,KAAKwK,EAAE,qBAAPxK,QAAS,CAAC,aAAa,MAAK8E;eACjDnG,GAAG,CAAC,CAACkC,QAAUA,MAAMlB,EAAE;IAC9B;AACF;AAEA,MAAMghB,iBAA4C;IAChD;IACA;IACA;IACA;IACA;IACA;CACD;AAED;;;CAGC,GACD,OAAO,SAASC,iBACdC,KAAoB,EACpB9X,UAAwB,EACxBzJ,IAAoB,EACpB6F,UAAiC,CAAC,CAAC;IAEnC,MAAM2b,SAAS7iB,iBAAiB,CAAC8K,WAAW;IAC5C,MAAMnD,aAAoC,EAAE;IAC5C,KAAK,MAAM2a,UAAUI,eAAgB;QACnC,MAAMzhB,QAAQ2hB,KAAK,CAACN,OAAO;QAC3B,MAAMxE,QAAQ+E,MAAM,CAACP,OAAO;QAC5B,IAAIrhB,UAAU,QAAQ6c,UAAUjX,aAAa5F,SAAS6c,OAAO;QAC7D,MAAMgF,YAAYN,SAASF,QAAQjhB,MAAMyJ,YAAY5D;QACrD,MAAM8E,QAAQ8W,UAAUhhB,MAAM,GAAG,CAAC,qBAAqB,EAAEmB,UAAU6f,WAAWzhB,MAAM,CAAC,CAAC,GAAG;QACzFsG,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM,CAAC,YAAY,EAAEua,QAAQ;YAC7BvhB,SAAS,CAAC,KAAK,EAAE+J,WAAW,UAAU,EAAEuX,OAAOC,QAAQrhB,OAAO,IAAI,EAAEmhB,aAAa,CAACE,OAAO,CAAC,qBAAqB,EAAED,OAAOC,QAAQxE,OAAO,CAAC,EAAE9R,OAAO;YACjJhE,SAAS8a;YACTT,QAAQ;gBAAEC;gBAAQrhB;gBAAO4hB,QAAQ/E;YAAM;QACzC;IACF;IACA,OAAOnW;AACT;AAEA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASob,qBACdH,KAAoB,EACpB9X,UAAwB;IAExB,IAAIA,eAAe,SAAS,OAAO;IACnC,MAAMkY,YACJlY,eAAe,UAAUA,eAAe,aAAanN,gCAAgC;IACvF,OAAO;QACLqlB;QACAC,eAAeL,MAAMrB,KAAK;QAC1BU,YAAYW,MAAMX,UAAU;QAC5BC,kBAAkBU,MAAMV,gBAAgB;QACxCpD,QAAQ8D,MAAM9D,MAAM;QACpBoE,YAAYhV,KAAKC,KAAK,CAAC6U,YAAYJ,MAAMrB,KAAK,GAAGqB,MAAMX,UAAU;IACnE;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GACD,OAAO,SAASkB,uBAAuBvU,KAAc;IACnD,IAAI,CAAC5N,SAAS4N,UAAU,OAAOA,KAAK,CAAC,SAAS,KAAK,YAAY,CAAC5N,SAAS4N,KAAK,CAAC,QAAQ,GAAG,OAAO,EAAE;IACnG,MAAMjN,SAASiN,KAAK,CAAC,SAAS;IAC9B,MAAM3M,QAAQ2M,KAAK,CAAC,QAAQ;IAC5B,IAAI,CAAC5N,SAASiB,KAAK,CAACN,OAAO,GAAG,OAAO,EAAE;IACvC,MAAMwE,aAAa,CAACzE;QAClB,MAAMK,OAAOE,KAAK,CAACP,GAAG;QACtB,MAAM+Y,SAASzZ,SAASe,QAAQA,IAAI,CAAC,QAAQ,GAAG8E;QAChD,OAAO3F,MAAMC,OAAO,CAACsZ,UAAUA,OAAOhW,MAAM,CAAC,CAACC,QAA2B,OAAOA,UAAU,YAAY,EAAE;IAC1G;IACA,MAAM0e,UAAU,IAAI5hB,IAAY;QAACG;KAAO;IACxC,MAAM0hB,UAAU,IAAIzf;IACpB,MAAM0f,QAAQ;QAAC3hB;KAAO;IACtB,MAAO2hB,MAAMxhB,MAAM,CAAE;QACnB,MAAMJ,KAAK4hB,MAAMC,KAAK;QACtB,KAAK,MAAM7e,SAASyB,WAAWzE,IAAK;YAClC,IAAI,CAACV,SAASiB,KAAK,CAACyC,MAAM,GAAG;oBACN2e;gBAArBA,QAAQ1e,GAAG,CAACjD,IAAI;wBAAK2hB,eAAAA,QAAQze,GAAG,CAAClD,eAAZ2hB,eAAmB,EAAE;oBAAG3e;iBAAM;gBACnD;YACF;YACA,IAAI0e,QAAQlhB,GAAG,CAACwC,QAAQ;YACxB0e,QAAQjhB,GAAG,CAACuC;YACZ4e,MAAMlhB,IAAI,CAACsC;QACb;IACF;IACA,MAAM8e,UAAUhjB,OAAOC,IAAI,CAACwB,OAAOwC,MAAM,CAAC,CAAC/C,KAAO,CAAC0hB,QAAQlhB,GAAG,CAACR,OAAOV,SAASiB,KAAK,CAACP,GAAG;IACxF,MAAMiG,aAAoC,EAAE;IAC5C,IAAI0b,QAAQ5c,IAAI,EAAE;QAChB,MAAMyI,QAAQnM,OAAO;eAAIsgB,QAAQrgB,MAAM;SAAG,CAACwc,IAAI;QAC/C7X,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACF0iB,QAAQ,CAAC,kDAAkD,EAAEvU,MAAMxO,GAAG,CAAC,CAACgB,KAAO,CAAC,CAAC,EAAEA,GAAG,CAAC,CAAC,EAAE0B,IAAI,CAAC,MAAM,CAAC,CAAC;YACvG4E,SAAS;mBAAIqb,QAAQ5iB,IAAI;aAAG;QAC9B;IACF;IACA,IAAI+iB,QAAQ1hB,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFiH,SAASwb;QACX;IACF;IACA,OAAO7b;AACT;AAEA,mHAAmH,GACnH,MAAM+b,aAAa;AAEnB;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,OAAO,SAASC,yBAAyB/U,KAAc;IACrD,IAAI,CAAC5N,SAAS4N,UAAU,OAAOA,KAAK,CAAC,SAAS,KAAK,YAAY,CAAC5N,SAAS4N,KAAK,CAAC,QAAQ,GAAG,OAAOA;IACjG,MAAMjN,SAASiN,KAAK,CAAC,SAAS;IAC9B,MAAMgV,SAAShV,KAAK,CAAC,QAAQ;IAC7B,IAAI,CAAC5N,SAAS4iB,MAAM,CAACjiB,OAAO,GAAG,OAAOiN;IACtC,MAAM3M,QAAiC,aAAK2hB;IAC5C,IAAIC,UAAU;IACd,MAAMpJ,SAAS,CAAC/Y;QACd,MAAMK,OAAOE,KAAK,CAACP,GAAG;QACtB,OAAOV,SAASe,SAASb,MAAMC,OAAO,CAACY,IAAI,CAAC,QAAQ,IAAIA,IAAI,CAAC,QAAQ,GAAG,EAAE;IAC5E;IACA,MAAM+hB,YAAY,CAACpiB,IAAYW;QAC7BJ,KAAK,CAACP,GAAG,GAAG,aAAMO,KAAK,CAACP,GAAG;YAA8BO,OAAOI;;QAChEwhB,UAAU;IACZ;IACA,MAAME,QAAQ,CAACriB;YAEuDtB;QADpE,MAAM2B,OAAOE,KAAK,CAACP,GAAG;QACtB,OAAOV,SAASe,SAAS,OAAOA,IAAI,CAAC,cAAc,KAAK,YAAY3B,EAAAA,+BAAAA,UAAU,CAAC2B,IAAI,CAAC,cAAc,CAAC,qBAA/B3B,6BAAiCgf,eAAe,MAAK;IAC3H;IACA,MAAM4E,QAAQ;QACZ,MAAMZ,UAAU,IAAI5hB,IAAY;YAACG;SAAO;QACxC,MAAM2hB,QAAQ;YAAC3hB;SAAO;QACtB,MAAO2hB,MAAMxhB,MAAM,CAAE;YACnB,KAAK,MAAM4C,SAAS+V,OAAO6I,MAAMC,KAAK,IAAe;gBACnD,IAAI,OAAO7e,UAAU,YAAY0e,QAAQlhB,GAAG,CAACwC,UAAU,CAAC1D,SAASiB,KAAK,CAACyC,MAAM,GAAG;gBAChF0e,QAAQjhB,GAAG,CAACuC;gBACZ4e,MAAMlhB,IAAI,CAACsC;YACb;QACF;QACA,OAAO0e;IACT;IAEA,sEAAsE;IACtE,KAAK,MAAM1hB,MAAMlB,OAAOC,IAAI,CAACwB,OAAQ;QACnC,MAAMI,WAAWoY,OAAO/Y;QACxB,MAAMqO,UAAU1N,SAASoC,MAAM,CAAC,CAACC,QAAU,OAAOA,UAAU,YAAY1D,SAASiB,KAAK,CAACyC,MAAM;QAC7F,IAAIqL,QAAQjO,MAAM,KAAKO,SAASP,MAAM,EAAEgiB,UAAUpiB,IAAIqO;IACxD;IAEA,IAAIqT,UAAUY;IACd,MAAMR,UAAUhjB,OAAOC,IAAI,CAACwB,OAAOwC,MAAM,CAAC,CAAC/C,KAAO,CAAC0hB,QAAQlhB,GAAG,CAACR,OAAOV,SAASiB,KAAK,CAACP,GAAG;IACxF,IAAI8hB,QAAQ1hB,MAAM,EAAE;QAClB,MAAMmiB,WAAW,IAAIziB,IAAIgiB,QAAQ5d,OAAO,CAAC,CAAClE,KAAO+Y,OAAO/Y;QACxD,MAAMwiB,QAAQV,QAAQ/e,MAAM,CAAC,CAAC/C,KAAO,CAACuiB,SAAS/hB,GAAG,CAACR;QACnD,MAAMid,QAAQ;eAAIyE;SAAQ,CAAC3e,MAAM,CAAC,CAAC/C,KAAOA,OAAOC,UAAUoiB,MAAMriB,OAAO+Y,OAAO/Y,IAAII,MAAM,KAAK;QAC9F,KAAK,MAAMJ,MAAMwiB,MAAO;YACtB,MAAMhV,QAAQ,AAACjN,KAAK,CAACP,GAAG,AAA4B,CAAC,WAAW;YAChE,MAAMoF,SACJ,OAAOoI,UAAU,YAAYkU,QAAQlhB,GAAG,CAACgN,UAAU6U,MAAM7U,SACrDA,QACAgV,MAAMpiB,MAAM,KAAK,KAAK6c,MAAM7c,MAAM,KAAK,IACrC6c,KAAK,CAAC,EAAE,GACR;YACR,IAAI7X,QAAQgd,UAAUhd,QAAQ;mBAAI2T,OAAO3T;gBAASpF;aAAG;QACvD;QACA0hB,UAAUY;QACV,MAAMG,WAAW3jB,OAAOC,IAAI,CAACwB,OAAOwC,MAAM,CAAC,CAAC/C,KAAO,CAAC0hB,QAAQlhB,GAAG,CAACR,OAAOV,SAASiB,KAAK,CAACP,GAAG;QACzF,uEAAuE;QACvE,MAAM0iB,OAAO,IAAI5iB;QACjB,MAAM8hB,QAAQa,SAAS1f,MAAM,CAAC,CAAC/C,KAAO,AAACO,KAAK,CAACP,GAAG,AAA4B,CAACgiB,WAAW,KAAK7c;QAC7F,MAAOyc,MAAMxhB,MAAM,CAAE;YACnB,MAAMJ,KAAK4hB,MAAMC,KAAK;YACtB,IAAIa,KAAKliB,GAAG,CAACR,OAAO,CAACV,SAASiB,KAAK,CAACP,GAAG,GAAG;YAC1C0iB,KAAKjiB,GAAG,CAACT;YACT,KAAK,MAAMgD,SAAS+V,OAAO/Y,IAAK,IAAI,OAAOgD,UAAU,UAAU4e,MAAMlhB,IAAI,CAACsC;QAC5E;QACA,KAAK,MAAMhD,MAAMyiB,SAAU;YACzB,IAAIC,KAAKliB,GAAG,CAACR,KAAK;YAClB,OAAOO,KAAK,CAACP,GAAG;YAChBmiB,UAAU;QACZ;IACF;IACA,OAAOA,UAAU,aAAKjV;QAAO3M;SAAU2M;AACzC;AAGA,sFAAsF,GACtF,MAAMyV,wBAAwB;AAC9B,sEAAsE,GACtE,MAAMC,wBAAwB;AAC9B,6CAA6C,GAC7C,MAAMC,eAAe;AACrB,8CAA8C,GAC9C,MAAMC,aAAa;AAEnB;;;;CAIC,GACD,SAASC,cAAc5H,IAAY,EAAEiB,KAAa;IAChD,MAAM4G,QAAQ,CAACC,OACbA,KAAKxa,KAAK,CAAC,OAAOrI,MAAM,IAAIuiB,yBAAyBM,KAAK7iB,MAAM,IAAIgc,QAAQwG;IAC9E,KAAK,MAAM,CAACM,SAASC,SAAS,IAAI;QAChC;YAACN;YAAc;SAAK;QACpB;YAACC;YAAY;SAAM;KACpB,CAAW;QACV,IAAIrV,OAAsB;QAC1B,KAAK,MAAMwC,SAASkL,KAAKvB,QAAQ,CAACsJ,SAAU;gBACdjT;YAA5B,MAAMgT,OAAO9H,KAAKxZ,KAAK,CAAC,GAAG,EAACsO,eAAAA,MAAMrP,KAAK,YAAXqP,eAAe,KAAMkT,CAAAA,WAAWlT,KAAK,CAAC,EAAE,CAAC7P,MAAM,GAAG,CAAA,GAAIwI,IAAI;YACtF,IAAIqa,KAAK7iB,MAAM,GAAGgc,OAAO;YACzB3O,OAAOwV;QACT;QACA,IAAIxV,SAAS,QAAQuV,MAAMvV,OAAO,OAAOA;IAC3C;IACA,OAAO;AACT;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAAS2V,oBAAoBlW,KAAc;;QAEzBxO,sCAAAA;IADvB,IAAI,CAACY,SAAS4N,UAAU,CAAC5N,SAAS4N,KAAK,CAAC,QAAQ,GAAG,OAAOA;IAC1D,MAAMkP,QAAQ5P,KAAKiG,GAAG,UAAC/T,4BAAAA,UAAU,CAAC,gBAAgB,sBAA3BA,uCAAAA,0BAA6B2kB,UAAU,qBAAvC3kB,oCAAyC,CAAC,WAAW,mBAAI4kB,UAAU9kB,eAAe+kB,QAAQ;IACjH,IAAIhjB,QAAwC;IAC5C,KAAK,MAAM,CAACP,IAAIK,KAAK,IAAIvB,OAAOkF,OAAO,CAACkJ,KAAK,CAAC,QAAQ,EAAG;QACvD,IAAI,CAAC5N,SAASe,SAASA,IAAI,CAAC,cAAc,KAAK,mBAAmB,CAACf,SAASe,IAAI,CAAC,QAAQ,GAAG;QAC5F,MAAM8a,OAAO9a,IAAI,CAAC,QAAQ,CAAC,WAAW;QACtC,IAAI,CAAC5B,kBAAkB4B,IAAI,CAAC,QAAQ,CAAC,UAAU,KAAK,OAAO8a,SAAS,UAAU;QAC9E,MAAMqI,UAAUrI,KAAKvS,IAAI;QACzB,IAAI4a,QAAQpjB,MAAM,IAAIgc,SAASoH,QAAQ3a,QAAQ,CAAC,OAAO;QACvD,MAAMoa,OAAOF,cAAcS,SAASpH;QACpC,IAAI6G,SAAS,MAAM;QACnB1iB,gBAAAA,QAAAA,QAAU,aAAK2M,KAAK,CAAC,QAAQ;QAC7B3M,KAAK,CAACP,GAAG,GAAG,aAAKK;YAAMW,OAAO,aAAKX,IAAI,CAAC,QAAQ;gBAAEM,UAAUsiB;;;IAC9D;IACA,OAAO1iB,QAAQ,aAAK2M;QAAO3M;SAAU2M;AACvC;AAEA,4EAA4E;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCC,GACD,OAAO,SAASuW,wBAAkD9jB,IAAO,EAAEyJ,UAAwB;IACjG,IAAI,CAACzJ,KAAKY,KAAK,CAACZ,KAAKM,MAAM,CAAC,EAAE,OAAON;IACrC,MAAMY,QAAwC,aAAKZ,KAAKY,KAAK;IAC7D,MAAM6U,SAAS,IAAItV;IACnB,MAAMuV,OAAO,CAACrV;QACZ,IAAI,CAACoV,OAAO5U,GAAG,CAACR,KAAK;YACnB,MAAMK,OAAOE,KAAK,CAACP,GAAG;YACtBO,KAAK,CAACP,GAAG,GAAG,aACPK,MACCA,KAAKW,KAAK,GAAG;gBAAEA,OAAO,aAAKX,KAAKW,KAAK;YAAG,IAAI,CAAC,GAC7CX,KAAKwK,EAAE,GAAG;gBAAEA,IAAI,aAAKxK,KAAKwK,EAAE;YAAG,IAAI,CAAC;YAE1CuK,OAAO3U,GAAG,CAACT;QACb;QACA,OAAOO,KAAK,CAACP,GAAG;IAClB;IACA,MAAM0jB,YAAY,CAAC1jB,IAAYoG;YACzB7F;QAAJ,IAAIA,EAAAA,kBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAAfT,eAAiB,CAAC6F,KAAK,MAAKjB,WAAW;QAC3C,OAAO,AAACkQ,KAAKrV,IAAIgB,KAAK,AAA4B,CAACoF,KAAK;IAC1D;IACA,MAAMud,UAAU,CAAC3jB,IAAYoG,MAAc7G;YAGtBc;YAFfE;QAAJ,IAAIA,EAAAA,kBAAAA,KAAK,CAACP,GAAG,CAACgB,KAAK,qBAAfT,eAAiB,CAAC6F,KAAK,MAAK7G,OAAO;QACvC,MAAMc,OAAOgV,KAAKrV;QAClBK,KAAKW,KAAK,GAAG,cAAMX,cAAAA,KAAKW,KAAK,YAAVX,cAAc,CAAC;YAAI,CAAC+F,KAAK,EAAE7G;;IAChD;IACA,MAAMqkB,UAAU,CAAC5jB,IAAYoG;YACvB7F;QAAJ,IAAIA,EAAAA,eAAAA,KAAK,CAACP,GAAG,CAAC6K,EAAE,qBAAZtK,YAAc,CAAC6F,KAAK,MAAKjB,WAAW;QACxC,OAAO,AAACkQ,KAAKrV,IAAI6K,EAAE,AAA4B,CAACzE,KAAK;IACvD;IACA,MAAMxG,SAASF,SAASC;IACxB,MAAMkkB,QAAQza,eAAe;IAC7B,MAAM0a,SAAS,CAACD,SAASza,eAAe;IACxC,MAAM2a,WAAW3a,eAAe,eAAeya,SAASza,eAAe;IAEvE,IAAImU,SAAS;IACb,IAAInN,QAAQ;IACZ,KAAK,MAAM,EAAEpQ,EAAE,EAAEK,IAAI,EAAE,IAAIT,OAAQ;YAYnBS,UAU6BA;QArB3C,4EAA4E;QAC5E,IAAIA,KAAKS,WAAW,KAAK,SAAS;gBAEdT;YADlBkd,UAAU;YACV,IAAIA,SAAS,KAAKld,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,SAASqjB,UAAU1jB,IAAI;QACvE;QACA,qDAAqD;QACrD,IAAIK,KAAKS,WAAW,KAAK,SAAS;gBAC5BT,cACAA;YADJ,IAAIA,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,WAAW,MAAK,MAAMqjB,UAAU1jB,IAAI;YACrD,IAAIK,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,QAAQqjB,UAAU1jB,IAAI;QACxD;QACA,qDAAqD;QACrD,IAAI,CAAC6jB,SAASxjB,EAAAA,WAAAA,KAAKwK,EAAE,qBAAPxK,QAAS,CAAC,aAAa,MAAK8E,WAAWye,QAAQ5jB,IAAI;QACjE,uEAAuE;QACvE,IAAIe,UAAUV,UAAU,QAAQ;YAC9B+P,SAAS;YACT,IAAI2T,YAAY3T,QAAQ,GAAG;oBACrB/P,cACAA;gBADJ,IAAIA,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,YAAY,MAAK,QAAQqjB,UAAU1jB,IAAI;gBACxD,IAAIK,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK,QAAQqjB,UAAU1jB,IAAI;YACxD;QACF;QACA,oEAAoE;QACpE,IAAI8jB,UAAUzjB,KAAKS,WAAW,KAAKmQ,QAAQ5Q,EAAAA,cAAAA,KAAKW,KAAK,qBAAVX,WAAY,CAAC,YAAY,MAAK,MAAM;YAC7E,MAAMsU,MAAMpD,iBAAiBxL,IAAI,CAAC,CAACvD;oBAAQnC;uBAAAA,EAAAA,WAAAA,KAAKwK,EAAE,qBAAPxK,QAAS,CAACmC,IAAI,MAAK2C;;YAC9D,IAAIwP,KAAK;oBACOtU,WAEVA;gBAFJ,MAAMd,SAAQc,YAAAA,KAAKwK,EAAE,qBAAPxK,SAAS,CAACsU,IAAI;gBAC5B,KAAK,MAAMnS,OAAO+O,iBAAkBqS,QAAQ5jB,IAAIwC;gBAChD,IAAInC,EAAAA,eAAAA,KAAKW,KAAK,qBAAVX,YAAY,CAAC,UAAU,MAAK8E,WAAWwe,QAAQ3jB,IAAI,WAAW,OAAOT,UAAU,WAAWA,QAAQ;YACxG;QACF;IACF;IAEA,mDAAmD;IACnD,IAAIukB,QAAQ;QACV,MAAM3T,WAAWvQ,OACdZ,GAAG,CAAC,CAACkC,QAAW,CAAA;gBAAElB,IAAIkB,MAAMlB,EAAE;gBAAE2E,OAAOC,eAAerE,KAAK,CAACW,MAAMlB,EAAE,CAAC;YAAE,CAAA,GACvE+C,MAAM,CAAC,CAACuG,QAAkDA,MAAM3E,KAAK,KAAK;QAC7E,MAAMgM,OAAOvH,eAAe,UAAUA,eAAe;QACrD,MAAM4a,UAAU7T,SAAS8T,SAAS,CAAC,CAACvT,UAAYA,QAAQ/L,KAAK,KAAK;QAClE,qGAAqG;QACrG,MAAMuf,QAAQvT,OAAOqT,UAAU;QAC/B,IAAInT,WAA0BF,OAAO,IAAI;QACzC,IAAK,IAAI/P,QAAQ4L,KAAKkG,GAAG,CAACwR,OAAO,IAAIA,SAAS,KAAKtjB,QAAQuP,SAAS/P,MAAM,EAAEQ,SAAS,EAAG;YACtF,MAAM8P,UAAUP,QAAQ,CAACvP,MAAM;YAC/B,uEAAuE;YACvE,MAAMujB,UAAU/a,eAAe,YAAYxI,UAAUojB;YACrD,IAAIrf,QAAQ+L,QAAQ/L,KAAK,KAAK,KAAK,CAACwf,UAAU,IAAIzT,QAAQ/L,KAAK;YAC/DkM,mBAAAA,WAAAA,WAAalM,QAAQ;YACrB,IAAIA,QAAQkM,WAAW,GAAGlM,QAAQkM,WAAW;YAC7C,IAAIlM,UAAU+L,QAAQ/L,KAAK,EAAEgf,QAAQjT,QAAQ1Q,EAAE,EAAE,aAAa,CAAC,CAAC,EAAE2E,OAAO;YACzEkM,WAAWlM;QACb;IACF;IAEA,0FAA0F;IAC1F,IAAImf,QAAQ;QACV,MAAMnW,UAA0B;YAAE1N,QAAQN,KAAKM,MAAM;YAAEM;QAAM;QAC7D,KAAK,MAAMW,SAASxB,SAASiO,SAAU;gBAMrBtN;YALhB,IAAI,CAAC4V,gBAAgBzV,GAAG,CAACU,MAAMb,IAAI,CAACS,WAAW,GAAG;YAClD,MAAMyK,SAASiL,gBAAgBtV,MAAMb,IAAI;YACzC,MAAMuW,OAAOrL,SAAS+K,OAAO3I,SAASzM,SAAS;YAC/C,IAAI,CAAC0V,QAAQA,KAAKrL,MAAM,KAAKA,QAAQ;YACrC,MAAMlL,OAAOgV,KAAKnU,MAAMlB,EAAE;YAC1BK,KAAKwK,EAAE,GAAG,cAAMxK,YAAAA,KAAKwK,EAAE,YAAPxK,YAAW,CAAC;gBAAIoO,OAAO,GAAGlD,OAAO,aAAa,CAAC;;QACjE;IACF;IACA,OAAO6J,OAAOrQ,IAAI,GAAI,aAAKpF;QAAMY;SAAgBZ;AACnD;AAEA;;;;;CAKC,GACD,OAAO,SAASykB,+BAA+BlX,KAAc,EAAE9D,UAAwB;IACrF,IAAI,CAAC9J,SAAS4N,UAAU,OAAOA,KAAK,CAAC,SAAS,KAAK,YAAY,CAAC5N,SAAS4N,KAAK,CAAC,QAAQ,GAAG,OAAOA;IACjG,MAAMmX,WAAWvlB,OAAOkF,OAAO,CAACkJ,KAAK,CAAC,QAAQ,EAAEnK,MAAM,CACpD,CAAC,GAAG1C,KAAK,GACPf,SAASe,SACT,OAAOA,IAAI,CAAC,cAAc,KAAK,YAC9BA,CAAAA,IAAI,CAAC,QAAQ,KAAK8E,aAAa7F,SAASe,IAAI,CAAC,QAAQ,CAAA,KACrDA,CAAAA,IAAI,CAAC,KAAK,KAAK8E,aAAa7F,SAASe,IAAI,CAAC,KAAK,CAAA,KAC/CA,CAAAA,IAAI,CAAC,QAAQ,KAAK8E,aAChB3F,MAAMC,OAAO,CAACY,IAAI,CAAC,QAAQ,KAAKA,IAAI,CAAC,QAAQ,CAAC+D,KAAK,CAAC,CAACpB,QAAU,OAAOA,UAAU,SAAS;IAEhG,MAAMrD,OAAO;QACXM,QAAQiN,KAAK,CAAC,SAAS;QACvB3M,OAAOzB,OAAOiX,WAAW,CAACsO;IAC5B;IACA,MAAM1W,UAAU8V,wBAAwB9jB,MAAMyJ;IAC9C,OAAOuE,YAAYhO,OAAOuN,QAAQ,aAAKA;QAAO3M,OAAO,aAAK2M,KAAK,CAAC,QAAQ,EAAKS,QAAQpN,KAAK;;AAC5F;AAWA;;;;CAIC,GACD,OAAO,SAAS+jB,uBACdpX,KAAc,EACd9D,UAAwB,EACxB5D,UAAiC,CAAC,CAAC,EACnCD,aAAwC,EAAE;IAE1C,MAAMgf,UAAUpL,oBAAoBjM;IACpC,yEAAyE;IACzE,0EAA0E;IAC1E,yBAAyB;IACzB,MAAMsX,cAAc/C,uBAAuBvU;IAC3C,IAAIsX,YAAYpkB,MAAM,EAAE;QACtB,OAAO;YAAEqkB,IAAI;YAAO9kB,MAAM;YAAMsG,YAAY;mBAAIue;mBAAgBD;aAAQ;YAAErD,OAAO;YAAMwD,MAAM;QAAK;IACpG;IACA,MAAMC,YAAY1mB,mBAAmBiP,OAAO3O,iBAAiB,CAAC6K,WAAW,EAAE5D;IAC3E,IAAImf,UAAUF,EAAE,KAAK,OAAO;QAC1B,OAAO;YACLA,IAAI;YACJ9kB,MAAM;YACNsG,YAAY;gBACV;oBACE7G,MAAM;oBACNiH,MAAM,CAAC,KAAK,EAAEse,UAAUte,IAAI,EAAE;oBAC9BhH,SAAS,CAAC,kCAAkC,EAAE+J,WAAW,CAAC,CAAC;oBAC3D2Y,QAAQ4C,UAAUC,KAAK;gBACzB;mBACGL;aACJ;YACDrD,OAAO;YACPwD,MAAM;QACR;IACF;IACA,MAAM/kB,OAAuB;QAC3BM,QAAQ0kB,UAAU1kB,MAAM;QACxBM,OAAOokB,UAAUpkB,KAAK;IACxB;IACA,mGAAmG;IACnG,MAAMskB,SAAS,IAAI3iB,IAAIpD,OAAOkF,OAAO,CAAC2gB,UAAUG,SAAS,EAAE9lB,GAAG,CAAC,CAAC,CAACgB,IAAIkiB,OAAO,GAAK;YAACA;YAAQliB;SAAG;IAC7F,MAAMqO,UAAU/O,SAAS4N,UAAU5N,SAAS4N,KAAK,CAAC,QAAQ,IAAIA,KAAK,CAAC,QAAQ,GAAG,CAAC;IAChF,8EAA8E;IAC9E,wEAAwE;IACxE,MAAM6X,YAAY,CAAC/kB;YACF2kB;QAAf,MAAMzC,UAASyC,0BAAAA,UAAUG,SAAS,CAAC9kB,GAAG,YAAvB2kB,0BAA2B3kB;QAC1C,OAAOwF,QAAQwf,WAAW,GAAGxf,QAAQwf,WAAW,CAAC9C,UAAU7T,OAAO,CAAC6T,OAAO;IAC5E;IACA,oGAAoG;IACpG,MAAM+C,WAAW,CAACjlB;YAAgC2kB;eAARtW,OAAO,EAACsW,0BAAAA,UAAUG,SAAS,CAAC9kB,GAAG,YAAvB2kB,0BAA2B3kB,GAAG;;IAChF,MAAMiG,aAAa;WACdse;QACH,sEAAsE;QACtE,iEAAiE;QACjE,kDAAkD;WAC9Cnb,eAAe,SAAS,EAAE,GAAG9D,uBAAuB3F,MAAM4F,YAAYC;WACvE2D,oBAAoBxJ,MAAMyJ;WAC1BG,kBAAkB5J,MAAMyJ;WACxBqB,oBAAoB9K,MAAMyJ;WAC1BsN,qBAAqB/W,MAAMyJ;WAC3B4B,oBAAoBrL,MAAMyJ,YAAY5D,QAAQyF,KAAK;WACnD4D,gBAAgBlP;WAChBuP,wBAAwBvP,MAAM6F;WAC9BoK,mBAAmBjQ,MAAM6F;WACzByS,2BAA2BtY,MAAMyJ,YAAY5D;WAC7C2S,8BAA8BxY,MAAMyJ,YAAY5D,SAASuf,WAAWE;WACpE/U,wBAAwBvQ,MAAMyJ;WAC9B2H,kBAAkBpR,MAAMyJ;WACxB0J,wBAAwBnT,MAAMyJ,YAAY2b;WAC1C/K,mBAAmBO,WAAW5a,MAAM6F,UAAUA,QAAQ0U,OAAO;WAC7D6B,eAAe4I,UAAU3I,OAAO,EAAE3N,SAAS,CAACrO;gBAAO6kB;oBAAAA,cAAAA,OAAO3hB,GAAG,CAAClD,eAAX6kB,cAAkB7kB;;WACrEwb,oBAAoB7b;WACpBod,oBAAoBpd,MAAMyJ,YAAY5D;WACtC+Y,iBAAiB5e;KACrB;IACD,MAAMuhB,QAAQlB,cAAcrgB,MAAMyJ,YAAY5D;IAC9CS,WAAWvF,IAAI,IAAIugB,iBAAiBC,OAAO9X,YAAYzJ,MAAM6F;IAC7D,OAAO;QACLif,IAAIxe,WAAW7F,MAAM,KAAK;QAC1BT,MAAMglB;QACN1e;QACAib;QACAwD,MAAMrD,qBAAqBH,OAAO9X;IACpC;AACF;AAaA,MAAM8b,iBAAiB,IAAIplB,IAAI;IAC7B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,SAASqlB,WAAW5lB,KAAa;IAC/B,OAAOA,MACJoJ,WAAW,GACXD,OAAO,CAAC,eAAe,KACvBD,KAAK,CAAC,KACN1F,MAAM,CAACJ,SACP3D,GAAG,CAAC,CAACsJ,OACJA,KAAKlI,MAAM,GAAG,KAAKkI,KAAK8c,QAAQ,CAAC,QAAQ,CAAC9c,KAAK8c,QAAQ,CAAC,QAAQ9c,KAAK3G,KAAK,CAAC,GAAG,CAAC,KAAK2G,MAErFvF,MAAM,CAAC,CAACuF,OAAS,CAAC4c,eAAe1kB,GAAG,CAAC8H;AAC1C;AAEA;;;CAGC,GACD,OAAO,SAAS+c,aAAaC,IAAY,EAAEC,KAAa;IACtD,MAAM5Y,IAAI,IAAI7M,IAAIqlB,WAAWG;IAC7B,MAAMvZ,IAAI,IAAIjM,IAAIqlB,WAAWI;IAC7B,IAAI,CAAC5Y,EAAE5H,IAAI,IAAI,CAACgH,EAAEhH,IAAI,EAAE,OAAO;IAC/B,MAAM,CAACygB,OAAOC,MAAM,GAAG9Y,EAAE5H,IAAI,IAAIgH,EAAEhH,IAAI,GAAG;QAAC4H;QAAGZ;KAAE,GAAG;QAACA;QAAGY;KAAE;IACzD,OACE;WAAI6Y;KAAM,CAACphB,KAAK,CAAC,CAACkE,OAASmd,MAAMjlB,GAAG,CAAC8H,UACpCkd,CAAAA,MAAMzgB,IAAI,KAAK0gB,MAAM1gB,IAAI,IAAIygB,MAAMzgB,IAAI,IAAI,CAAA;AAEhD;AAEA,SAAS2gB,eAAeC,SAAiC;IACvD,MAAM7gB,QAAQ,IAAI5C;IAClB,IAAI,CAACyjB,WAAW,OAAO7gB;IACvB,MAAMrE,MAAM,CAACiT,MAA6BiF;QACxC,KAAK,MAAMiN,OAAOlS,KAAM5O,MAAM7B,GAAG,CAAC2iB,IAAI5lB,EAAE,EAAE2Y;IAC5C;IACAlY,IAAIklB,UAAUE,UAAU,EAAE;IAC1BplB,IAAIklB,UAAUG,OAAO,EAAE;IACvBrlB,IAAIklB,UAAUI,SAAS,EAAE;IACzBtlB,IAAIklB,UAAUtO,KAAK,EAAE;IACrB5W,IAAIklB,UAAUK,QAAQ,EAAE;IACxBvlB,IAAIklB,UAAUM,WAAW,EAAE;IAC3BxlB,IAAIklB,UAAUO,OAAO,EAAE;IACvB,OAAOphB;AACT;AAEA,oFAAoF,GACpF,SAASqhB,QACPlX,GAAkB,EAClBmX,IAAiB,EACjBthB,KAA8B;cAIvBA;QADyB/H;IADhC,IAAI,CAACkS,KAAK,OAAO;IACjB,IAAI7R,eAAe6R,MAAM,gBAAOlS,mBAAAA,gBAAgBqpB,MAAMnX,yBAAtBlS,iBAA4B4b,IAAI,mBAAI;IACpE,QAAO7T,aAAAA,MAAM5B,GAAG,CAAC+L,gBAAVnK,aAAkB;AAC3B;AAEA,SAASuhB,aAAaD,IAAiB;IACrC,OAAOA,KAAKF,OAAO,CAAChiB,OAAO,CAAC,CAACoiB,QAAQC,cACnCD,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,SAASC,eAAkB,CAAA;gBAC9CH;gBACAC;gBACAC;gBACApZ,MAAM,CAAC,QAAQ,EAAEmZ,YAAY,WAAW,EAAEE,aAAa,CAAC,CAAC;YAC3D,CAAA;AAEJ;AAEA,MAAMC,qBACJ;AACF,MAAMC,oBACJ;AAEF;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,kBACdR,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,IAAIA,CAAAA,gCAAAA,aAAcphB,kBAAkB,MAAK,OAAO,OAAO,EAAE;IACzD,MAAMX,QAAQ4gB,eAAeC;IAC7B,MAAM1f,aAAoC,EAAE;IAC5C,MAAM6gB,kBAAkB,CAACC,OACvBA,KAAK3lB,IAAI,CAAC,CAAC6N,MAAQkX,QAAQlX,KAAKmX,MAAMthB,WAAW;IACnD,MAAM6E,QAAQ,CAACod,OACbA,KAAK3lB,IAAI,CAAC,CAAC6N,MAAQ;gBAAC;gBAAW;aAAa,CAACpG,QAAQ,CAAC/F,OAAOqjB,QAAQlX,KAAKmX,MAAMthB;IAClF,MAAMf,WAAW8iB,CAAAA,gCAAAA,aAAc1gB,eAAe,IAC1C,EAAE,GACFkgB,aAAaD,MAAMrjB,MAAM,CACvB,CAAC,EAAEyjB,OAAO,EAAE,GACVA,QAAQjU,KAAK,IAAI1Q,uBAAuB,CAACilB,gBAAgBN,QAAQO,IAAI,KAAK,CAACpd,MAAM6c,QAAQO,IAAI;IAErG,IAAIhjB,SAAS3D,MAAM,EAAE;QACnB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOtV,SAAS/E,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC3C;IACF;IACA,MAAM4Z,SAAS,IAAI9kB;IACnB,KAAK,MAAMoH,SAAS+c,aAAaD,MAAO;YAGjBY;QAFrB,MAAMxkB,MAAM2iB,WAAW7b,MAAMkd,OAAO,CAACpgB,IAAI,EAAE1E,IAAI,CAAC;QAChD,IAAI,CAACc,OAAOkkB,mBAAmBvlB,IAAI,CAACmI,MAAMkd,OAAO,CAACpgB,IAAI,GAAG;QACzD4gB,OAAO/jB,GAAG,CAACT,KAAK;gBAAKwkB,cAAAA,OAAO9jB,GAAG,CAACV,gBAAXwkB,cAAmB,EAAE;YAAG1d;SAAM;IACrD;IACA,KAAK,MAAMtF,WAAWgjB,OAAO1lB,MAAM,GAAI;QACrC,MAAM4kB,UAAU,IAAIpmB,IAAIkE,QAAQhF,GAAG,CAAC,CAACsK,QAAUA,MAAMid,WAAW;QAChE,IAAIL,QAAQnhB,IAAI,GAAG,GAAG;QACtB,MAAM2B,SAAS1C,QACZhF,GAAG,CAAC,CAACsK,QAAUA,MAAMkd,OAAO,CAACO,IAAI,CAAChkB,MAAM,CAAC,CAACkM,MAAQkX,QAAQlX,KAAKmX,MAAMthB,WAAW,cAChF3B,MAAM,CAAC,CAAC8jB,QAAQC,OAASD,OAAOlkB,MAAM,CAAC,CAACkM,MAAQiY,KAAKre,QAAQ,CAACoG;QACjE,IAAIvI,OAAOtG,MAAM,EAAE;QACnB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,KAAK,EAAE2E,OAAO,CAAC,EAAE,CAACwiB,OAAO,CAACpgB,IAAI,CAAC,wBAAwB,EAAE8f,QAAQnhB,IAAI,CAAC,+DAA+D,CAAC;YAChJsU,OAAOrV,QAAQhF,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC1C;IACF;IACA,OAAOnH;AACT;AAEA,kGAAkG,GAClG,OAAO,MAAMkhB,6BAA6B,EAAC;AAE3C,2HAA2H,GAC3H,MAAMC,gBAAgB;AAEtB,iDAAiD,GACjD,SAASC,SAASjhB,IAAY;IAC5B,MAAMmV,QAAQnV,KAAKwC,IAAI;IACvB,IAAI,MAAMzH,IAAI,CAACoa,QAAQ,OAAOA;IAC9B,OAAO,cAAcpa,IAAI,CAACoa,SAAS,GAAGA,MAAM5Z,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG4Z,MAAM,CAAC,CAAC;AAC7E;AAEA;;;;;CAKC,GACD,SAAS+L,gBACPd,OAA2B,EAC3BJ,IAAiB,EACjBthB,KAA8B,EAC9B6gB,SAAiC;;QAGnByB,sBAAAA;IADd,IAAIZ,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC6N,MAAQ;YAAC;YAAW;SAAa,CAACpG,QAAQ,CAAC/F,OAAOqjB,QAAQlX,KAAKmX,MAAMthB,WAAW,OAAO;IAC9G,MAAMiS,iBAAQqQ,sBAAAA,cAAcxb,IAAI,CAAC4a,QAAQpgB,IAAI,uBAA/BghB,uBAAAA,mBAAkC,CAAC,EAAE,qBAArCA,qBAAuCxe,IAAI,qBAAM;IAC/D,MAAMid,aAAaW,QAAQO,IAAI,CAAChkB,MAAM,CAAC,CAACkM,MAAQkX,QAAQlX,KAAKmX,MAAMthB,WAAW;IAC9E,IAAI+gB,WAAWzlB,MAAM,EAAE;YAGjBrD,kBACA4oB;QAHJ,MAAM,CAAChgB,MAAM,GAAGkgB;QAChB,MAAMrY,QAAQpQ,eAAeuI,UACzB5I,mBAAAA,gBAAgBqpB,MAAMzgB,2BAAtB5I,iBAA8BqJ,IAAI,GAClCuf,8BAAAA,6BAAAA,UAAWE,UAAU,CAAC9f,IAAI,CAAC,CAAC6f,MAAQA,IAAI5lB,EAAE,KAAK2F,2BAA/CggB,2BAAuDvf,IAAI;QAC/D,OAAO;YACL5D,KAAK,CAAC,UAAU,EAAEqjB,WAAW7mB,GAAG,CAAC,CAACiQ,MAAQA,IAAItG,WAAW,IAAIpG,IAAI,GAAGb,IAAI,CAAC,MAAM;YAC/E0E,MAAMihB,SAAStQ,SAASvJ,SAAS7H;YACjCkgB;QACF;IACF;IACA,MAAMtK,QAAQ4J,WAAWpO,OAAOrV,IAAI,CAAC;IACrC,OAAO6Z,QAAQ;QAAE/Y,KAAK,CAAC,MAAM,EAAE+Y,OAAO;QAAEnV,MAAMihB,SAAStQ;QAAQ8O,YAAY,EAAE;IAAC,IAAI;AACpF;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAAS0B,qBACdnB,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,MAAM/hB,QAAQ4gB,eAAeC;IAC7B,MAAM1f,aAAoC,EAAE;IAC5CmgB,KAAKF,OAAO,CAAC5M,OAAO,CAAC,CAACgN,QAAQC;QAC5B,IAAIiB,MAAuF,EAAE;QAC7F,MAAMC,QAAQ;YACZ,IAAID,IAAIpnB,MAAM,IAAI+mB,4BAA4B;gBAC5C,MAAM1lB,QAAQ+lB,IAAIxoB,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,CAAC,EAAE0lB,OAAOjO,QAAQ,CAACzX,MAAM,CAACwF,IAAI,CAAC,CAAC,CAAC;gBACvE,MAAM2S,SAAS,GAAGtX,MAAME,KAAK,CAAC,GAAG,CAAC,GAAGD,IAAI,CAAC,MAAM,KAAK,EAAED,KAAK,CAACA,MAAMrB,MAAM,GAAG,EAAE,EAAE;gBAChF,MAAM,CAAC,EAAEuY,IAAI,EAAE,CAAC,GAAG6O;gBACnB,+FAA+F;gBAC/F,MAAME,YACJ,CAAC/O,KAAKkN,UAAU,CAACzlB,MAAM,IACvBymB,CAAAA,gCAAAA,aAAcphB,kBAAkB,MAAK,SACrC,EAACohB,gCAAAA,aAAc1gB,eAAe,KAC9BqhB,IAAIpnB,MAAM,IAAIyB;gBAChB,MAAM2kB,UAAU;oBAAEpgB,MAAMuS,KAAKvS,IAAI;oBAAE2gB,MAAMW,YAAY;wBAAC;qBAAa,GAAG/O,KAAKkN,UAAU;oBAAEtT,OAAOiV,IAAIpnB,MAAM;gBAAC;gBACzG,MAAM6Y,UAAUyO,YACZ,CAAC,4IAA4I,EAAE7jB,KAAKC,SAAS,CAAC0iB,SAAS,CAAC,CAAC,GACzK,CAAC,EAAE,EAAE3iB,KAAKC,SAAS,CAAC0iB,SAAS,CAAC,CAAC;gBACnCvgB,WAAWvF,IAAI,CAAC;oBACdtB,MAAM;oBACNiH,MAAM;oBACNhH,SAAS,CAAC,aAAa,EAAE0Z,OAAO,uGAAuG,EAAEyO,IAAIpnB,MAAM,CAAC,aAAa,EAAE6Y,SAAS;oBAC5KI,OAAOmO,IAAIxoB,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,QAAQ,EAAE2lB,YAAY,WAAW,EAAE3lB,MAAM,CAAC,CAAC;gBAC5E;YACF;YACA4mB,MAAM,EAAE;QACV;QACAlB,OAAOjO,QAAQ,CAACiB,OAAO,CAAC,CAACkN,SAAS5lB;YAChC,MAAM+X,OAAO6N,QAAQjU,KAAK,KAAK,IAAI+U,gBAAgBd,SAASJ,MAAMthB,OAAO6gB,aAAa;YACtF,IAAI,CAAChN,QAAS6O,IAAIpnB,MAAM,IAAIonB,GAAG,CAAC,EAAE,CAAC7O,IAAI,CAACnW,GAAG,KAAKmW,KAAKnW,GAAG,EAAGilB;YAC3D,IAAI9O,MAAM6O,IAAI9mB,IAAI,CAAC;gBAAEE;gBAAO+X;YAAK;QACnC;QACA8O;IACF;IACA,OAAOxhB;AACT;AAEA,+FAA+F,GAC/F,SAAS0hB,aACPvB,IAAiB,EACjBthB,KAA8B,EAC9B6T,IAAgB;IAEhB,OAAO0N,aAAaD,MAAMliB,OAAO,CAAC,CAAC,EAAEsiB,OAAO,EAAEpZ,IAAI,EAAE,GAClDoZ,QAAQO,IAAI,CAAC7iB,OAAO,CAAC,CAAC+K,KAAKrO,QACzBulB,QAAQlX,KAAKmX,MAAMthB,WAAW6T,OAAO;gBAAC,GAAGvL,KAAK,MAAM,EAAExM,MAAM,CAAC,CAAC;aAAC,GAAG,EAAE;AAG1E;AAEA,4EAA4E,GAC5E,SAASgnB,YAAYxhB,IAAY;IAC/B,OAAOA,KAAKuC,WAAW,GAAGD,OAAO,CAAC,eAAe;AACnD;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASmf,iBACdzB,IAAiB,EACjBT,YAAoC,IAAI;IAExC,IAAI,CAACS,KAAK0B,MAAM,CAAC1nB,MAAM,EAAE,OAAOgmB;IAChC,MAAMthB,QAAQ4gB,eAAeC;IAC7B,MAAMoC,UAAU,CAAC9Y;QACf,IAAI,CAACA,OAAOnK,MAAMtE,GAAG,CAACyO,QAAQlS,gBAAgBqpB,MAAMnX,MAAM,OAAOA;QACjE,MAAMzM,MAAMolB,YAAYxqB,eAAe6R,OAAOA,IAAItN,KAAK,CAAC,OAAOvB,MAAM,IAAI6O;QACzE,IAAI,CAACzM,KAAK,OAAOyM;QACjB,MAAM+Y,UAAU5B,KAAK0B,MAAM,CAAC/kB,MAAM,CAAC,CAACuG,QAAUse,YAAYte,MAAMlD,IAAI,MAAM5D;QAC1E,OAAOwlB,QAAQ5nB,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE4nB,OAAO,CAAC,EAAE,CAAC5hB,IAAI,EAAE,GAAG6I;IAC3D;IACA,IAAIkT,UAAU;IACd,MAAM5U,SAAS,CAAC0B;QACd,MAAM+I,OAAO+P,QAAQ9Y;QACrB,IAAI+I,SAAS/I,KAAKkT,UAAU;QAC5B,OAAOnK;IACT;IACA,MAAMkO,UAAUE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,SAAY,aACzCA;YACH2B,QAAQ1a,OAAO+Y,OAAO2B,MAAM;YAC5BC,UAAU3a,OAAO+Y,OAAO4B,QAAQ;YAChC7P,UAAUiO,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,UAAa,aACvCA;oBACHO,MAAMP,QAAQO,IAAI,CAAC/nB,GAAG,CAAC,CAACiQ;4BAAQ1B;gCAAAA,UAAAA,OAAO0B,gBAAP1B,UAAe0B;;;;IAGnD,OAAOkT,UAAU,aAAKiE;QAAMF;SAAYE;AAC1C;AAEA;;;;CAIC,GACD,OAAO,MAAM+B,uBAAuB,sEAAqE;AAEzG;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,SAASC,qBAAqBhC,IAAiB,EAAES,eAA0C,IAAI;cAGxCvd;IAF5D,MAAMA,QAAQud,gCAAAA,aAAciB,MAAM,CAACO,OAAO;IAC1C,IAAI,EAAC/e,yBAAAA,MAAO4B,OAAO,GAAE,OAAOkb;IAC5B,MAAMkC,MAAM9b,KAAKiG,GAAG,SAACoU,gCAAAA,aAAc0B,WAAW,mBAAIjF,WAAUha,cAAAA,MAAMgc,IAAI,YAAVhc,cAAcga;IAC1E,MAAM0C,WAAWI,KAAK0B,MAAM,CAAC/kB,MAAM,CAAC,CAACuM,MAAQA,IAAIqJ,IAAI,KAAK;IAC1D,sEAAsE;IACtE,wEAAwE;IACxE,MAAM6P,WAAWxrB,uBAAuBopB;IACxC,MAAMqC,OAAO,CAACnZ,MACZ,CAACkZ,SAAShoB,GAAG,CAAC8O,IAAIlJ,IAAI,CAACwC,IAAI,GAAGD,WAAW,OACxCwf,CAAAA,qBAAqBhnB,IAAI,CAACmO,IAAIlJ,IAAI,KAAKkJ,IAAIoZ,MAAM,CAACtnB,IAAI,CAAC,CAACunB,QAAUR,qBAAqBhnB,IAAI,CAACwnB,OAAM;IACrG,IAAI,CAAC3C,SAAS5kB,IAAI,CAACqnB,SAAU,CAAA,CAACxpB,OAAOoN,QAAQ,CAACic,QAAQtC,SAAS5lB,MAAM,IAAIkoB,GAAE,GAAI,OAAOlC;IACtF,MAAM5Y,QAAQ,CAACyB,KAAgC7I,OAC7C,CAAC,CAAC6I,OAAO7R,eAAe6R,QAAQA,IAAItN,KAAK,CAAC,OAAOvB,MAAM,EAAEwI,IAAI,GAAGD,WAAW,OAAOvC,KAAKwC,IAAI,GAAGD,WAAW;IAC3G,qEAAqE;IACrE,uCAAuC;IACvC,MAAMuY,QAAQ,CAAC9a,OACb,AAACoiB,CAAAA,SAAShoB,GAAG,CAAC4F,KAAKwC,IAAI,GAAGD,WAAW,MAAM,IAAI,CAAA,IAC/Cyd,KAAKF,OAAO,CAAC/iB,MAAM,CACjB,CAACylB,OAAOtC;gBAECA;mBADPsC,QACCpb,CAAAA,OAAM8Y,iBAAAA,OAAOuC,MAAM,qBAAbvC,eAAe+B,OAAO,EAAEjiB,QAAQ,IAAI,CAAA,IAC3CkgB,OAAOjO,QAAQ,CAACtV,MAAM,CAAC,CAACyjB,UAAYA,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC6N,MAAQzB,MAAMyB,KAAK7I,QAAQhG,MAAM;WAC1F;IAEJ,MAAM0oB,SAAS9C,SACZjjB,MAAM,CAAC,CAACuM,MAAQ,CAACmZ,KAAKnZ,MACtBtQ,GAAG,CAAC,CAACsQ,KAAK1O,QAAW,CAAA;YAAEwF,MAAMkJ,IAAIlJ,IAAI;YAAExF;YAAOsgB,OAAOA,MAAM5R,IAAIlJ,IAAI;QAAE,CAAA,GACrE7D,IAAI,CAAC,CAACoK,GAAGZ,IAAMA,EAAEmV,KAAK,GAAGvU,EAAEuU,KAAK,IAAIvU,EAAE/L,KAAK,GAAGmL,EAAEnL,KAAK;IACxD,MAAM8hB,OAAO,IAAI5iB,IAAIgpB,OAAOnnB,KAAK,CAAC,GAAG6K,KAAKkG,GAAG,CAAC,GAAG4V,MAAMtpB,GAAG,CAAC,CAACsQ,MAAQA,IAAIlJ,IAAI,CAACwC,IAAI,GAAGD,WAAW;IAC/F,MAAMogB,UAAU,IAAIjpB,IAAIkmB,SAAShnB,GAAG,CAAC,CAACsQ,MAAQA,IAAIlJ,IAAI,CAACwC,IAAI,GAAGD,WAAW,IAAI5F,MAAM,CAAC,CAACqD,OAAS,CAACsc,KAAKliB,GAAG,CAAC4F;IACxG,MAAM4iB,YAAY,CAAC/Z,MAAmC;eAAI8Z;SAAQ,CAAC3nB,IAAI,CAAC,CAACgF,OAASoH,MAAMyB,KAAK7I;IAC7F,OAAO,aACFggB;QACH0B,QAAQ1B,KAAK0B,MAAM,CAChB/kB,MAAM,CAAC,CAACuM,MAAQA,IAAIqJ,IAAI,KAAK,aAAa,CAACoQ,QAAQvoB,GAAG,CAAC8O,IAAIlJ,IAAI,CAACwC,IAAI,GAAGD,WAAW,IACnF,2EAA2E;SAC1E3J,GAAG,CAAC,CAACsQ,MAASA,IAAIqJ,IAAI,KAAK,UAAUqQ,UAAU1Z,IAAI2Z,QAAQ,IAAIC,gBAAgB5Z,OAAOA;QACzF4W,SAASE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,SAAY,aAClCA;gBACHuC,QAAQvC,OAAOuC,MAAM,IAAIG,UAAU1C,OAAOuC,MAAM,CAACR,OAAO,IAAI,OAAO/B,OAAOuC,MAAM;gBAChFxQ,UAAUiO,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,UAC7BA,QAAQO,IAAI,CAAC3lB,IAAI,CAAC4nB,aACd,aACKxC;wBACHO,MAAMP,QAAQO,IAAI,CAAChkB,MAAM,CAAC,CAACkM,MAAQ,CAAC+Z,UAAU/Z;wBAC9CsD,OAAO/F,KAAKiG,GAAG,CAAC+T,QAAQjU,KAAK,EAAExQ,0BAA0B;yBAE3DykB;;;AAIZ;AAEA,wEAAwE,GACxE,SAAS0C,gBAAwDC,QAAW;IAC1E,MAAMC,OAAO,aAAKD;IAClB,OAAOC,KAAKH,QAAQ;IACpB,OAAOG;AACT;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASC,yBACdjD,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;;IAE9C,IAAI,CAACT,KAAK0B,MAAM,CAAC1mB,IAAI,CAAC,CAACkO,MAAQA,IAAIqJ,IAAI,KAAK,UAAUrJ,IAAI2Z,QAAQ,GAAG,OAAO7C;IAC5E,MAAMkD,eAAO3D,6BAAAA,UAAWK,QAAQ,mBAAI,EAAE;IACtC,MAAMuD,YAAY,CAAC1C,gBAAgBA,aAAaiB,MAAM,CAACO,OAAO,CAACnd,OAAO;IACtE,IAAIiX,UAAU;IACd,MAAM2F,SAAS1B,KAAK0B,MAAM,CAAC9oB,GAAG,CAAC,CAACsQ;QAC9B,IAAIA,IAAIqJ,IAAI,KAAK,UAAU,CAACrJ,IAAI2Z,QAAQ,EAAE,OAAO3Z;QACjD,MAAML,MAAMK,IAAI2Z,QAAQ,CAACrgB,IAAI;QAC7B,IAAIxL,eAAe6R,MAAM;gBACNlS,kBAEbE;YAFJ,IAAIssB,aAAaxsB,EAAAA,mBAAAA,gBAAgBqpB,MAAMnX,yBAAtBlS,iBAA4B4b,IAAI,MAAK,WAAW,OAAOrJ;YACxE,mEAAmE;YACnE,IAAIrS,EAAAA,iBAAAA,cAAcmpB,MAAMnX,yBAApBhS,eAA0BusB,EAAE,MAAK1sB,yBAAyB,OAAOwS;QACvE,OAAO;YACL,IAAIga,KAAKloB,IAAI,CAAC,CAACwkB,MAAQA,IAAI5lB,EAAE,KAAKiP,MAAM,OAAOK;YAC/C,MAAM0X,SAASsC,KAAKvjB,IAAI,CAAC,CAAC6f,MAAQP,aAAaO,IAAIxf,IAAI,EAAE6I;YACzD,IAAI+X,QAAQ;gBACV7E,UAAU;gBACV,OAAO,aAAK7S;oBAAK2Z,UAAUjC,OAAOhnB,EAAE;;YACtC;QACF;QACAmiB,UAAU;QACV,OAAO+G,gBAAgB5Z;IACzB;IACA,MAAM3B,UAAU,aAAKyY;QAAM0B;;IAC3B,MAAMU,WAAWxrB,uBAAuB2Q;IACxC,MAAM8b,WAAW,CAACxa,MAChB7R,eAAe6R,QAAQuZ,SAAShoB,GAAG,CAACyO,IAAItN,KAAK,CAAC,OAAOvB,MAAM,EAAEwI,IAAI,GAAGD,WAAW;IACjF,MAAMud,UAAUE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB;QAChC,MAAMuC,SAASvC,OAAOuC,MAAM,IAAIY,SAASnD,OAAOuC,MAAM,CAACR,OAAO,IAAI,OAAO/B,OAAOuC,MAAM;QACtF,MAAMxQ,WAAWiO,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,UACpCA,QAAQO,IAAI,CAAC3lB,IAAI,CAACqoB,YACd,aACKjD;gBACHO,MAAMP,QAAQO,IAAI,CAAChkB,MAAM,CAAC,CAACkM,MAAQ,CAACwa,SAASxa;gBAC7CsD,OAAO/F,KAAKiG,GAAG,CAAC+T,QAAQjU,KAAK,EAAExQ,0BAA0B;iBAE3DykB;QAEN,IAAIqC,WAAWvC,OAAOuC,MAAM,IAAIxQ,SAASjU,KAAK,CAAC,CAACoiB,SAAS5lB,QAAU4lB,YAAYF,OAAOjO,QAAQ,CAACzX,MAAM,GAAG,OAAO0lB;QAC/GnE,UAAU;QACV,OAAO,aAAKmE;YAAQuC;YAAQxQ;;IAC9B;IACA,OAAO8J,UAAU,aAAKxU;QAASuY;SAAYE;AAC7C;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASsD,oBACdtD,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,IAAI,CAAClB,aAAaA,UAAUG,OAAO,CAAC1lB,MAAM,GAAG,KAAK,CAACgmB,KAAKF,OAAO,CAAC9lB,MAAM,EAAE,OAAOgmB;IAC/E,MAAMthB,QAAQ4gB,eAAeC;IAC7B,MAAMgE,UAAUvD,KAAK0B,MAAM,CAAC/kB,MAAM,CAAC,CAACuG,QAAUA,MAAMqP,IAAI,KAAK;IAC7D,MAAMiR,SAASxD,KAAKF,OAAO,CAACnjB,MAAM,CAAC,CAACujB,SAAWH,QAAQG,OAAO2B,MAAM,EAAE7B,MAAMthB,WAAW;IACvF,IAAI,CAAC8kB,OAAOxpB,MAAM,EAAE,OAAOgmB;IAC3B,IAAIuD,QAAQvpB,MAAM,KAAK,GAAG;QACxB,MAAMypB,OAAO,CAAC,IAAI,EAAEF,OAAO,CAAC,EAAE,CAACvjB,IAAI,EAAE;QACrC,OAAO,aACFggB;YACHF,SAASE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,SACzBH,QAAQG,OAAO2B,MAAM,EAAE7B,MAAMthB,WAAW,WAAWwhB,SAAS,aAAKA;oBAAQ2B,QAAQ4B;;;IAGvF;IACA,yEAAyE;IACzE,4EAA4E;IAC5E,4EAA4E;IAC5E,uDAAuD;IACvD,MAAMC,kBAAkB,CAACjD,gBAAgBA,aAAaiB,MAAM,CAACG,MAAM,CAAC/c,OAAO;IAC3E,IAAIye,QAAQvpB,MAAM,GAAG,KAAK,CAAC0pB,iBAAiB,OAAO1D;IACnD,MAAM2D,QAAQ,IAAIjqB,IAAIsmB,KAAK0B,MAAM,CAAC9oB,GAAG,CAAC,CAACsK,QAAUA,MAAMlD,IAAI,CAACuC,WAAW;IACvE,MAAMvC,OAAO2jB,MAAMvpB,GAAG,CAAC,iBAAiB,2BAA2B;IACnE,OAAO,aACF4lB;QACH0B,QAAQ;YACN;gBACEnP,MAAM;gBACNvS;gBACA4jB,KAAK;gBACLC,aAAa;gBACbvB,QAAQ;oBAAC;oBAAU;oBAAO;oBAAQ;iBAAS;YAC7C;eACGtC,KAAK0B,MAAM;SACf;QACD5B,SAASE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,SAAY,aAAKA;gBAAQ2B,QAAQ,CAAC,IAAI,EAAE7hB,MAAM;;;AAE7E;AAEA;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAAS8jB,iCACd9D,IAAiB,EACjBT,SAAiC;IAEjC,MAAM7gB,QAAQ4gB,eAAeC;IAC7B,MAAMwE,YAAY,CAAC3D,UACjBE,mBAAmBvlB,IAAI,CAACqlB,QAAQpgB,IAAI,KACpCogB,QAAQO,IAAI,CAAC3iB,KAAK,CAAC,CAAC6K,MAAQkX,QAAQlX,KAAKmX,MAAMthB,WAAW;IAC5D,IAAIqd,UAAU;IACd,MAAM+D,UAAUE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB;QAChC,MAAM5D,OAAO4D,OAAOjO,QAAQ,CAACtV,MAAM,CAAC,CAACyjB,UAAY,CAAC2D,UAAU3D;QAC5D,IAAI9D,KAAKtiB,MAAM,KAAKkmB,OAAOjO,QAAQ,CAACjY,MAAM,IAAI,CAACsiB,KAAKtiB,MAAM,EAAE,OAAOkmB;QACnEnE,UAAU;QACV,OAAO,aAAKmE;YAAQjO,UAAUqK;;IAChC;IACA,OAAOP,UAAU,aAAKiE;QAAMF;SAAYE;AAC1C;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASgE,sBACdhE,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;;IAE9C,MAAMwD,gBAAQxD,gCAAAA,aAAcyD,eAAe,mBAAI;IAC/C,MAAMC,OAAO,CAAC/D,UAAgC5oB,uBAAuB4oB,QAAQpgB,IAAI,KAAKogB,QAAQjU,KAAK,GAAG8X;IACtG,IAAI,CAACjE,KAAKF,OAAO,CAAC9kB,IAAI,CAAC,CAACklB,SAAWA,OAAOjO,QAAQ,CAACjX,IAAI,CAACmpB,QAAQ,OAAOnE;IACvE,MAAM3d,QAAQ,IAAI3I,IAAIynB,qBAAqBnB,MAAMT,WAAWkB,cAAc3iB,OAAO,CAAC,CAAC/E;YAAcA;gBAAAA,mBAAAA,UAAUka,KAAK,YAAfla,mBAAmB,EAAE;;IACtH,IAAIgjB,UAAU;IACd,MAAM+D,UAAUE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,QAAQC;QACxC,IAAI,CAACD,OAAOjO,QAAQ,CAACjX,IAAI,CAACmpB,OAAO,OAAOjE;QACxC,OAAO,aACFA;YACHjO,UAAUiO,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,SAASC;gBACtC,IAAI,CAAC8D,KAAK/D,YAAY/d,MAAMjI,GAAG,CAAC,CAAC,QAAQ,EAAE+lB,YAAY,WAAW,EAAEE,aAAa,CAAC,CAAC,GAAG,OAAOD;gBAC7FrE,UAAU;gBACV,OAAO,aAAKqE;oBAASjU,OAAO8X;;YAC9B;;IAEJ;IACA,OAAOlI,UAAU,aAAKiE;QAAMF;SAAYE;AAC1C;AAUA,yEAAyE,GACzE,SAASoE,gBAAgBpE,IAAiB,EAAET,SAAiC;;IAC3E,OAAO;WACFS,KAAK0B,MAAM,CACX/kB,MAAM,CAAC,CAACuG,QAAUA,MAAMqP,IAAI,KAAK,QACjC3Z,GAAG,CAAC,CAACsK,QAAW,CAAA;gBAAE2F,KAAK,CAAC,IAAI,EAAE3F,MAAMlD,IAAI,EAAE;gBAAEA,MAAMkD,MAAMlD,IAAI;gBAAEujB,SAAS;YAAK,CAAA;WAC5E,SAAChE,6BAAAA,UAAWtO,KAAK,mBAAI,EAAE,EAAErY,GAAG,CAAC,CAACyrB,OAAU,CAAA;gBAAExb,KAAKwb,KAAKzqB,EAAE;gBAAEoG,MAAMqkB,KAAKrkB,IAAI;gBAAEujB,SAAS;YAAM,CAAA;KAC5F;AACH;AAEA,iGAAiG,GACjG,SAASe,cAAczb,GAAW,EAAEmX,IAAiB;IACnD,MAAMuD,UAAUvsB,eAAe6R,OAAOlS,gBAAgBqpB,MAAMnX,OAAO9J;IACnE,OAAOwkB,UAAU,CAAC,IAAI,EAAEA,QAAQvjB,IAAI,EAAE,GAAG6I;AAC3C;AAEA;;;;;CAKC,GACD,SAAS0b,aACPnE,OAA2B,EAC3BoE,OAAoC,EACpCC,MAAmC;QAW5B/B;IATP,MAAMvN,QAAQ,IAAIzb,IAAIqlB,WAAWqB,QAAQpgB,IAAI,EAAErD,MAAM,CAAC,CAACuF,OAASA,SAAS;IACzE,MAAM4Y,QAAQ,CAAC4J,SACb3F,WAAW2F,OAAO1kB,IAAI,EAAErD,MAAM,CAAC,CAACuF,OAASA,SAAS,UAAUiT,MAAM/a,GAAG,CAAC8H,OAAOlI,MAAM;IACrF,MAAM0oB,SAAS;WAAI8B;KAAQ,CAACroB,IAAI,CAC9B,CAACoK,GAAGZ;YAED8e,aAA2BA;eAD5B3J,MAAMnV,KAAKmV,MAAMvU,MACjB,EAACke,cAAAA,OAAO3nB,GAAG,CAAC6I,EAAEkD,GAAG,aAAhB4b,cAAqB,OAAMA,eAAAA,OAAO3nB,GAAG,CAACyJ,EAAEsC,GAAG,aAAhB4b,eAAqB,MACjD5rB,OAAO8M,EAAE4d,OAAO,IAAI1qB,OAAO0N,EAAEgd,OAAO;;IAExC,QAAOb,WAAAA,MAAM,CAAC,EAAE,YAATA,WAAa;AACtB;AAEA,iGAAiG,GACjG,OAAO,MAAMiC,uBAAuB;IAClC3kB,MAAM;IACN4jB,KAAK;IACLtB,QAAQ;QAAC;QAAQ;QAAS;KAAU;AACtC,EAAU;AAEV;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GACD,OAAO,SAASsC,kBACd5E,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,IAAI,CAACvpB,mBAAmBqoB,WAAWkB,eAAe,OAAOT;IACzD,MAAMthB,QAAQ4gB,eAAeC;IAC7B,MAAMlc,UAAU,CAACwhB,UACf5E,aAAa4E,SAASloB,MAAM,CAC1B,CAAC,EAAEyjB,OAAO,EAAE,GACVG,kBAAkBxlB,IAAI,CAACqlB,QAAQpgB,IAAI,KACnCogB,QAAQO,IAAI,CAAC3mB,MAAM,GAAG1D,qBAAqBqqB,IAAI,IAC/C,CAACP,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC6N,MAAQkX,QAAQlX,KAAKgc,SAASnmB,WAAW;IAEnE,MAAMa,QAAQ8D,QAAQ2c;IACtB,IAAI,CAACzgB,MAAMvF,MAAM,EAAE,OAAOgmB;IAC1B,IAAIpO,OAAOoO;IACX,IAAI,CAACoE,gBAAgBxS,MAAM2N,WAAWvlB,MAAM,EAAE;QAC5C,IAAIymB,gBAAgB,CAACA,aAAaiB,MAAM,CAAC2C,IAAI,CAACvf,OAAO,EAAE,OAAOkb;QAC9D,qFAAqF;QACrF,MAAM5Y,QAAQ7H,MACXzB,OAAO,CAAC,CAAC,EAAEsiB,OAAO,EAAE,GAAKA,QAAQO,IAAI,EACrChhB,IAAI,CAAC,CAACkJ,MAAQ7R,eAAe6R,QAAQ,CAAClS,gBAAgBib,MAAM/I,QAAQ,CAAChS,cAAc+a,MAAM/I;QAC5F,MAAM8a,QAAQ,IAAIjqB,IAAIkY,KAAK8P,MAAM,CAAC9oB,GAAG,CAAC,CAACsK,QAAUA,MAAMlD,IAAI,CAACuC,WAAW;QACvE,MAAMvC,OAAOoH,QACTA,MAAM7L,KAAK,CAAC,OAAOvB,MAAM,EAAEwI,IAAI,KAC/BmhB,MAAMvpB,GAAG,CAACuqB,qBAAqB3kB,IAAI,CAACuC,WAAW,MAC7C,sBACAoiB,qBAAqB3kB,IAAI;QAC/B4R,OAAO,aACFA;YACH8P,QAAQ;mBACH9P,KAAK8P,MAAM;gBACd;oBACEnP,MAAM;oBACNvS;oBACA4jB,KAAKe,qBAAqBf,GAAG;oBAC7BC,aAAa;oBACbvB,QAAQ;2BAAIqC,qBAAqBrC,MAAM;qBAAC;gBAC1C;aACD;;IAEL;IACA,MAAMkC,UAAUJ,gBAAgBxS,MAAM2N;IACtC,MAAMkF,SAAS,IAAI3oB;IACnB,KAAK,MAAM,EAAEskB,OAAO,EAAE,IAAIH,aAAarO,MAAO;QAC5C,KAAK,MAAM/I,OAAOuX,QAAQO,IAAI,CAAE;gBAGb8D;YAFjB,IAAI1E,QAAQlX,KAAK+I,MAAMlT,WAAW,QAAQ;YAC1C,MAAMtC,MAAMkoB,cAAczb,KAAK+I;YAC/B6S,OAAO5nB,GAAG,CAACT,KAAK,EAACqoB,cAAAA,OAAO3nB,GAAG,CAACV,gBAAXqoB,cAAmB,KAAK;QAC3C;IACF;IACA,MAAMtd,SAAS,IAAIrL;IACnB,KAAK,MAAM,EAAEskB,OAAO,EAAEpZ,IAAI,EAAE,IAAI3D,QAAQuO,MAAO;QAC7C,MAAMyS,OAAOE,aAAanE,SAASoE,SAASC;QAC5C,IAAIJ,MAAMld,OAAOtK,GAAG,CAACmK,MAAMqd,KAAKxb,GAAG;IACrC;IACA,IAAI,CAAC1B,OAAOxI,IAAI,EAAE,OAAOiT;IACzB,OAAO,aACFA;QACHkO,SAASlO,KAAKkO,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,QAAQC,cAAiB,aAC/CD;gBACHjO,UAAUiO,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,SAASC;oBACtC,MAAMxX,MAAM1B,OAAOrK,GAAG,CAAC,CAAC,QAAQ,EAAEqjB,YAAY,WAAW,EAAEE,aAAa,CAAC,CAAC;oBAC1E,IAAI,CAACxX,KAAK,OAAOuX;oBACjB,iFAAiF;oBACjF,MAAMO,OAAOP,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC8pB,MAAQR,cAAcQ,KAAKlT,UAAU/I,OAAOuX,QAAQO,IAAI,GAAG;2BAAIP,QAAQO,IAAI;wBAAE9X;qBAAI;oBACjH,OAAO,aAAKuX;wBAASO;;gBACvB;;;AAGN;AAEA,mFAAmF,GACnF,SAASoE,oBAAoB/E,IAAiB,EAAET,SAAiC;IAC/E,MAAMiF,UAAUJ,gBAAgBpE,MAAMT;IACtC,IAAI,CAACiF,QAAQxqB,MAAM,EAAE,OAAO;IAC5B,OAAO,CAAC,wCAAwC,EAAEwqB,QAC/C5rB,GAAG,CAAC,CAAC8rB,SAAYA,OAAOnB,OAAO,GAAGmB,OAAO7b,GAAG,GAAG,GAAG6b,OAAO7b,GAAG,CAAC,EAAE,EAAE6b,OAAO1kB,IAAI,CAAC,CAAC,CAAC,EAC/E1E,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB;AAEA;;;;;;;CAOC,GACD,OAAO,SAAS0pB,wBACdhF,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;;IAE9C,MAAM/hB,QAAQ4gB,eAAeC;IAC7B,MAAM1f,aAAoC,EAAE;IAC5C,MAAM6jB,kBAAkB,CAACjD,gBAAgBA,aAAaiB,MAAM,CAACG,MAAM,CAAC/c,OAAO;IAC3E,MAAMmgB,iBAAiB,CAACvB,mBAAmB,UAAEnE,6BAAAA,UAAWG,OAAO,CAAC1lB,MAAM,mBAAI;IAC1E,MAAMwpB,SAASxD,KAAKF,OAAO,CACxBlnB,GAAG,CAAC,CAACsnB,QAAQ1lB,QAAW,CAAA;YAAE0lB;YAAQ1lB;QAAM,CAAA,GACxCmC,MAAM,CACL,CAAC,EAAEujB,MAAM,EAAE,GACTH,QAAQG,OAAO2B,MAAM,EAAE7B,MAAMthB,WAAW,YACxC,CAAEumB,CAAAA,kBAAkB/E,OAAO2B,MAAM,KAAK,IAAG;IAE/C,IAAI2B,OAAOxpB,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAASgsB,iBACL,2GACAvB,kBACE,+GACA;YACNzQ,OAAOuQ,OAAO5qB,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,QAAQ,EAAEA,MAAM,QAAQ,CAAC;QAC7D;IACF;IACA,MAAMyI,UAAUgd,aAAaD,MAAMrjB,MAAM,CAAC,CAAC,EAAEyjB,OAAO,EAAE,GACpDE,mBAAmBvlB,IAAI,CAACqlB,QAAQpgB,IAAI;IAEtC,IAAIiD,QAAQjJ,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOhQ,QAAQrK,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC1C;IACF;IACA,MAAMyd,SAASlD,aAAavB,MAAMthB,OAAO;IACzC,IAAI+lB,OAAOzqB,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOwR;QACT;IACF;IACA,OAAO5kB;AACT;AAEA;;;;;;CAMC,GACD,OAAO,SAASqlB,sBACdlF,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,IAAI,CAACvpB,mBAAmBqoB,WAAWkB,eAAe,OAAO,EAAE;IAC3D,MAAM/hB,QAAQ4gB,eAAeC;IAC7B,MAAMlc,UAAU4c,aAAaD,MAAMrjB,MAAM,CACvC,CAAC,EAAEyjB,OAAO,EAAE,GACVG,kBAAkBxlB,IAAI,CAACqlB,QAAQpgB,IAAI,KACnC,CAACogB,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC6N,MAAQkX,QAAQlX,KAAKmX,MAAMthB,WAAW;IAE9D,OAAO2E,QAAQrJ,MAAM,GACjB;QACE;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACF0iB,QAAQoJ,oBAAoB/E,MAAMT;YAClCtM,OAAO5P,QAAQzK,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC1C;KACD,GACD,EAAE;AACR;AAEA,oEAAoE,GACpE,OAAO,MAAMme,uBAAuB,EAAC;AAErC;;;;;;;;;;;;CAYC,GACD,OAAO,SAASC,8BACdpF,IAAiB,EACjBT,YAAoC,IAAI;IAExC,MAAM7gB,QAAQ4gB,eAAeC;IAC7B,MAAM8F,SAAS,IAAIvpB;IACnBkkB,KAAKF,OAAO,CAAC5M,OAAO,CAAC,CAACgN,QAAQ1lB;YAKD6qB;QAJ3B,IAAInF,OAAOuC,MAAM,IAAIvC,OAAOjO,QAAQ,CAACjY,MAAM,GAAG,GAAG;QACjD,MAAMsrB,YAAYpF,OAAOjO,QAAQ,CAC9BrZ,GAAG,CAAC,CAACwnB,UAAYrB,WAAWqB,QAAQpgB,IAAI,EAAE1E,IAAI,CAAC,MAC/CA,IAAI,CAAC;QACR+pB,OAAOxoB,GAAG,CAACyoB,WAAW;gBAAKD,cAAAA,OAAOvoB,GAAG,CAACwoB,sBAAXD,cAAyB,EAAE;YAAG7qB;SAAM;IACjE;IACA,MAAMqF,aAAoC,EAAE;IAC5C,KAAK,MAAM0lB,WAAWF,OAAOnqB,MAAM,GAAI;QACrC,IAAIqqB,QAAQvrB,MAAM,GAAGmrB,sBAAsB;QAC3C,MAAMxF,YAAY,IAAIjmB,IAAI6rB,QAAQ3sB,GAAG,CAAC,CAAC4B,QAAUwlB,KAAKF,OAAO,CAACtlB,MAAM,CAACsnB,QAAQ;QAC7E,IAAInC,UAAUhhB,IAAI,KAAK,KAAK,CAACghB,UAAUvlB,GAAG,CAAC,OAAO;QAClDyF,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GAAGssB,QAAQvrB,MAAM,CAAC,uDAAuD,EAAEurB,QAAQvrB,MAAM,CAAC,iJAAiJ,CAAC;YACrPiZ,OAAOsS,QAAQ3sB,GAAG,CAAC,CAAC4B,QAAU,CAAC,QAAQ,EAAEA,MAAM,UAAU,CAAC;QAC5D;IACF;IACA,MAAM+I,QAAQyc,KAAKF,OAAO,CACvBlnB,GAAG,CAAC,CAACsnB,QAAQ1lB,QAAW,CAAA;YAAEioB,QAAQvC,OAAOuC,MAAM;YAAEjoB;QAAM,CAAA,GACvDmC,MAAM,CAAC,CAACuG,QAAiE3G,QAAQ2G,MAAMuf,MAAM;IAChG,MAAMnQ,UAAU/O,MAAM5G,MAAM,CAAC,CAAC,EAAE8lB,MAAM,EAAE,GAAK1C,QAAQ0C,OAAOR,OAAO,EAAEjC,MAAMthB,WAAW;IACtF,IAAI4T,QAAQtY,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOX,QAAQ1Z,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,QAAQ,EAAEA,MAAM,gBAAgB,CAAC;QACtE;IACF;IACA,MAAM8F,SAASiD,MAAM5G,MAAM,CAAC,CAAC,EAAE8lB,MAAM,EAAEjoB,KAAK,EAAE,GAC5C+I,MAAMvI,IAAI,CACR,CAACoF,QACCA,MAAM5F,KAAK,KAAKA,SACf4F,CAAAA,MAAMqiB,MAAM,CAAC1W,IAAI,KAAK0W,OAAO1W,IAAI,IAAI3L,MAAMqiB,MAAM,CAACR,OAAO,KAAKQ,OAAOR,OAAO,AAAD;IAGlF,IAAI3hB,OAAOtG,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAO3S,OAAO1H,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,QAAQ,EAAEA,MAAM,QAAQ,CAAC;QAC7D;IACF;IACA,MAAMiqB,SAASlD,aAAavB,MAAMthB,OAAO;IACzC,IAAI+lB,OAAOzqB,MAAM,EAAE;QACjB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOwR;QACT;IACF;IACA,OAAO5kB;AACT;AAEA,iEAAiE,GACjE,OAAO,SAAS2lB,wBAAwBxF,IAAiB;IACvD,MAAM/M,QAAkB,EAAE;IAC1B+M,KAAK0B,MAAM,CAACxO,OAAO,CAAC,CAAChQ,OAAO1I;QAC1B,IAAI0I,MAAMqP,IAAI,KAAK,gBAAgB;QACnC,IAAItO,gBAAgBf,MAAM0gB,GAAG,KAAK1gB,MAAMof,MAAM,CAACtnB,IAAI,CAACiJ,kBAAkB;YACpEgP,MAAM3Y,IAAI,CAAC,CAAC,OAAO,EAAEE,MAAM,CAAC,CAAC;QAC/B;IACF;IACA,KAAK,MAAM,EAAE4lB,OAAO,EAAEpZ,IAAI,EAAE,IAAIiZ,aAAaD,MAAO;QAClD,IAAI/b,gBAAgBmc,QAAQpgB,IAAI,GAAGiT,MAAM3Y,IAAI,CAAC0M;IAChD;IACA,OAAOiM,MAAMjZ,MAAM,GACf;QACE;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga;QACF;KACD,GACD,EAAE;AACR;AAEA,MAAMwS,4BAAgE,IAAI/rB,IAAI;IAC5E;IACA;IACA;IACA;CACD;AAED,2FAA2F,GAC3F,OAAO,SAASgsB,wBACd1F,IAAiB,EACjBT,SAAiC;;IAEjC,MAAM7gB,QAAQ4gB,eAAeC;IAC7B,MAAM1f,aAAoC,EAAE;IAC5C,MAAMyS,UAAU0N,KAAK2F,KAAK,CACvB/sB,GAAG,CAAC,CAACsK,OAAO1I,QAAW,CAAA;YAAE0I;YAAO1I;QAAM,CAAA,GACtCmC,MAAM,CAAC,CAAC,EAAEuG,KAAK,EAAE,GAAKA,MAAMqP,IAAI,KAAK,WAAW7T,MAAM5B,GAAG,CAACoG,MAAMtJ,EAAE,MAAMsJ,MAAMqP,IAAI;IACrF,IAAID,QAAQtY,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOX,QAAQ1Z,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,MAAM,EAAEA,MAAM,CAAC,CAAC;QACrD;IACF;IACA,MAAMorB,cAAc5F,KAAK0B,MAAM,CAC5B9oB,GAAG,CAAC,CAACsK,OAAO1I,QAAW,CAAA;YAAE0I;YAAO1I;QAAM,CAAA,GACtCmC,MAAM,CAAC,CAAC,EAAEuG,KAAK,EAAE,GAAK,CAACA,MAAM0gB,GAAG,CAACphB,IAAI;IACxC,IAAIojB,YAAY5rB,MAAM,EAAE;QACtB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS;YACTga,OAAO2S,YAAYhtB,GAAG,CAAC,CAAC,EAAE4B,KAAK,EAAE,GAAK,CAAC,OAAO,EAAEA,MAAM,KAAK,CAAC;QAC9D;IACF;IACA,MAAM8S,OAA4D;QAChEgU,SAAS,UAAE/B,6BAAAA,UAAWE,UAAU,mBAAI,EAAE;QACtCoC,MAAM,WAAEtC,6BAAAA,UAAWG,OAAO,oBAAI,EAAE;QAChC2E,IAAI,WAAE9E,6BAAAA,UAAWtO,KAAK,oBAAI,EAAE;QAC5BgR,OAAO,WAAE1C,6BAAAA,UAAWK,QAAQ,oBAAI,EAAE;IACpC;IACAI,KAAK0B,MAAM,CAACxO,OAAO,CAAC,CAAChQ,OAAO1I;QAC1B,IAAI,CAACirB,0BAA0BrrB,GAAG,CAAC8I,MAAMqP,IAAI,KAAKrP,MAAM2gB,WAAW,EAAE;QACrE,MAAMgC,WAAWvY,IAAI,CAACpK,MAAMqP,IAAI,CAAC,CAAC5S,IAAI,CAAC,CAAC6f,MAAQP,aAAaO,IAAIxf,IAAI,EAAEkD,MAAMlD,IAAI;QACjF,IAAI,CAAC6lB,UAAU;QACfhmB,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,uBAAuB,EAAEiK,MAAMqP,IAAI,CAAC,QAAQ,EAAEsT,SAAS7lB,IAAI,CAAC,2DAA2D,EAAEkD,MAAMlD,IAAI,CAAC,EAAE,CAAC;YACjJiT,OAAO;gBAAC,CAAC,OAAO,EAAEzY,MAAM,CAAC,CAAC;aAAC;QAC7B;IACF;IACA,OAAOqF;AACT;AAEA;;;;;CAKC,GACD,OAAO,SAASimB,sBACd9F,IAAiB,EACjBS,YAAuC;IAEvC,IAAI,CAACA,cAAc,OAAO,EAAE;IAC5B,OAAOtpB,kBAAkB6oB,MAAMS,cAAc7nB,GAAG,CAAC,CAACsK,QAAW,CAAA;YAC3DlK,MAAM;YACNiH,MAAM;YACNhH,SAASiK,MAAMjK,OAAO;YACtBga,OAAO;gBAAC/P,MAAM8D,IAAI;aAAC;QACrB,CAAA;AACF;AAEA;;;;;;CAMC,GACD,SAAS+e,wBACP/lB,IAAY,EACZogB,OAA2B,EAC3BJ,IAAiB,EACjBthB,KAA8B;IAE9B,IAAI6hB,kBAAkBxlB,IAAI,CAACiF,OAAO,OAAO;IACzC,MAAMgmB,aAAa5F,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC6N,MAAQkX,QAAQlX,KAAKmX,MAAMthB,WAAW;IAC5E,OAAO6hB,kBAAkBxlB,IAAI,CAACqlB,QAAQpgB,IAAI,KAAK,CAACgmB,aAAa,SAAS;AACxE;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,8BACdjG,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,MAAM/hB,QAAQ4gB,eAAeC;IAC7B,MAAMqB,SAAS,IAAI9kB;IACnB,KAAK,MAAM+M,OAAO9R,qBAAqBipB,MAAO;YAGvBY;QAFrB,IAAI/X,IAAI0Z,KAAK,KAAK,UAAU;QAC5B,MAAMnmB,MAAMyM,IAAI7I,IAAI,CAACuC,WAAW;QAChCqe,OAAO/jB,GAAG,CAACT,KAAK;gBAAKwkB,cAAAA,OAAO9jB,GAAG,CAACV,gBAAXwkB,cAAmB,EAAE;YAAG/X;SAAI;IACnD;IACA,OAAO;WAAI+X,OAAO1lB,MAAM;KAAG,CAACtC,GAAG,CAAC,CAACkoB;QAC/B,MAAM,CAACvhB,MAAM,GAAGuhB;QAChB,MAAMZ,SAASF,KAAKF,OAAO,CAACvgB,MAAM4gB,WAAW,CAAC;QAC9C,MAAMC,UAAU7gB,MAAMgjB,KAAK,KAAK,SAASrC,OAAOjO,QAAQ,CAAC1S,MAAM8gB,YAAY,CAAC,GAAG;QAC/E,MAAM9N,OAA8B6N,UAChC2F,wBAAwBxmB,MAAMS,IAAI,EAAEogB,SAASJ,MAAMthB,SACnD;QACJ,MAAM2O,UAAUoT,eAAerpB,sBAAsB4oB,MAAMzN,MAAMkO,gBAAgB;QACjF,MAAM3d,QAAQsd,UACV,GAAGA,QAAQpgB,IAAI,GAAG,CAAC,KAAK,EAAEogB,QAAQpgB,IAAI,CAAC,SAAS,CAAC,GAAG,YAAY,0BAA0B,EAAET,MAAMS,IAAI,CAAC,gCAAgC,CAAC,GACxI,GAAGkgB,OAAOgG,KAAK,GAAG,CAAC,UAAU,EAAEhG,OAAOgG,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,2BAA2B,EAAE3mB,MAAMS,IAAI,CAAC,gCAAgC,CAAC;QACvI,IAAI/G;QACJ,IAAI,CAACoU,SAAS;YACZ,MAAM8Y,YAAY/F,UACd,CAAC,MAAM,EAAEnpB,eAAesb,MAAM,+BAA+B,CAAC,GAC9D;YACJtZ,UAAU,GAAG6J,MAAM,0BAA0B,EAAE7L,eAAesb,MAAM,4CAA4C,EAAE4T,UAAU,CAAC,CAAC;QAChI,OAAO,IAAI/F,SAAS;YAClBnnB,UAAU,GAAG6J,MAAM,MAAM,EAAEuK,QAAQ+Y,MAAM,CAAC,EAAE,EAAE/Y,QAAQwF,OAAO,CAAC,mCAAmC,CAAC;QACpG,OAAO;YACL5Z,UAAU,GAAG6J,MAAM,MAAM,EAAEuK,QAAQ+Y,MAAM,CAAC,4EAA4E,CAAC;QACzH;QACA,OAAO;YAAEptB,MAAM;YAAGiH,MAAM;YAA4BhH;YAASga,OAAO6N,KAAKloB,GAAG,CAAC,CAACiQ,MAAQA,IAAI7B,IAAI;QAAE;IAClG;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASqf,oBACdrG,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;;IAE9C,MAAM/hB,QAAQ4gB,eAAeC;IAC7B,MAAM1f,aAAoC,EAAE;IAC5C,MAAMymB,OAAO;mBAAK/G,6BAAAA,UAAWK,QAAQ,mBAAI,EAAE;oBAAOL,6BAAAA,UAAWM,WAAW,oBAAI,EAAE;KAAE;IAChF,MAAM0G,QAAkB,EAAE;IAC1B,MAAMljB,UAAiD,EAAE;IACzD,KAAK,MAAM,EAAE+c,OAAO,EAAEpZ,IAAI,EAAE,IAAIiZ,aAAaD,MAAO;QAClD,MAAMwG,YAAYpG,QAAQO,IAAI,CAAC3lB,IAAI,CAAC,CAAC6N,MACnC;gBAAC;gBAAW;aAAa,CAACpG,QAAQ,CAAC/F,OAAOqjB,QAAQlX,KAAKmX,MAAMthB;QAE/D,IAAI8nB,WAAW;QACf,IAAIpG,QAAQjU,KAAK,IAAIxQ,yBAAyB4qB,MAAMjsB,IAAI,CAAC0M;QACzD,MAAM6C,QAAQyc,KAAK3mB,IAAI,CAAC,CAAC6f,MAAQP,aAAaO,IAAIxf,IAAI,EAAEogB,QAAQpgB,IAAI;QACpE,IAAI6J,OAAOxG,QAAQ/I,IAAI,CAAC;YAAE0M;YAAMhH,MAAM6J,MAAM7J,IAAI;QAAC;IACnD;IACA,IAAIumB,MAAMvsB,MAAM,EAAE;QAChB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACEwnB,gBAAgB,CAACA,aAAaiB,MAAM,CAACO,OAAO,CAACnd,OAAO,GAChD,CAAC,oHAAoH,EAAEnJ,wBAAwB,OAAO,CAAC,GACvJ;YACNsX,OAAOsT;QACT;IACF;IACA,IAAIljB,QAAQrJ,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,wBAAwB,EAAEoK,OAAO,CAAC,EAAE,CAACrD,IAAI,CAAC,sEAAsE,CAAC;YAC3HiT,OAAO5P,QAAQzK,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC1C;IACF;IACA,OAAOnH;AACT;AAEA,MAAM4mB,OAAO;AACb,OAAO,MAAMC,mBAAmB,GAAE;AAClC,OAAO,MAAMC,yBAAyB,IAAG;AAEzC,SAASC,QAAQC,IAAY;IAC3B,OAAOA,KAAKrkB,IAAI,GAAGD,WAAW,GAAGD,OAAO,CAAC,cAAc;AACzD;AAEA,6FAA6F,GAC7F,OAAO,SAASwkB,uBACd9G,IAAiB,EACjBT,SAAiC;;IAEjC,MAAM1f,aAAoC,EAAE;IAC5C,oEAAoE;IACpE,wEAAwE;IACxE,MAAM8jB,QAAQ,IAAI7nB,IAChB,SAACyjB,6BAAAA,UAAWO,OAAO,mBAAI,EAAE,EACtBnjB,MAAM,CAAC,CAACujB,SAAW,CAACA,OAAO6G,WAAW,EACtCnuB,GAAG,CAAC,CAACsnB,SAAW;YAAC0G,QAAQ1G,OAAO2G,IAAI;YAAG3G,OAAOlgB,IAAI;SAAC;IAExD,MAAMgnB,UAAU,IAAIttB;IACpB,MAAMD,OAAO,IAAIC;IACjB,MAAMutB,WAAqB,EAAE;IAC7B,MAAMC,aAAuB,EAAE;IAC/B,MAAMC,MAAgB,EAAE;IACxBnH,KAAKF,OAAO,CAAC5M,OAAO,CAAC,CAACgN,QAAQ1lB;QAC5B,MAAM4B,MAAMwqB,QAAQ1G,OAAO2G,IAAI;QAC/B,IAAI,CAAC3G,OAAO2G,IAAI,CAACrkB,IAAI,MAAM,CAACikB,KAAK1rB,IAAI,CAACmlB,OAAO2G,IAAI,CAACrkB,IAAI,KAAK;YACzDykB,SAAS3sB,IAAI,CAAC,CAAC,QAAQ,EAAEE,MAAM,MAAM,CAAC;QACxC,OAAO,IAAIf,KAAKW,GAAG,CAACgC,QAAQunB,MAAMvpB,GAAG,CAACgC,MAAM;YAC1C8qB,WAAW5sB,IAAI,CAAC,CAAC,QAAQ,EAAEE,MAAM,MAAM,CAAC;YACxCwsB,QAAQ3sB,GAAG,CAAC,CAAC,CAAC,EAAE+B,KAAK;QACvB;QACA3C,KAAKY,GAAG,CAAC+B;QACT,IAAI,CAAC8jB,OAAOkH,QAAQ,IAAIlH,OAAOkH,QAAQ,CAACptB,MAAM,GAAG0sB,kBAAkB;YACjES,IAAI7sB,IAAI,CAAC,CAAC,QAAQ,EAAEE,MAAM,UAAU,CAAC;QACvC;QACA,IAAI,CAAC0lB,OAAOmH,cAAc,IAAInH,OAAOmH,cAAc,CAACrtB,MAAM,GAAG2sB,wBAAwB;YACnFQ,IAAI7sB,IAAI,CAAC,CAAC,QAAQ,EAAEE,MAAM,gBAAgB,CAAC;QAC7C;IACF;IACA,IAAIysB,SAASjtB,MAAM,EAAE;QACnB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOgU;QACT;IACF;IACA,IAAIC,WAAWltB,MAAM,EAAE;QACrB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACN,qEAAqE;YACrEhH,SAAS,CAAC,4DAA4D,EAAE;mBAAI+tB;aAAQ,CAAC1rB,IAAI,CAAC,MAAM,+BAA+B,CAAC;YAChI2X,OAAOiU;QACT;IACF;IACA,IAAIC,IAAIntB,MAAM,EAAE;QACd6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,gEAAgE,EAAEytB,iBAAiB,KAAK,EAAEC,uBAAuB,uCAAuC,CAAC;YACnK1T,OAAOkU;QACT;IACF;IACA,OAAOtnB;AACT;AAEA,uDAAuD,GACvD,OAAO,SAASynB,WAAWtH,IAAiB;IAC1C,MAAMnM,UAA0B,EAAE;IAClCmM,KAAKF,OAAO,CAAC5M,OAAO,CAAC,CAACgN,QAAQ1lB;QAC5BqZ,QAAQvZ,IAAI,CAAC;YAAEsF,IAAI,CAAC,QAAQ,EAAEpF,MAAM,OAAO,CAAC;YAAE+K,MAAM2a,OAAOgG,KAAK;QAAC;QACjErS,QAAQvZ,IAAI,CAAC;YAAEsF,IAAI,CAAC,QAAQ,EAAEpF,MAAM,UAAU,CAAC;YAAE+K,MAAM2a,OAAOkH,QAAQ;QAAC;QACvEvT,QAAQvZ,IAAI,CAAC;YAAEsF,IAAI,CAAC,QAAQ,EAAEpF,MAAM,gBAAgB,CAAC;YAAE+K,MAAM2a,OAAOmH,cAAc;QAAC;IACrF;IACArH,KAAK0B,MAAM,CAACxO,OAAO,CAAC,CAAChQ,OAAO1I;QAC1BqZ,QAAQvZ,IAAI,CAAC;YAAEsF,IAAI,CAAC,OAAO,EAAEpF,MAAM,MAAM,CAAC;YAAE+K,MAAMrC,MAAMlD,IAAI;QAAC;IAC/D;IACA,OAAO6T;AACT;AAEA,wFAAwF,GACxF,OAAO,SAAS0T,sBACdvH,IAAiB,EACjBT,SAAiC;IAEjC,MAAM7gB,QAAQ4gB,eAAeC;IAC7B,MAAM1f,aAAoC,EAAE;IAC5C,MAAM2nB,aAAuB,EAAE;IAC/BxH,KAAKF,OAAO,CAAC5M,OAAO,CAAC,CAACgN,QAAQ1lB;;QAC5B,IAAI0lB,OAAO2D,WAAW,EAAE;YACtB,IAAInlB,MAAM5B,GAAG,CAACojB,OAAO2D,WAAW,MAAM,UAAU;gBAC9C2D,WAAWltB,IAAI,CAAC,CAAC,QAAQ,EAAEE,MAAM,aAAa,CAAC;YACjD;YACA;QACF;QACA,yDAAyD;QACzD,MAAMitB,UAAU,SAAClI,6BAAAA,UAAWO,OAAO,mBAAI,EAAE,EAAEngB,IAAI,CAC7C,CAACkmB,WACC,CAACA,SAAS/D,QAAQ,IAAI,CAAC+D,SAASkB,WAAW,IAAI9H,aAAa4G,SAAS7lB,IAAI,EAAEkgB,OAAOgG,KAAK;QAE3F,IAAIuB,SAAS;YACX5nB,WAAWvF,IAAI,CAAC;gBACdtB,MAAM;gBACNiH,MAAM;gBACNhH,SAAS,CAAC,sBAAsB,EAAEwuB,QAAQznB,IAAI,CAAC,8FAA8F,CAAC;gBAC9IiT,OAAO;oBAAC,CAAC,QAAQ,EAAEzY,MAAM,aAAa,CAAC;iBAAC;YAC1C;QACF;IACF;IACAwlB,KAAK0B,MAAM,CAACxO,OAAO,CAAC,CAAChQ,OAAO1I;;QAC1B,IAAI0I,MAAM2gB,WAAW,EAAE;YACrB,MAAMtR,OAAO7T,MAAM5B,GAAG,CAACoG,MAAM2gB,WAAW;YACxC,IAAI,CAACtR,QAASA,SAASrP,MAAMqP,IAAI,IAAI,CAAErP,CAAAA,MAAMqP,IAAI,KAAK,cAAcA,SAAS,QAAO,GAAK;gBACvFiV,WAAWltB,IAAI,CAAC,CAAC,OAAO,EAAEE,MAAM,aAAa,CAAC;YAChD;YACA;QACF;QACA,IAAI0I,MAAMqP,IAAI,KAAK,YAAY;QAC/B,MAAMkV,UAAU,SAAClI,6BAAAA,UAAWI,SAAS,mBAAI,EAAE,EAAEhgB,IAAI,CAAC,CAACkmB,WACjD5G,aAAa4G,SAAS7lB,IAAI,EAAEkD,MAAMlD,IAAI;QAExC,IAAIynB,SAAS;YACX5nB,WAAWvF,IAAI,CAAC;gBACdtB,MAAM;gBACNiH,MAAM;gBACNhH,SAAS,CAAC,0BAA0B,EAAEwuB,QAAQznB,IAAI,CAAC,uDAAuD,CAAC;gBAC3GiT,OAAO;oBAAC,CAAC,OAAO,EAAEzY,MAAM,aAAa,CAAC;iBAAC;YACzC;QACF;IACF;IACA,IAAIgtB,WAAWxtB,MAAM,EAAE;QACrB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOuU;QACT;IACF;IACA,OAAO3nB;AACT;AAgBA;;;;;;;CAOC,GACD,OAAO,MAAM6nB,kCAAiE;IAC5E1H,MAAM;IACN6B,QAAQ;IACR8F,cAAc;IACdC,cAAc;IACdC,SAAS;AACX,EAAC;AAED;;;;;;;CAOC,GACD,OAAO,SAASC,yBACdC,SAA8C,EAC9CC,UAAyCN,+BAA+B;QAGjBK;IADvD,MAAM9S,SACJ+S,QAAQhI,IAAI,GAAG+H,UAAUrI,OAAO,GAAGsI,QAAQnG,MAAM,GAAG,EAACkG,mBAAAA,UAAUE,KAAK,YAAfF,mBAAmB,KAAKC,QAAQH,OAAO,GAAGG,QAAQL,YAAY;IACrH,IAAI1S,SAASlf,iCAAiC,OAAO;IACrD,OAAO,IAAIqQ,KAAKoG,KAAK,CAAC,AAACzW,CAAAA,kCAAkCkf,MAAK,IAAK+S,QAAQJ,YAAY;AACzF;AAEA;;;;CAIC,GACD,SAASM,gBAAgBlI,IAAiB,EAAET,SAAiC,EAAEkB,YAAgC;;IAC7G,MAAMpT,UAAUlW,kBAAkB6oB,MAAMS,cAAc9jB,MAAM,CAAC,CAACuG,QAAUA,MAAMqP,IAAI,KAAK,UAAUvY,MAAM;IACvG,MAAMmuB,UAAUnI,KAAK0B,MAAM,CAAC/kB,MAAM,CAAC,CAACuG,QAAUA,MAAMqP,IAAI,KAAK,UAAUvY,MAAM,GAAGqT;IAChF,MAAM+a,QAAQ,UAAE7I,6BAAAA,UAAWG,OAAO,CAAC1lB,MAAM,mBAAI,MAAMymB,aAAaiB,MAAM,CAACG,MAAM,CAAC/c,OAAO,GAAG,IAAI;IAC5F,OAAOsB,KAAKkG,GAAG,CAAC6b,SAASC;AAC3B;AAkBA,qFAAqF,GACrF,SAASC,aACPrI,IAAiB,EACjBT,SAAiC,EACjCkB,YAAuC;IAEvC,IAAI,EAACA,gCAAAA,aAAc6H,SAAS,GAAE,OAAO;IACrC,MAAMC,QAAQvI,KAAKF,OAAO,CAAC/iB,MAAM,CAAC,CAACC,KAAKkjB,SAAWljB,MAAMkjB,OAAOjO,QAAQ,CAACjY,MAAM,EAAE;IACjF,MAAM0lB,UAAUwI,gBAAgBlI,MAAMT,WAAWkB;IACjD,MAAMwH,QAAQ7hB,KAAKkG,GAAG,CAAC0T,KAAKF,OAAO,CAAC9lB,MAAM,EAAE;IAC5C,6EAA6E;IAC7E,4EAA4E;IAC5E,MAAMwuB,YAAY/H,aAAagI,aAAa;IAC5C,MAAMC,YAAYF,cAAczpB,aAAaihB,KAAKF,OAAO,CAAC9lB,MAAM,GAAGwuB;IACnE,iGAAiG;IACjG,MAAMvX,QACJ+O,KAAK0B,MAAM,CAAC/kB,MAAM,CAAC,CAACuG,QAAUA,MAAMqP,IAAI,KAAK,QAAQvY,MAAM,GAC3D7C,kBAAkB6oB,MAAMS,cAAc9jB,MAAM,CAAC,CAACuG,QAAUA,MAAMqP,IAAI,KAAK,QAAQvY,MAAM;IACvF,MAAM2uB,OACJH,cAAczpB,YACV1H,yBAAyB;QAAEqoB;QAASuI;QAAOhX,OAAO7K,KAAKkG,GAAG,CAAC,GAAG2E;IAAO,GAAGlb,mCACxE+xB,yBAAyB;QAAEpI;QAASuI;IAAM;IAChD,yEAAyE;IACzE,2EAA2E;IAC3E,kEAAkE;IAClE,MAAMW,UACJJ,cAAczpB,aAAaihB,KAAKF,OAAO,CAAC9kB,IAAI,CAACzD,oBACzCD,sBAAsB;QAAE2wB;QAAO7b,QAAQuc;IAAK,KAC5C;IACN,OAAO;QAAEJ;QAAOI;QAAMjJ;QAASuI;QAAOO;QAAWE;QAAWE;IAAQ;AACtE;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,MAAMC,+BAA+B,EAAC;AAE7C,sFAAsF,GACtF,MAAMC,qBACJ;AAEF;;;;;;;CAOC,GACD,SAASC,cAAc7I,MAAsC,EAAE1lB,KAAa;IAC1E,MAAM4lB,UAAUF,OAAOjO,QAAQ,CAACzX,MAAM;IACtC,IAAIA,UAAU,KAAK4lB,QAAQO,IAAI,CAAC3mB,MAAM,GAAG,GAAG,OAAO;IACnD,IAAIumB,kBAAkBxlB,IAAI,CAACqlB,QAAQpgB,IAAI,KAAK8oB,mBAAmB/tB,IAAI,CAACqlB,QAAQpgB,IAAI,GAAG,OAAO;IAC1F,IACErI,iBAAiB,YAAYyoB,QAAQpgB,IAAI,KACzCrI,iBAAiB,eAAeyoB,QAAQpgB,IAAI,KAC5CrI,iBAAiB,UAAUyoB,QAAQpgB,IAAI,GACvC;QACA,OAAO;IACT;IACA,OAAOvI,mBAAmByoB,WAAWxoB,wBAAwBwoB,OAAOjO,QAAQ,MAAMzX;AACpF;AAEA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,SAASwuB,qBACdhJ,IAAiB,EACjBT,SAAiC,EACjCkB,eAA0C,IAAI;IAE9C,MAAMwI,OAAOZ,aAAarI,MAAMT,WAAWkB;IAC3C,IAAI,CAACwI,QAAQA,KAAKP,SAAS,EAAE,OAAO1I;IACpC,MAAM9Z,OAAO+iB,KAAKV,KAAK,GAAGU,KAAKN,IAAI;IACnC,IAAIziB,QAAQ,KAAKA,OAAO2iB,8BAA8B,OAAO7I;IAC7D,4EAA4E;IAC5E,sEAAsE;IACtE,IAAImB,qBAAqBnB,MAAMT,WAAWkB,cAAczmB,MAAM,EAAE,OAAOgmB;IACvE,MAAM1D,OAAO0D,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,SAAWA,OAAOjO,QAAQ,CAACrZ,GAAG,CAAC,CAACwnB,SAAS5lB,QAAW,CAAA;gBAAE4lB;gBAAS5lB;YAAM,CAAA;IACpG,MAAMuW,OAAOiP,KAAKF,OAAO,CAACjC,SAAS,CAACtmB;IACpC,MAAMiV,QAAQ,CAAC2T,cAAyBA,gBAAgBpP,OAAO3K,KAAKkG,GAAG,CAAC2c,KAAKL,OAAO,EAAE,KAAK;IAC3F,MAAMthB,SAAS,CAAC6Y,cAAyBA,gBAAgBpP,OAAO3K,KAAKkG,GAAG,CAAC2c,KAAKL,OAAO,EAAE,KAAK;IAC5F,uDAAuD;IACvD,MAAMM,OAAO,CAAC/I;QACZ,MAAMviB,UAAU0e,IAAI,CAAC6D,YAAY;QACjC,IAAIviB,QAAQ5D,MAAM,IAAIwS,MAAM2T,cAAc,OAAO,CAAC;QAClD,IAAK,IAAIvgB,KAAKhC,QAAQ5D,MAAM,GAAG,GAAG4F,KAAK,GAAGA,MAAM,EAAG;YACjD,IAAI,CAACmpB,cAAc/I,KAAKF,OAAO,CAACK,YAAY,EAAEviB,OAAO,CAACgC,GAAG,CAACpF,KAAK,GAAG,OAAOoF;QAC3E;QACA,OAAO,CAAC;IACV;IACA,IAAK,IAAIsf,OAAOhZ,MAAMgZ,OAAO,GAAGA,QAAQ,EAAG;QACzC,IAAIiK,OAAO,CAAC;QACZ,IAAK,IAAI3uB,QAAQ,GAAGA,QAAQ8hB,KAAKtiB,MAAM,EAAEQ,SAAS,EAAG;YACnD,IAAI0uB,KAAK1uB,WAAW,CAAC,GAAG;YACxB,MAAM4uB,OAAO9M,IAAI,CAAC9hB,MAAM,CAACR,MAAM,GAAGsN,OAAO9M;YACzC,MAAM6M,OAAO8hB,SAAS,CAAC,IAAI,OAAO7M,IAAI,CAAC6M,KAAK,CAACnvB,MAAM,GAAGsN,OAAO6hB;YAC7D,IACE9hB,SAAS,QACT+hB,OAAO/hB,QACN+hB,SAAS/hB,QAASiV,CAAAA,IAAI,CAAC9hB,MAAM,CAACR,MAAM,GAAGsiB,IAAI,CAAC6M,KAAK,CAACnvB,MAAM,IAAKsiB,IAAI,CAAC9hB,MAAM,CAACR,MAAM,KAAKsiB,IAAI,CAAC6M,KAAK,CAACnvB,MAAM,IAAIQ,UAAUuW,IAAI,GACxH;gBACAoY,OAAO3uB;YACT;QACF;QACA,IAAI2uB,SAAS,CAAC,GAAG,OAAOnJ;QACxB1D,IAAI,CAAC6M,KAAK,CAACE,MAAM,CAACH,KAAKC,OAAO;IAChC;IACA,OAAO,aACFnJ;QACHF,SAASE,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAACsnB,QAAQ1lB,QACjC8hB,IAAI,CAAC9hB,MAAM,CAACR,MAAM,KAAKkmB,OAAOjO,QAAQ,CAACjY,MAAM,GACzCkmB,SACA,aAAKA;gBAAQjO,UAAUqK,IAAI,CAAC9hB,MAAM,CAAC5B,GAAG,CAAC,CAACsK,QAAUA,MAAMkd,OAAO;;;AAGzE;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASkJ,uBACdtJ,IAAiB,EACjBT,SAAiC,EACjCkB,YAAuC;IAEvC,MAAMwI,OAAOZ,aAAarI,MAAMT,WAAWkB;IAC3C,IAAI,CAACwI,MAAM,OAAO,EAAE;IACpB,MAAM,EAAEV,KAAK,EAAE7I,OAAO,EAAEuI,KAAK,EAAEO,SAAS,EAAEG,IAAI,EAAEC,OAAO,EAAE,GAAGK;IAC5D,IAAIT,cAAczpB,aAAakqB,KAAKP,SAAS,EAAE;QAC7C,OAAO;YACL;gBACE1vB,MAAM;gBACNiH,MAAM;gBACNhH,SAAS,CAAC,iBAAiB,EAAE+mB,KAAKF,OAAO,CAAC9lB,MAAM,CAAC,yDAAyD,EAAEwuB,UAAU,2DAA2D,CAAC;gBAClLvV,OAAO;oBAAC;iBAAU;YACpB;SACD;IACH;IACA,IAAIsV,SAASI,MAAM,OAAO,EAAE;IAC5B,MAAMY,MAAMtB,QAAQ,IAAI,CAAC,eAAe,EAAEA,MAAM,MAAM,CAAC,GAAG;IAC1D,MAAMuB,SAAS9J,UAAU,CAAC,cAAc,EAAEA,UAAU,IAAI,GAAGA,QAAQ,QAAQ,CAAC,GAAG,cAAc,GAAG;IAChG,MAAM+J,WAAWb,UACb,CAAC,4BAA4B,EAAEA,QAAQ,oDAAoD,EAAEX,QAAQ,IAAI,UAAU,OAAO,CAAC,CAAC,GAC5H;IACJ,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAMyB,OACJlB,cAAczpB,aAAa4pB,QAAQ,IAC/B,CAAC,KAAK,EAAEA,OAAO,EAAE,IAAI,EAAEA,KAAK,MAAM,EAAEA,KAAK,uJAAuJ,CAAC,GACjM,CAAC,aAAa,EAAEA,KAAK,kGAAkG,CAAC;IAC9H,OAAO;QACL;YACE3vB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,mBAAmB,EAAEsvB,MAAM,eAAe,EAAEgB,MAAMC,OAAO,MAAM,EAAEb,KAAK,QAAQ,EAAE5yB,gCAAgC,0CAA0C,EAAE2zB,OAAOD,UAAU;YACvLxW,OAAO+M,KAAKF,OAAO,CAAClnB,GAAG,CAAC,CAAC+wB,GAAGnvB,QAAU,CAAC,QAAQ,EAAEA,MAAM,UAAU,CAAC;QACpE;KACD;AACH;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASovB,4BAA4B5J,IAAiB;IAC3D,MAAM6J,aAAoD,EAAE;IAC5D7J,KAAK0B,MAAM,CAACxO,OAAO,CAAC,CAAChQ,OAAO1I;QAC1B,IAAI0I,MAAMqP,IAAI,KAAK,UAAU;QAC7BrP,MAAMof,MAAM,CAACpP,OAAO,CAAC,CAACqP,OAAOuH;YAC3B,IAAI,CAAC7nB,iBAAiBsgB,QAAQ;gBAC5BsH,WAAWvvB,IAAI,CAAC;oBAAE4H,MAAMqgB;oBAAOvb,MAAM,CAAC,OAAO,EAAExM,MAAM,SAAS,EAAEsvB,WAAW,CAAC,CAAC;gBAAC;YAChF;QACF;IACF;IACA,IAAI,CAACD,WAAW7vB,MAAM,EAAE,OAAO,EAAE;IACjC,MAAMkP,MAAM2gB,WAAW7vB,MAAM,KAAK;IAClC,OAAO;QACL;YACEhB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,eAAe,EAAE4wB,WACxBjxB,GAAG,CAAC,CAACsK,QAAU,CAAC,CAAC,EAAEA,MAAMhB,IAAI,CAAC,CAAC,CAAC,EAChC5G,IAAI,CAAC,MAAM,iDAAiD,EAAEiG,uBAAuBjG,IAAI,CAC1F,MACA,OAAO,EAAE4N,MAAM,OAAO,OAAO,6BAA6B,EAAEA,MAAM,OAAO,OAAO,gBAAgB,CAAC;YACnG+J,OAAO4W,WAAWjxB,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC7C;KACD;AACH;AAEA;;;;;;CAMC,GACD,OAAO,SAAS+iB,iBAAiB/J,IAAiB;QAK9CA;IAJF,MAAMgK,UAAoB,EAAE;IAC5B,MAAM7pB,YAAkE,EAAE;IAC1E,MAAM8pB,YAAsB,EAAE;IAC9B,MAAMxF,SAAS,IAAI3oB;IAClB,EAACkkB,eAAAA,KAAKhJ,MAAM,YAAXgJ,eAAe,EAAE,EAAE9M,OAAO,CAAC,CAACuD,OAAOjc;YAmBrBiqB;QAlBd,MAAMzd,OAAO,CAAC,OAAO,EAAExM,MAAM,CAAC,CAAC;QAC/B,IAAIic,MAAMD,GAAG,KAAK,QAAQhgB,cAAcigB,MAAMD,GAAG,MAAMC,MAAMnH,IAAI,EAAE2a,UAAU3vB,IAAI,CAAC,GAAG0M,KAAK,IAAI,CAAC;QAC/F,IAAIM,SAA4E;QAChF,IAAItQ,eAAeyf,MAAM3T,KAAK,GAAG;YAC/B,MAAMigB,WAAWpsB,gBAAgBqpB,MAAMvJ,MAAM3T,KAAK;YAClD,IAAIigB,YAAYA,SAASxQ,IAAI,KAAK,aAAa;gBAC7CpS,UAAU7F,IAAI,CAAC;oBAAEiY,MAAMwQ,SAASxQ,IAAI;oBAAEvL,MAAM,GAAGA,KAAK,MAAM,CAAC;gBAAC;gBAC5D;YACF;YACA,IAAI+b,UAAUzb,SAAS;gBAAElL,KAAKqa,MAAM3T,KAAK,CAACN,IAAI,GAAGD,WAAW;gBAAIoO,OAAOoS,SAAS/iB,IAAI;gBAAEuS,MAAM;YAAY;QAC1G,OAAO;YACL,MAAM2N,SAASF,KAAKF,OAAO,CAACngB,IAAI,CAAC,CAAC6f,MAAQ1oB,cAAc0oB,IAAIqH,IAAI,MAAM/vB,cAAc2f,MAAM3T,KAAK;YAC/F,IAAIod,QAAQ5Y,SAAS;gBAAElL,KAAKtF,cAAcopB,OAAO2G,IAAI;gBAAGlW,OAAOuP,OAAO2G,IAAI;gBAAEtU,MAAM;YAAO;QAC3F;QACA,IAAI,CAACjL,QAAQ;YACX0iB,QAAQ1vB,IAAI,CAAC,GAAG0M,KAAK,MAAM,CAAC;YAC5B;QACF;QACA,MAAM9D,SAAQuhB,cAAAA,OAAO3nB,GAAG,CAACwK,OAAOlL,GAAG,aAArBqoB,cAA0B;YAAE9T,OAAOrJ,OAAOqJ,KAAK;YAAE4B,MAAMjL,OAAOiL,IAAI;YAAEU,OAAO,EAAE;QAAC;QAC5F/P,MAAM+P,KAAK,CAAC3Y,IAAI,CAAC0M;QACjByd,OAAO5nB,GAAG,CAACyK,OAAOlL,GAAG,EAAE8G;IACzB;IACA,MAAMrD,aAAoC,EAAE;IAC5C,IAAImqB,QAAQhwB,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAO+W;QACT;IACF;IACA,IAAI7pB,UAAUnG,MAAM,EAAE;QACpB,MAAMqe,QAAQ;eAAI,IAAI3e,IAAIyG,UAAUvH,GAAG,CAAC,CAACsK,QAAU9M,4BAA4B,CAAC8M,MAAMqP,IAAI,CAAC,CAAC6F,IAAI;SAAG;QACnGvY,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,qFAAqF,EAAEof,MAAM/c,IAAI,CACzG,WACA,kIAAkI,CAAC;YACrI2X,OAAO9S,UAAUvH,GAAG,CAAC,CAACsK,QAAUA,MAAM8D,IAAI;QAC5C;IACF;IACA,KAAK,MAAM9D,SAASuhB,OAAOvpB,MAAM,GAAI;QACnC,MAAM8a,QAAQ9d,iBAAiB,CAACgL,MAAMqP,IAAI,CAAC,CAACyE,MAAM;QAClD,IAAI9T,MAAM+P,KAAK,CAACjZ,MAAM,IAAIgc,OAAO;QACjCnW,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,GAAGiK,MAAMyN,KAAK,CAAC,YAAY,EAAEzN,MAAM+P,KAAK,CAACjZ,MAAM,CAAC,gBAAgB,EAAEkJ,MAAMqP,IAAI,CAAC,iBAAiB,EAAEyD,MAAM,uCAAuC,CAAC;YACvJ/C,OAAO/P,MAAM+P,KAAK;QACpB;IACF;IACA,IAAIgX,UAAUjwB,MAAM,EAAE;QACpB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SAAS,CAAC,yDAAyD,EAAEP,OAAOwC,MAAM,CAChF7E,gCACAiF,IAAI,CAAC,QAAQ,mDAAmD,CAAC;YACnE2X,OAAOgX;QACT;IACF;IACA,OAAOpqB;AACT;AAEA,+EAA+E,GAC/E,SAASqqB,UAAU3kB,IAAY;IAC7B,OAAOA,KACJhD,WAAW,GACXD,OAAO,CAAC,cAAc,IACtBA,OAAO,CAAC,QAAQ,KAChBE,IAAI;AACT;AAEA;;;;;;CAMC,GACD,OAAO,SAAS2nB,2BAA2BnK,IAAiB,EAAEoK,KAAa;QAGtEA,cAMDpK;IARF,MAAMqC,OAAO6H,UAAUE;IACvB,MAAMC,QAAQ,IAAI3wB,IAChB,EAAC0wB,eAAAA,MAAMvgB,KAAK,CAAC,6BAAZugB,eAAiC,EAAE,EACjCxxB,GAAG,CAAC,CAAC0xB,OAAS7zB,gBAAgB6zB,KAAKhoB,OAAO,CAAC,cAAc,MACzD3F,MAAM,CAAC,CAACP,MAAuBA,QAAQ;IAE5C,MAAMmuB,UAAoB,EAAE;IAC5B,MAAMC,UAAoB,EAAE;IAC3B,EAACxK,eAAAA,KAAKhJ,MAAM,YAAXgJ,eAAe,EAAE,EAAE9M,OAAO,CAAC,CAACuD,OAAOjc;QACnC,MAAM+tB,QAAQ2B,UAAUzT,MAAM8R,KAAK;QACnC,IAAI,CAACA,SAAS,CAAClG,KAAK5f,QAAQ,CAAC8lB,UAAU,CAAChyB,uBAAuBwE,IAAI,CAACwtB,QAAQ;YAC1EgC,QAAQjwB,IAAI,CAAC,CAAC,OAAO,EAAEE,MAAM,OAAO,CAAC;QACvC;QACA,IAAIic,MAAMD,GAAG,KAAK,MAAM;YACtB,MAAMpa,MAAM3F,gBAAgBggB,MAAMD,GAAG;YACrC,IAAI,CAACpa,OAAO,CAACiuB,MAAMjwB,GAAG,CAACgC,MAAMouB,QAAQlwB,IAAI,CAAC,CAAC,OAAO,EAAEE,MAAM,KAAK,CAAC;QAClE;IACF;IACA,MAAMqF,aAAoC,EAAE;IAC5C,IAAI0qB,QAAQvwB,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOsX;QACT;IACF;IACA,IAAIC,QAAQxwB,MAAM,EAAE;QAClB6F,WAAWvF,IAAI,CAAC;YACdtB,MAAM;YACNiH,MAAM;YACNhH,SACE;YACFga,OAAOuX;QACT;IACF;IACA,OAAO3qB;AACT;AAEA;;;;CAIC,GACD,OAAO,SAAS4qB,oBACdzK,IAAiB,EACjBT,SAAiC,EACjCzL,UAAyB,IAAI,EAC7B2M,eAA0C,IAAI;IAE9C,OAAO;WACFD,kBAAkBR,MAAMT,WAAWkB;WACnCU,qBAAqBnB,MAAMT,WAAWkB;WACtC6I,uBAAuBtJ,MAAMT,WAAWkB;WACxCuE,wBAAwBhF,MAAMT,WAAWkB;WACzCmJ,4BAA4B5J;WAC5BkF,sBAAsBlF,MAAMT,WAAWkB;WACvC2E,8BAA8BpF,MAAMT;WACpCiG,wBAAwBxF;WACxB+J,iBAAiB/J;WACjB0F,wBAAwB1F,MAAMT;WAC9BuG,sBAAsB9F,MAAMS;WAC5BwF,8BAA8BjG,MAAMT,WAAWkB;WAC/C4F,oBAAoBrG,MAAMT,WAAWkB;WACrCqG,uBAAuB9G,MAAMT;WAC7B3L,mBAAmB0T,WAAWtH,OAAOlM;WACrCyT,sBAAsBvH,MAAMT;KAChC;AACH"}