@aglyn/plugins-ai 1.0.0-beta.143

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 (717) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +25 -0
  3. package/package.json +60 -0
  4. package/src/index.d.ts +21 -0
  5. package/src/index.js +22 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/activity/ai-activity-actions.d.ts +106 -0
  8. package/src/lib/activity/ai-activity-actions.js +209 -0
  9. package/src/lib/activity/ai-activity-actions.js.map +1 -0
  10. package/src/lib/activity/ai-activity.d.ts +219 -0
  11. package/src/lib/activity/ai-activity.js +251 -0
  12. package/src/lib/activity/ai-activity.js.map +1 -0
  13. package/src/lib/billing/ai-overage-charge.d.ts +102 -0
  14. package/src/lib/billing/ai-overage-charge.js +258 -0
  15. package/src/lib/billing/ai-overage-charge.js.map +1 -0
  16. package/src/lib/billing/ai-overage-close.d.ts +62 -0
  17. package/src/lib/billing/ai-overage-close.js +129 -0
  18. package/src/lib/billing/ai-overage-close.js.map +1 -0
  19. package/src/lib/billing/ai-overage-cutover.d.ts +63 -0
  20. package/src/lib/billing/ai-overage-cutover.js +114 -0
  21. package/src/lib/billing/ai-overage-cutover.js.map +1 -0
  22. package/src/lib/billing/ai-overage-events.d.ts +77 -0
  23. package/src/lib/billing/ai-overage-events.js +174 -0
  24. package/src/lib/billing/ai-overage-events.js.map +1 -0
  25. package/src/lib/billing/ai-overage-gate.d.ts +147 -0
  26. package/src/lib/billing/ai-overage-gate.js +177 -0
  27. package/src/lib/billing/ai-overage-gate.js.map +1 -0
  28. package/src/lib/billing/ai-overage-ledger.d.ts +135 -0
  29. package/src/lib/billing/ai-overage-ledger.js +278 -0
  30. package/src/lib/billing/ai-overage-ledger.js.map +1 -0
  31. package/src/lib/billing/ai-overage-standing-writes.d.ts +110 -0
  32. package/src/lib/billing/ai-overage-standing-writes.js +205 -0
  33. package/src/lib/billing/ai-overage-standing-writes.js.map +1 -0
  34. package/src/lib/billing/ai-overage-standing.d.ts +168 -0
  35. package/src/lib/billing/ai-overage-standing.js +215 -0
  36. package/src/lib/billing/ai-overage-standing.js.map +1 -0
  37. package/src/lib/billing/ai-overage-trigger.d.ts +30 -0
  38. package/src/lib/billing/ai-overage-trigger.js +76 -0
  39. package/src/lib/billing/ai-overage-trigger.js.map +1 -0
  40. package/src/lib/components/ai-allotment-editor.component.d.ts +40 -0
  41. package/src/lib/components/ai-allotment-editor.component.js +213 -0
  42. package/src/lib/components/ai-allotment-editor.component.js.map +1 -0
  43. package/src/lib/components/ai-assist-actions-context.d.ts +13 -0
  44. package/src/lib/components/ai-assist-actions-context.js +21 -0
  45. package/src/lib/components/ai-assist-actions-context.js.map +1 -0
  46. package/src/lib/components/ai-assist-provider.component.d.ts +51 -0
  47. package/src/lib/components/ai-assist-provider.component.js +519 -0
  48. package/src/lib/components/ai-assist-provider.component.js.map +1 -0
  49. package/src/lib/components/ai-brief-dialog.component.d.ts +56 -0
  50. package/src/lib/components/ai-brief-dialog.component.js +319 -0
  51. package/src/lib/components/ai-brief-dialog.component.js.map +1 -0
  52. package/src/lib/components/ai-collaborator-permissions-column.component.d.ts +32 -0
  53. package/src/lib/components/ai-collaborator-permissions-column.component.js +132 -0
  54. package/src/lib/components/ai-collaborator-permissions-column.component.js.map +1 -0
  55. package/src/lib/components/ai-credits-card.component.d.ts +34 -0
  56. package/src/lib/components/ai-credits-card.component.js +131 -0
  57. package/src/lib/components/ai-credits-card.component.js.map +1 -0
  58. package/src/lib/components/ai-credits-columns.component.d.ts +56 -0
  59. package/src/lib/components/ai-credits-columns.component.js +118 -0
  60. package/src/lib/components/ai-credits-columns.component.js.map +1 -0
  61. package/src/lib/components/ai-crm-email-draft.component.d.ts +17 -0
  62. package/src/lib/components/ai-crm-email-draft.component.js +159 -0
  63. package/src/lib/components/ai-crm-email-draft.component.js.map +1 -0
  64. package/src/lib/components/ai-crm-import-mapping.component.d.ts +20 -0
  65. package/src/lib/components/ai-crm-import-mapping.component.js +167 -0
  66. package/src/lib/components/ai-crm-import-mapping.component.js.map +1 -0
  67. package/src/lib/components/ai-crm-record-card.component.d.ts +27 -0
  68. package/src/lib/components/ai-crm-record-card.component.js +263 -0
  69. package/src/lib/components/ai-crm-record-card.component.js.map +1 -0
  70. package/src/lib/components/ai-describe-automation.component.d.ts +31 -0
  71. package/src/lib/components/ai-describe-automation.component.js +226 -0
  72. package/src/lib/components/ai-describe-automation.component.js.map +1 -0
  73. package/src/lib/components/ai-describe-button.component.d.ts +39 -0
  74. package/src/lib/components/ai-describe-button.component.js +87 -0
  75. package/src/lib/components/ai-describe-button.component.js.map +1 -0
  76. package/src/lib/components/ai-describe-page.component.d.ts +26 -0
  77. package/src/lib/components/ai-describe-page.component.js +18 -0
  78. package/src/lib/components/ai-describe-page.component.js.map +1 -0
  79. package/src/lib/components/ai-experiment-cards.component.d.ts +75 -0
  80. package/src/lib/components/ai-experiment-cards.component.js +573 -0
  81. package/src/lib/components/ai-experiment-cards.component.js.map +1 -0
  82. package/src/lib/components/ai-explain-automation.component.d.ts +31 -0
  83. package/src/lib/components/ai-explain-automation.component.js +265 -0
  84. package/src/lib/components/ai-explain-automation.component.js.map +1 -0
  85. package/src/lib/components/ai-insight-dialog.component.d.ts +37 -0
  86. package/src/lib/components/ai-insight-dialog.component.js +441 -0
  87. package/src/lib/components/ai-insight-dialog.component.js.map +1 -0
  88. package/src/lib/components/ai-job-plan.component.d.ts +46 -0
  89. package/src/lib/components/ai-job-plan.component.js +192 -0
  90. package/src/lib/components/ai-job-plan.component.js.map +1 -0
  91. package/src/lib/components/ai-model-selector.component.d.ts +21 -0
  92. package/src/lib/components/ai-model-selector.component.js +109 -0
  93. package/src/lib/components/ai-model-selector.component.js.map +1 -0
  94. package/src/lib/components/ai-page-brief-dialog.component.d.ts +29 -0
  95. package/src/lib/components/ai-page-brief-dialog.component.js +27 -0
  96. package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -0
  97. package/src/lib/components/ai-permissions-on-host.component.d.ts +55 -0
  98. package/src/lib/components/ai-permissions-on-host.component.js +91 -0
  99. package/src/lib/components/ai-permissions-on-host.component.js.map +1 -0
  100. package/src/lib/components/ai-product-copy-card.component.d.ts +25 -0
  101. package/src/lib/components/ai-product-copy-card.component.js +328 -0
  102. package/src/lib/components/ai-product-copy-card.component.js.map +1 -0
  103. package/src/lib/components/ai-product-import-option.component.d.ts +14 -0
  104. package/src/lib/components/ai-product-import-option.component.js +58 -0
  105. package/src/lib/components/ai-product-import-option.component.js.map +1 -0
  106. package/src/lib/components/ai-products-hub-card.component.d.ts +15 -0
  107. package/src/lib/components/ai-products-hub-card.component.js +418 -0
  108. package/src/lib/components/ai-products-hub-card.component.js.map +1 -0
  109. package/src/lib/components/ai-products-proposals.component.d.ts +19 -0
  110. package/src/lib/components/ai-products-proposals.component.js +547 -0
  111. package/src/lib/components/ai-products-proposals.component.js.map +1 -0
  112. package/src/lib/components/ai-save-as-component.component.d.ts +38 -0
  113. package/src/lib/components/ai-save-as-component.component.js +231 -0
  114. package/src/lib/components/ai-save-as-component.component.js.map +1 -0
  115. package/src/lib/components/ai-seo-audit-card.component.d.ts +9 -0
  116. package/src/lib/components/ai-seo-audit-card.component.js +620 -0
  117. package/src/lib/components/ai-seo-audit-card.component.js.map +1 -0
  118. package/src/lib/components/ai-seo-fields-card.component.d.ts +10 -0
  119. package/src/lib/components/ai-seo-fields-card.component.js +453 -0
  120. package/src/lib/components/ai-seo-fields-card.component.js.map +1 -0
  121. package/src/lib/components/ai-site-batch-card.component.d.ts +32 -0
  122. package/src/lib/components/ai-site-batch-card.component.js +531 -0
  123. package/src/lib/components/ai-site-batch-card.component.js.map +1 -0
  124. package/src/lib/components/ai-site-seo-start-card.component.d.ts +26 -0
  125. package/src/lib/components/ai-site-seo-start-card.component.js +178 -0
  126. package/src/lib/components/ai-site-seo-start-card.component.js.map +1 -0
  127. package/src/lib/components/ai-site-start-card.component.d.ts +19 -0
  128. package/src/lib/components/ai-site-start-card.component.js +348 -0
  129. package/src/lib/components/ai-site-start-card.component.js.map +1 -0
  130. package/src/lib/components/ai-template-collection-field.component.d.ts +32 -0
  131. package/src/lib/components/ai-template-collection-field.component.js +63 -0
  132. package/src/lib/components/ai-template-collection-field.component.js.map +1 -0
  133. package/src/lib/components/ai-theme-proposal-card.component.d.ts +6 -0
  134. package/src/lib/components/ai-theme-proposal-card.component.js +619 -0
  135. package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -0
  136. package/src/lib/components/ai-usage-strip.component.d.ts +27 -0
  137. package/src/lib/components/ai-usage-strip.component.js +145 -0
  138. package/src/lib/components/ai-usage-strip.component.js.map +1 -0
  139. package/src/lib/components/assist-edit-canvas.d.ts +169 -0
  140. package/src/lib/components/assist-edit-canvas.js +636 -0
  141. package/src/lib/components/assist-edit-canvas.js.map +1 -0
  142. package/src/lib/components/assist-edit-card.component.d.ts +16 -0
  143. package/src/lib/components/assist-edit-card.component.js +181 -0
  144. package/src/lib/components/assist-edit-card.component.js.map +1 -0
  145. package/src/lib/components/assist-jobs-drawer.component.d.ts +72 -0
  146. package/src/lib/components/assist-jobs-drawer.component.js +626 -0
  147. package/src/lib/components/assist-jobs-drawer.component.js.map +1 -0
  148. package/src/lib/components/assist-panel.component.d.ts +136 -0
  149. package/src/lib/components/assist-panel.component.js +1099 -0
  150. package/src/lib/components/assist-panel.component.js.map +1 -0
  151. package/src/lib/components/assist-signals-page.component.d.ts +3 -0
  152. package/src/lib/components/assist-signals-page.component.js +1017 -0
  153. package/src/lib/components/assist-signals-page.component.js.map +1 -0
  154. package/src/lib/components/besigner-ai-controls.component.d.ts +29 -0
  155. package/src/lib/components/besigner-ai-controls.component.js +81 -0
  156. package/src/lib/components/besigner-ai-controls.component.js.map +1 -0
  157. package/src/lib/components/billing-ai-allotments.component.d.ts +36 -0
  158. package/src/lib/components/billing-ai-allotments.component.js +486 -0
  159. package/src/lib/components/billing-ai-allotments.component.js.map +1 -0
  160. package/src/lib/components/billing-ai-top-users.component.d.ts +44 -0
  161. package/src/lib/components/billing-ai-top-users.component.js +304 -0
  162. package/src/lib/components/billing-ai-top-users.component.js.map +1 -0
  163. package/src/lib/components/billing-assist-overage-card.component.d.ts +69 -0
  164. package/src/lib/components/billing-assist-overage-card.component.js +437 -0
  165. package/src/lib/components/billing-assist-overage-card.component.js.map +1 -0
  166. package/src/lib/components/host-ai-allotments.component.d.ts +40 -0
  167. package/src/lib/components/host-ai-allotments.component.js +239 -0
  168. package/src/lib/components/host-ai-allotments.component.js.map +1 -0
  169. package/src/lib/components/member-ai-allotment-card.component.d.ts +28 -0
  170. package/src/lib/components/member-ai-allotment-card.component.js +172 -0
  171. package/src/lib/components/member-ai-allotment-card.component.js.map +1 -0
  172. package/src/lib/components/member-ai-usage-card.component.d.ts +28 -0
  173. package/src/lib/components/member-ai-usage-card.component.js +240 -0
  174. package/src/lib/components/member-ai-usage-card.component.js.map +1 -0
  175. package/src/lib/components/staff-org-ai-card.component.d.ts +17 -0
  176. package/src/lib/components/staff-org-ai-card.component.js +739 -0
  177. package/src/lib/components/staff-org-ai-card.component.js.map +1 -0
  178. package/src/lib/components/staff-org-usage-ai-columns.component.d.ts +41 -0
  179. package/src/lib/components/staff-org-usage-ai-columns.component.js +65 -0
  180. package/src/lib/components/staff-org-usage-ai-columns.component.js.map +1 -0
  181. package/src/lib/components/staff-orgs-ai-spend-column.component.d.ts +28 -0
  182. package/src/lib/components/staff-orgs-ai-spend-column.component.js +89 -0
  183. package/src/lib/components/staff-orgs-ai-spend-column.component.js.map +1 -0
  184. package/src/lib/components/staff-user-ai-usage-card.component.d.ts +27 -0
  185. package/src/lib/components/staff-user-ai-usage-card.component.js +183 -0
  186. package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -0
  187. package/src/lib/components/use-ai-allotments.d.ts +49 -0
  188. package/src/lib/components/use-ai-allotments.js +171 -0
  189. package/src/lib/components/use-ai-allotments.js.map +1 -0
  190. package/src/lib/components/use-ai-crm-answer.d.ts +50 -0
  191. package/src/lib/components/use-ai-crm-answer.js +220 -0
  192. package/src/lib/components/use-ai-crm-answer.js.map +1 -0
  193. package/src/lib/components/use-ai-job-run.d.ts +51 -0
  194. package/src/lib/components/use-ai-job-run.js +176 -0
  195. package/src/lib/components/use-ai-job-run.js.map +1 -0
  196. package/src/lib/components/use-ai-model-choice.d.ts +47 -0
  197. package/src/lib/components/use-ai-model-choice.js +150 -0
  198. package/src/lib/components/use-ai-model-choice.js.map +1 -0
  199. package/src/lib/components/use-ai-products-jobs.d.ts +36 -0
  200. package/src/lib/components/use-ai-products-jobs.js +190 -0
  201. package/src/lib/components/use-ai-products-jobs.js.map +1 -0
  202. package/src/lib/components/use-ai-usage-meter.d.ts +11 -0
  203. package/src/lib/components/use-ai-usage-meter.js +96 -0
  204. package/src/lib/components/use-ai-usage-meter.js.map +1 -0
  205. package/src/lib/components/use-org-ai-usage.d.ts +42 -0
  206. package/src/lib/components/use-org-ai-usage.js +181 -0
  207. package/src/lib/components/use-org-ai-usage.js.map +1 -0
  208. package/src/lib/components/use-staff-orgs-ai-spend.d.ts +18 -0
  209. package/src/lib/components/use-staff-orgs-ai-spend.js +127 -0
  210. package/src/lib/components/use-staff-orgs-ai-spend.js.map +1 -0
  211. package/src/lib/constants.d.ts +24 -0
  212. package/src/lib/constants.js +23 -0
  213. package/src/lib/constants.js.map +1 -0
  214. package/src/lib/declarations.d.ts +48 -0
  215. package/src/lib/declarations.js +129 -0
  216. package/src/lib/declarations.js.map +1 -0
  217. package/src/lib/declarations.server.d.ts +35 -0
  218. package/src/lib/declarations.server.js +138 -0
  219. package/src/lib/declarations.server.js.map +1 -0
  220. package/src/lib/insights/ai-figure-readers.d.ts +90 -0
  221. package/src/lib/insights/ai-figure-readers.js +863 -0
  222. package/src/lib/insights/ai-figure-readers.js.map +1 -0
  223. package/src/lib/insights/ai-insight-digest.d.ts +165 -0
  224. package/src/lib/insights/ai-insight-digest.js +363 -0
  225. package/src/lib/insights/ai-insight-digest.js.map +1 -0
  226. package/src/lib/insights/ai-insight-readers.d.ts +71 -0
  227. package/src/lib/insights/ai-insight-readers.js +141 -0
  228. package/src/lib/insights/ai-insight-readers.js.map +1 -0
  229. package/src/lib/jobs/ai-crm-access.d.ts +61 -0
  230. package/src/lib/jobs/ai-crm-access.js +94 -0
  231. package/src/lib/jobs/ai-crm-access.js.map +1 -0
  232. package/src/lib/jobs/ai-email-bindings.d.ts +97 -0
  233. package/src/lib/jobs/ai-email-bindings.js +147 -0
  234. package/src/lib/jobs/ai-email-bindings.js.map +1 -0
  235. package/src/lib/jobs/ai-job-admission.d.ts +82 -0
  236. package/src/lib/jobs/ai-job-admission.js +45 -0
  237. package/src/lib/jobs/ai-job-admission.js.map +1 -0
  238. package/src/lib/jobs/ai-job-budget.d.ts +167 -0
  239. package/src/lib/jobs/ai-job-budget.js +161 -0
  240. package/src/lib/jobs/ai-job-budget.js.map +1 -0
  241. package/src/lib/jobs/ai-job-campaign-step.d.ts +108 -0
  242. package/src/lib/jobs/ai-job-campaign-step.js +340 -0
  243. package/src/lib/jobs/ai-job-campaign-step.js.map +1 -0
  244. package/src/lib/jobs/ai-job-component-checks.d.ts +74 -0
  245. package/src/lib/jobs/ai-job-component-checks.js +442 -0
  246. package/src/lib/jobs/ai-job-component-checks.js.map +1 -0
  247. package/src/lib/jobs/ai-job-component-step.d.ts +75 -0
  248. package/src/lib/jobs/ai-job-component-step.js +262 -0
  249. package/src/lib/jobs/ai-job-component-step.js.map +1 -0
  250. package/src/lib/jobs/ai-job-crm-step.d.ts +192 -0
  251. package/src/lib/jobs/ai-job-crm-step.js +734 -0
  252. package/src/lib/jobs/ai-job-crm-step.js.map +1 -0
  253. package/src/lib/jobs/ai-job-draft-ids.d.ts +62 -0
  254. package/src/lib/jobs/ai-job-draft-ids.js +132 -0
  255. package/src/lib/jobs/ai-job-draft-ids.js.map +1 -0
  256. package/src/lib/jobs/ai-job-drafts.d.ts +304 -0
  257. package/src/lib/jobs/ai-job-drafts.js +557 -0
  258. package/src/lib/jobs/ai-job-drafts.js.map +1 -0
  259. package/src/lib/jobs/ai-job-email-step.d.ts +195 -0
  260. package/src/lib/jobs/ai-job-email-step.js +547 -0
  261. package/src/lib/jobs/ai-job-email-step.js.map +1 -0
  262. package/src/lib/jobs/ai-job-experiment-step.d.ts +105 -0
  263. package/src/lib/jobs/ai-job-experiment-step.js +445 -0
  264. package/src/lib/jobs/ai-job-experiment-step.js.map +1 -0
  265. package/src/lib/jobs/ai-job-form-step.d.ts +250 -0
  266. package/src/lib/jobs/ai-job-form-step.js +634 -0
  267. package/src/lib/jobs/ai-job-form-step.js.map +1 -0
  268. package/src/lib/jobs/ai-job-generation.d.ts +114 -0
  269. package/src/lib/jobs/ai-job-generation.js +384 -0
  270. package/src/lib/jobs/ai-job-generation.js.map +1 -0
  271. package/src/lib/jobs/ai-job-insight-budget.d.ts +41 -0
  272. package/src/lib/jobs/ai-job-insight-budget.js +46 -0
  273. package/src/lib/jobs/ai-job-insight-budget.js.map +1 -0
  274. package/src/lib/jobs/ai-job-insight-step.d.ts +58 -0
  275. package/src/lib/jobs/ai-job-insight-step.js +350 -0
  276. package/src/lib/jobs/ai-job-insight-step.js.map +1 -0
  277. package/src/lib/jobs/ai-job-layout-step.d.ts +103 -0
  278. package/src/lib/jobs/ai-job-layout-step.js +340 -0
  279. package/src/lib/jobs/ai-job-layout-step.js.map +1 -0
  280. package/src/lib/jobs/ai-job-page-budget.d.ts +57 -0
  281. package/src/lib/jobs/ai-job-page-budget.js +60 -0
  282. package/src/lib/jobs/ai-job-page-budget.js.map +1 -0
  283. package/src/lib/jobs/ai-job-page-sections.d.ts +150 -0
  284. package/src/lib/jobs/ai-job-page-sections.js +450 -0
  285. package/src/lib/jobs/ai-job-page-sections.js.map +1 -0
  286. package/src/lib/jobs/ai-job-page-step.d.ts +198 -0
  287. package/src/lib/jobs/ai-job-page-step.js +667 -0
  288. package/src/lib/jobs/ai-job-page-step.js.map +1 -0
  289. package/src/lib/jobs/ai-job-plan-conformance.d.ts +107 -0
  290. package/src/lib/jobs/ai-job-plan-conformance.js +164 -0
  291. package/src/lib/jobs/ai-job-plan-conformance.js.map +1 -0
  292. package/src/lib/jobs/ai-job-plan-step.d.ts +196 -0
  293. package/src/lib/jobs/ai-job-plan-step.js +458 -0
  294. package/src/lib/jobs/ai-job-plan-step.js.map +1 -0
  295. package/src/lib/jobs/ai-job-plugin-drafts.d.ts +76 -0
  296. package/src/lib/jobs/ai-job-plugin-drafts.js +91 -0
  297. package/src/lib/jobs/ai-job-plugin-drafts.js.map +1 -0
  298. package/src/lib/jobs/ai-job-products-step.d.ts +106 -0
  299. package/src/lib/jobs/ai-job-products-step.js +436 -0
  300. package/src/lib/jobs/ai-job-products-step.js.map +1 -0
  301. package/src/lib/jobs/ai-job-seo-budget.d.ts +52 -0
  302. package/src/lib/jobs/ai-job-seo-budget.js +63 -0
  303. package/src/lib/jobs/ai-job-seo-budget.js.map +1 -0
  304. package/src/lib/jobs/ai-job-seo-step.d.ts +145 -0
  305. package/src/lib/jobs/ai-job-seo-step.js +809 -0
  306. package/src/lib/jobs/ai-job-seo-step.js.map +1 -0
  307. package/src/lib/jobs/ai-job-site-step.d.ts +252 -0
  308. package/src/lib/jobs/ai-job-site-step.js +538 -0
  309. package/src/lib/jobs/ai-job-site-step.js.map +1 -0
  310. package/src/lib/jobs/ai-job-template-step.d.ts +105 -0
  311. package/src/lib/jobs/ai-job-template-step.js +391 -0
  312. package/src/lib/jobs/ai-job-template-step.js.map +1 -0
  313. package/src/lib/jobs/ai-job-text-step.d.ts +125 -0
  314. package/src/lib/jobs/ai-job-text-step.js +128 -0
  315. package/src/lib/jobs/ai-job-text-step.js.map +1 -0
  316. package/src/lib/jobs/ai-job-theme-budget.d.ts +38 -0
  317. package/src/lib/jobs/ai-job-theme-budget.js +43 -0
  318. package/src/lib/jobs/ai-job-theme-budget.js.map +1 -0
  319. package/src/lib/jobs/ai-job-theme-step.d.ts +115 -0
  320. package/src/lib/jobs/ai-job-theme-step.js +337 -0
  321. package/src/lib/jobs/ai-job-theme-step.js.map +1 -0
  322. package/src/lib/jobs/ai-job-workflow-step.d.ts +139 -0
  323. package/src/lib/jobs/ai-job-workflow-step.js +530 -0
  324. package/src/lib/jobs/ai-job-workflow-step.js.map +1 -0
  325. package/src/lib/jobs/ai-jobs-beat.d.ts +78 -0
  326. package/src/lib/jobs/ai-jobs-beat.js +93 -0
  327. package/src/lib/jobs/ai-jobs-beat.js.map +1 -0
  328. package/src/lib/jobs/ai-jobs-pause.d.ts +38 -0
  329. package/src/lib/jobs/ai-jobs-pause.js +45 -0
  330. package/src/lib/jobs/ai-jobs-pause.js.map +1 -0
  331. package/src/lib/jobs/ai-jobs.d.ts +558 -0
  332. package/src/lib/jobs/ai-jobs.js +1410 -0
  333. package/src/lib/jobs/ai-jobs.js.map +1 -0
  334. package/src/lib/jobs/ai-media-asset-server.d.ts +34 -0
  335. package/src/lib/jobs/ai-media-asset-server.js +34 -0
  336. package/src/lib/jobs/ai-media-asset-server.js.map +1 -0
  337. package/src/lib/jobs/ai-media-asset.d.ts +59 -0
  338. package/src/lib/jobs/ai-media-asset.js +86 -0
  339. package/src/lib/jobs/ai-media-asset.js.map +1 -0
  340. package/src/lib/jobs/ai-product-image.d.ts +78 -0
  341. package/src/lib/jobs/ai-product-image.js +113 -0
  342. package/src/lib/jobs/ai-product-image.js.map +1 -0
  343. package/src/lib/jobs/ai-theme-brand-inputs.d.ts +125 -0
  344. package/src/lib/jobs/ai-theme-brand-inputs.js +378 -0
  345. package/src/lib/jobs/ai-theme-brand-inputs.js.map +1 -0
  346. package/src/lib/jobs/ai-theme-brand-server.d.ts +33 -0
  347. package/src/lib/jobs/ai-theme-brand-server.js +33 -0
  348. package/src/lib/jobs/ai-theme-brand-server.js.map +1 -0
  349. package/src/lib/jobs/ai-workflow-records.d.ts +84 -0
  350. package/src/lib/jobs/ai-workflow-records.js +158 -0
  351. package/src/lib/jobs/ai-workflow-records.js.map +1 -0
  352. package/src/lib/jobs/fixtures/ai-free-page-built-recording.d.ts +31 -0
  353. package/src/lib/jobs/fixtures/ai-free-page-built-recording.js +367 -0
  354. package/src/lib/jobs/fixtures/ai-free-page-built-recording.js.map +1 -0
  355. package/src/lib/jobs/fixtures/ai-free-page-recording.d.ts +69 -0
  356. package/src/lib/jobs/fixtures/ai-free-page-recording.js +442 -0
  357. package/src/lib/jobs/fixtures/ai-free-page-recording.js.map +1 -0
  358. package/src/lib/jobs/fixtures/ai-page-briefs.d.ts +146 -0
  359. package/src/lib/jobs/fixtures/ai-page-briefs.js +1850 -0
  360. package/src/lib/jobs/fixtures/ai-page-briefs.js.map +1 -0
  361. package/src/lib/model/ai-allotments.d.ts +208 -0
  362. package/src/lib/model/ai-allotments.js +269 -0
  363. package/src/lib/model/ai-allotments.js.map +1 -0
  364. package/src/lib/model/ai-automation-draft.d.ts +74 -0
  365. package/src/lib/model/ai-automation-draft.js +310 -0
  366. package/src/lib/model/ai-automation-draft.js.map +1 -0
  367. package/src/lib/model/ai-automation-outline.d.ts +50 -0
  368. package/src/lib/model/ai-automation-outline.js +262 -0
  369. package/src/lib/model/ai-automation-outline.js.map +1 -0
  370. package/src/lib/model/ai-build-plan.d.ts +197 -0
  371. package/src/lib/model/ai-build-plan.js +438 -0
  372. package/src/lib/model/ai-build-plan.js.map +1 -0
  373. package/src/lib/model/ai-crm.d.ts +237 -0
  374. package/src/lib/model/ai-crm.js +225 -0
  375. package/src/lib/model/ai-crm.js.map +1 -0
  376. package/src/lib/model/ai-experiment-proposal.d.ts +68 -0
  377. package/src/lib/model/ai-experiment-proposal.js +146 -0
  378. package/src/lib/model/ai-experiment-proposal.js.map +1 -0
  379. package/src/lib/model/ai-experiment.d.ts +309 -0
  380. package/src/lib/model/ai-experiment.js +395 -0
  381. package/src/lib/model/ai-experiment.js.map +1 -0
  382. package/src/lib/model/ai-insight.d.ts +178 -0
  383. package/src/lib/model/ai-insight.js +201 -0
  384. package/src/lib/model/ai-insight.js.map +1 -0
  385. package/src/lib/model/ai-jobs.types.d.ts +412 -0
  386. package/src/lib/model/ai-jobs.types.js +42 -0
  387. package/src/lib/model/ai-jobs.types.js.map +1 -0
  388. package/src/lib/model/ai-page-job.d.ts +92 -0
  389. package/src/lib/model/ai-page-job.js +159 -0
  390. package/src/lib/model/ai-page-job.js.map +1 -0
  391. package/src/lib/model/ai-permissions.d.ts +49 -0
  392. package/src/lib/model/ai-permissions.js +97 -0
  393. package/src/lib/model/ai-permissions.js.map +1 -0
  394. package/src/lib/model/ai-plan-capabilities.d.ts +139 -0
  395. package/src/lib/model/ai-plan-capabilities.js +149 -0
  396. package/src/lib/model/ai-plan-capabilities.js.map +1 -0
  397. package/src/lib/model/ai-products.d.ts +251 -0
  398. package/src/lib/model/ai-products.js +253 -0
  399. package/src/lib/model/ai-products.js.map +1 -0
  400. package/src/lib/model/ai-seo.d.ts +208 -0
  401. package/src/lib/model/ai-seo.js +150 -0
  402. package/src/lib/model/ai-seo.js.map +1 -0
  403. package/src/lib/model/ai-site-inventory.d.ts +164 -0
  404. package/src/lib/model/ai-site-inventory.js +145 -0
  405. package/src/lib/model/ai-site-inventory.js.map +1 -0
  406. package/src/lib/model/ai-site-job.d.ts +247 -0
  407. package/src/lib/model/ai-site-job.js +314 -0
  408. package/src/lib/model/ai-site-job.js.map +1 -0
  409. package/src/lib/model/ai-site-start-seo.d.ts +103 -0
  410. package/src/lib/model/ai-site-start-seo.js +154 -0
  411. package/src/lib/model/ai-site-start-seo.js.map +1 -0
  412. package/src/lib/model/ai-site-start.d.ts +122 -0
  413. package/src/lib/model/ai-site-start.js +159 -0
  414. package/src/lib/model/ai-site-start.js.map +1 -0
  415. package/src/lib/model/ai-site-switch.d.ts +56 -0
  416. package/src/lib/model/ai-site-switch.js +73 -0
  417. package/src/lib/model/ai-site-switch.js.map +1 -0
  418. package/src/lib/model/ai-storefront-claims.d.ts +70 -0
  419. package/src/lib/model/ai-storefront-claims.js +130 -0
  420. package/src/lib/model/ai-storefront-claims.js.map +1 -0
  421. package/src/lib/model/ai-template-subjects.d.ts +82 -0
  422. package/src/lib/model/ai-template-subjects.js +136 -0
  423. package/src/lib/model/ai-template-subjects.js.map +1 -0
  424. package/src/lib/model/ai-theme-proposal.d.ts +210 -0
  425. package/src/lib/model/ai-theme-proposal.js +506 -0
  426. package/src/lib/model/ai-theme-proposal.js.map +1 -0
  427. package/src/lib/model/ai-tokens.d.ts +96 -0
  428. package/src/lib/model/ai-tokens.js +117 -0
  429. package/src/lib/model/ai-tokens.js.map +1 -0
  430. package/src/lib/model/ai-usage-by-user.d.ts +120 -0
  431. package/src/lib/model/ai-usage-by-user.js +139 -0
  432. package/src/lib/model/ai-usage-by-user.js.map +1 -0
  433. package/src/lib/model/ai-workflow-job.d.ts +111 -0
  434. package/src/lib/model/ai-workflow-job.js +183 -0
  435. package/src/lib/model/ai-workflow-job.js.map +1 -0
  436. package/src/lib/model/assist-edit.d.ts +261 -0
  437. package/src/lib/model/assist-edit.js +175 -0
  438. package/src/lib/model/assist-edit.js.map +1 -0
  439. package/src/lib/plugin-config.d.ts +33 -0
  440. package/src/lib/plugin-config.js +118 -0
  441. package/src/lib/plugin-config.js.map +1 -0
  442. package/src/lib/plugin.d.ts +30 -0
  443. package/src/lib/plugin.js +525 -0
  444. package/src/lib/plugin.js.map +1 -0
  445. package/src/lib/providers/anthropic.d.ts +84 -0
  446. package/src/lib/providers/anthropic.js +432 -0
  447. package/src/lib/providers/anthropic.js.map +1 -0
  448. package/src/lib/providers/catalog.d.ts +197 -0
  449. package/src/lib/providers/catalog.js +312 -0
  450. package/src/lib/providers/catalog.js.map +1 -0
  451. package/src/lib/providers/contract.d.ts +464 -0
  452. package/src/lib/providers/contract.js +274 -0
  453. package/src/lib/providers/contract.js.map +1 -0
  454. package/src/lib/providers/model-choice.d.ts +119 -0
  455. package/src/lib/providers/model-choice.js +416 -0
  456. package/src/lib/providers/model-choice.js.map +1 -0
  457. package/src/lib/providers/openai-compatible.d.ts +58 -0
  458. package/src/lib/providers/openai-compatible.js +361 -0
  459. package/src/lib/providers/openai-compatible.js.map +1 -0
  460. package/src/lib/providers/registry.d.ts +49 -0
  461. package/src/lib/providers/registry.js +71 -0
  462. package/src/lib/providers/registry.js.map +1 -0
  463. package/src/lib/providers/routing.d.ts +98 -0
  464. package/src/lib/providers/routing.js +450 -0
  465. package/src/lib/providers/routing.js.map +1 -0
  466. package/src/lib/runtime/ai-abuse-guards.d.ts +113 -0
  467. package/src/lib/runtime/ai-abuse-guards.js +148 -0
  468. package/src/lib/runtime/ai-abuse-guards.js.map +1 -0
  469. package/src/lib/runtime/ai-component-bindings.d.ts +67 -0
  470. package/src/lib/runtime/ai-component-bindings.js +106 -0
  471. package/src/lib/runtime/ai-component-bindings.js.map +1 -0
  472. package/src/lib/runtime/ai-device-audit.d.ts +109 -0
  473. package/src/lib/runtime/ai-device-audit.js +97 -0
  474. package/src/lib/runtime/ai-device-audit.js.map +1 -0
  475. package/src/lib/runtime/ai-doctrine-validators.d.ts +720 -0
  476. package/src/lib/runtime/ai-doctrine-validators.js +3133 -0
  477. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -0
  478. package/src/lib/runtime/ai-doctrine.d.ts +372 -0
  479. package/src/lib/runtime/ai-doctrine.js +944 -0
  480. package/src/lib/runtime/ai-doctrine.js.map +1 -0
  481. package/src/lib/runtime/ai-eval-live.d.ts +321 -0
  482. package/src/lib/runtime/ai-eval-live.js +1257 -0
  483. package/src/lib/runtime/ai-eval-live.js.map +1 -0
  484. package/src/lib/runtime/ai-eval-memory-firestore.d.ts +51 -0
  485. package/src/lib/runtime/ai-eval-memory-firestore.js +183 -0
  486. package/src/lib/runtime/ai-eval-memory-firestore.js.map +1 -0
  487. package/src/lib/runtime/ai-eval.d.ts +441 -0
  488. package/src/lib/runtime/ai-eval.js +1151 -0
  489. package/src/lib/runtime/ai-eval.js.map +1 -0
  490. package/src/lib/runtime/ai-gate.d.ts +130 -0
  491. package/src/lib/runtime/ai-gate.js +272 -0
  492. package/src/lib/runtime/ai-gate.js.map +1 -0
  493. package/src/lib/runtime/ai-generation-bounds.d.ts +24 -0
  494. package/src/lib/runtime/ai-generation-bounds.js +23 -0
  495. package/src/lib/runtime/ai-generation-bounds.js.map +1 -0
  496. package/src/lib/runtime/ai-insight-check.d.ts +76 -0
  497. package/src/lib/runtime/ai-insight-check.js +281 -0
  498. package/src/lib/runtime/ai-insight-check.js.map +1 -0
  499. package/src/lib/runtime/ai-node-tree.d.ts +181 -0
  500. package/src/lib/runtime/ai-node-tree.js +931 -0
  501. package/src/lib/runtime/ai-node-tree.js.map +1 -0
  502. package/src/lib/runtime/ai-page-links.d.ts +79 -0
  503. package/src/lib/runtime/ai-page-links.js +135 -0
  504. package/src/lib/runtime/ai-page-links.js.map +1 -0
  505. package/src/lib/runtime/ai-palette.d.ts +252 -0
  506. package/src/lib/runtime/ai-palette.generated.d.ts +34 -0
  507. package/src/lib/runtime/ai-palette.generated.js +5263 -0
  508. package/src/lib/runtime/ai-palette.generated.js.map +1 -0
  509. package/src/lib/runtime/ai-palette.js +187 -0
  510. package/src/lib/runtime/ai-palette.js.map +1 -0
  511. package/src/lib/runtime/ai-products-generation.d.ts +107 -0
  512. package/src/lib/runtime/ai-products-generation.js +250 -0
  513. package/src/lib/runtime/ai-products-generation.js.map +1 -0
  514. package/src/lib/runtime/ai-repeated-items.d.ts +95 -0
  515. package/src/lib/runtime/ai-repeated-items.js +397 -0
  516. package/src/lib/runtime/ai-repeated-items.js.map +1 -0
  517. package/src/lib/runtime/ai-runtime.d.ts +148 -0
  518. package/src/lib/runtime/ai-runtime.js +237 -0
  519. package/src/lib/runtime/ai-runtime.js.map +1 -0
  520. package/src/lib/runtime/ai-template-examples.d.ts +71 -0
  521. package/src/lib/runtime/ai-template-examples.js +135 -0
  522. package/src/lib/runtime/ai-template-examples.js.map +1 -0
  523. package/src/lib/runtime/assist-answer-cache.d.ts +80 -0
  524. package/src/lib/runtime/assist-answer-cache.js +184 -0
  525. package/src/lib/runtime/assist-answer-cache.js.map +1 -0
  526. package/src/lib/runtime/seo-audit.d.ts +93 -0
  527. package/src/lib/runtime/seo-audit.js +260 -0
  528. package/src/lib/runtime/seo-audit.js.map +1 -0
  529. package/src/lib/runtime/seo-content-fixes.d.ts +41 -0
  530. package/src/lib/runtime/seo-content-fixes.js +168 -0
  531. package/src/lib/runtime/seo-content-fixes.js.map +1 -0
  532. package/src/lib/runtime/seo-fields.d.ts +152 -0
  533. package/src/lib/runtime/seo-fields.js +215 -0
  534. package/src/lib/runtime/seo-fields.js.map +1 -0
  535. package/src/lib/runtime/seo-page-facts.d.ts +61 -0
  536. package/src/lib/runtime/seo-page-facts.js +150 -0
  537. package/src/lib/runtime/seo-page-facts.js.map +1 -0
  538. package/src/lib/runtime/site-inventory.d.ts +63 -0
  539. package/src/lib/runtime/site-inventory.js +230 -0
  540. package/src/lib/runtime/site-inventory.js.map +1 -0
  541. package/src/lib/server/ai-admin-org.d.ts +33 -0
  542. package/src/lib/server/ai-admin-org.js +381 -0
  543. package/src/lib/server/ai-admin-org.js.map +1 -0
  544. package/src/lib/server/ai-admin-orgs-spend.d.ts +40 -0
  545. package/src/lib/server/ai-admin-orgs-spend.js +129 -0
  546. package/src/lib/server/ai-admin-orgs-spend.js.map +1 -0
  547. package/src/lib/server/ai-admin-overage.d.ts +19 -0
  548. package/src/lib/server/ai-admin-overage.js +246 -0
  549. package/src/lib/server/ai-admin-overage.js.map +1 -0
  550. package/src/lib/server/ai-admin-signals.d.ts +34 -0
  551. package/src/lib/server/ai-admin-signals.js +330 -0
  552. package/src/lib/server/ai-admin-signals.js.map +1 -0
  553. package/src/lib/server/ai-admin-user.d.ts +27 -0
  554. package/src/lib/server/ai-admin-user.js +128 -0
  555. package/src/lib/server/ai-admin-user.js.map +1 -0
  556. package/src/lib/server/ai-allotments.d.ts +27 -0
  557. package/src/lib/server/ai-allotments.js +544 -0
  558. package/src/lib/server/ai-allotments.js.map +1 -0
  559. package/src/lib/server/ai-assist-prompts.d.ts +102 -0
  560. package/src/lib/server/ai-assist-prompts.js +207 -0
  561. package/src/lib/server/ai-assist-prompts.js.map +1 -0
  562. package/src/lib/server/ai-assist.d.ts +119 -0
  563. package/src/lib/server/ai-assist.js +517 -0
  564. package/src/lib/server/ai-assist.js.map +1 -0
  565. package/src/lib/server/ai-crm-answer.d.ts +30 -0
  566. package/src/lib/server/ai-crm-answer.js +98 -0
  567. package/src/lib/server/ai-crm-answer.js.map +1 -0
  568. package/src/lib/server/ai-generate-component.d.ts +111 -0
  569. package/src/lib/server/ai-generate-component.js +643 -0
  570. package/src/lib/server/ai-generate-component.js.map +1 -0
  571. package/src/lib/server/ai-host-permissions.d.ts +46 -0
  572. package/src/lib/server/ai-host-permissions.js +204 -0
  573. package/src/lib/server/ai-host-permissions.js.map +1 -0
  574. package/src/lib/server/ai-insight-answer.d.ts +30 -0
  575. package/src/lib/server/ai-insight-answer.js +83 -0
  576. package/src/lib/server/ai-insight-answer.js.map +1 -0
  577. package/src/lib/server/ai-insight-digest-route.d.ts +30 -0
  578. package/src/lib/server/ai-insight-digest-route.js +156 -0
  579. package/src/lib/server/ai-insight-digest-route.js.map +1 -0
  580. package/src/lib/server/ai-jobs-batch.d.ts +48 -0
  581. package/src/lib/server/ai-jobs-batch.js +306 -0
  582. package/src/lib/server/ai-jobs-batch.js.map +1 -0
  583. package/src/lib/server/ai-jobs-beat-route.d.ts +36 -0
  584. package/src/lib/server/ai-jobs-beat-route.js +86 -0
  585. package/src/lib/server/ai-jobs-beat-route.js.map +1 -0
  586. package/src/lib/server/ai-jobs-cancel.d.ts +30 -0
  587. package/src/lib/server/ai-jobs-cancel.js +74 -0
  588. package/src/lib/server/ai-jobs-cancel.js.map +1 -0
  589. package/src/lib/server/ai-jobs-events-route.d.ts +31 -0
  590. package/src/lib/server/ai-jobs-events-route.js +51 -0
  591. package/src/lib/server/ai-jobs-events-route.js.map +1 -0
  592. package/src/lib/server/ai-jobs-events.d.ts +55 -0
  593. package/src/lib/server/ai-jobs-events.js +144 -0
  594. package/src/lib/server/ai-jobs-events.js.map +1 -0
  595. package/src/lib/server/ai-jobs-gate.d.ts +47 -0
  596. package/src/lib/server/ai-jobs-gate.js +106 -0
  597. package/src/lib/server/ai-jobs-gate.js.map +1 -0
  598. package/src/lib/server/ai-jobs-resume.d.ts +23 -0
  599. package/src/lib/server/ai-jobs-resume.js +209 -0
  600. package/src/lib/server/ai-jobs-resume.js.map +1 -0
  601. package/src/lib/server/ai-jobs-route.d.ts +32 -0
  602. package/src/lib/server/ai-jobs-route.js +307 -0
  603. package/src/lib/server/ai-jobs-route.js.map +1 -0
  604. package/src/lib/server/ai-models.d.ts +18 -0
  605. package/src/lib/server/ai-models.js +134 -0
  606. package/src/lib/server/ai-models.js.map +1 -0
  607. package/src/lib/server/ai-seo-apply.d.ts +53 -0
  608. package/src/lib/server/ai-seo-apply.js +294 -0
  609. package/src/lib/server/ai-seo-apply.js.map +1 -0
  610. package/src/lib/server/ai-usage.d.ts +18 -0
  611. package/src/lib/server/ai-usage.js +220 -0
  612. package/src/lib/server/ai-usage.js.map +1 -0
  613. package/src/lib/server/assist-chat.d.ts +234 -0
  614. package/src/lib/server/assist-chat.js +1446 -0
  615. package/src/lib/server/assist-chat.js.map +1 -0
  616. package/src/lib/server/assist-edit-applied.d.ts +22 -0
  617. package/src/lib/server/assist-edit-applied.js +239 -0
  618. package/src/lib/server/assist-edit-applied.js.map +1 -0
  619. package/src/lib/server/assist-edit.d.ts +124 -0
  620. package/src/lib/server/assist-edit.js +1000 -0
  621. package/src/lib/server/assist-edit.js.map +1 -0
  622. package/src/lib/server/assist-feedback.d.ts +31 -0
  623. package/src/lib/server/assist-feedback.js +115 -0
  624. package/src/lib/server/assist-feedback.js.map +1 -0
  625. package/src/lib/server/assist-view-context.d.ts +343 -0
  626. package/src/lib/server/assist-view-context.js +690 -0
  627. package/src/lib/server/assist-view-context.js.map +1 -0
  628. package/src/lib/server/billing-credits.d.ts +59 -0
  629. package/src/lib/server/billing-credits.js +146 -0
  630. package/src/lib/server/billing-credits.js.map +1 -0
  631. package/src/lib/server/billing-overage.d.ts +19 -0
  632. package/src/lib/server/billing-overage.js +337 -0
  633. package/src/lib/server/billing-overage.js.map +1 -0
  634. package/src/lib/server.d.ts +32 -0
  635. package/src/lib/server.js +265 -0
  636. package/src/lib/server.js.map +1 -0
  637. package/src/lib/subprocessors.d.ts +18 -0
  638. package/src/lib/subprocessors.js +52 -0
  639. package/src/lib/subprocessors.js.map +1 -0
  640. package/src/lib/tools/ai-component-tool.d.ts +99 -0
  641. package/src/lib/tools/ai-component-tool.js +369 -0
  642. package/src/lib/tools/ai-component-tool.js.map +1 -0
  643. package/src/lib/tools/ai-crm-tool.d.ts +106 -0
  644. package/src/lib/tools/ai-crm-tool.js +488 -0
  645. package/src/lib/tools/ai-crm-tool.js.map +1 -0
  646. package/src/lib/tools/ai-duplicate-resource-tool.d.ts +71 -0
  647. package/src/lib/tools/ai-duplicate-resource-tool.js +164 -0
  648. package/src/lib/tools/ai-duplicate-resource-tool.js.map +1 -0
  649. package/src/lib/tools/ai-experiment-tool.d.ts +40 -0
  650. package/src/lib/tools/ai-experiment-tool.js +155 -0
  651. package/src/lib/tools/ai-experiment-tool.js.map +1 -0
  652. package/src/lib/tools/ai-insight-tool.d.ts +46 -0
  653. package/src/lib/tools/ai-insight-tool.js +200 -0
  654. package/src/lib/tools/ai-insight-tool.js.map +1 -0
  655. package/src/lib/tools/ai-inventory-lookup-tool.d.ts +86 -0
  656. package/src/lib/tools/ai-inventory-lookup-tool.js +164 -0
  657. package/src/lib/tools/ai-inventory-lookup-tool.js.map +1 -0
  658. package/src/lib/tools/ai-products-tool.d.ts +65 -0
  659. package/src/lib/tools/ai-products-tool.js +644 -0
  660. package/src/lib/tools/ai-products-tool.js.map +1 -0
  661. package/src/lib/tools/ai-seo-tool.d.ts +162 -0
  662. package/src/lib/tools/ai-seo-tool.js +546 -0
  663. package/src/lib/tools/ai-seo-tool.js.map +1 -0
  664. package/src/lib/tools/ai-theme-tool.d.ts +101 -0
  665. package/src/lib/tools/ai-theme-tool.js +562 -0
  666. package/src/lib/tools/ai-theme-tool.js.map +1 -0
  667. package/src/lib/tools/ai-workflow-tool.d.ts +166 -0
  668. package/src/lib/tools/ai-workflow-tool.js +860 -0
  669. package/src/lib/tools/ai-workflow-tool.js.map +1 -0
  670. package/src/lib/usage/ai-allotment-alerts.d.ts +72 -0
  671. package/src/lib/usage/ai-allotment-alerts.js +157 -0
  672. package/src/lib/usage/ai-allotment-alerts.js.map +1 -0
  673. package/src/lib/usage/ai-allotments.d.ts +125 -0
  674. package/src/lib/usage/ai-allotments.js +239 -0
  675. package/src/lib/usage/ai-allotments.js.map +1 -0
  676. package/src/lib/usage/ai-model-sample.d.ts +36 -0
  677. package/src/lib/usage/ai-model-sample.js +68 -0
  678. package/src/lib/usage/ai-model-sample.js.map +1 -0
  679. package/src/lib/usage/ai-usage-alerts.d.ts +55 -0
  680. package/src/lib/usage/ai-usage-alerts.js +114 -0
  681. package/src/lib/usage/ai-usage-alerts.js.map +1 -0
  682. package/src/lib/usage/ai-usage-by-user.d.ts +161 -0
  683. package/src/lib/usage/ai-usage-by-user.js +211 -0
  684. package/src/lib/usage/ai-usage-by-user.js.map +1 -0
  685. package/src/lib/usage/ai-usage-eraser.d.ts +29 -0
  686. package/src/lib/usage/ai-usage-eraser.js +40 -0
  687. package/src/lib/usage/ai-usage-eraser.js.map +1 -0
  688. package/src/lib/usage/ai-usage-meter.d.ts +39 -0
  689. package/src/lib/usage/ai-usage-meter.js +85 -0
  690. package/src/lib/usage/ai-usage-meter.js.map +1 -0
  691. package/src/lib/usage/ai-usage-wire.d.ts +184 -0
  692. package/src/lib/usage/ai-usage-wire.js +98 -0
  693. package/src/lib/usage/ai-usage-wire.js.map +1 -0
  694. package/src/lib/usage/assist-ceiling.d.ts +87 -0
  695. package/src/lib/usage/assist-ceiling.js +110 -0
  696. package/src/lib/usage/assist-ceiling.js.map +1 -0
  697. package/src/lib/usage/assist-free-taste.d.ts +225 -0
  698. package/src/lib/usage/assist-free-taste.js +308 -0
  699. package/src/lib/usage/assist-free-taste.js.map +1 -0
  700. package/src/lib/usage/assist-refusals.d.ts +69 -0
  701. package/src/lib/usage/assist-refusals.js +79 -0
  702. package/src/lib/usage/assist-refusals.js.map +1 -0
  703. package/src/lib/usage/assist-signal-mining.d.ts +375 -0
  704. package/src/lib/usage/assist-signal-mining.js +344 -0
  705. package/src/lib/usage/assist-signal-mining.js.map +1 -0
  706. package/src/lib/usage/assist-usage.d.ts +571 -0
  707. package/src/lib/usage/assist-usage.js +978 -0
  708. package/src/lib/usage/assist-usage.js.map +1 -0
  709. package/src/lib/usage/staff-org-ai.d.ts +242 -0
  710. package/src/lib/usage/staff-org-ai.js +173 -0
  711. package/src/lib/usage/staff-org-ai.js.map +1 -0
  712. package/src/lib/usage/staff-org-usage-ai.d.ts +83 -0
  713. package/src/lib/usage/staff-org-usage-ai.js +59 -0
  714. package/src/lib/usage/staff-org-usage-ai.js.map +1 -0
  715. package/src/lib/usage/staff-orgs-ai-spend.d.ts +83 -0
  716. package/src/lib/usage/staff-orgs-ai-spend.js +114 -0
  717. package/src/lib/usage/staff-orgs-ai-spend.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-eval.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { HostTheme } from '@aglyn/shared-data-types'\nimport { validateHostAction, type HostAction } from '@aglyn/aglyn/app-utils/actions'\nimport type { HostThemeSource } from '@aglyn/aglyn/app-utils/marketplace-theme'\nimport {\n aiAutomationDraft,\n emptyAiAutomationRecords,\n type AiAutomationRecords,\n} from '../model/ai-automation-draft'\nimport type { ConsoleImportColumn } from '@aglyn/aglyn/plugin-manager/record-zone-props'\nimport { AI_BUILD_PLAN_CREATE_KINDS, type AiBuildPlanCreateKind } from '../model/ai-build-plan'\nimport {\n aiUnrestrictedPlanCapabilities,\n type AiPlanCapabilities,\n type AiPlanCreation,\n} from '../model/ai-plan-capabilities'\nimport {\n AI_EXPERIMENT_BODY_MAX_CHARS,\n AI_EXPERIMENT_HEADLINE_MAX_CHARS,\n AI_EXPERIMENT_LINE_MAX_CHARS,\n AI_EXPERIMENT_MAX_POINTS,\n AI_EXPERIMENT_NAME_MAX_CHARS,\n AI_EXPERIMENT_NEXT_MAX_CHARS,\n AI_EXPERIMENT_POINT_MAX_CHARS,\n AI_EXPERIMENT_RATIONALE_MAX_CHARS,\n aiExperimentVariantFields,\n checkAiExperimentExplanation,\n checkAiExperimentVariants,\n readAiExperimentResult,\n type AiExperimentArm,\n type AiExperimentTarget,\n type AiExperimentTask,\n} from '../model/ai-experiment'\nimport {\n parseAiExperimentExplanation,\n parseAiExperimentVariants,\n} from '../tools/ai-experiment-tool'\nimport type { AiSiteInventory } from '../model/ai-site-inventory'\nimport type { AiAutomationCapabilities } from '../model/ai-workflow-job'\nimport type { AiStepKind } from '../providers/catalog'\nimport type { AiEffort, AiUsage } from '../providers/contract'\nimport { aiComponentCheck } from '../jobs/ai-job-component-checks'\nimport {\n aiProductMerchantWords,\n type AiProductCategory,\n type AiProductFacts,\n type AiProductPhotoRead,\n} from '../model/ai-products'\nimport type { AiRunRecord } from '../model/ai-automation-outline'\nimport { checkAiCatalog, checkAiCategories, checkAiProductCopy } from '../tools/ai-products-tool'\nimport type { AiCrmRecordKind, AiCrmTask } from '../model/ai-crm'\nimport {\n aiCrmEmailMergeFields,\n aiCrmImportFields,\n aiCrmRecordCheckContext,\n checkAiCrmEmail,\n checkAiCrmMapping,\n checkAiCrmRecord,\n} from '../tools/ai-crm-tool'\nimport { parseAiThemeToolInput } from '../tools/ai-theme-tool'\nimport {\n AI_AUTOMATION_OVERSIZE_CODES,\n AI_AUTOMATION_UNREADABLE_CODES,\n readAiAutomationAnswer,\n readAiWorkflowExplanation,\n} from '../tools/ai-workflow-tool'\nimport type { AiInsightTable } from '../model/ai-insight'\nimport { parseAiInsightAnswer } from '../tools/ai-insight-tool'\nimport { checkAiInsightAnswer } from './ai-insight-check'\nimport { aiDeviceAuditFindings, type AiDeviceAudit } from './ai-device-audit'\nimport {\n aiAnswerTree,\n aiDoctrinePlanCheck,\n aiDoctrineTreeCheck,\n aiDoctrineTreeContext,\n type AiGenerationCheckResult,\n type AiValidatedTree,\n} from './ai-doctrine'\nimport {\n AI_SEO_DESCRIPTION_MAX,\n AI_SEO_TITLE_MAX,\n detectOffVoiceCopy,\n detectPublishIntent,\n type AiAssetFacts,\n type AiCopyFraming,\n type AiDoctrineViolation,\n} from './ai-doctrine-validators'\nimport { AI_TEXT_LIMITS, type AiOutputKind } from './ai-palette'\nimport { expandAiRepeatedItems } from './ai-repeated-items'\n\n/**\n * THE EVAL HARNESS (AGL-2937): the measure that gates every token lever.\n *\n * A token saved on a page the customer then has to fix costs more than the\n * token. So no lever ships on its token figure alone: each golden brief is\n * held to the same checks the doctrine holds a live answer to, and a kind's\n * pass rate and mean score must stay at or above its floor.\n *\n * A case is a golden brief for one output kind — the site it is built for,\n * the plan shape a good answer has, reference answers, and controls that\n * must fail. Every answer is scored on four checks:\n *\n * - **readable** — it reads as its kind: `validateAiNodeTree` admits the\n * tree, the plan parses, the fields and the copy are there;\n * - **rules** — no doctrine rule is broken (`ai-doctrine-validators.ts`),\n * nor any rule of the kind's own (a link to a page the answer was not\n * given, a title line on a blog body);\n * - **budget** — within the kind's measured budget: rule 17 for a document,\n * the length ceiling for copy;\n * - **rubric** — a grade against the brief for structure, copy fit and\n * reuse decisions, recorded from a stronger model on a live run.\n *\n * A document of a kind a site renders is also held to **responsive** (AGL-3020):\n * rendered at every device of the besigner's switcher, nothing runs past the\n * screen and no band keeps its desktop columns on a phone. It is measured in a\n * browser by `tools/scripts/record-ai-page-axe.mts` and read back from that\n * recording, so it gates a pass without moving a score: a page that only works\n * on desktop does not pass, whatever its checks and grade average to.\n *\n * A planned kind's answer also carries the plan, held to the plan rules and\n * to the case's expected shape.\n *\n * Offline is the default and the only mode CI runs: answers and grades are\n * read from the fixtures under `tools/ai-eval/cases`, so a run costs nothing\n * and asserts the same verdicts every time. An answer marked `authored` was\n * written by hand as a reference and is graded by hand; one marked\n * `recorded` came from a live run. A live run spends real money and is\n * refused unless `AI_EVAL_LIVE=1` names it.\n */\n\n/** The output kinds the harness holds golden briefs for. */\nexport type AiEvalKind =\n | 'page'\n | 'template'\n | 'component'\n | 'layout'\n | 'form'\n | 'email'\n | 'section'\n | 'seo'\n | 'product'\n | 'catalog'\n | 'categories'\n | 'theme'\n | 'element'\n | 'blog'\n | 'text'\n | 'chat'\n | 'workflow'\n | 'insight'\n | 'crm'\n | 'experiment'\n\nexport const AI_EVAL_KINDS: readonly AiEvalKind[] = [\n 'page',\n 'template',\n 'component',\n 'layout',\n 'form',\n 'email',\n 'section',\n 'seo',\n 'product',\n 'catalog',\n 'categories',\n 'theme',\n 'element',\n 'blog',\n 'text',\n 'chat',\n 'workflow',\n 'insight',\n 'crm',\n 'experiment',\n]\n\n/** The document kind a tree kind is held to; a section rewrite is one reusable block. */\nexport const AI_EVAL_TREE_OUTPUT: Partial<Record<AiEvalKind, AiOutputKind>> = {\n page: 'page',\n template: 'template',\n component: 'component',\n layout: 'layout',\n form: 'form',\n email: 'email',\n section: 'component',\n}\n\n/**\n * Whether a kind's answer is a document a site renders, and so is held to\n * every device width (AGL-3020). An email is not: its column is fixed at 600px\n * by the medium, which rule 12 exempts it for.\n */\nexport function aiEvalRendersAtDeviceWidths(kind: AiEvalKind): boolean {\n const output = AI_EVAL_TREE_OUTPUT[kind]\n return output !== undefined && output !== 'email'\n}\n\n/**\n * The recorded device audit of an answer, or `null` when none was recorded\n * from it. The spec that scores the cases reads the recordings and answers\n * this; a scorer given none holds nothing to its widths.\n */\nexport type AiEvalAudits = (evalCase: AiEvalCase, answer: unknown) => AiDeviceAudit | null\n\n/** The checks an answer is scored on, beside its rubric. */\nexport type AiEvalCheck = 'readable' | 'rules' | 'budget' | 'plan' | 'responsive' | 'rubric'\n\n/** A grade against the brief, each criterion from 1 (fails) to 5 (excellent). */\nexport interface AiEvalRubric {\n /** Organized the way the brief needs, nothing missing, nothing extra. */\n structure: number\n /** The words fit the brief, the site and its audience, with no filler. */\n copy: number\n /** Reuses what the site lists before creating; `null` for a kind that places nothing. */\n reuse: number | null\n /** The model that graded it, or `authored` for a grade given by hand. */\n grader: string\n notes?: string\n}\n\n/** A plan's expected shape: what a good plan for the brief has. */\nexport interface AiEvalPlanShape {\n /** Screens planned, as `[min, max]`. */\n screens: [number, number]\n /** Inventory ids the plan must reuse. */\n reuse?: string[]\n /** The layout every planned screen renders inside. */\n layout?: string\n /** The most creations a good plan needs. */\n maxCreate?: number\n /** The kinds a creation may be. */\n createKinds?: AiBuildPlanCreateKind[]\n}\n\nexport interface AiEvalCandidate {\n /** `authored` for a reference written by hand; `recorded` for one a live run captured. */\n source: 'authored' | 'recorded'\n /**\n * `full` for an answer to the whole brief, the default; `plan` for the plan\n * alone, which a live run records for a planned kind whose generator has\n * not landed. A plan answer is held to the plan checks and its rubric, and\n * counts toward the plan step's score rather than the kind's floor.\n */\n scope?: 'full' | 'plan'\n /** The routing step and model a recorded answer came from; `null` for an authored one. */\n step: AiStepKind | null\n model: string | null\n effort: AiEffort | null\n /** The plan the plan step answered with, for a planned kind. */\n plan: unknown\n /**\n * The output as the kind's door answers: a tree tool's input (or the node\n * map itself), the copy as text, `{ title, description }` for search\n * fields, or the theme tool's input.\n */\n answer: unknown\n /** What a recorded answer spent; `null` for an authored one. */\n usage: AiUsage | null\n /**\n * A recorded answer's spend, one entry per metered exchange in the order\n * the job ran them — the plan, then every pass of its generation — with\n * the credits each came to as the machine meters a step (AGL-3030).\n * Absent on an authored answer, and on a recording that keeps its tokens\n * alone.\n */\n steps?: AiEvalRecordedStep[]\n /**\n * What a recorded product copy answer was written with of its product's\n * photo, as the products step reports it (AGL-3074): `read` when the\n * picture rode the request.\n */\n photo?: AiProductPhotoRead\n /**\n * What a recorded page was built as beside its tree (AGL-3073): its\n * screen's address and listing, and the layout it renders inside. Absent\n * on an authored answer, and on a recording made before it was kept.\n */\n screen?: AiEvalRecordedScreen\n /**\n * The grade, or `null` where the grader itself failed and there is none\n * (AGL-3143). An authored candidate always carries one.\n *\n * A brief's answer is bought before it is graded, so a grader that throws\n * would otherwise take the answer down with it and the run would pay\n * again for what it already had. The answer is kept and the grade is\n * marked missing instead of being invented: a fabricated 1/1 would read\n * as \"the model answered badly\" and pull the kind's floor down for\n * something the model never did, and the floors are the whole reason the\n * harness exists. An ungraded recording passes nothing — `rubric` is what\n * a score is taken from — so a missing grade can only read low, never\n * high, and the run that wrote it exits non-zero naming the throw.\n */\n rubric: AiEvalRubric | null\n note?: string\n /**\n * What the provider wrote when the answer ran out of ceiling (AGL-3143):\n * the bytes `answer` is only as much of as still parsed. Absent on every\n * recording but one whose answer was cut off. It is here because the\n * recording is the only place a live run's output outlives the run, and\n * it is what says whether the ceiling went on a runaway string or on a\n * decoding stall that wrote nothing usable. Never authored by hand.\n */\n rawOutput?: string\n}\n\n/** One metered exchange of a recorded job. */\nexport interface AiEvalRecordedStep {\n step: AiStepKind\n model: string\n usage: AiUsage\n estCostUsd: number\n /** What the machine meters it as: the billed cost in credits, rounded up per exchange. */\n credits: number\n}\n\n/**\n * A recorded page's screen, as the page step stored its draft. None of it is\n * a node of the page's tree: the address and the listing are fields of the\n * screen, the navigation entry is a proposal beside it, and the header, the\n * footer and the main landmark belong to the layout it renders inside.\n */\nexport interface AiEvalRecordedScreen {\n /** The draft's one-segment address, as the draft writer stored it. */\n slug: string\n /** The search title and description the draft holds; `null` where it holds none. */\n seoTitle: string | null\n seoDescription: string | null\n /** Whether a navigation entry for the page travels with it as a proposal. */\n nav: boolean\n /** The layout the draft renders inside; `null` for a page that renders inside none. */\n layout: AiEvalRecordedLayout | null\n}\n\n/** The layout a recorded page renders inside. */\nexport interface AiEvalRecordedLayout {\n id: string\n name: string\n /** `true` for a layout the job built before the page; `false` for one the site already had. */\n built: boolean\n /** Its tree as stored; `null` for a layout the case's site lists by name alone. */\n tree: { rootId: string; nodes: Record<string, unknown> } | null\n}\n\n/** An answer that must fail, and the checks it must fail. */\nexport interface AiEvalControl {\n why: string\n answer: unknown\n plan?: unknown\n fails: AiEvalCheck[]\n}\n\nexport interface AiEvalCase {\n id: string\n kind: AiEvalKind\n brief: string\n framing: AiCopyFraming\n /** The site the answer is built for; `null` for a brief that builds from none. */\n inventory: AiSiteInventory | null\n /**\n * The site's name as its visitors read it, where the case gives one\n * (AGL-3077): a recorded page's listing names the site by it. A case that\n * gives none is recorded on an untitled site.\n */\n siteName?: string\n /** Media library facts the image budget reads, by media id. */\n assets?: Record<string, AiAssetFacts>\n /** The documentation URLs a chat answer was grounded in; it may link only these. */\n docsUrls?: string[]\n /** Copy ceilings the brief sets, beside the kind's own. */\n maxChars?: number\n maxWords?: number\n /**\n * For an insight brief (AGL-2915): the tables the readers returned, which\n * every insight an answer writes is traced against.\n */\n tables?: AiInsightTable[]\n /**\n * For a product copy brief (AGL-2916): the product as its editor handed it\n * over, and the site's categories the request lists.\n */\n product?: { facts: AiProductFacts; categories: AiProductCategory[] }\n /** For a categories brief: the names of the categories the store already has. */\n existingCategoryNames?: string[]\n /** For a theme brief: the site's current theme and where it comes from. */\n siteTheme?: HostTheme\n themeSource?: HostThemeSource\n /**\n * For an automation brief (AGL-2919): what the workspace can run, and the\n * site's records the answer's words are looked up among. Absent, the\n * workspace runs everything and the site holds nothing.\n */\n automationCapabilities?: AiAutomationCapabilities\n automationRecords?: AiAutomationRecords\n /**\n * For an automation brief about a saved automation (AGL-3074): the action\n * as the site stores it, and for a run's diagnosis, what the run history\n * recorded of the failed run. Absent, the brief asks for a draft.\n */\n automation?: AiEvalAutomation\n /**\n * The media library assets of the case's site a recording reads\n * (AGL-3074), by media id: each the path of the file under\n * `tools/ai-eval/fixtures` that holds its bytes. A product's photo is\n * `media:<site id>/<media id>`, where the site is the inventory's, or\n * `AI_EVAL_SITE_ID` for a case that describes none.\n */\n media?: Record<string, string>\n /**\n * For a CRM brief (AGL-2917): what the job was asked, about which kind of\n * record, the facts the CRM reported for it, and a mapping's columns.\n */\n crm?: AiEvalCrmContext\n /**\n * For an A/B test brief (AGL-2914): which half of the step the brief asks\n * for, what the test varies, the copy under test, and — for a result — the\n * test's arms as the results reader published them.\n */\n experiment?: AiEvalExperiment\n /**\n * What the workspace may create on the case's site (AGL-3030): a brief\n * for a workspace that keeps no reusable components is held to the inline\n * doctrine, and its plan to what the workspace may create. Absent, the\n * doctrine applies whole.\n */\n capabilities?: AiPlanCapabilities\n expected?: { plan?: AiEvalPlanShape }\n candidates: AiEvalCandidate[]\n controls: AiEvalControl[]\n}\n\n/** The site a case's job runs on when the case describes no inventory. */\nexport const AI_EVAL_SITE_ID = 'eval-site'\n\n/** What an automation brief's workspace can run when the case does not say: everything. */\nexport const AI_EVAL_AUTOMATION_CAPABILITIES: AiAutomationCapabilities = { crm: true, webhooks: true, bookings: true }\n\n/** A saved automation an automation brief asks about, as the workflow step reads one. */\nexport interface AiEvalAutomation {\n /** The action as `hosts/{hostId}/actions/{id}` holds it. */\n action: HostAction\n /** A failed run of it; given, the brief asks why that run failed. */\n run?: AiRunRecord\n}\n\n/** An A/B test brief, as the experiment step is given one. */\nexport interface AiEvalExperiment {\n task: AiExperimentTask\n /** What the test varies; a variants brief always names one. */\n target?: AiExperimentTarget\n /** The copy under test, as the surface handed it over. */\n subject?: string\n /** A result brief's test, and its arms as the results reader published them. */\n test?: string\n arms?: AiExperimentArm[]\n}\n\n/** A fixture file a case's media names: a relative path to a picture, never out of its folder. */\nconst AI_EVAL_MEDIA_FILE = /^(?!.*(?:^|\\/)\\.\\.?(?:\\/|$))[A-Za-z0-9][A-Za-z0-9._/-]*\\.(?:jpe?g|png|webp|gif|avif)$/\n\n/** What a CRM brief's answer is checked against, as the `crm` step checks it. */\nexport interface AiEvalCrmContext {\n task: AiCrmTask\n /** The record a `record` or `email` brief is about. */\n record?: AiCrmRecordKind\n /** The facts the CRM's reader reported: a record's, or an import's field catalog. */\n facts?: Record<string, unknown>\n /** A mapping brief's columns: each header and its shape. */\n columns?: ConsoleImportColumn[]\n}\n\n/** A kind's floor: the pass rate and the mean score its candidates may not fall below. */\nexport interface AiEvalFloor {\n passRate: number\n meanScore: number\n}\n\n/**\n * The floors, per kind. Every reference answer must pass, because each was\n * written to; the mean floor leaves room for a rubric grade of four on an\n * answer that passes every mechanical check. Recorded answers are held to\n * the same floors, and a lever that lowers a kind below its floor does not\n * ship.\n */\nexport const AI_EVAL_FLOORS: Readonly<Record<AiEvalKind, AiEvalFloor>> = {\n page: { passRate: 1, meanScore: 0.9 },\n template: { passRate: 1, meanScore: 0.9 },\n component: { passRate: 1, meanScore: 0.9 },\n layout: { passRate: 1, meanScore: 0.9 },\n form: { passRate: 1, meanScore: 0.9 },\n email: { passRate: 1, meanScore: 0.9 },\n section: { passRate: 1, meanScore: 0.9 },\n seo: { passRate: 1, meanScore: 0.9 },\n product: { passRate: 1, meanScore: 0.9 },\n catalog: { passRate: 1, meanScore: 0.9 },\n categories: { passRate: 1, meanScore: 0.9 },\n theme: { passRate: 1, meanScore: 0.9 },\n element: { passRate: 1, meanScore: 0.9 },\n blog: { passRate: 1, meanScore: 0.9 },\n text: { passRate: 1, meanScore: 0.9 },\n chat: { passRate: 1, meanScore: 0.9 },\n workflow: { passRate: 1, meanScore: 0.9 },\n insight: { passRate: 1, meanScore: 0.9 },\n crm: { passRate: 1, meanScore: 0.9 },\n experiment: { passRate: 1, meanScore: 0.9 },\n}\n\n/** A rubric passes at this mean, with no criterion below three. */\nexport const AI_EVAL_RUBRIC_PASS_MEAN = 3.5\n\n/** How long a blog body may run: the blog mode's output ceiling, at four characters a token. */\nexport const AI_EVAL_BLOG_MAX_CHARS = 8_000\n\n/** How long a job's copy may run when the brief implies no length: the text step's own rule. */\nexport const AI_EVAL_TEXT_MAX_WORDS = 150\n\n/** How long a chat answer may run: the chat door's output ceiling, at four characters a token. */\nexport const AI_EVAL_CHAT_MAX_CHARS = 4_000\n\nexport interface AiEvalScore {\n caseId: string\n kind: AiEvalKind\n source: AiEvalCandidate['source']\n scope: NonNullable<AiEvalCandidate['scope']>\n model: string | null\n /** A check that does not apply to the answer — the plan of an unplanned kind, the document of a plan answer — is `null`. */\n checks: Record<'rubric', boolean> & Record<Exclude<AiEvalCheck, 'rubric'>, boolean | null>\n /** The rubric's mean, from 0 (every criterion 1) to 1 (every criterion 5). */\n rubricScore: number\n /** The checks and the rubric, averaged: from 0 to 1. */\n score: number\n pass: boolean\n /** Why a check failed: violation codes and the kind's own findings. */\n findings: string[]\n}\n\ninterface Checked {\n readable: boolean\n rules: boolean\n budget: boolean\n findings: string[]\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst codes = (violations: readonly AiDoctrineViolation[]) =>\n violations.map((violation) => violation.code)\n\n// ── The kinds ─────────────────────────────────────────────────────────────\n\ninterface ReadTree {\n /** The answer as the check reads it: a page's repeated items drawn. */\n input: Record<string, unknown>\n declaresProps: boolean\n /** Why a page's repeated item could not be drawn; the tree is not read then. */\n undrawn: AiDoctrineViolation[] | null\n result: AiGenerationCheckResult<AiValidatedTree> | null\n}\n\n/**\n * The sections a page answer's plan lays out, by name, which a link on the\n * page may take a visitor to as the page step lets it (AGL-3097); empty for an\n * answer of another kind, or with no plan to read them from.\n */\nfunction planSections(evalCase: AiEvalCase, plan: unknown): string[] {\n const screens = evalCase.kind === 'page' && isRecord(plan) && Array.isArray(plan['screens']) ? plan['screens'] : []\n const sections = isRecord(screens[0]) && Array.isArray(screens[0]['sections']) ? screens[0]['sections'] : []\n return sections.flatMap((section: unknown) =>\n isRecord(section) && typeof section['name'] === 'string' ? [section['name']] : [],\n )\n}\n\nfunction readTree(evalCase: AiEvalCase, outputKind: AiOutputKind, answer: unknown, plan?: unknown): ReadTree {\n const inline = evalCase.capabilities?.reusableComponents === false\n let input = isRecord(answer) ? answer : { tree: answer }\n // A component answer that declares its properties binds them in its tree,\n // and is held to the component step's own checks as that step holds it\n // (AGL-3054).\n const declaresProps = evalCase.kind === 'component' && Array.isArray(input['props'])\n const sections = planSections(evalCase, plan)\n const check = aiDoctrineTreeCheck(\n outputKind,\n aiDoctrineTreeContext(evalCase.inventory, {\n ...(evalCase.assets ? { assets: evalCase.assets } : {}),\n framing: evalCase.framing,\n ...(inline ? { reusableComponents: false } : {}),\n ...(declaresProps ? { definesComponent: true } : {}),\n ...(sections.length ? { pageSections: sections } : {}),\n }),\n )\n // A page's repeated item written once is drawn into its copies first, as the\n // page step draws it, and refused as the page step refuses it (AGL-3053).\n if (evalCase.kind === 'page') {\n const drawn = expandAiRepeatedItems(aiAnswerTree(input), { inline, noun: 'page' })\n if (drawn.ok === false) return { input, declaresProps, undrawn: drawn.violations, result: null }\n if (drawn.items) input = { tree: drawn.tree }\n }\n return { input, declaresProps, undrawn: null, result: check(input) }\n}\n\n/**\n * The tree an answer of a tree kind is checked as — a page's repeated items\n * drawn into their copies — or `null` when it cannot be read as one. The\n * device audit renders exactly this tree (AGL-3020).\n */\nexport function aiEvalAnswerTree(evalCase: AiEvalCase, answer: unknown): AiValidatedTree | null {\n const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind]\n return outputKind ? (readTree(evalCase, outputKind, answer).result?.value ?? null) : null\n}\n\nfunction checkTree(evalCase: AiEvalCase, outputKind: AiOutputKind, answer: unknown, plan?: unknown): Checked {\n const { input, declaresProps, undrawn, result } = readTree(evalCase, outputKind, answer, plan)\n if (undrawn || !result) {\n return { readable: false, rules: false, budget: false, findings: codes(undrawn ?? []) }\n }\n const violations = [\n ...result.violations,\n ...(declaresProps && result.value\n ? aiComponentCheck({ inventory: evalCase.inventory, plan: null, onProps: () => undefined })(result.value, input)\n : []),\n ]\n const budget = violations.filter((violation) => violation.rule === 17)\n const rules = violations.filter((violation) => violation.rule !== 17)\n return {\n readable: result.value !== null,\n rules: result.value !== null && rules.length === 0,\n budget: result.value !== null && budget.length === 0,\n findings: codes(violations),\n }\n}\n\nconst FENCE = /```/\nconst PREAMBLE = /^\\s*(?:sure|certainly|of course|here(?:'s| is| are))\\b/i\nconst QUOTED = /^\\s*[\"“'].*[\"”']\\s*$/s\nconst MARKUP = /<\\/?[a-z][^>]*>/i\n\nfunction words(text: string): number {\n return text.trim().split(/\\s+/).filter(Boolean).length\n}\n\n/** Copy answered as text: there, unwrapped, in the site's voice, within its ceiling. */\nfunction checkCopy(\n evalCase: AiEvalCase,\n answer: unknown,\n limits: { maxChars?: number; maxWords?: number },\n own: (text: string) => string[] = () => [],\n): Checked {\n if (typeof answer !== 'string' || !answer.trim()) {\n return { readable: false, rules: false, budget: false, findings: ['copy-missing'] }\n }\n const text = answer.trim()\n const unreadable = [\n ...(FENCE.test(text) ? ['copy-fenced'] : []),\n ...(PREAMBLE.test(text) ? ['copy-preamble'] : []),\n ...(QUOTED.test(text) ? ['copy-quoted'] : []),\n ]\n const broken = [\n ...codes(detectOffVoiceCopy([{ at: 'answer', text }], evalCase.framing)),\n ...(MARKUP.test(text) ? ['copy-markup'] : []),\n ...own(text),\n ]\n const maxChars = evalCase.maxChars ?? limits.maxChars\n const maxWords = evalCase.maxWords ?? limits.maxWords\n const over = [\n ...(maxChars !== undefined && text.length > maxChars ? ['copy-over-chars'] : []),\n ...(maxWords !== undefined && words(text) > maxWords ? ['copy-over-words'] : []),\n ]\n return {\n readable: unreadable.length === 0,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...unreadable, ...broken, ...over],\n }\n}\n\nconst MARKDOWN_LINK = /\\[[^\\]]*\\]\\(([^)\\s]+)\\)/g\n\n/** A chat answer links only the documentation it was given and console paths. */\nfunction chatLinks(evalCase: AiEvalCase): (text: string) => string[] {\n const allowed = new Set(evalCase.docsUrls ?? [])\n return (text) =>\n [...text.matchAll(MARKDOWN_LINK)]\n .map((match) => match[1])\n .filter((url) => !url.startsWith('/') && !allowed.has(url))\n .map((url) => `chat-link-not-given:${url}`)\n}\n\nfunction checkBlog(evalCase: AiEvalCase, answer: unknown): Checked {\n const checked = checkCopy(evalCase, answer, { maxChars: AI_EVAL_BLOG_MAX_CHARS })\n if (typeof answer !== 'string') return checked\n const head = answer.trimStart()\n const extra = [\n ...(head.startsWith('---') ? ['blog-front-matter'] : []),\n ...(/^#\\s/.test(head) ? ['blog-title-line'] : []),\n ]\n return extra.length\n ? { ...checked, readable: false, findings: [...checked.findings, ...extra] }\n : checked\n}\n\nfunction checkSeo(evalCase: AiEvalCase, answer: unknown): Checked {\n const title = isRecord(answer) && typeof answer['title'] === 'string' ? answer['title'].trim() : ''\n const description =\n isRecord(answer) && typeof answer['description'] === 'string' ? answer['description'].trim() : ''\n if (!title || !description) {\n return { readable: false, rules: false, budget: false, findings: ['seo-field-missing'] }\n }\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(\n detectOffVoiceCopy(\n [\n { at: 'title', text: title },\n { at: 'description', text: description },\n ],\n evalCase.framing,\n ),\n ),\n ...(MARKUP.test(title) || MARKUP.test(description) ? ['seo-markup'] : []),\n ]\n const over = [\n ...(title.length > AI_SEO_TITLE_MAX ? ['seo-title-over'] : []),\n ...(description.length > AI_SEO_DESCRIPTION_MAX ? ['seo-description-over'] : []),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...broken, ...over],\n }\n}\n\n/** What a products check refuses an answer for, by the check it fails. */\nconst PRODUCTS_UNREADABLE = new Set(['type', 'missing', 'option-count'])\nconst PRODUCTS_OVER_BUDGET = new Set(['too-long', 'too-many', 'product-count'])\n\n/**\n * A products answer (AGL-2916), held by the check its generation is held by:\n * a product's copy, a catalog, or categories with discounts. A finding about\n * the answer's shape makes it unreadable, one about a length or a count is\n * over its budget, and every other one — a claim, a price, markup, a category\n * the request did not list — breaks a rule.\n */\nfunction checkProducts(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['products-not-a-call'] }\n }\n const result =\n evalCase.kind === 'product'\n ? checkAiProductCopy(answer, {\n categoryIds: (evalCase.product?.categories ?? []).map((category) => category.id),\n optionCount: evalCase.product?.facts.options.length ?? 0,\n merchantWords: evalCase.product ? aiProductMerchantWords(evalCase.product.facts) : evalCase.brief,\n })\n : evalCase.kind === 'catalog'\n ? checkAiCatalog(answer, { merchantWords: evalCase.brief })\n : checkAiCategories(answer, {\n existingCategoryNames: evalCase.existingCategoryNames ?? [],\n merchantWords: evalCase.brief,\n })\n const found = [...codes(result.violations), ...codes(detectPublishIntent(answer))]\n return {\n readable: !found.some((code) => PRODUCTS_UNREADABLE.has(code)),\n rules: !found.some((code) => !PRODUCTS_UNREADABLE.has(code) && !PRODUCTS_OVER_BUDGET.has(code)),\n budget: !found.some((code) => PRODUCTS_OVER_BUDGET.has(code)),\n findings: found,\n }\n}\n\nfunction checkTheme(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['theme-not-a-call'] }\n }\n const parse = parseAiThemeToolInput(answer)\n const changes = parse.changes.length + parse.components.length + (parse.resetComponents ? 1 : 0)\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy([{ at: 'summary', text: parse.summary }], evalCase.framing)),\n ]\n return {\n readable: changes > 0 && parse.dropped.length === 0,\n rules: broken.length === 0,\n budget: true,\n findings: [...parse.dropped.map((reason) => `theme-dropped:${reason}`), ...broken],\n }\n}\n\n/**\n * An automation (AGL-2919), or an explanation of one: read through the tool's\n * own reader, and an automation also made into the document the workflows\n * plugin stores and held to the Actions editor's validator.\n */\nfunction checkWorkflow(evalCase: AiEvalCase, answer: unknown): Checked {\n if (!isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['workflow-not-a-call'] }\n }\n const publish = codes(detectPublishIntent(answer))\n if ('summary' in answer) {\n const read = readAiWorkflowExplanation(answer)\n const lines = [\n String(answer['summary'] ?? ''),\n ...(Array.isArray(answer['points']) ? answer['points'] : []),\n ...(Array.isArray(answer['suggestions']) ? answer['suggestions'] : []),\n ].map(String)\n const offVoice = codes(\n detectOffVoiceCopy(lines.map((text, index) => ({ at: `line[${index}]`, text })), evalCase.framing),\n )\n const found = codes(read.violations)\n return {\n readable: !found.includes('explanation-shape'),\n rules: read.value !== null && publish.length === 0 && offVoice.length === 0,\n budget: true,\n findings: [...found, ...publish, ...offVoice],\n }\n }\n const capabilities = evalCase.automationCapabilities ?? AI_EVAL_AUTOMATION_CAPABILITIES\n const read = readAiAutomationAnswer(answer, capabilities)\n const found = codes(read.violations)\n const unreadable = found.filter((code) => AI_AUTOMATION_UNREADABLE_CODES.includes(code))\n const oversize = found.filter((code) => AI_AUTOMATION_OVERSIZE_CODES.includes(code))\n const broken = found.filter((code) => !unreadable.includes(code) && !oversize.includes(code))\n const invalid =\n read.value && !read.value.unsupported\n ? validateHostAction(aiAutomationDraft(read.value, evalCase.automationRecords ?? emptyAiAutomationRecords()).action)\n : null\n return {\n readable: unreadable.length === 0,\n rules: broken.length === 0 && publish.length === 0 && invalid === null,\n budget: oversize.length === 0,\n findings: [...found, ...publish, ...(invalid ? [`workflow-invalid:${invalid}`] : [])],\n }\n}\n\n/**\n * An insight answer held to the trace (AGL-2915): readable when it is a\n * `submit_insights` call that keeps an insight, within the rules when no\n * insight is left out for its numbers, its citations or its words, and within\n * the budget when no insight runs long and there are no more than five.\n */\nfunction checkInsight(evalCase: AiEvalCase, answer: unknown): Checked {\n const parsed = parseAiInsightAnswer(answer)\n if (!parsed || !parsed.insights.length) {\n return { readable: false, rules: false, budget: false, findings: ['insight-no-answer'] }\n }\n const check = checkAiInsightAnswer(parsed, evalCase.tables ?? [])\n const findings = check.findings.map((finding) => finding.split(':')[0])\n const over = findings.filter((code) => code === 'insight-too-long' || code === 'insight-too-many')\n return {\n readable: check.kept.length > 0,\n rules: findings.length === over.length,\n budget: over.length === 0,\n findings: check.findings,\n }\n}\n\n/** The CRM findings that mean the answer could not be read as one, and the ones over a length. */\nconst CRM_UNREADABLE = new Set(['type', 'missing'])\nconst CRM_OVER = new Set(['too-long'])\n\n/**\n * A CRM answer, held by the checks the `crm` step holds it to (AGL-2917),\n * with rule 13 and the site's voice on everything a person reads.\n */\nfunction checkCrm(evalCase: AiEvalCase, answer: unknown): Checked {\n const context = evalCase.crm\n if (!context || !isRecord(answer)) {\n return { readable: false, rules: false, budget: false, findings: ['crm-not-a-call'] }\n }\n const facts = context.facts ?? {}\n const kind = context.record ?? 'contact'\n const result =\n context.task === 'mapping'\n ? checkAiCrmMapping(answer, { columns: context.columns ?? [], fields: aiCrmImportFields(facts) })\n : context.task === 'email'\n ? checkAiCrmEmail(answer, { mergeFields: aiCrmEmailMergeFields(kind) })\n : checkAiCrmRecord(answer, aiCrmRecordCheckContext(kind, facts))\n const own = codes(result.violations)\n const read = (path: string[]): string => {\n let value: unknown = answer\n for (const key of path) value = isRecord(value) ? value[key] : undefined\n return typeof value === 'string' ? value : ''\n }\n const samples = [\n ['summary'],\n ['standing'],\n ['nextStep', 'title'],\n ['nextStep', 'reason'],\n ['stage', 'reason'],\n ['subject'],\n ['body'],\n ]\n .map((path) => ({ at: path.join('.'), text: read(path) }))\n .filter((sample) => sample.text)\n const broken = [\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples, evalCase.framing)),\n ...own.filter((code) => !CRM_UNREADABLE.has(code) && !CRM_OVER.has(code)),\n ]\n return {\n readable: !own.some((code) => CRM_UNREADABLE.has(code)),\n rules: broken.length === 0,\n budget: !own.some((code) => CRM_OVER.has(code)),\n findings: [...new Set([...own, ...broken])],\n }\n}\n\n/** What an experiment answer is refused for, by the check it fails. */\nconst EXPERIMENT_RULE_FINDINGS = new Set([\n 'variant-carries-markup',\n 'variant-fills-another-targets-fields',\n 'variant-repeats-another',\n 'variant-has-no-copy',\n])\n\n/**\n * An A/B test answer (AGL-2914), held by the checks its step holds it by.\n *\n * A variants answer is readable when at least two variants survive, breaks a\n * rule when one carried markup, repeated another or answered a different\n * target, and is over budget when a field ran past the length the card\n * stores. A result answer is readable when an explanation survives its\n * reading, and breaks a rule when the reading had to take a winner out of it\n * — which is the whole point of the kind: an explanation that claims more\n * than the figures support does not pass here.\n */\nfunction checkExperiment(evalCase: AiEvalCase, answer: unknown): Checked {\n const brief = evalCase.experiment\n if (!brief) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-brief-missing'] }\n }\n if (brief.task === 'variants') {\n const target: AiExperimentTarget = brief.target ?? 'screen'\n const parsed = parseAiExperimentVariants(answer)\n const checked = checkAiExperimentVariants(parsed, target)\n if (!parsed || !checked) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-no-variants'] }\n }\n const fields = aiExperimentVariantFields(target)\n const over = parsed.variants.flatMap((variant) => [\n ...(variant.name.length > AI_EXPERIMENT_NAME_MAX_CHARS ? ['experiment-name-over'] : []),\n ...(variant.rationale.length > AI_EXPERIMENT_RATIONALE_MAX_CHARS ? ['experiment-rationale-over'] : []),\n ...fields.flatMap((field) =>\n String(variant[field] ?? '').length >\n (field === 'body' ? AI_EXPERIMENT_BODY_MAX_CHARS : AI_EXPERIMENT_LINE_MAX_CHARS)\n ? [`experiment-${field}-over`]\n : [],\n ),\n ])\n const samples = checked.proposal.variants.flatMap((variant) =>\n fields.map((field) => ({ at: `${variant.name}.${field}`, text: String(variant[field] ?? '') })),\n )\n const broken = [\n ...checked.findings.filter((finding) => EXPERIMENT_RULE_FINDINGS.has(finding)),\n ...codes(detectPublishIntent(answer)),\n ...codes(detectOffVoiceCopy(samples.filter((sample) => sample.text), evalCase.framing)),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...new Set([...broken, ...over])],\n }\n }\n\n const reading = readAiExperimentResult(brief.test ?? '', brief.arms ?? [])\n const parsed = parseAiExperimentExplanation(answer)\n const explained = checkAiExperimentExplanation(parsed, reading)\n if (!parsed || !explained) {\n return { readable: false, rules: false, budget: false, findings: ['experiment-no-explanation'] }\n }\n const over = [\n ...(parsed.headline.length > AI_EXPERIMENT_HEADLINE_MAX_CHARS ? ['experiment-headline-over'] : []),\n ...(parsed.points.length > AI_EXPERIMENT_MAX_POINTS ? ['experiment-points-over'] : []),\n ...parsed.points.flatMap((point) =>\n point.length > AI_EXPERIMENT_POINT_MAX_CHARS ? ['experiment-point-over'] : [],\n ),\n ...(parsed.next.length > AI_EXPERIMENT_NEXT_MAX_CHARS ? ['experiment-next-over'] : []),\n ]\n const broken = [\n ...explained.findings,\n ...codes(detectPublishIntent(answer)),\n ...codes(\n detectOffVoiceCopy(\n [\n { at: 'headline', text: explained.headline },\n ...explained.points.map((point, index) => ({ at: `points.${index}`, text: point })),\n ],\n evalCase.framing,\n ),\n ),\n ]\n return {\n readable: true,\n rules: broken.length === 0,\n budget: over.length === 0,\n findings: [...new Set([...broken, ...over])],\n }\n}\n\n/** An answer held to its kind's checks; a page's links to the sections of the plan it was built from. */\nfunction checkAnswer(evalCase: AiEvalCase, answer: unknown, plan?: unknown): Checked {\n const outputKind = AI_EVAL_TREE_OUTPUT[evalCase.kind]\n if (outputKind) return checkTree(evalCase, outputKind, answer, plan)\n switch (evalCase.kind) {\n case 'seo':\n return checkSeo(evalCase, answer)\n case 'product':\n case 'catalog':\n case 'categories':\n return checkProducts(evalCase, answer)\n case 'theme':\n return checkTheme(evalCase, answer)\n case 'element':\n return checkCopy(evalCase, answer, { maxChars: AI_TEXT_LIMITS.body })\n case 'blog':\n return checkBlog(evalCase, answer)\n case 'text':\n return checkCopy(evalCase, answer, { maxWords: AI_EVAL_TEXT_MAX_WORDS })\n case 'chat':\n return checkCopy(evalCase, answer, { maxChars: AI_EVAL_CHAT_MAX_CHARS }, chatLinks(evalCase))\n case 'workflow':\n return checkWorkflow(evalCase, answer)\n case 'insight':\n return checkInsight(evalCase, answer)\n case 'crm':\n return checkCrm(evalCase, answer)\n case 'experiment':\n return checkExperiment(evalCase, answer)\n default:\n return { readable: false, rules: false, budget: false, findings: ['kind-unknown'] }\n }\n}\n\n/** The plan held to the plan rules, then to the shape the case expects. */\nexport function checkAiEvalPlan(\n evalCase: AiEvalCase,\n plan: unknown,\n): { pass: boolean; findings: string[] } {\n const shape = evalCase.expected?.plan\n if (!shape) return { pass: true, findings: [] }\n const result = aiDoctrinePlanCheck(evalCase.inventory, evalCase.framing, evalCase.capabilities ?? null)(\n isRecord(plan) ? plan : {},\n )\n if (!result.value) return { pass: false, findings: ['plan-unreadable', ...codes(result.violations)] }\n const value = result.value\n const shapeFindings = [\n ...(value.screens.length < shape.screens[0] || value.screens.length > shape.screens[1]\n ? [`plan-screens:${value.screens.length}`]\n : []),\n ...(shape.reuse ?? [])\n .filter((id) => !value.reuse.some((entry) => entry.id === id))\n .map((id) => `plan-reuse-missing:${id}`),\n ...(shape.layout\n ? value.screens\n .filter((screen) => screen.layout !== shape.layout)\n .map((screen) => `plan-layout:${screen.slug}`)\n : []),\n ...(shape.maxCreate !== undefined && value.create.length > shape.maxCreate\n ? [`plan-create:${value.create.length}`]\n : []),\n ...(shape.createKinds\n ? value.create\n .filter((entry) => !shape.createKinds?.includes(entry.kind))\n .map((entry) => `plan-create-kind:${entry.kind}`)\n : []),\n ]\n const findings = [...codes(result.violations), ...shapeFindings]\n return { pass: findings.length === 0, findings }\n}\n\nconst clampGrade = (value: unknown): number | null => {\n if (value === null || value === undefined) return null\n const parsed = Number(value)\n return Number.isFinite(parsed) ? Math.min(5, Math.max(1, parsed)) : null\n}\n\n/** A rubric's mean and whether it passes: the mean at `AI_EVAL_RUBRIC_PASS_MEAN`, nothing under three. */\nexport function aiEvalRubricVerdict(rubric: AiEvalRubric | null | undefined): {\n mean: number\n pass: boolean\n} {\n const grades = [rubric?.structure, rubric?.copy, rubric?.reuse]\n .map(clampGrade)\n .filter((grade): grade is number => grade !== null)\n if (!grades.length) return { mean: 1, pass: false }\n const mean = grades.reduce((sum, grade) => sum + grade, 0) / grades.length\n return { mean, pass: mean >= AI_EVAL_RUBRIC_PASS_MEAN && Math.min(...grades) >= 3 }\n}\n\n/**\n * The widths a readable document of a rendered kind is held to, from its\n * recorded device audit: `null` when the answer is not such a document or no\n * audits were given; failing, with `widths-unrecorded`, when none was recorded\n * from this answer.\n */\nfunction checkWidths(\n evalCase: AiEvalCase,\n answer: unknown,\n checked: Checked | null,\n audits: AiEvalAudits | undefined,\n): { pass: boolean; findings: string[] } | null {\n if (!audits || !checked?.readable || !aiEvalRendersAtDeviceWidths(evalCase.kind)) return null\n const audit = audits(evalCase, answer)\n if (!audit) return { pass: false, findings: ['widths-unrecorded'] }\n const findings = aiDeviceAuditFindings(audit)\n return { pass: findings.length === 0, findings }\n}\n\n/** One answer to one golden brief, scored. */\nexport function scoreAiEvalCandidate(\n evalCase: AiEvalCase,\n candidate: AiEvalCandidate,\n audits?: AiEvalAudits,\n): AiEvalScore {\n const scope = candidate.scope ?? 'full'\n const checked = scope === 'full' ? checkAnswer(evalCase, candidate.answer, candidate.plan) : null\n const widths = checkWidths(evalCase, candidate.answer, checked, audits)\n const plan = evalCase.expected?.plan ? checkAiEvalPlan(evalCase, candidate.plan) : null\n const rubric = aiEvalRubricVerdict(candidate.rubric)\n const rubricScore = (rubric.mean - 1) / 4\n const parts = [\n ...(checked ? [checked.readable ? 1 : 0, checked.rules ? 1 : 0, checked.budget ? 1 : 0] : []),\n ...(plan ? [plan.pass ? 1 : 0] : []),\n rubricScore,\n ]\n const score = Math.round((parts.reduce((sum, part) => sum + part, 0) / parts.length) * 10_000) / 10_000\n const documentPasses = checked ? checked.readable && checked.rules && checked.budget : true\n return {\n caseId: evalCase.id,\n kind: evalCase.kind,\n source: candidate.source,\n scope,\n model: candidate.model,\n checks: {\n readable: checked ? checked.readable : null,\n rules: checked ? checked.rules : null,\n budget: checked ? checked.budget : null,\n plan: plan ? plan.pass : null,\n responsive: widths ? widths.pass : null,\n rubric: rubric.pass,\n },\n rubricScore: Math.round(rubricScore * 10_000) / 10_000,\n score,\n // A plan answer to a brief with no expected plan has nothing to pass.\n pass: documentPasses && (widths?.pass ?? true) && (plan?.pass ?? scope === 'full') && rubric.pass,\n findings: [...(checked?.findings ?? []), ...(widths?.findings ?? []), ...(plan?.findings ?? [])],\n }\n}\n\n/**\n * The checks a control failed; the harness requires every one it names. A\n * control whose widths were never recorded fails none of them.\n */\nexport function scoreAiEvalControl(\n evalCase: AiEvalCase,\n control: AiEvalControl,\n audits?: AiEvalAudits,\n): AiEvalCheck[] {\n // A control is the case's first answer with one thing wrong, built from its plan unless it carries its own.\n const checked = checkAnswer(evalCase, control.answer, control.plan ?? evalCase.candidates[0]?.plan)\n const widths = audits?.(evalCase, control.answer) ? checkWidths(evalCase, control.answer, checked, audits) : null\n const plan =\n control.plan !== undefined && evalCase.expected?.plan\n ? checkAiEvalPlan(evalCase, control.plan)\n : null\n return [\n ...(checked.readable ? [] : (['readable'] as const)),\n ...(checked.rules ? [] : (['rules'] as const)),\n ...(checked.budget ? [] : (['budget'] as const)),\n ...(plan && !plan.pass ? (['plan'] as const) : []),\n ...(widths && !widths.pass ? (['responsive'] as const) : []),\n ]\n}\n\nexport interface AiEvalKindSummary {\n kind: AiEvalKind\n candidates: number\n passed: number\n /** Passed over candidates; `null` with none, which is below every floor. */\n passRate: number | null\n meanScore: number | null\n floor: AiEvalFloor\n belowFloor: boolean\n}\n\n/** Every kind's pass rate and mean score against its floor; a kind with no candidate is below it. */\nexport function summarizeAiEval(scores: readonly AiEvalScore[]): AiEvalKindSummary[] {\n return AI_EVAL_KINDS.map((kind) => {\n const own = scores.filter((score) => score.kind === kind && score.scope === 'full')\n const passed = own.filter((score) => score.pass).length\n const passRate = own.length ? passed / own.length : null\n const meanScore = own.length\n ? Math.round((own.reduce((sum, score) => sum + score.score, 0) / own.length) * 10_000) / 10_000\n : null\n const floor = AI_EVAL_FLOORS[kind]\n return {\n kind,\n candidates: own.length,\n passed,\n passRate,\n meanScore,\n floor,\n belowFloor:\n passRate === null ||\n meanScore === null ||\n passRate < floor.passRate ||\n meanScore < floor.meanScore,\n }\n })\n}\n\n/** How the plans a planned kind's answers carry score, across every brief. */\nexport interface AiEvalPlanSummary {\n plans: number\n passed: number\n passRate: number | null\n}\n\n/**\n * The plan step's own score: every answer that carried a plan checked\n * against its brief's expected shape, whole answers and plan answers alike.\n */\nexport function summarizeAiEvalPlans(scores: readonly AiEvalScore[]): AiEvalPlanSummary {\n const plans = scores.filter((score) => score.checks.plan !== null)\n const passed = plans.filter((score) => score.checks.plan && score.checks.rubric).length\n return { plans: plans.length, passed, passRate: plans.length ? passed / plans.length : null }\n}\n\n/** A recording a live run wrote: the brief it answers, and the answer. */\nexport interface AiEvalRecording {\n caseId: string\n candidate: AiEvalCandidate\n}\n\n/** A recording file read and checked for shape; throws naming the field at fault. */\nexport function readAiEvalRecording(raw: unknown, file: string): AiEvalRecording {\n if (!isRecord(raw) || typeof raw['caseId'] !== 'string' || !isRecord(raw['candidate'])) {\n throw new Error(`${file}: a recording holds a caseId and a candidate`)\n }\n const candidate = raw['candidate'] as Record<string, unknown>\n // `null` says the grader failed and this answer was kept ungraded\n // (AGL-3143); a missing key is a recording written by something that does\n // not know what a grade is.\n if (candidate['source'] !== 'recorded' || !(isRecord(candidate['rubric']) || candidate['rubric'] === null)) {\n throw new Error(`${file}: a recording's candidate is recorded, and graded or explicitly ungraded`)\n }\n return raw as unknown as AiEvalRecording\n}\n\n// ── Reading a case file ───────────────────────────────────────────────────\n\n/** A case file read and checked for shape; throws naming the field at fault. */\nexport function readAiEvalCase(raw: unknown, file: string): AiEvalCase {\n const fail = (why: string): never => {\n throw new Error(`${file}: ${why}`)\n }\n if (!isRecord(raw)) return fail('not an object')\n const kind = raw['kind']\n if (typeof raw['id'] !== 'string' || !raw['id']) fail('no id')\n if (typeof kind !== 'string' || !(AI_EVAL_KINDS as readonly string[]).includes(kind)) {\n fail(`kind \"${String(kind)}\" is not one of ${AI_EVAL_KINDS.join(', ')}`)\n }\n if (typeof raw['brief'] !== 'string' || !raw['brief'].trim()) fail('no brief')\n if (raw['siteName'] !== undefined && (typeof raw['siteName'] !== 'string' || !raw['siteName'].trim())) {\n fail('siteName, where given, is the site’s name')\n }\n const automation = raw['automation']\n if (automation !== undefined) {\n const action = isRecord(automation) ? automation['action'] : undefined\n const problem = isRecord(action) ? validateHostAction(action as unknown as HostAction) : 'it holds no action'\n if (problem) fail(`automation.action is not an action the Actions editor would save: ${problem}`)\n if (isRecord(automation) && automation['run'] !== undefined && !isRecord(automation['run'])) {\n fail('automation.run, where given, is what the run history recorded')\n }\n }\n const media = raw['media']\n if (media !== undefined) {\n if (!isRecord(media) || !Object.keys(media).length) fail('media, where given, names at least one asset')\n for (const [mediaId, file] of Object.entries(media as Record<string, unknown>)) {\n if (typeof file !== 'string' || !AI_EVAL_MEDIA_FILE.test(file)) {\n fail(`media.${mediaId} is not a picture's path under tools/ai-eval/fixtures`)\n }\n }\n }\n const candidates = raw['candidates']\n const controls = raw['controls']\n if (!Array.isArray(candidates) || !candidates.length) fail('no candidates')\n if (!Array.isArray(controls) || !controls.length) fail('no controls: every case proves it can fail')\n for (const [index, candidate] of (candidates as unknown[]).entries()) {\n if (!isRecord(candidate)) fail(`candidates[${index}] is not an object`)\n const source = (candidate as Record<string, unknown>)['source']\n if (source !== 'authored' && source !== 'recorded') {\n fail(`candidates[${index}].source is neither authored nor recorded`)\n }\n if (!isRecord((candidate as Record<string, unknown>)['rubric'])) {\n fail(`candidates[${index}] has no rubric`)\n }\n }\n for (const [index, control] of (controls as unknown[]).entries()) {\n const fails = isRecord(control) ? control['fails'] : undefined\n if (!Array.isArray(fails) || !fails.length) fail(`controls[${index}] names no check it fails`)\n }\n const capabilities =\n raw['capabilities'] === undefined ? undefined : readAiEvalCapabilities(raw['capabilities'], fail)\n return {\n framing: null,\n inventory: null,\n ...(raw as object),\n ...(capabilities ? { capabilities } : {}),\n } as AiEvalCase\n}\n\n/**\n * A case's capabilities read and checked for shape. A creation kind the case\n * leaves out may be created, so a case names only what its workspace lacks;\n * a Free workspace's case says so with `freeTaste`, which holds its plan to\n * the sections the Free wall pays for (AGL-3070).\n */\nfunction readAiEvalCapabilities(raw: unknown, fail: (why: string) => never): AiPlanCapabilities {\n if (!isRecord(raw) || typeof raw['reusableComponents'] !== 'boolean') {\n return fail('capabilities.reusableComponents is not true or false')\n }\n const create = isRecord(raw['create']) ? raw['create'] : {}\n const unrestricted = aiUnrestrictedPlanCapabilities()\n const entries: Array<[AiBuildPlanCreateKind, AiPlanCreation]> = AI_BUILD_PLAN_CREATE_KINDS.map((kind) => {\n const entry = create[kind]\n if (entry === undefined) return [kind, unrestricted.create[kind]]\n if (!isRecord(entry) || typeof entry['allowed'] !== 'boolean') {\n return fail(`capabilities.create.${kind}.allowed is not true or false`)\n }\n const left = entry['left']\n const reason = entry['reason']\n return [\n kind,\n {\n allowed: entry['allowed'],\n left: typeof left === 'number' ? left : null,\n reason: typeof reason === 'string' ? reason : null,\n },\n ]\n })\n for (const kind of Object.keys(create)) {\n if (!(AI_BUILD_PLAN_CREATE_KINDS as readonly string[]).includes(kind)) {\n fail(`capabilities.create.${kind} is not a creation kind`)\n }\n }\n if (raw['freeTaste'] !== undefined && typeof raw['freeTaste'] !== 'boolean') {\n return fail('capabilities.freeTaste is not true or false')\n }\n return {\n reusableComponents: raw['reusableComponents'],\n create: Object.fromEntries(entries) as AiPlanCapabilities['create'],\n ...(raw['freeTaste'] === true ? { freeTaste: true } : {}),\n }\n}\n"],"names":["validateHostAction","aiAutomationDraft","emptyAiAutomationRecords","AI_BUILD_PLAN_CREATE_KINDS","aiUnrestrictedPlanCapabilities","AI_EXPERIMENT_BODY_MAX_CHARS","AI_EXPERIMENT_HEADLINE_MAX_CHARS","AI_EXPERIMENT_LINE_MAX_CHARS","AI_EXPERIMENT_MAX_POINTS","AI_EXPERIMENT_NAME_MAX_CHARS","AI_EXPERIMENT_NEXT_MAX_CHARS","AI_EXPERIMENT_POINT_MAX_CHARS","AI_EXPERIMENT_RATIONALE_MAX_CHARS","aiExperimentVariantFields","checkAiExperimentExplanation","checkAiExperimentVariants","readAiExperimentResult","parseAiExperimentExplanation","parseAiExperimentVariants","aiComponentCheck","aiProductMerchantWords","checkAiCatalog","checkAiCategories","checkAiProductCopy","aiCrmEmailMergeFields","aiCrmImportFields","aiCrmRecordCheckContext","checkAiCrmEmail","checkAiCrmMapping","checkAiCrmRecord","parseAiThemeToolInput","AI_AUTOMATION_OVERSIZE_CODES","AI_AUTOMATION_UNREADABLE_CODES","readAiAutomationAnswer","readAiWorkflowExplanation","parseAiInsightAnswer","checkAiInsightAnswer","aiDeviceAuditFindings","aiAnswerTree","aiDoctrinePlanCheck","aiDoctrineTreeCheck","aiDoctrineTreeContext","AI_SEO_DESCRIPTION_MAX","AI_SEO_TITLE_MAX","detectOffVoiceCopy","detectPublishIntent","AI_TEXT_LIMITS","expandAiRepeatedItems","AI_EVAL_KINDS","AI_EVAL_TREE_OUTPUT","page","template","component","layout","form","email","section","aiEvalRendersAtDeviceWidths","kind","output","undefined","AI_EVAL_SITE_ID","AI_EVAL_AUTOMATION_CAPABILITIES","crm","webhooks","bookings","AI_EVAL_MEDIA_FILE","AI_EVAL_FLOORS","passRate","meanScore","seo","product","catalog","categories","theme","element","blog","text","chat","workflow","insight","experiment","AI_EVAL_RUBRIC_PASS_MEAN","AI_EVAL_BLOG_MAX_CHARS","AI_EVAL_TEXT_MAX_WORDS","AI_EVAL_CHAT_MAX_CHARS","isRecord","value","Array","isArray","codes","violations","map","violation","code","planSections","evalCase","plan","screens","sections","flatMap","readTree","outputKind","answer","inline","capabilities","reusableComponents","input","tree","declaresProps","check","inventory","assets","framing","definesComponent","length","pageSections","drawn","noun","ok","undrawn","result","items","aiEvalAnswerTree","checkTree","readable","rules","budget","findings","onProps","filter","rule","FENCE","PREAMBLE","QUOTED","MARKUP","words","trim","split","Boolean","checkCopy","limits","own","unreadable","test","broken","at","maxChars","maxWords","over","MARKDOWN_LINK","chatLinks","allowed","Set","docsUrls","matchAll","match","url","startsWith","has","checkBlog","checked","head","trimStart","extra","checkSeo","title","description","PRODUCTS_UNREADABLE","PRODUCTS_OVER_BUDGET","checkProducts","categoryIds","category","id","optionCount","facts","options","merchantWords","brief","existingCategoryNames","found","some","checkTheme","parse","changes","components","resetComponents","summary","dropped","reason","checkWorkflow","publish","read","lines","String","offVoice","index","includes","automationCapabilities","oversize","invalid","unsupported","automationRecords","action","checkInsight","parsed","insights","tables","finding","kept","CRM_UNREADABLE","CRM_OVER","checkCrm","context","record","task","columns","fields","mergeFields","path","key","samples","join","sample","EXPERIMENT_RULE_FINDINGS","checkExperiment","target","variants","variant","name","rationale","field","proposal","reading","arms","explained","headline","points","point","next","checkAnswer","body","checkAiEvalPlan","shape","expected","pass","shapeFindings","reuse","entry","screen","slug","maxCreate","create","createKinds","clampGrade","Number","isFinite","Math","min","max","aiEvalRubricVerdict","rubric","grades","structure","copy","grade","mean","reduce","sum","checkWidths","audits","audit","scoreAiEvalCandidate","candidate","scope","widths","rubricScore","parts","score","round","part","documentPasses","caseId","source","model","checks","responsive","scoreAiEvalControl","control","candidates","summarizeAiEval","scores","passed","floor","belowFloor","summarizeAiEvalPlans","plans","readAiEvalRecording","raw","file","Error","readAiEvalCase","fail","why","automation","problem","media","Object","keys","mediaId","entries","controls","fails","readAiEvalCapabilities","unrestricted","left","fromEntries","freeTaste"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC;AAGD,SAASA,kBAAkB,QAAyB,iCAAgC;AAEpF,SACEC,iBAAiB,EACjBC,wBAAwB,QAEnB,kCAA8B;AAErC,SAASC,0BAA0B,QAAoC,4BAAwB;AAC/F,SACEC,8BAA8B,QAGzB,mCAA+B;AACtC,SACEC,4BAA4B,EAC5BC,gCAAgC,EAChCC,4BAA4B,EAC5BC,wBAAwB,EACxBC,4BAA4B,EAC5BC,4BAA4B,EAC5BC,6BAA6B,EAC7BC,iCAAiC,EACjCC,yBAAyB,EACzBC,4BAA4B,EAC5BC,yBAAyB,EACzBC,sBAAsB,QAIjB,4BAAwB;AAC/B,SACEC,4BAA4B,EAC5BC,yBAAyB,QACpB,iCAA6B;AAKpC,SAASC,gBAAgB,QAAQ,qCAAiC;AAClE,SACEC,sBAAsB,QAIjB,0BAAsB;AAE7B,SAASC,cAAc,EAAEC,iBAAiB,EAAEC,kBAAkB,QAAQ,+BAA2B;AAEjG,SACEC,qBAAqB,EACrBC,iBAAiB,EACjBC,uBAAuB,EACvBC,eAAe,EACfC,iBAAiB,EACjBC,gBAAgB,QACX,0BAAsB;AAC7B,SAASC,qBAAqB,QAAQ,4BAAwB;AAC9D,SACEC,4BAA4B,EAC5BC,8BAA8B,EAC9BC,sBAAsB,EACtBC,yBAAyB,QACpB,+BAA2B;AAElC,SAASC,oBAAoB,QAAQ,8BAA0B;AAC/D,SAASC,oBAAoB,QAAQ,wBAAoB;AACzD,SAASC,qBAAqB,QAA4B,uBAAmB;AAC7E,SACEC,YAAY,EACZC,mBAAmB,EACnBC,mBAAmB,EACnBC,qBAAqB,QAGhB,mBAAe;AACtB,SACEC,sBAAsB,EACtBC,gBAAgB,EAChBC,kBAAkB,EAClBC,mBAAmB,QAId,8BAA0B;AACjC,SAASC,cAAc,QAA2B,kBAAc;AAChE,SAASC,qBAAqB,QAAQ,yBAAqB;AAiE3D,OAAO,MAAMC,gBAAuC;IAClD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAA;AAED,uFAAuF,GACvF,OAAO,MAAMC,sBAAiE;IAC5EC,MAAM;IACNC,UAAU;IACVC,WAAW;IACXC,QAAQ;IACRC,MAAM;IACNC,OAAO;IACPC,SAAS;AACX,EAAC;AAED;;;;CAIC,GACD,OAAO,SAASC,4BAA4BC,IAAgB;IAC1D,MAAMC,SAASV,mBAAmB,CAACS,KAAK;IACxC,OAAOC,WAAWC,aAAaD,WAAW;AAC5C;AA2OA,wEAAwE,GACxE,OAAO,MAAME,kBAAkB,YAAW;AAE1C,yFAAyF,GACzF,OAAO,MAAMC,kCAA4D;IAAEC,KAAK;IAAMC,UAAU;IAAMC,UAAU;AAAK,EAAC;AAsBtH,gGAAgG,GAChG,MAAMC,qBAAqB;AAmB3B;;;;;;CAMC,GACD,OAAO,MAAMC,iBAA4D;IACvEjB,MAAM;QAAEkB,UAAU;QAAGC,WAAW;IAAI;IACpClB,UAAU;QAAEiB,UAAU;QAAGC,WAAW;IAAI;IACxCjB,WAAW;QAAEgB,UAAU;QAAGC,WAAW;IAAI;IACzChB,QAAQ;QAAEe,UAAU;QAAGC,WAAW;IAAI;IACtCf,MAAM;QAAEc,UAAU;QAAGC,WAAW;IAAI;IACpCd,OAAO;QAAEa,UAAU;QAAGC,WAAW;IAAI;IACrCb,SAAS;QAAEY,UAAU;QAAGC,WAAW;IAAI;IACvCC,KAAK;QAAEF,UAAU;QAAGC,WAAW;IAAI;IACnCE,SAAS;QAAEH,UAAU;QAAGC,WAAW;IAAI;IACvCG,SAAS;QAAEJ,UAAU;QAAGC,WAAW;IAAI;IACvCI,YAAY;QAAEL,UAAU;QAAGC,WAAW;IAAI;IAC1CK,OAAO;QAAEN,UAAU;QAAGC,WAAW;IAAI;IACrCM,SAAS;QAAEP,UAAU;QAAGC,WAAW;IAAI;IACvCO,MAAM;QAAER,UAAU;QAAGC,WAAW;IAAI;IACpCQ,MAAM;QAAET,UAAU;QAAGC,WAAW;IAAI;IACpCS,MAAM;QAAEV,UAAU;QAAGC,WAAW;IAAI;IACpCU,UAAU;QAAEX,UAAU;QAAGC,WAAW;IAAI;IACxCW,SAAS;QAAEZ,UAAU;QAAGC,WAAW;IAAI;IACvCN,KAAK;QAAEK,UAAU;QAAGC,WAAW;IAAI;IACnCY,YAAY;QAAEb,UAAU;QAAGC,WAAW;IAAI;AAC5C,EAAC;AAED,iEAAiE,GACjE,OAAO,MAAMa,2BAA2B,IAAG;AAE3C,8FAA8F,GAC9F,OAAO,MAAMC,yBAAyB,KAAK;AAE3C,8FAA8F,GAC9F,OAAO,MAAMC,yBAAyB,IAAG;AAEzC,gGAAgG,GAChG,OAAO,MAAMC,yBAAyB,KAAK;AA0B3C,MAAMC,WAAW,CAACC,QAChB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,OAAO,CAACF;AAEhE,MAAMG,QAAQ,CAACC,aACbA,WAAWC,GAAG,CAAC,CAACC,YAAcA,UAAUC,IAAI;AAa9C;;;;CAIC,GACD,SAASC,aAAaC,QAAoB,EAAEC,IAAa;IACvD,MAAMC,UAAUF,SAAStC,IAAI,KAAK,UAAU4B,SAASW,SAAST,MAAMC,OAAO,CAACQ,IAAI,CAAC,UAAU,IAAIA,IAAI,CAAC,UAAU,GAAG,EAAE;IACnH,MAAME,WAAWb,SAASY,OAAO,CAAC,EAAE,KAAKV,MAAMC,OAAO,CAACS,OAAO,CAAC,EAAE,CAAC,WAAW,IAAIA,OAAO,CAAC,EAAE,CAAC,WAAW,GAAG,EAAE;IAC5G,OAAOC,SAASC,OAAO,CAAC,CAAC5C,UACvB8B,SAAS9B,YAAY,OAAOA,OAAO,CAAC,OAAO,KAAK,WAAW;YAACA,OAAO,CAAC,OAAO;SAAC,GAAG,EAAE;AAErF;AAEA,SAAS6C,SAASL,QAAoB,EAAEM,UAAwB,EAAEC,MAAe,EAAEN,IAAc;QAChFD;IAAf,MAAMQ,SAASR,EAAAA,yBAAAA,SAASS,YAAY,qBAArBT,uBAAuBU,kBAAkB,MAAK;IAC7D,IAAIC,QAAQrB,SAASiB,UAAUA,SAAS;QAAEK,MAAML;IAAO;IACvD,0EAA0E;IAC1E,uEAAuE;IACvE,cAAc;IACd,MAAMM,gBAAgBb,SAAStC,IAAI,KAAK,eAAe8B,MAAMC,OAAO,CAACkB,KAAK,CAAC,QAAQ;IACnF,MAAMR,WAAWJ,aAAaC,UAAUC;IACxC,MAAMa,QAAQtE,oBACZ8D,YACA7D,sBAAsBuD,SAASe,SAAS,EAAE,aACpCf,SAASgB,MAAM,GAAG;QAAEA,QAAQhB,SAASgB,MAAM;IAAC,IAAI,CAAC;QACrDC,SAASjB,SAASiB,OAAO;OACrBT,SAAS;QAAEE,oBAAoB;IAAM,IAAI,CAAC,GAC1CG,gBAAgB;QAAEK,kBAAkB;IAAK,IAAI,CAAC,GAC9Cf,SAASgB,MAAM,GAAG;QAAEC,cAAcjB;IAAS,IAAI,CAAC;IAGxD,6EAA6E;IAC7E,0EAA0E;IAC1E,IAAIH,SAAStC,IAAI,KAAK,QAAQ;QAC5B,MAAM2D,QAAQtE,sBAAsBT,aAAaqE,QAAQ;YAAEH;YAAQc,MAAM;QAAO;QAChF,IAAID,MAAME,EAAE,KAAK,OAAO,OAAO;YAAEZ;YAAOE;YAAeW,SAASH,MAAM1B,UAAU;YAAE8B,QAAQ;QAAK;QAC/F,IAAIJ,MAAMK,KAAK,EAAEf,QAAQ;YAAEC,MAAMS,MAAMT,IAAI;QAAC;IAC9C;IACA,OAAO;QAAED;QAAOE;QAAeW,SAAS;QAAMC,QAAQX,MAAMH;IAAO;AACrE;AAEA;;;;CAIC,GACD,OAAO,SAASgB,iBAAiB3B,QAAoB,EAAEO,MAAe;;QAE/CF;IADrB,MAAMC,aAAarD,mBAAmB,CAAC+C,SAAStC,IAAI,CAAC;IACrD,OAAO4C,sBAAcD,mBAAAA,SAASL,UAAUM,YAAYC,QAAQkB,MAAM,qBAA7CpB,iBAA+Cd,KAAK,mBAAI,OAAQ;AACvF;AAEA,SAASqC,UAAU5B,QAAoB,EAAEM,UAAwB,EAAEC,MAAe,EAAEN,IAAc;IAChG,MAAM,EAAEU,KAAK,EAAEE,aAAa,EAAEW,OAAO,EAAEC,MAAM,EAAE,GAAGpB,SAASL,UAAUM,YAAYC,QAAQN;IACzF,IAAIuB,WAAW,CAACC,QAAQ;QACtB,OAAO;YAAEI,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAUtC,MAAM8B,kBAAAA,UAAW,EAAE;QAAE;IACxF;IACA,MAAM7B,aAAa;WACd8B,OAAO9B,UAAU;WAChBkB,iBAAiBY,OAAOlC,KAAK,GAC7BpE,iBAAiB;YAAE4F,WAAWf,SAASe,SAAS;YAAEd,MAAM;YAAMgC,SAAS,IAAMrE;QAAU,GAAG6D,OAAOlC,KAAK,EAAEoB,SACxG,EAAE;KACP;IACD,MAAMoB,SAASpC,WAAWuC,MAAM,CAAC,CAACrC,YAAcA,UAAUsC,IAAI,KAAK;IACnE,MAAML,QAAQnC,WAAWuC,MAAM,CAAC,CAACrC,YAAcA,UAAUsC,IAAI,KAAK;IAClE,OAAO;QACLN,UAAUJ,OAAOlC,KAAK,KAAK;QAC3BuC,OAAOL,OAAOlC,KAAK,KAAK,QAAQuC,MAAMX,MAAM,KAAK;QACjDY,QAAQN,OAAOlC,KAAK,KAAK,QAAQwC,OAAOZ,MAAM,KAAK;QACnDa,UAAUtC,MAAMC;IAClB;AACF;AAEA,MAAMyC,QAAQ;AACd,MAAMC,WAAW;AACjB,MAAMC,SAAS;AACf,MAAMC,SAAS;AAEf,SAASC,MAAM3D,IAAY;IACzB,OAAOA,KAAK4D,IAAI,GAAGC,KAAK,CAAC,OAAOR,MAAM,CAACS,SAASxB,MAAM;AACxD;AAEA,sFAAsF,GACtF,SAASyB,UACP5C,QAAoB,EACpBO,MAAe,EACfsC,MAAgD,EAChDC,MAAkC,IAAM,EAAE;QAgBzB9C,oBACAA;IAfjB,IAAI,OAAOO,WAAW,YAAY,CAACA,OAAOkC,IAAI,IAAI;QAChD,OAAO;YAAEZ,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAe;QAAC;IACpF;IACA,MAAMnD,OAAO0B,OAAOkC,IAAI;IACxB,MAAMM,aAAa;WACbX,MAAMY,IAAI,CAACnE,QAAQ;YAAC;SAAc,GAAG,EAAE;WACvCwD,SAASW,IAAI,CAACnE,QAAQ;YAAC;SAAgB,GAAG,EAAE;WAC5CyD,OAAOU,IAAI,CAACnE,QAAQ;YAAC;SAAc,GAAG,EAAE;KAC7C;IACD,MAAMoE,SAAS;WACVvD,MAAM9C,mBAAmB;YAAC;gBAAEsG,IAAI;gBAAUrE;YAAK;SAAE,EAAEmB,SAASiB,OAAO;WAClEsB,OAAOS,IAAI,CAACnE,QAAQ;YAAC;SAAc,GAAG,EAAE;WACzCiE,IAAIjE;KACR;IACD,MAAMsE,YAAWnD,qBAAAA,SAASmD,QAAQ,YAAjBnD,qBAAqB6C,OAAOM,QAAQ;IACrD,MAAMC,YAAWpD,qBAAAA,SAASoD,QAAQ,YAAjBpD,qBAAqB6C,OAAOO,QAAQ;IACrD,MAAMC,OAAO;WACPF,aAAavF,aAAaiB,KAAKsC,MAAM,GAAGgC,WAAW;YAAC;SAAkB,GAAG,EAAE;WAC3EC,aAAaxF,aAAa4E,MAAM3D,QAAQuE,WAAW;YAAC;SAAkB,GAAG,EAAE;KAChF;IACD,OAAO;QACLvB,UAAUkB,WAAW5B,MAAM,KAAK;QAChCW,OAAOmB,OAAO9B,MAAM,KAAK;QACzBY,QAAQsB,KAAKlC,MAAM,KAAK;QACxBa,UAAU;eAAIe;eAAeE;eAAWI;SAAK;IAC/C;AACF;AAEA,MAAMC,gBAAgB;AAEtB,+EAA+E,GAC/E,SAASC,UAAUvD,QAAoB;QACbA;IAAxB,MAAMwD,UAAU,IAAIC,KAAIzD,qBAAAA,SAAS0D,QAAQ,YAAjB1D,qBAAqB,EAAE;IAC/C,OAAO,CAACnB,OACN;eAAIA,KAAK8E,QAAQ,CAACL;SAAe,CAC9B1D,GAAG,CAAC,CAACgE,QAAUA,KAAK,CAAC,EAAE,EACvB1B,MAAM,CAAC,CAAC2B,MAAQ,CAACA,IAAIC,UAAU,CAAC,QAAQ,CAACN,QAAQO,GAAG,CAACF,MACrDjE,GAAG,CAAC,CAACiE,MAAQ,CAAC,oBAAoB,EAAEA,KAAK;AAChD;AAEA,SAASG,UAAUhE,QAAoB,EAAEO,MAAe;IACtD,MAAM0D,UAAUrB,UAAU5C,UAAUO,QAAQ;QAAE4C,UAAUhE;IAAuB;IAC/E,IAAI,OAAOoB,WAAW,UAAU,OAAO0D;IACvC,MAAMC,OAAO3D,OAAO4D,SAAS;IAC7B,MAAMC,QAAQ;WACRF,KAAKJ,UAAU,CAAC,SAAS;YAAC;SAAoB,GAAG,EAAE;WACnD,OAAOd,IAAI,CAACkB,QAAQ;YAAC;SAAkB,GAAG,EAAE;KACjD;IACD,OAAOE,MAAMjD,MAAM,GACf,aAAK8C;QAASpC,UAAU;QAAOG,UAAU;eAAIiC,QAAQjC,QAAQ;eAAKoC;SAAM;SACxEH;AACN;AAEA,SAASI,SAASrE,QAAoB,EAAEO,MAAe;IACrD,MAAM+D,QAAQhF,SAASiB,WAAW,OAAOA,MAAM,CAAC,QAAQ,KAAK,WAAWA,MAAM,CAAC,QAAQ,CAACkC,IAAI,KAAK;IACjG,MAAM8B,cACJjF,SAASiB,WAAW,OAAOA,MAAM,CAAC,cAAc,KAAK,WAAWA,MAAM,CAAC,cAAc,CAACkC,IAAI,KAAK;IACjG,IAAI,CAAC6B,SAAS,CAACC,aAAa;QAC1B,OAAO;YAAE1C,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAoB;QAAC;IACzF;IACA,MAAMiB,SAAS;WACVvD,MAAM7C,oBAAoB0D;WAC1Bb,MACD9C,mBACE;YACE;gBAAEsG,IAAI;gBAASrE,MAAMyF;YAAM;YAC3B;gBAAEpB,IAAI;gBAAerE,MAAM0F;YAAY;SACxC,EACDvE,SAASiB,OAAO;WAGhBsB,OAAOS,IAAI,CAACsB,UAAU/B,OAAOS,IAAI,CAACuB,eAAe;YAAC;SAAa,GAAG,EAAE;KACzE;IACD,MAAMlB,OAAO;WACPiB,MAAMnD,MAAM,GAAGxE,mBAAmB;YAAC;SAAiB,GAAG,EAAE;WACzD4H,YAAYpD,MAAM,GAAGzE,yBAAyB;YAAC;SAAuB,GAAG,EAAE;KAChF;IACD,OAAO;QACLmF,UAAU;QACVC,OAAOmB,OAAO9B,MAAM,KAAK;QACzBY,QAAQsB,KAAKlC,MAAM,KAAK;QACxBa,UAAU;eAAIiB;eAAWI;SAAK;IAChC;AACF;AAEA,wEAAwE,GACxE,MAAMmB,sBAAsB,IAAIf,IAAI;IAAC;IAAQ;IAAW;CAAe;AACvE,MAAMgB,uBAAuB,IAAIhB,IAAI;IAAC;IAAY;IAAY;CAAgB;AAE9E;;;;;;CAMC,GACD,SAASiB,cAAc1E,QAAoB,EAAEO,MAAe;qBAczBP;QAPXA,mBACDA;IAPrB,IAAI,CAACV,SAASiB,SAAS;QACrB,OAAO;YAAEsB,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAsB;QAAC;IAC3F;IACA,MAAMP,SACJzB,SAAStC,IAAI,KAAK,YACdnC,mBAAmBgF,QAAQ;QACzBoE,aAAa,UAAC3E,oBAAAA,SAASzB,OAAO,qBAAhByB,kBAAkBvB,UAAU,mBAAI,EAAE,EAAEmB,GAAG,CAAC,CAACgF,WAAaA,SAASC,EAAE;QAC/EC,WAAW,YAAE9E,qBAAAA,SAASzB,OAAO,qBAAhByB,mBAAkB+E,KAAK,CAACC,OAAO,CAAC7D,MAAM,oBAAI;QACvD8D,eAAejF,SAASzB,OAAO,GAAGnD,uBAAuB4E,SAASzB,OAAO,CAACwG,KAAK,IAAI/E,SAASkF,KAAK;IACnG,KACAlF,SAAStC,IAAI,KAAK,YAChBrC,eAAekF,QAAQ;QAAE0E,eAAejF,SAASkF,KAAK;IAAC,KACvD5J,kBAAkBiF,QAAQ;QACxB4E,qBAAqB,GAAEnF,kCAAAA,SAASmF,qBAAqB,YAA9BnF,kCAAkC,EAAE;QAC3DiF,eAAejF,SAASkF,KAAK;IAC/B;IACR,MAAME,QAAQ;WAAI1F,MAAM+B,OAAO9B,UAAU;WAAMD,MAAM7C,oBAAoB0D;KAAS;IAClF,OAAO;QACLsB,UAAU,CAACuD,MAAMC,IAAI,CAAC,CAACvF,OAAS0E,oBAAoBT,GAAG,CAACjE;QACxDgC,OAAO,CAACsD,MAAMC,IAAI,CAAC,CAACvF,OAAS,CAAC0E,oBAAoBT,GAAG,CAACjE,SAAS,CAAC2E,qBAAqBV,GAAG,CAACjE;QACzFiC,QAAQ,CAACqD,MAAMC,IAAI,CAAC,CAACvF,OAAS2E,qBAAqBV,GAAG,CAACjE;QACvDkC,UAAUoD;IACZ;AACF;AAEA,SAASE,WAAWtF,QAAoB,EAAEO,MAAe;IACvD,IAAI,CAACjB,SAASiB,SAAS;QACrB,OAAO;YAAEsB,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAmB;QAAC;IACxF;IACA,MAAMuD,QAAQzJ,sBAAsByE;IACpC,MAAMiF,UAAUD,MAAMC,OAAO,CAACrE,MAAM,GAAGoE,MAAME,UAAU,CAACtE,MAAM,GAAIoE,CAAAA,MAAMG,eAAe,GAAG,IAAI,CAAA;IAC9F,MAAMzC,SAAS;WACVvD,MAAM7C,oBAAoB0D;WAC1Bb,MAAM9C,mBAAmB;YAAC;gBAAEsG,IAAI;gBAAWrE,MAAM0G,MAAMI,OAAO;YAAC;SAAE,EAAE3F,SAASiB,OAAO;KACvF;IACD,OAAO;QACLY,UAAU2D,UAAU,KAAKD,MAAMK,OAAO,CAACzE,MAAM,KAAK;QAClDW,OAAOmB,OAAO9B,MAAM,KAAK;QACzBY,QAAQ;QACRC,UAAU;eAAIuD,MAAMK,OAAO,CAAChG,GAAG,CAAC,CAACiG,SAAW,CAAC,cAAc,EAAEA,QAAQ;eAAM5C;SAAO;IACpF;AACF;AAEA;;;;CAIC,GACD,SAAS6C,cAAc9F,QAAoB,EAAEO,MAAe;QAuBrCP,kCAQkCA;IA9BvD,IAAI,CAACV,SAASiB,SAAS;QACrB,OAAO;YAAEsB,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAsB;QAAC;IAC3F;IACA,MAAM+D,UAAUrG,MAAM7C,oBAAoB0D;IAC1C,IAAI,aAAaA,QAAQ;YAGdA;QAFT,MAAMyF,OAAO9J,0BAA0BqE;QACvC,MAAM0F,QAAQ;YACZC,QAAO3F,kBAAAA,MAAM,CAAC,UAAU,YAAjBA,kBAAqB;eACxBf,MAAMC,OAAO,CAACc,MAAM,CAAC,SAAS,IAAIA,MAAM,CAAC,SAAS,GAAG,EAAE;eACvDf,MAAMC,OAAO,CAACc,MAAM,CAAC,cAAc,IAAIA,MAAM,CAAC,cAAc,GAAG,EAAE;SACtE,CAACX,GAAG,CAACsG;QACN,MAAMC,WAAWzG,MACf9C,mBAAmBqJ,MAAMrG,GAAG,CAAC,CAACf,MAAMuH,QAAW,CAAA;gBAAElD,IAAI,CAAC,KAAK,EAAEkD,MAAM,CAAC,CAAC;gBAAEvH;YAAK,CAAA,IAAKmB,SAASiB,OAAO;QAEnG,MAAMmE,QAAQ1F,MAAMsG,KAAKrG,UAAU;QACnC,OAAO;YACLkC,UAAU,CAACuD,MAAMiB,QAAQ,CAAC;YAC1BvE,OAAOkE,KAAKzG,KAAK,KAAK,QAAQwG,QAAQ5E,MAAM,KAAK,KAAKgF,SAAShF,MAAM,KAAK;YAC1EY,QAAQ;YACRC,UAAU;mBAAIoD;mBAAUW;mBAAYI;aAAS;QAC/C;IACF;IACA,MAAM1F,gBAAeT,mCAAAA,SAASsG,sBAAsB,YAA/BtG,mCAAmClC;IACxD,MAAMkI,OAAO/J,uBAAuBsE,QAAQE;IAC5C,MAAM2E,QAAQ1F,MAAMsG,KAAKrG,UAAU;IACnC,MAAMoD,aAAaqC,MAAMlD,MAAM,CAAC,CAACpC,OAAS9D,+BAA+BqK,QAAQ,CAACvG;IAClF,MAAMyG,WAAWnB,MAAMlD,MAAM,CAAC,CAACpC,OAAS/D,6BAA6BsK,QAAQ,CAACvG;IAC9E,MAAMmD,SAASmC,MAAMlD,MAAM,CAAC,CAACpC,OAAS,CAACiD,WAAWsD,QAAQ,CAACvG,SAAS,CAACyG,SAASF,QAAQ,CAACvG;IACvF,MAAM0G,UACJR,KAAKzG,KAAK,IAAI,CAACyG,KAAKzG,KAAK,CAACkH,WAAW,GACjCzM,mBAAmBC,kBAAkB+L,KAAKzG,KAAK,GAAES,8BAAAA,SAAS0G,iBAAiB,YAA1B1G,8BAA8B9F,4BAA4ByM,MAAM,IACjH;IACN,OAAO;QACL9E,UAAUkB,WAAW5B,MAAM,KAAK;QAChCW,OAAOmB,OAAO9B,MAAM,KAAK,KAAK4E,QAAQ5E,MAAM,KAAK,KAAKqF,YAAY;QAClEzE,QAAQwE,SAASpF,MAAM,KAAK;QAC5Ba,UAAU;eAAIoD;eAAUW;eAAaS,UAAU;gBAAC,CAAC,iBAAiB,EAAEA,SAAS;aAAC,GAAG,EAAE;SAAE;IACvF;AACF;AAEA;;;;;CAKC,GACD,SAASI,aAAa5G,QAAoB,EAAEO,MAAe;QAKdP;IAJ3C,MAAM6G,SAAS1K,qBAAqBoE;IACpC,IAAI,CAACsG,UAAU,CAACA,OAAOC,QAAQ,CAAC3F,MAAM,EAAE;QACtC,OAAO;YAAEU,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAoB;QAAC;IACzF;IACA,MAAMlB,QAAQ1E,qBAAqByK,SAAQ7G,mBAAAA,SAAS+G,MAAM,YAAf/G,mBAAmB,EAAE;IAChE,MAAMgC,WAAWlB,MAAMkB,QAAQ,CAACpC,GAAG,CAAC,CAACoH,UAAYA,QAAQtE,KAAK,CAAC,IAAI,CAAC,EAAE;IACtE,MAAMW,OAAOrB,SAASE,MAAM,CAAC,CAACpC,OAASA,SAAS,sBAAsBA,SAAS;IAC/E,OAAO;QACL+B,UAAUf,MAAMmG,IAAI,CAAC9F,MAAM,GAAG;QAC9BW,OAAOE,SAASb,MAAM,KAAKkC,KAAKlC,MAAM;QACtCY,QAAQsB,KAAKlC,MAAM,KAAK;QACxBa,UAAUlB,MAAMkB,QAAQ;IAC1B;AACF;AAEA,gGAAgG,GAChG,MAAMkF,iBAAiB,IAAIzD,IAAI;IAAC;IAAQ;CAAU;AAClD,MAAM0D,WAAW,IAAI1D,IAAI;IAAC;CAAW;AAErC;;;CAGC,GACD,SAAS2D,SAASpH,QAAoB,EAAEO,MAAe;QAKvC8G,gBACDA,iBAG8BA;IAR3C,MAAMA,UAAUrH,SAASjC,GAAG;IAC5B,IAAI,CAACsJ,WAAW,CAAC/H,SAASiB,SAAS;QACjC,OAAO;YAAEsB,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAAiB;QAAC;IACtF;IACA,MAAM+C,SAAQsC,iBAAAA,QAAQtC,KAAK,YAAbsC,iBAAiB,CAAC;IAChC,MAAM3J,QAAO2J,kBAAAA,QAAQC,MAAM,YAAdD,kBAAkB;IAC/B,MAAM5F,SACJ4F,QAAQE,IAAI,KAAK,YACb3L,kBAAkB2E,QAAQ;QAAEiH,OAAO,GAAEH,mBAAAA,QAAQG,OAAO,YAAfH,mBAAmB,EAAE;QAAEI,QAAQhM,kBAAkBsJ;IAAO,KAC7FsC,QAAQE,IAAI,KAAK,UACf5L,gBAAgB4E,QAAQ;QAAEmH,aAAalM,sBAAsBkC;IAAM,KACnE7B,iBAAiB0E,QAAQ7E,wBAAwBgC,MAAMqH;IAC/D,MAAMjC,MAAMpD,MAAM+B,OAAO9B,UAAU;IACnC,MAAMqG,OAAO,CAAC2B;QACZ,IAAIpI,QAAiBgB;QACrB,KAAK,MAAMqH,OAAOD,KAAMpI,QAAQD,SAASC,SAASA,KAAK,CAACqI,IAAI,GAAGhK;QAC/D,OAAO,OAAO2B,UAAU,WAAWA,QAAQ;IAC7C;IACA,MAAMsI,UAAU;QACd;YAAC;SAAU;QACX;YAAC;SAAW;QACZ;YAAC;YAAY;SAAQ;QACrB;YAAC;YAAY;SAAS;QACtB;YAAC;YAAS;SAAS;QACnB;YAAC;SAAU;QACX;YAAC;SAAO;KACT,CACEjI,GAAG,CAAC,CAAC+H,OAAU,CAAA;YAAEzE,IAAIyE,KAAKG,IAAI,CAAC;YAAMjJ,MAAMmH,KAAK2B;QAAM,CAAA,GACtDzF,MAAM,CAAC,CAAC6F,SAAWA,OAAOlJ,IAAI;IACjC,MAAMoE,SAAS;WACVvD,MAAM7C,oBAAoB0D;WAC1Bb,MAAM9C,mBAAmBiL,SAAS7H,SAASiB,OAAO;WAClD6B,IAAIZ,MAAM,CAAC,CAACpC,OAAS,CAACoH,eAAenD,GAAG,CAACjE,SAAS,CAACqH,SAASpD,GAAG,CAACjE;KACpE;IACD,OAAO;QACL+B,UAAU,CAACiB,IAAIuC,IAAI,CAAC,CAACvF,OAASoH,eAAenD,GAAG,CAACjE;QACjDgC,OAAOmB,OAAO9B,MAAM,KAAK;QACzBY,QAAQ,CAACe,IAAIuC,IAAI,CAAC,CAACvF,OAASqH,SAASpD,GAAG,CAACjE;QACzCkC,UAAU;eAAI,IAAIyB,IAAI;mBAAIX;mBAAQG;aAAO;SAAE;IAC7C;AACF;AAEA,qEAAqE,GACrE,MAAM+E,2BAA2B,IAAIvE,IAAI;IACvC;IACA;IACA;IACA;CACD;AAED;;;;;;;;;;CAUC,GACD,SAASwE,gBAAgBjI,QAAoB,EAAEO,MAAe;QAuCrB2E,aAAkBA;IAtCzD,MAAMA,QAAQlF,SAASf,UAAU;IACjC,IAAI,CAACiG,OAAO;QACV,OAAO;YAAErD,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAA2B;QAAC;IAChG;IACA,IAAIkD,MAAMqC,IAAI,KAAK,YAAY;YACMrC;QAAnC,MAAMgD,UAA6BhD,gBAAAA,MAAMgD,MAAM,YAAZhD,gBAAgB;QACnD,MAAM2B,SAAS3L,0BAA0BqF;QACzC,MAAM0D,UAAUlJ,0BAA0B8L,QAAQqB;QAClD,IAAI,CAACrB,UAAU,CAAC5C,SAAS;YACvB,OAAO;gBAAEpC,UAAU;gBAAOC,OAAO;gBAAOC,QAAQ;gBAAOC,UAAU;oBAAC;iBAAyB;YAAC;QAC9F;QACA,MAAMyF,SAAS5M,0BAA0BqN;QACzC,MAAM7E,OAAOwD,OAAOsB,QAAQ,CAAC/H,OAAO,CAAC,CAACgI,UAAY;mBAC5CA,QAAQC,IAAI,CAAClH,MAAM,GAAG1G,+BAA+B;oBAAC;iBAAuB,GAAG,EAAE;mBAClF2N,QAAQE,SAAS,CAACnH,MAAM,GAAGvG,oCAAoC;oBAAC;iBAA4B,GAAG,EAAE;mBAClG6M,OAAOrH,OAAO,CAAC,CAACmI;wBACVH;2BAAPlC,QAAOkC,iBAAAA,OAAO,CAACG,MAAM,YAAdH,iBAAkB,IAAIjH,MAAM,GAClCoH,CAAAA,UAAU,SAASlO,+BAA+BE,4BAA2B,IAC1E;wBAAC,CAAC,WAAW,EAAEgO,MAAM,KAAK,CAAC;qBAAC,GAC5B,EAAE;;aAET;QACD,MAAMV,UAAU5D,QAAQuE,QAAQ,CAACL,QAAQ,CAAC/H,OAAO,CAAC,CAACgI,UACjDX,OAAO7H,GAAG,CAAC,CAAC2I;oBAA0DH;uBAA/C;oBAAElF,IAAI,GAAGkF,QAAQC,IAAI,CAAC,CAAC,EAAEE,OAAO;oBAAE1J,MAAMqH,QAAOkC,iBAAAA,OAAO,CAACG,MAAM,YAAdH,iBAAkB;gBAAI;;QAE9F,MAAMnF,SAAS;eACVgB,QAAQjC,QAAQ,CAACE,MAAM,CAAC,CAAC8E,UAAYgB,yBAAyBjE,GAAG,CAACiD;eAClEtH,MAAM7C,oBAAoB0D;eAC1Bb,MAAM9C,mBAAmBiL,QAAQ3F,MAAM,CAAC,CAAC6F,SAAWA,OAAOlJ,IAAI,GAAGmB,SAASiB,OAAO;SACtF;QACD,OAAO;YACLY,UAAU;YACVC,OAAOmB,OAAO9B,MAAM,KAAK;YACzBY,QAAQsB,KAAKlC,MAAM,KAAK;YACxBa,UAAU;mBAAI,IAAIyB,IAAI;uBAAIR;uBAAWI;iBAAK;aAAE;QAC9C;IACF;IAEA,MAAMoF,UAAUzN,wBAAuBkK,cAAAA,MAAMlC,IAAI,YAAVkC,cAAc,KAAIA,cAAAA,MAAMwD,IAAI,YAAVxD,cAAc,EAAE;IACzE,MAAM2B,SAAS5L,6BAA6BsF;IAC5C,MAAMoI,YAAY7N,6BAA6B+L,QAAQ4B;IACvD,IAAI,CAAC5B,UAAU,CAAC8B,WAAW;QACzB,OAAO;YAAE9G,UAAU;YAAOC,OAAO;YAAOC,QAAQ;YAAOC,UAAU;gBAAC;aAA4B;QAAC;IACjG;IACA,MAAMqB,OAAO;WACPwD,OAAO+B,QAAQ,CAACzH,MAAM,GAAG7G,mCAAmC;YAAC;SAA2B,GAAG,EAAE;WAC7FuM,OAAOgC,MAAM,CAAC1H,MAAM,GAAG3G,2BAA2B;YAAC;SAAyB,GAAG,EAAE;WAClFqM,OAAOgC,MAAM,CAACzI,OAAO,CAAC,CAAC0I,QACxBA,MAAM3H,MAAM,GAAGxG,gCAAgC;gBAAC;aAAwB,GAAG,EAAE;WAE3EkM,OAAOkC,IAAI,CAAC5H,MAAM,GAAGzG,+BAA+B;YAAC;SAAuB,GAAG,EAAE;KACtF;IACD,MAAMuI,SAAS;WACV0F,UAAU3G,QAAQ;WAClBtC,MAAM7C,oBAAoB0D;WAC1Bb,MACD9C,mBACE;YACE;gBAAEsG,IAAI;gBAAYrE,MAAM8J,UAAUC,QAAQ;YAAC;eACxCD,UAAUE,MAAM,CAACjJ,GAAG,CAAC,CAACkJ,OAAO1C,QAAW,CAAA;oBAAElD,IAAI,CAAC,OAAO,EAAEkD,OAAO;oBAAEvH,MAAMiK;gBAAM,CAAA;SACjF,EACD9I,SAASiB,OAAO;KAGrB;IACD,OAAO;QACLY,UAAU;QACVC,OAAOmB,OAAO9B,MAAM,KAAK;QACzBY,QAAQsB,KAAKlC,MAAM,KAAK;QACxBa,UAAU;eAAI,IAAIyB,IAAI;mBAAIR;mBAAWI;aAAK;SAAE;IAC9C;AACF;AAEA,uGAAuG,GACvG,SAAS2F,YAAYhJ,QAAoB,EAAEO,MAAe,EAAEN,IAAc;IACxE,MAAMK,aAAarD,mBAAmB,CAAC+C,SAAStC,IAAI,CAAC;IACrD,IAAI4C,YAAY,OAAOsB,UAAU5B,UAAUM,YAAYC,QAAQN;IAC/D,OAAQD,SAAStC,IAAI;QACnB,KAAK;YACH,OAAO2G,SAASrE,UAAUO;QAC5B,KAAK;QACL,KAAK;QACL,KAAK;YACH,OAAOmE,cAAc1E,UAAUO;QACjC,KAAK;YACH,OAAO+E,WAAWtF,UAAUO;QAC9B,KAAK;YACH,OAAOqC,UAAU5C,UAAUO,QAAQ;gBAAE4C,UAAUrG,eAAemM,IAAI;YAAC;QACrE,KAAK;YACH,OAAOjF,UAAUhE,UAAUO;QAC7B,KAAK;YACH,OAAOqC,UAAU5C,UAAUO,QAAQ;gBAAE6C,UAAUhE;YAAuB;QACxE,KAAK;YACH,OAAOwD,UAAU5C,UAAUO,QAAQ;gBAAE4C,UAAU9D;YAAuB,GAAGkE,UAAUvD;QACrF,KAAK;YACH,OAAO8F,cAAc9F,UAAUO;QACjC,KAAK;YACH,OAAOqG,aAAa5G,UAAUO;QAChC,KAAK;YACH,OAAO6G,SAASpH,UAAUO;QAC5B,KAAK;YACH,OAAO0H,gBAAgBjI,UAAUO;QACnC;YACE,OAAO;gBAAEsB,UAAU;gBAAOC,OAAO;gBAAOC,QAAQ;gBAAOC,UAAU;oBAAC;iBAAe;YAAC;IACtF;AACF;AAEA,yEAAyE,GACzE,OAAO,SAASkH,gBACdlJ,QAAoB,EACpBC,IAAa;QAI4DD,wBASnEmJ;QAXQnJ;IAAd,MAAMmJ,SAAQnJ,qBAAAA,SAASoJ,QAAQ,qBAAjBpJ,mBAAmBC,IAAI;IACrC,IAAI,CAACkJ,OAAO,OAAO;QAAEE,MAAM;QAAMrH,UAAU,EAAE;IAAC;IAC9C,MAAMP,SAASlF,oBAAoByD,SAASe,SAAS,EAAEf,SAASiB,OAAO,GAAEjB,yBAAAA,SAASS,YAAY,YAArBT,yBAAyB,MAChGV,SAASW,QAAQA,OAAO,CAAC;IAE3B,IAAI,CAACwB,OAAOlC,KAAK,EAAE,OAAO;QAAE8J,MAAM;QAAOrH,UAAU;YAAC;eAAsBtC,MAAM+B,OAAO9B,UAAU;SAAE;IAAC;IACpG,MAAMJ,QAAQkC,OAAOlC,KAAK;IAC1B,MAAM+J,gBAAgB;WAChB/J,MAAMW,OAAO,CAACiB,MAAM,GAAGgI,MAAMjJ,OAAO,CAAC,EAAE,IAAIX,MAAMW,OAAO,CAACiB,MAAM,GAAGgI,MAAMjJ,OAAO,CAAC,EAAE,GAClF;YAAC,CAAC,aAAa,EAAEX,MAAMW,OAAO,CAACiB,MAAM,EAAE;SAAC,GACxC,EAAE;WACH,EAACgI,eAAAA,MAAMI,KAAK,YAAXJ,eAAe,EAAE,EAClBjH,MAAM,CAAC,CAAC2C,KAAO,CAACtF,MAAMgK,KAAK,CAAClE,IAAI,CAAC,CAACmE,QAAUA,MAAM3E,EAAE,KAAKA,KACzDjF,GAAG,CAAC,CAACiF,KAAO,CAAC,mBAAmB,EAAEA,IAAI;WACrCsE,MAAM9L,MAAM,GACZkC,MAAMW,OAAO,CACVgC,MAAM,CAAC,CAACuH,SAAWA,OAAOpM,MAAM,KAAK8L,MAAM9L,MAAM,EACjDuC,GAAG,CAAC,CAAC6J,SAAW,CAAC,YAAY,EAAEA,OAAOC,IAAI,EAAE,IAC/C,EAAE;WACFP,MAAMQ,SAAS,KAAK/L,aAAa2B,MAAMqK,MAAM,CAACzI,MAAM,GAAGgI,MAAMQ,SAAS,GACtE;YAAC,CAAC,YAAY,EAAEpK,MAAMqK,MAAM,CAACzI,MAAM,EAAE;SAAC,GACtC,EAAE;WACFgI,MAAMU,WAAW,GACjBtK,MAAMqK,MAAM,CACT1H,MAAM,CAAC,CAACsH;gBAAWL;mBAAD,GAACA,qBAAAA,MAAMU,WAAW,qBAAjBV,mBAAmB9C,QAAQ,CAACmD,MAAM9L,IAAI;WACzDkC,GAAG,CAAC,CAAC4J,QAAU,CAAC,iBAAiB,EAAEA,MAAM9L,IAAI,EAAE,IAClD,EAAE;KACP;IACD,MAAMsE,WAAW;WAAItC,MAAM+B,OAAO9B,UAAU;WAAM2J;KAAc;IAChE,OAAO;QAAED,MAAMrH,SAASb,MAAM,KAAK;QAAGa;IAAS;AACjD;AAEA,MAAM8H,aAAa,CAACvK;IAClB,IAAIA,UAAU,QAAQA,UAAU3B,WAAW,OAAO;IAClD,MAAMiJ,SAASkD,OAAOxK;IACtB,OAAOwK,OAAOC,QAAQ,CAACnD,UAAUoD,KAAKC,GAAG,CAAC,GAAGD,KAAKE,GAAG,CAAC,GAAGtD,WAAW;AACtE;AAEA,wGAAwG,GACxG,OAAO,SAASuD,oBAAoBC,MAAuC;IAIzE,MAAMC,SAAS;QAACD,0BAAAA,OAAQE,SAAS;QAAEF,0BAAAA,OAAQG,IAAI;QAAEH,0BAAAA,OAAQd,KAAK;KAAC,CAC5D3J,GAAG,CAACkK,YACJ5H,MAAM,CAAC,CAACuI,QAA2BA,UAAU;IAChD,IAAI,CAACH,OAAOnJ,MAAM,EAAE,OAAO;QAAEuJ,MAAM;QAAGrB,MAAM;IAAM;IAClD,MAAMqB,OAAOJ,OAAOK,MAAM,CAAC,CAACC,KAAKH,QAAUG,MAAMH,OAAO,KAAKH,OAAOnJ,MAAM;IAC1E,OAAO;QAAEuJ;QAAMrB,MAAMqB,QAAQxL,4BAA4B+K,KAAKC,GAAG,IAAII,WAAW;IAAE;AACpF;AAEA;;;;;CAKC,GACD,SAASO,YACP7K,QAAoB,EACpBO,MAAe,EACf0D,OAAuB,EACvB6G,MAAgC;IAEhC,IAAI,CAACA,UAAU,EAAC7G,2BAAAA,QAASpC,QAAQ,KAAI,CAACpE,4BAA4BuC,SAAStC,IAAI,GAAG,OAAO;IACzF,MAAMqN,QAAQD,OAAO9K,UAAUO;IAC/B,IAAI,CAACwK,OAAO,OAAO;QAAE1B,MAAM;QAAOrH,UAAU;YAAC;SAAoB;IAAC;IAClE,MAAMA,WAAW3F,sBAAsB0O;IACvC,OAAO;QAAE1B,MAAMrH,SAASb,MAAM,KAAK;QAAGa;IAAS;AACjD;AAEA,4CAA4C,GAC5C,OAAO,SAASgJ,qBACdhL,QAAoB,EACpBiL,SAA0B,EAC1BH,MAAqB;QAEPG;QAGDjL;IAHb,MAAMkL,SAAQD,mBAAAA,UAAUC,KAAK,YAAfD,mBAAmB;IACjC,MAAMhH,UAAUiH,UAAU,SAASlC,YAAYhJ,UAAUiL,UAAU1K,MAAM,EAAE0K,UAAUhL,IAAI,IAAI;IAC7F,MAAMkL,SAASN,YAAY7K,UAAUiL,UAAU1K,MAAM,EAAE0D,SAAS6G;IAChE,MAAM7K,OAAOD,EAAAA,qBAAAA,SAASoJ,QAAQ,qBAAjBpJ,mBAAmBC,IAAI,IAAGiJ,gBAAgBlJ,UAAUiL,UAAUhL,IAAI,IAAI;IACnF,MAAMoK,SAASD,oBAAoBa,UAAUZ,MAAM;IACnD,MAAMe,cAAc,AAACf,CAAAA,OAAOK,IAAI,GAAG,CAAA,IAAK;IACxC,MAAMW,QAAQ;WACRpH,UAAU;YAACA,QAAQpC,QAAQ,GAAG,IAAI;YAAGoC,QAAQnC,KAAK,GAAG,IAAI;YAAGmC,QAAQlC,MAAM,GAAG,IAAI;SAAE,GAAG,EAAE;WACxF9B,OAAO;YAACA,KAAKoJ,IAAI,GAAG,IAAI;SAAE,GAAG,EAAE;QACnC+B;KACD;IACD,MAAME,QAAQrB,KAAKsB,KAAK,CAAC,AAACF,MAAMV,MAAM,CAAC,CAACC,KAAKY,OAASZ,MAAMY,MAAM,KAAKH,MAAMlK,MAAM,GAAI,SAAU;IACjG,MAAMsK,iBAAiBxH,UAAUA,QAAQpC,QAAQ,IAAIoC,QAAQnC,KAAK,IAAImC,QAAQlC,MAAM,GAAG;IACvF,OAAO;QACL2J,QAAQ1L,SAAS6E,EAAE;QACnBnH,MAAMsC,SAAStC,IAAI;QACnBiO,QAAQV,UAAUU,MAAM;QACxBT;QACAU,OAAOX,UAAUW,KAAK;QACtBC,QAAQ;YACNhK,UAAUoC,UAAUA,QAAQpC,QAAQ,GAAG;YACvCC,OAAOmC,UAAUA,QAAQnC,KAAK,GAAG;YACjCC,QAAQkC,UAAUA,QAAQlC,MAAM,GAAG;YACnC9B,MAAMA,OAAOA,KAAKoJ,IAAI,GAAG;YACzByC,YAAYX,SAASA,OAAO9B,IAAI,GAAG;YACnCgB,QAAQA,OAAOhB,IAAI;QACrB;QACA+B,aAAanB,KAAKsB,KAAK,CAACH,cAAc,SAAU;QAChDE;QACA,sEAAsE;QACtEjC,MAAMoC,2BAAmBN,0BAAAA,OAAQ9B,IAAI,mBAAI,mBAAUpJ,wBAAAA,KAAMoJ,IAAI,oBAAI6B,UAAU,WAAWb,OAAOhB,IAAI;QACjGrH,UAAU;wBAAKiC,2BAAAA,QAASjC,QAAQ,oBAAI,EAAE;wBAAOmJ,0BAAAA,OAAQnJ,QAAQ,oBAAI,EAAE;wBAAO/B,wBAAAA,KAAM+B,QAAQ,oBAAI,EAAE;SAAE;IAClG;AACF;AAEA;;;CAGC,GACD,OAAO,SAAS+J,mBACd/L,QAAoB,EACpBgM,OAAsB,EACtBlB,MAAqB;QAGiCkB;QAAgBhM,uBAGtCA;IAJhC,4GAA4G;IAC5G,MAAMiE,UAAU+E,YAAYhJ,UAAUgM,QAAQzL,MAAM,GAAEyL,gBAAAA,QAAQ/L,IAAI,YAAZ+L,iBAAgBhM,wBAAAA,SAASiM,UAAU,CAAC,EAAE,qBAAtBjM,sBAAwBC,IAAI;IAClG,MAAMkL,SAASL,CAAAA,0BAAAA,OAAS9K,UAAUgM,QAAQzL,MAAM,KAAIsK,YAAY7K,UAAUgM,QAAQzL,MAAM,EAAE0D,SAAS6G,UAAU;IAC7G,MAAM7K,OACJ+L,QAAQ/L,IAAI,KAAKrC,eAAaoC,qBAAAA,SAASoJ,QAAQ,qBAAjBpJ,mBAAmBC,IAAI,IACjDiJ,gBAAgBlJ,UAAUgM,QAAQ/L,IAAI,IACtC;IACN,OAAO;WACDgE,QAAQpC,QAAQ,GAAG,EAAE,GAAI;YAAC;SAAW;WACrCoC,QAAQnC,KAAK,GAAG,EAAE,GAAI;YAAC;SAAQ;WAC/BmC,QAAQlC,MAAM,GAAG,EAAE,GAAI;YAAC;SAAS;WACjC9B,QAAQ,CAACA,KAAKoJ,IAAI,GAAI;YAAC;SAAO,GAAa,EAAE;WAC7C8B,UAAU,CAACA,OAAO9B,IAAI,GAAI;YAAC;SAAa,GAAa,EAAE;KAC5D;AACH;AAaA,mGAAmG,GACnG,OAAO,SAAS6C,gBAAgBC,MAA8B;IAC5D,OAAOnP,cAAc4C,GAAG,CAAC,CAAClC;QACxB,MAAMoF,MAAMqJ,OAAOjK,MAAM,CAAC,CAACoJ,QAAUA,MAAM5N,IAAI,KAAKA,QAAQ4N,MAAMJ,KAAK,KAAK;QAC5E,MAAMkB,SAAStJ,IAAIZ,MAAM,CAAC,CAACoJ,QAAUA,MAAMjC,IAAI,EAAElI,MAAM;QACvD,MAAM/C,WAAW0E,IAAI3B,MAAM,GAAGiL,SAAStJ,IAAI3B,MAAM,GAAG;QACpD,MAAM9C,YAAYyE,IAAI3B,MAAM,GACxB8I,KAAKsB,KAAK,CAAC,AAACzI,IAAI6H,MAAM,CAAC,CAACC,KAAKU,QAAUV,MAAMU,MAAMA,KAAK,EAAE,KAAKxI,IAAI3B,MAAM,GAAI,SAAU,QACvF;QACJ,MAAMkL,QAAQlO,cAAc,CAACT,KAAK;QAClC,OAAO;YACLA;YACAuO,YAAYnJ,IAAI3B,MAAM;YACtBiL;YACAhO;YACAC;YACAgO;YACAC,YACElO,aAAa,QACbC,cAAc,QACdD,WAAWiO,MAAMjO,QAAQ,IACzBC,YAAYgO,MAAMhO,SAAS;QAC/B;IACF;AACF;AASA;;;CAGC,GACD,OAAO,SAASkO,qBAAqBJ,MAA8B;IACjE,MAAMK,QAAQL,OAAOjK,MAAM,CAAC,CAACoJ,QAAUA,MAAMO,MAAM,CAAC5L,IAAI,KAAK;IAC7D,MAAMmM,SAASI,MAAMtK,MAAM,CAAC,CAACoJ,QAAUA,MAAMO,MAAM,CAAC5L,IAAI,IAAIqL,MAAMO,MAAM,CAACxB,MAAM,EAAElJ,MAAM;IACvF,OAAO;QAAEqL,OAAOA,MAAMrL,MAAM;QAAEiL;QAAQhO,UAAUoO,MAAMrL,MAAM,GAAGiL,SAASI,MAAMrL,MAAM,GAAG;IAAK;AAC9F;AAQA,mFAAmF,GACnF,OAAO,SAASsL,oBAAoBC,GAAY,EAAEC,IAAY;IAC5D,IAAI,CAACrN,SAASoN,QAAQ,OAAOA,GAAG,CAAC,SAAS,KAAK,YAAY,CAACpN,SAASoN,GAAG,CAAC,YAAY,GAAG;QACtF,MAAM,IAAIE,MAAM,GAAGD,KAAK,4CAA4C,CAAC;IACvE;IACA,MAAM1B,YAAYyB,GAAG,CAAC,YAAY;IAClC,kEAAkE;IAClE,0EAA0E;IAC1E,4BAA4B;IAC5B,IAAIzB,SAAS,CAAC,SAAS,KAAK,cAAc,CAAE3L,CAAAA,SAAS2L,SAAS,CAAC,SAAS,KAAKA,SAAS,CAAC,SAAS,KAAK,IAAG,GAAI;QAC1G,MAAM,IAAI2B,MAAM,GAAGD,KAAK,wEAAwE,CAAC;IACnG;IACA,OAAOD;AACT;AAEA,6EAA6E;AAE7E,8EAA8E,GAC9E,OAAO,SAASG,eAAeH,GAAY,EAAEC,IAAY;IACvD,MAAMG,OAAO,CAACC;QACZ,MAAM,IAAIH,MAAM,GAAGD,KAAK,EAAE,EAAEI,KAAK;IACnC;IACA,IAAI,CAACzN,SAASoN,MAAM,OAAOI,KAAK;IAChC,MAAMpP,OAAOgP,GAAG,CAAC,OAAO;IACxB,IAAI,OAAOA,GAAG,CAAC,KAAK,KAAK,YAAY,CAACA,GAAG,CAAC,KAAK,EAAEI,KAAK;IACtD,IAAI,OAAOpP,SAAS,YAAY,CAAC,AAACV,cAAoCqJ,QAAQ,CAAC3I,OAAO;QACpFoP,KAAK,CAAC,MAAM,EAAE5G,OAAOxI,MAAM,gBAAgB,EAAEV,cAAc8K,IAAI,CAAC,OAAO;IACzE;IACA,IAAI,OAAO4E,GAAG,CAAC,QAAQ,KAAK,YAAY,CAACA,GAAG,CAAC,QAAQ,CAACjK,IAAI,IAAIqK,KAAK;IACnE,IAAIJ,GAAG,CAAC,WAAW,KAAK9O,aAAc,CAAA,OAAO8O,GAAG,CAAC,WAAW,KAAK,YAAY,CAACA,GAAG,CAAC,WAAW,CAACjK,IAAI,EAAC,GAAI;QACrGqK,KAAK;IACP;IACA,MAAME,aAAaN,GAAG,CAAC,aAAa;IACpC,IAAIM,eAAepP,WAAW;QAC5B,MAAM+I,SAASrH,SAAS0N,cAAcA,UAAU,CAAC,SAAS,GAAGpP;QAC7D,MAAMqP,UAAU3N,SAASqH,UAAU3M,mBAAmB2M,UAAmC;QACzF,IAAIsG,SAASH,KAAK,CAAC,kEAAkE,EAAEG,SAAS;QAChG,IAAI3N,SAAS0N,eAAeA,UAAU,CAAC,MAAM,KAAKpP,aAAa,CAAC0B,SAAS0N,UAAU,CAAC,MAAM,GAAG;YAC3FF,KAAK;QACP;IACF;IACA,MAAMI,QAAQR,GAAG,CAAC,QAAQ;IAC1B,IAAIQ,UAAUtP,WAAW;QACvB,IAAI,CAAC0B,SAAS4N,UAAU,CAACC,OAAOC,IAAI,CAACF,OAAO/L,MAAM,EAAE2L,KAAK;QACzD,KAAK,MAAM,CAACO,SAASV,KAAK,IAAIQ,OAAOG,OAAO,CAACJ,OAAmC;YAC9E,IAAI,OAAOP,SAAS,YAAY,CAACzO,mBAAmB8E,IAAI,CAAC2J,OAAO;gBAC9DG,KAAK,CAAC,MAAM,EAAEO,QAAQ,qDAAqD,CAAC;YAC9E;QACF;IACF;IACA,MAAMpB,aAAaS,GAAG,CAAC,aAAa;IACpC,MAAMa,WAAWb,GAAG,CAAC,WAAW;IAChC,IAAI,CAAClN,MAAMC,OAAO,CAACwM,eAAe,CAACA,WAAW9K,MAAM,EAAE2L,KAAK;IAC3D,IAAI,CAACtN,MAAMC,OAAO,CAAC8N,aAAa,CAACA,SAASpM,MAAM,EAAE2L,KAAK;IACvD,KAAK,MAAM,CAAC1G,OAAO6E,UAAU,IAAI,AAACgB,WAAyBqB,OAAO,GAAI;QACpE,IAAI,CAAChO,SAAS2L,YAAY6B,KAAK,CAAC,WAAW,EAAE1G,MAAM,kBAAkB,CAAC;QACtE,MAAMuF,SAAS,AAACV,SAAqC,CAAC,SAAS;QAC/D,IAAIU,WAAW,cAAcA,WAAW,YAAY;YAClDmB,KAAK,CAAC,WAAW,EAAE1G,MAAM,yCAAyC,CAAC;QACrE;QACA,IAAI,CAAC9G,SAAS,AAAC2L,SAAqC,CAAC,SAAS,GAAG;YAC/D6B,KAAK,CAAC,WAAW,EAAE1G,MAAM,eAAe,CAAC;QAC3C;IACF;IACA,KAAK,MAAM,CAACA,OAAO4F,QAAQ,IAAI,AAACuB,SAAuBD,OAAO,GAAI;QAChE,MAAME,QAAQlO,SAAS0M,WAAWA,OAAO,CAAC,QAAQ,GAAGpO;QACrD,IAAI,CAAC4B,MAAMC,OAAO,CAAC+N,UAAU,CAACA,MAAMrM,MAAM,EAAE2L,KAAK,CAAC,SAAS,EAAE1G,MAAM,yBAAyB,CAAC;IAC/F;IACA,MAAM3F,eACJiM,GAAG,CAAC,eAAe,KAAK9O,YAAYA,YAAY6P,uBAAuBf,GAAG,CAAC,eAAe,EAAEI;IAC9F,OAAO;QACL7L,SAAS;QACTF,WAAW;OACP2L,KACAjM,eAAe;QAAEA;IAAa,IAAI,CAAC;AAE3C;AAEA;;;;;CAKC,GACD,SAASgN,uBAAuBf,GAAY,EAAEI,IAA4B;IACxE,IAAI,CAACxN,SAASoN,QAAQ,OAAOA,GAAG,CAAC,qBAAqB,KAAK,WAAW;QACpE,OAAOI,KAAK;IACd;IACA,MAAMlD,SAAStK,SAASoN,GAAG,CAAC,SAAS,IAAIA,GAAG,CAAC,SAAS,GAAG,CAAC;IAC1D,MAAMgB,eAAetT;IACrB,MAAMkT,UAA0DnT,2BAA2ByF,GAAG,CAAC,CAAClC;QAC9F,MAAM8L,QAAQI,MAAM,CAAClM,KAAK;QAC1B,IAAI8L,UAAU5L,WAAW,OAAO;YAACF;YAAMgQ,aAAa9D,MAAM,CAAClM,KAAK;SAAC;QACjE,IAAI,CAAC4B,SAASkK,UAAU,OAAOA,KAAK,CAAC,UAAU,KAAK,WAAW;YAC7D,OAAOsD,KAAK,CAAC,oBAAoB,EAAEpP,KAAK,6BAA6B,CAAC;QACxE;QACA,MAAMiQ,OAAOnE,KAAK,CAAC,OAAO;QAC1B,MAAM3D,SAAS2D,KAAK,CAAC,SAAS;QAC9B,OAAO;YACL9L;YACA;gBACE8F,SAASgG,KAAK,CAAC,UAAU;gBACzBmE,MAAM,OAAOA,SAAS,WAAWA,OAAO;gBACxC9H,QAAQ,OAAOA,WAAW,WAAWA,SAAS;YAChD;SACD;IACH;IACA,KAAK,MAAMnI,QAAQyP,OAAOC,IAAI,CAACxD,QAAS;QACtC,IAAI,CAAC,AAACzP,2BAAiDkM,QAAQ,CAAC3I,OAAO;YACrEoP,KAAK,CAAC,oBAAoB,EAAEpP,KAAK,uBAAuB,CAAC;QAC3D;IACF;IACA,IAAIgP,GAAG,CAAC,YAAY,KAAK9O,aAAa,OAAO8O,GAAG,CAAC,YAAY,KAAK,WAAW;QAC3E,OAAOI,KAAK;IACd;IACA,OAAO;QACLpM,oBAAoBgM,GAAG,CAAC,qBAAqB;QAC7C9C,QAAQuD,OAAOS,WAAW,CAACN;OACvBZ,GAAG,CAAC,YAAY,KAAK,OAAO;QAAEmB,WAAW;IAAK,IAAI,CAAC;AAE3D"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { DecodedIdToken } from 'firebase-admin/auth';
18
+ import { type LockdownFeatureKey, type ReleaseFlagKey } from '@aglyn/aglyn/server';
19
+ import type { AglynOrganization } from '@aglyn/aglyn/foundation/definitions/organization.types';
20
+ import type { OrgFeatureFlags } from '@aglyn/aglyn/foundation/definitions/org-billing.types';
21
+ import { type RateLimitResult } from '@aglyn/tenant-data-admin/server/api-http';
22
+ import { type AssistReservation } from '../usage/assist-usage';
23
+ /**
24
+ * The gate ladder every AI door climbs before it spends a token (AGL-2903).
25
+ *
26
+ * The rungs, in order — each one a refusal the door sends as is, and each
27
+ * composed from the helper the existing doors already call rather than a
28
+ * second implementation of it:
29
+ *
30
+ * 405 not POST
31
+ * 401 no bearer token, or a token the verifier refused
32
+ * 403 email unverified (an impersonation session is exempt)
33
+ * 400 the body did not NAME the org it is metered against (AGL-1934)
34
+ * 403 the caller is not a member of that org
35
+ * 403 the member's role lacks the door's AI permission (AGL-2927) — only
36
+ * when the door names one; a verified staff claim passes, as it does
37
+ * at every other org route
38
+ * 404 the release flag is off — a released-off feature does not exist;
39
+ * a verified staff claim previews through it
40
+ * 403 the org's plan lacks the entitlement — a plan-less org resolves as
41
+ * free, which is a real answer, never a loading default
42
+ * 423 lockdown: the scope verdict (platform/org/user) and then the
43
+ * feature kill switch, with its per-feature staff bypass
44
+ * 429 the per-uid rate limit, which fails SOFT: it is a per-instance
45
+ * window that smooths bursts and is not the spend bound
46
+ * 429 the per-address rate limit (AGL-2925), the same window keyed on
47
+ * the trusted-hop client address, so a farm rotating accounts
48
+ * behind one address meets one budget; skipped when no address is
49
+ * readable
50
+ * 403 account age (AGL-2925): a Free workspace's caller must hold an
51
+ * account older than `AI_FREE_MIN_ACCOUNT_AGE_HOURS`; paid
52
+ * workspaces and staff never consult it, and a record that cannot
53
+ * be read is a 503 rather than an admission
54
+ * --- the reservation, which fails CLOSED: it is the only global, atomic
55
+ * bound on provider spend, so a reservation that cannot be taken
56
+ * refuses with 503 rather than calling the provider uncapped. On a
57
+ * Free workspace it also decides the taste's own rungs — the
58
+ * account's daily requests, its refusal pause, its monthly
59
+ * allowance across every workspace it owns, and the platform-wide
60
+ * daily ceiling — inside the same transaction
61
+ * 429 a hard AI allotment (AGL-2942) — the caller's, the caller's on the
62
+ * named site, or the site's — decided inside the same transaction
63
+ * once the workspace's own ceilings admitted the request, so it sits
64
+ * inside the band and never admits what the band refused
65
+ *
66
+ * A door that gets a context back has a reservation in hand and owes the
67
+ * meter a record — or `releaseAssistMessage` if the provider was never
68
+ * reached. What differs between doors is parameters: which entitlement,
69
+ * which flag, which lockdown key, which rate window.
70
+ *
71
+ * The console chat route keeps its own copy of these rungs rather than
72
+ * calling this: its retrieval-first design (AGL-2486) answers from the
73
+ * docs BETWEEN the rate limit and the reservation, so its ladder is not a
74
+ * prefix of this one, and it resolves the entitlement after the rate limit
75
+ * because a free workspace is admitted in limited mode rather than refused.
76
+ * The copy assistant differs the same way at the entitlement and carries no
77
+ * flag by design. Both are documented at the route.
78
+ */
79
+ export interface AiGateConfig {
80
+ /** The plan entitlement the door sells under (`checkEntitlement`). */
81
+ feature: keyof OrgFeatureFlags;
82
+ /** The release flag that makes the door exist. */
83
+ releaseFlag: ReleaseFlagKey;
84
+ /** The feature kill switch on the staff lockdown page. */
85
+ lockdownFeature: LockdownFeatureKey;
86
+ /**
87
+ * The org permission the door sells under (AGL-2927): `ai.use` for the
88
+ * assistants, `ai.generate` for a generation job. Resolved by
89
+ * `memberHasPermissionOnHost` on the org axis or, for a site collaborator, on
90
+ * the host the body named (`AiGateInput.hostId`). Omitted, the rung is
91
+ * skipped — which is the right reading for a door that has not decided
92
+ * which key it sells under, and the wrong one for any door a customer
93
+ * can reach, so every shipped door names one.
94
+ */
95
+ permission?: 'ai.use' | 'ai.generate';
96
+ rateLimit: {
97
+ /** Prefix of the per-uid key, so two doors do not share one window. */
98
+ key: string;
99
+ limit: number;
100
+ windowMs: number;
101
+ };
102
+ }
103
+ export interface AiGateInput {
104
+ request: Request;
105
+ /** The org the parsed body named; empty when it named none. */
106
+ orgId: string;
107
+ /**
108
+ * The site the parsed body named, when it named one. A collaborator's
109
+ * permission is decided on this site; an org-wide member's is the same
110
+ * everywhere, so a door on an org-level surface may leave it empty.
111
+ */
112
+ hostId?: string | null;
113
+ now?: Date;
114
+ }
115
+ /** Everything a door needs after the ladder admitted the request. */
116
+ export interface AiGateContext {
117
+ uid: string;
118
+ decoded: DecodedIdToken;
119
+ staff: boolean;
120
+ orgId: string;
121
+ org: Partial<AglynOrganization>;
122
+ firestore: FirebaseFirestore.Firestore;
123
+ rate: RateLimitResult;
124
+ reservation: AssistReservation;
125
+ }
126
+ /**
127
+ * Climb the ladder. Resolves to the `Response` to send when a rung
128
+ * refuses, or to the resolved context when every rung admitted the request.
129
+ */
130
+ export declare function aiGateLadder(input: AiGateInput, config: AiGateConfig): Promise<Response | AiGateContext>;
@@ -0,0 +1,272 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { checkEntitlement } from "@aglyn/aglyn/server";
17
+ import { assistFreeTasteRefusalText, assistHardCapRefusalText, assistRefusedByHardCap } from "@aglyn/aglyn/app-utils/assist-credits";
18
+ import { checkAiClientIpRateLimit, freeAccountAgeRefusal } from "./ai-abuse-guards.js";
19
+ import { checkRateLimit, rateLimitHeaders } from "@aglyn/tenant-data-admin/server/api-http";
20
+ import { aiOverageReservationRefusal } from "../billing/ai-overage-gate.js";
21
+ import { recordUserAiRefusal } from "../usage/ai-usage-by-user.js";
22
+ import { authForPool } from "@aglyn/tenant-data-admin/server/auth-pools";
23
+ import { publicAssistQuota, reserveAssistMessage } from "../usage/assist-usage.js";
24
+ import { aiAllotmentRefusalText } from "../model/ai-allotments.js";
25
+ import { aiUsageMeter } from "../usage/ai-usage-meter.js";
26
+ import { emailUnverifiedResponse, firebaseAdmin, isImpersonationSession } from "@aglyn/tenant-data-admin/server/firebase-admin";
27
+ import { isRefusedIdToken } from "@aglyn/tenant-data-admin/server/id-token-refusal";
28
+ import { featureLockdownRefusal, lockdownRefusal } from "@aglyn/tenant-data-admin/server/lockdown";
29
+ import { permissionRefusal, getOrgForUser, memberHasPermissionOnHost } from "@aglyn/tenant-data-admin/server/organizations";
30
+ import { isServerReleaseFlagOnForOrg } from "@aglyn/tenant-data-admin/server/release-flags";
31
+ function bearerToken(request) {
32
+ var _request_headers_get;
33
+ const authorization = (_request_headers_get = request.headers.get('authorization')) != null ? _request_headers_get : '';
34
+ return authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : undefined;
35
+ }
36
+ /**
37
+ * Climb the ladder. Resolves to the `Response` to send when a rung
38
+ * refuses, or to the resolved context when every rung admitted the request.
39
+ */ export async function aiGateLadder(input, config) {
40
+ var _resolved_org;
41
+ const { request } = input;
42
+ if (request.method !== 'POST') {
43
+ return Response.json({
44
+ error: 'Method not allowed'
45
+ }, {
46
+ status: 405
47
+ });
48
+ }
49
+ const idToken = bearerToken(request);
50
+ if (!idToken) {
51
+ return Response.json({
52
+ error: 'Unauthenticated'
53
+ }, {
54
+ status: 401
55
+ });
56
+ }
57
+ const app = firebaseAdmin.app();
58
+ let decoded;
59
+ try {
60
+ decoded = await app.auth().verifyIdToken(idToken);
61
+ } catch (error) {
62
+ // A refused credential is the caller's fault and a 401; anything else
63
+ // — the verifier's own key endpoint unreachable — is ours, and it
64
+ // propagates so the door answers 500 rather than telling every user
65
+ // their credential is bad during an outage (AGL-1993).
66
+ if (isRefusedIdToken(error)) {
67
+ return Response.json({
68
+ error: 'Unauthenticated'
69
+ }, {
70
+ status: 401
71
+ });
72
+ }
73
+ throw error;
74
+ }
75
+ if (!decoded.email_verified && !isImpersonationSession(decoded)) {
76
+ return emailUnverifiedResponse();
77
+ }
78
+ const staff = decoded['staff'] === true;
79
+ const orgId = input.orgId.trim();
80
+ if (!orgId) {
81
+ return Response.json({
82
+ error: 'Open a workspace before using this feature'
83
+ }, {
84
+ status: 400
85
+ });
86
+ }
87
+ // Scoped to the NAMED org: membership of some other paid org is not a key
88
+ // to this one, and the org this returns is the one every later rung and
89
+ // the meter read.
90
+ const resolved = await getOrgForUser(decoded.uid, orgId);
91
+ if (!resolved || resolved.orgId !== orgId) {
92
+ return Response.json({
93
+ error: 'You are not a member of that organization'
94
+ }, {
95
+ status: 403
96
+ });
97
+ }
98
+ const org = (_resolved_org = resolved.org) != null ? _resolved_org : {};
99
+ // Permission (AGL-2927), directly after membership: it is a fact about
100
+ // the CALLER, so it is answered before anything about the workspace —
101
+ // the plan, the lockdown state, the quota — is disclosed. Staff pass, as
102
+ // they do at every other org route.
103
+ if (config.permission && !staff && !await memberHasPermissionOnHost(orgId, input.hostId, resolved.member, config.permission)) {
104
+ return permissionRefusal(config.permission);
105
+ }
106
+ // The flag closes the ROUTE, not just the UI (AGL-1653): a released-off
107
+ // feature does not exist, so nothing below this line — not the plan, not
108
+ // the lockdown state — is disclosed while it is off.
109
+ if (!staff && !await isServerReleaseFlagOnForOrg(config.releaseFlag, orgId)) {
110
+ return Response.json({
111
+ error: 'Not found'
112
+ }, {
113
+ status: 404
114
+ });
115
+ }
116
+ if (!checkEntitlement(org, config.feature)) {
117
+ return Response.json({
118
+ error: "This workspace's plan does not include that feature",
119
+ reason: 'entitlement'
120
+ }, {
121
+ status: 403
122
+ });
123
+ }
124
+ const locked = await lockdownRefusal({
125
+ request,
126
+ staff,
127
+ uid: decoded.uid,
128
+ org: org
129
+ });
130
+ if (locked) return locked;
131
+ const featureLocked = await featureLockdownRefusal({
132
+ feature: config.lockdownFeature,
133
+ staff,
134
+ // The workspace-scoped pause on the same key (AGL-2927): the staff org
135
+ // page's spend stop, which leaves the entitlement in place.
136
+ orgId
137
+ });
138
+ if (featureLocked) return featureLocked;
139
+ const rate = checkRateLimit(`${config.rateLimit.key}:${decoded.uid}`, {
140
+ limit: config.rateLimit.limit,
141
+ windowMs: config.rateLimit.windowMs
142
+ });
143
+ if (!rate.allowed) {
144
+ return Response.json({
145
+ error: 'Too many requests — slow down a moment',
146
+ reason: 'rate'
147
+ }, {
148
+ status: 429,
149
+ headers: rateLimitHeaders(rate)
150
+ });
151
+ }
152
+ // The same window keyed on the address (AGL-2925): a farm rotating
153
+ // fresh accounts behind one NAT meets one budget rather than one per
154
+ // account. Answered with the same status and reason so the panel's
155
+ // handling is unchanged.
156
+ const ipRate = checkAiClientIpRateLimit(request.headers);
157
+ if (ipRate && !ipRate.allowed) {
158
+ return Response.json({
159
+ error: 'Too many requests — slow down a moment',
160
+ reason: 'rate'
161
+ }, {
162
+ status: 429,
163
+ headers: rateLimitHeaders(ipRate)
164
+ });
165
+ }
166
+ // A Free workspace's caller must have held an account for a day
167
+ // (AGL-2925). Read from the pool the token was minted in — a tenant
168
+ // user's record is not in the project pool — and after the rate limits,
169
+ // so a burst cannot turn one cached read into many.
170
+ const tooYoung = await freeAccountAgeRefusal({
171
+ uid: decoded.uid,
172
+ org,
173
+ staff,
174
+ getUser: (uid)=>{
175
+ var _decoded_firebase;
176
+ return authForPool((_decoded_firebase = decoded.firebase) == null ? void 0 : _decoded_firebase.tenant).getUser(uid);
177
+ },
178
+ now: input.now
179
+ });
180
+ if (tooYoung) return tooYoung;
181
+ // RESERVED, not merely checked (AGL-2057/2073): read-and-increment in one
182
+ // transaction BEFORE a token is spent, so N concurrent requests cannot all
183
+ // read "under the cap", and a caller that hangs up has been counted. The
184
+ // org document is passed so the plan's own band binds, not only the
185
+ // operator backstop.
186
+ const firestore = app.firestore();
187
+ let reservation;
188
+ try {
189
+ var _input_now, _input_hostId;
190
+ reservation = await reserveAssistMessage(firestore, orgId, true, (_input_now = input.now) != null ? _input_now : new Date(), org, // Who is asking and on which site, for the allotments that apply.
191
+ {
192
+ uid: decoded.uid,
193
+ hostId: (_input_hostId = input.hostId) != null ? _input_hostId : null
194
+ });
195
+ } catch (error) {
196
+ console.error('ai reservation failed', error);
197
+ return Response.json({
198
+ error: 'This feature is temporarily unavailable'
199
+ }, {
200
+ status: 503
201
+ });
202
+ }
203
+ // A refusal is the caller's as well as the workspace's (AGL-2928): the
204
+ // per-person month counts it beside the org counter the reservation moved.
205
+ recordUserAiRefusal(firestore, orgId, decoded.uid, reservation);
206
+ if (!reservation.allowed) {
207
+ var // sentences: each names a clock or an upgrade, never a figure.
208
+ _assistFreeTasteRefusalText;
209
+ const refusedBy = reservation.refusedBy;
210
+ // The usage strip's envelope (AGL-2942), on the refusal as on an answer,
211
+ // so the strip shows why the request stopped without a read of its own.
212
+ const meter = aiUsageMeter(reservation);
213
+ // A hard allotment is a monthly line a manager drew inside the band: a
214
+ // 429 like the message cap, because it resets on the calendar, with the
215
+ // sentence naming who can raise it.
216
+ if (refusedBy === 'allotment') {
217
+ var _reservation_allotment_refusal, _reservation_allotment;
218
+ return Response.json({
219
+ error: aiAllotmentRefusalText((_reservation_allotment = reservation.allotment) == null ? void 0 : (_reservation_allotment_refusal = _reservation_allotment.refusal) == null ? void 0 : _reservation_allotment_refusal.scope),
220
+ reason: 'quota',
221
+ refusedBy,
222
+ quota: publicAssistQuota(reservation),
223
+ meter
224
+ }, {
225
+ status: 429
226
+ });
227
+ }
228
+ // AGLYN'S OWN OVERAGE GUARDS (AGL-3011), before the workspace's own
229
+ // controls because they are the narrower answer: a refusal here already
230
+ // knows WHICH limit stopped the request and whether the workspace can do
231
+ // anything about it. Everything else falls through unchanged.
232
+ const overage = aiOverageReservationRefusal(reservation);
233
+ if (overage) {
234
+ return Response.json({
235
+ error: overage.text,
236
+ reason: 'quota',
237
+ refusedBy,
238
+ quota: publicAssistQuota(reservation),
239
+ meter
240
+ }, {
241
+ status: overage.status
242
+ });
243
+ }
244
+ // The org's own wall is a 402 (AGL-2653): credits past the band are for
245
+ // sale and this workspace switched the sale off, so the sentence names
246
+ // the switch. A spend ceiling and a message cap keep the 429, and are
247
+ // told apart in words because one resets on a clock and one does not.
248
+ const hardCapped = assistRefusedByHardCap(org, refusedBy);
249
+ return Response.json({
250
+ error: hardCapped ? assistHardCapRefusalText(org) : (_assistFreeTasteRefusalText = assistFreeTasteRefusalText(refusedBy)) != null ? _assistFreeTasteRefusalText : refusedBy === 'budget' || refusedBy === 'band' ? reservation.budgetUsd === null ? 'This workspace reached its AI spending limit for the month' : 'This workspace used its AI credits for the month' : 'This workspace reached its AI limit for the month',
251
+ reason: 'quota',
252
+ // CREDITS, never the reservation itself — its figures are our
253
+ // provider bill and do not leave the server.
254
+ quota: publicAssistQuota(reservation),
255
+ meter
256
+ }, {
257
+ status: hardCapped ? 402 : 429
258
+ });
259
+ }
260
+ return {
261
+ uid: decoded.uid,
262
+ decoded,
263
+ staff,
264
+ orgId,
265
+ org,
266
+ firestore,
267
+ rate,
268
+ reservation
269
+ };
270
+ }
271
+
272
+ //# sourceMappingURL=ai-gate.js.map