@exponential-at/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +54 -0
  3. package/README.md +360 -2
  4. package/catalog/a11y.json +668 -0
  5. package/catalog/basic-map.json +104 -0
  6. package/catalog/code.json +58 -0
  7. package/catalog/core.catalog.json +4752 -0
  8. package/catalog/core.schema.json +22667 -0
  9. package/catalog/host.json +64 -0
  10. package/catalog/layout.json +20 -0
  11. package/catalog/limits.json +9 -0
  12. package/catalog/locale.json +48 -0
  13. package/catalog/macros.json +3417 -0
  14. package/catalog/recipes.json +61 -0
  15. package/catalog/strings.json +72 -0
  16. package/catalog/style.json +128 -0
  17. package/catalog/theme.schema.json +42543 -0
  18. package/catalog/tokens.json +47 -0
  19. package/conformance/README.md +217 -0
  20. package/conformance/baseline.ts +101 -0
  21. package/conformance/browser-page.ts +146 -0
  22. package/conformance/browser-suites.ts +683 -0
  23. package/conformance/compare.ts +201 -0
  24. package/conformance/dom.ts +96 -0
  25. package/conformance/dump.ts +163 -0
  26. package/conformance/fonts.json +154 -0
  27. package/conformance/manifest.json +224 -0
  28. package/conformance/parity-compare.ts +191 -0
  29. package/conformance/parity-report.schema.json +73 -0
  30. package/conformance/parity.ts +412 -0
  31. package/conformance/pixel.ts +177 -0
  32. package/conformance/primitives-page.ts +49 -0
  33. package/conformance/report.schema.json +66 -0
  34. package/conformance/run.ts +118 -0
  35. package/dist/chunks/index-98npjvsd.js +3940 -0
  36. package/dist/chunks/index-98npjvsd.js.map +27 -0
  37. package/dist/chunks/index-gwkt14w3.js +7314 -0
  38. package/dist/chunks/index-gwkt14w3.js.map +10 -0
  39. package/dist/chunks/index-njt7yzzm.js +134 -0
  40. package/dist/chunks/index-njt7yzzm.js.map +9 -0
  41. package/dist/chunks/index-we7va6v6.js +7984 -0
  42. package/dist/chunks/index-we7va6v6.js.map +15 -0
  43. package/dist/chunks/index-xrm6f7wc.js +2563 -0
  44. package/dist/chunks/index-xrm6f7wc.js.map +10 -0
  45. package/dist/conformance.js +182749 -0
  46. package/dist/conformance.js.map +10 -0
  47. package/dist/entries/prompt.js +251 -0
  48. package/dist/entries/prompt.js.map +11 -0
  49. package/dist/entries/schema.js +1725 -0
  50. package/dist/entries/schema.js.map +11 -0
  51. package/dist/host/index.js +122 -0
  52. package/dist/host/index.js.map +9 -0
  53. package/dist/index.js +3213 -0
  54. package/dist/index.js.map +27 -0
  55. package/dist/types/src/a11y.d.ts +21 -0
  56. package/dist/types/src/animation.d.ts +76 -0
  57. package/dist/types/src/basic-map.d.ts +38 -0
  58. package/dist/types/src/builder.d.ts +50 -0
  59. package/dist/types/src/catalog.d.ts +54 -0
  60. package/dist/types/src/catalog.described.d.ts +33 -0
  61. package/dist/types/src/catalog.generated.d.ts +829 -0
  62. package/dist/types/src/chart.d.ts +46 -0
  63. package/dist/types/src/code.d.ts +44 -0
  64. package/dist/types/src/color.d.ts +20 -0
  65. package/dist/types/src/conformance.d.ts +39 -0
  66. package/dist/types/src/connector/app.d.ts +14 -0
  67. package/dist/types/src/connector/connector.d.ts +77 -0
  68. package/dist/types/src/connector/index.d.ts +4 -0
  69. package/dist/types/src/css.d.ts +29 -0
  70. package/dist/types/src/define.d.ts +66 -0
  71. package/dist/types/src/direction.d.ts +16 -0
  72. package/dist/types/src/dynamic.d.ts +159 -0
  73. package/dist/types/src/entries/prompt.d.ts +11 -0
  74. package/dist/types/src/entries/schema.d.ts +8 -0
  75. package/dist/types/src/expr.d.ts +71 -0
  76. package/dist/types/src/extension.d.ts +4 -0
  77. package/dist/types/src/format.d.ts +112 -0
  78. package/dist/types/src/geometry.d.ts +40 -0
  79. package/dist/types/src/host/contract.d.ts +188 -0
  80. package/dist/types/src/host/decoders.d.ts +61 -0
  81. package/dist/types/src/host/index.d.ts +11 -0
  82. package/dist/types/src/host/package.d.ts +58 -0
  83. package/dist/types/src/host/policy.d.ts +105 -0
  84. package/dist/types/src/host/router.d.ts +34 -0
  85. package/dist/types/src/host/runtime.d.ts +205 -0
  86. package/dist/types/src/host/sources.d.ts +15 -0
  87. package/dist/types/src/host/transports.d.ts +109 -0
  88. package/dist/types/src/index.d.ts +63 -0
  89. package/dist/types/src/layout.d.ts +20 -0
  90. package/dist/types/src/limits.d.ts +21 -0
  91. package/dist/types/src/list.d.ts +133 -0
  92. package/dist/types/src/locale.d.ts +22 -0
  93. package/dist/types/src/macros.d.ts +29 -0
  94. package/dist/types/src/overlay.d.ts +27 -0
  95. package/dist/types/src/prompt.d.ts +44 -0
  96. package/dist/types/src/recipes.d.ts +17 -0
  97. package/dist/types/src/reducer.d.ts +41 -0
  98. package/dist/types/src/resizable.d.ts +38 -0
  99. package/dist/types/src/schema.d.ts +7 -0
  100. package/dist/types/src/strings.d.ts +13 -0
  101. package/dist/types/src/style.d.ts +201 -0
  102. package/dist/types/src/test-preload.d.ts +1 -0
  103. package/dist/types/src/text-shimmer.d.ts +24 -0
  104. package/dist/types/src/theme-types.d.ts +162 -0
  105. package/dist/types/src/theme.d.ts +73 -0
  106. package/dist/types/src/themes.d.ts +22 -0
  107. package/dist/types/src/tree-guides.d.ts +17 -0
  108. package/dist/types/src/types.d.ts +314 -0
  109. package/dist/types/src/validate.d.ts +31 -0
  110. package/dist/types/src/web/base-css.d.ts +1 -0
  111. package/dist/types/src/web/box-css.d.ts +55 -0
  112. package/dist/types/src/web/coerce.d.ts +32 -0
  113. package/dist/types/src/web/data.d.ts +105 -0
  114. package/dist/types/src/web/dates.d.ts +12 -0
  115. package/dist/types/src/web/form.d.ts +44 -0
  116. package/dist/types/src/web/host-types.d.ts +119 -0
  117. package/dist/types/src/web/index.d.ts +28 -0
  118. package/dist/types/src/web/inputs.d.ts +55 -0
  119. package/dist/types/src/web/list.d.ts +13 -0
  120. package/dist/types/src/web/listbox.d.ts +14 -0
  121. package/dist/types/src/web/markdown.d.ts +96 -0
  122. package/dist/types/src/web/media.d.ts +62 -0
  123. package/dist/types/src/web/parts.d.ts +4 -0
  124. package/dist/types/src/web/primitives/alert-dialog.d.ts +10 -0
  125. package/dist/types/src/web/primitives/alert.d.ts +9 -0
  126. package/dist/types/src/web/primitives/avatar-color.d.ts +2 -0
  127. package/dist/types/src/web/primitives/avatar.d.ts +13 -0
  128. package/dist/types/src/web/primitives/badge.d.ts +10 -0
  129. package/dist/types/src/web/primitives/breadcrumb.d.ts +10 -0
  130. package/dist/types/src/web/primitives/button.d.ts +6 -0
  131. package/dist/types/src/web/primitives/calendar.d.ts +43 -0
  132. package/dist/types/src/web/primitives/card.d.ts +9 -0
  133. package/dist/types/src/web/primitives/checkbox.d.ts +5 -0
  134. package/dist/types/src/web/primitives/choice-tiles.d.ts +32 -0
  135. package/dist/types/src/web/primitives/cn.d.ts +3 -0
  136. package/dist/types/src/web/primitives/code-block.d.ts +24 -0
  137. package/dist/types/src/web/primitives/command.d.ts +134 -0
  138. package/dist/types/src/web/primitives/context-ring.d.ts +24 -0
  139. package/dist/types/src/web/primitives/dialog-arms.d.ts +6 -0
  140. package/dist/types/src/web/primitives/dialog.d.ts +24 -0
  141. package/dist/types/src/web/primitives/disclosure-header.d.ts +5 -0
  142. package/dist/types/src/web/primitives/dock.d.ts +42 -0
  143. package/dist/types/src/web/primitives/dropdown-menu.d.ts +14 -0
  144. package/dist/types/src/web/primitives/empty-state.d.ts +15 -0
  145. package/dist/types/src/web/primitives/glass-card.d.ts +4 -0
  146. package/dist/types/src/web/primitives/hover-card.d.ts +7 -0
  147. package/dist/types/src/web/primitives/icon-disc.d.ts +12 -0
  148. package/dist/types/src/web/primitives/index.d.ts +48 -0
  149. package/dist/types/src/web/primitives/input.d.ts +5 -0
  150. package/dist/types/src/web/primitives/kbd.d.ts +4 -0
  151. package/dist/types/src/web/primitives/label.d.ts +3 -0
  152. package/dist/types/src/web/primitives/menu-surface.d.ts +17 -0
  153. package/dist/types/src/web/primitives/meter.d.ts +21 -0
  154. package/dist/types/src/web/primitives/popover.d.ts +3 -0
  155. package/dist/types/src/web/primitives/progress-ring.d.ts +5 -0
  156. package/dist/types/src/web/primitives/progress.d.ts +8 -0
  157. package/dist/types/src/web/primitives/scroll-area.d.ts +49 -0
  158. package/dist/types/src/web/primitives/segmented-control.d.ts +5 -0
  159. package/dist/types/src/web/primitives/select.d.ts +47 -0
  160. package/dist/types/src/web/primitives/separator.d.ts +3 -0
  161. package/dist/types/src/web/primitives/sheet-chrome.d.ts +4 -0
  162. package/dist/types/src/web/primitives/sheet.d.ts +20 -0
  163. package/dist/types/src/web/primitives/skeleton.d.ts +3 -0
  164. package/dist/types/src/web/primitives/spinner.d.ts +3 -0
  165. package/dist/types/src/web/primitives/switch.d.ts +4 -0
  166. package/dist/types/src/web/primitives/table.d.ts +11 -0
  167. package/dist/types/src/web/primitives/tabs.d.ts +13 -0
  168. package/dist/types/src/web/primitives/textarea.d.ts +3 -0
  169. package/dist/types/src/web/primitives/toast.d.ts +163 -0
  170. package/dist/types/src/web/primitives/tooltip.d.ts +3 -0
  171. package/dist/types/src/web/primitives/truncate.d.ts +7 -0
  172. package/dist/types/src/web/primitives/typeahead-portal.d.ts +12 -0
  173. package/dist/types/src/web/share.d.ts +6 -0
  174. package/dist/types/src/web/table.d.ts +20 -0
  175. package/dist/types/src/web/theme-css.d.ts +69 -0
  176. package/dist/types/src/web/urls.d.ts +21 -0
  177. package/dist/web/index.js +2303 -0
  178. package/dist/web/index.js.map +26 -0
  179. package/dist/web/primitives/index.js +1450 -0
  180. package/dist/web/primitives/index.js.map +57 -0
  181. package/docs/components.generated.json +6238 -0
  182. package/docs/round-1-contract.md +679 -0
  183. package/docs/round-2-contract.md +476 -0
  184. package/docs/round-3-contract.md +174 -0
  185. package/docs/themes.generated.json +3503 -0
  186. package/fixtures/animations.json +2890 -0
  187. package/fixtures/bench-list.json +58 -0
  188. package/fixtures/bind-time.json +30664 -0
  189. package/fixtures/catalog-basic-map.json +1692 -0
  190. package/fixtures/catalog-components.json +9323 -0
  191. package/fixtures/catalog-extension.json +620 -0
  192. package/fixtures/catalog-macros.json +36370 -0
  193. package/fixtures/code-tokens.json +1993 -0
  194. package/fixtures/conformance-baseline.json +55544 -0
  195. package/fixtures/conformance-cases.json +49 -0
  196. package/fixtures/conformance-known.json +2123 -0
  197. package/fixtures/control-geometry.json +4200 -0
  198. package/fixtures/dashboard.data.json +74 -0
  199. package/fixtures/dashboard.json +752 -0
  200. package/fixtures/demo-surface.json +47 -0
  201. package/fixtures/format.json +870 -0
  202. package/fixtures/host-policy.json +1067 -0
  203. package/fixtures/host-router.json +1152 -0
  204. package/fixtures/host-transport.json +590 -0
  205. package/fixtures/interactions-round1.json +773 -0
  206. package/fixtures/kitchen-sink.expanded.json +10844 -0
  207. package/fixtures/kitchen-sink.json +3049 -0
  208. package/fixtures/layout-geometry-round1.json +7278 -0
  209. package/fixtures/layout-geometry.json +2072 -0
  210. package/fixtures/overlay-geometry.json +272 -0
  211. package/fixtures/primitive-specimens.json +58 -0
  212. package/fixtures/prompt-budget.json +33 -0
  213. package/fixtures/resizable.json +714 -0
  214. package/fixtures/round4-contract.json +2985 -0
  215. package/fixtures/specimens.json +9832 -0
  216. package/fixtures/style-conditions.json +336 -0
  217. package/fixtures/template-items.json +2215 -0
  218. package/fixtures/text-direction.json +309 -0
  219. package/fixtures/text-shimmer.json +96 -0
  220. package/fixtures/theme-extends.json +573 -0
  221. package/fixtures/theme-invalid.json +1296 -0
  222. package/fixtures/theme-recipes.json +58600 -0
  223. package/fixtures/theme-resolved.json +23949 -0
  224. package/fixtures/toast-stack.json +215 -0
  225. package/fixtures/tree-guides.json +224 -0
  226. package/fixtures/virtual-list.json +733 -0
  227. package/generated/ExponentialUICatalog.generated.kt +67 -0
  228. package/generated/ExponentialUICatalog.generated.swift +67 -0
  229. package/generated/ExponentialUIThemes.generated.kt +23 -0
  230. package/generated/ExponentialUIThemes.generated.swift +23 -0
  231. package/generated/catalog.descriptions.generated.rs +6 -0
  232. package/generated/catalog.generated.rs +80 -0
  233. package/generated/catalog.themes.generated.rs +34 -0
  234. package/generated/core.descriptions.json +2505 -0
  235. package/generated/core.runtime.json +3609 -0
  236. package/package.json +87 -4
  237. package/themes/exponential.recipes.json +49 -0
  238. package/themes/exponential.theme.json +755 -0
  239. package/themes/neutral.theme.json +5676 -0
  240. package/themes/orange.theme.json +43 -0
  241. package/themes/playful.theme.json +219 -0
  242. package/vendor/a2ui/LICENSE.txt +203 -0
  243. package/vendor/a2ui/README.md +27 -0
  244. package/vendor/a2ui/v0_9/basic_catalog.json +1387 -0
  245. package/vendor/a2ui/v0_9/basic_catalog_rules.txt +5 -0
  246. package/vendor/a2ui/v0_9/client_capabilities.json +97 -0
  247. package/vendor/a2ui/v0_9/client_to_server.json +104 -0
  248. package/vendor/a2ui/v0_9/common_types.json +315 -0
  249. package/vendor/a2ui/v0_9/server_to_client.json +132 -0
  250. package/vendor/json-render/LICENSE.txt +201 -0
  251. package/vendor/json-render/README.md +13 -0
@@ -0,0 +1,57 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/web/primitives/button.ts", "../src/web/primitives/alert-dialog.ts", "../src/web/primitives/alert.ts", "../src/web/primitives/avatar-color.ts", "../src/web/primitives/avatar.ts", "../src/web/primitives/badge.ts", "../src/web/primitives/breadcrumb.ts", "../src/web/primitives/calendar.ts", "../src/web/primitives/glass-card.ts", "../src/web/primitives/card.ts", "../src/web/primitives/checkbox.ts", "../src/web/primitives/choice-tiles.ts", "../src/web/primitives/cn.ts", "../src/web/primitives/code-block.ts", "../src/web/primitives/command.ts", "../src/web/primitives/context-ring.ts", "../src/web/primitives/dialog-arms.ts", "../src/web/primitives/dialog.ts", "../src/web/primitives/disclosure-header.ts", "../src/web/primitives/toast.ts", "../src/web/primitives/dock.ts", "../src/web/primitives/menu-surface.ts", "../src/web/primitives/dropdown-menu.ts", "../src/web/primitives/empty-state.ts", "../src/web/primitives/hover-card.ts", "../src/web/primitives/icon-disc.ts", "../src/web/primitives/input.ts", "../src/web/primitives/kbd.ts", "../src/web/primitives/label.ts", "../src/web/primitives/meter.ts", "../src/web/primitives/popover.ts", "../src/web/primitives/progress-ring.ts", "../src/web/primitives/progress.ts", "../src/web/primitives/scroll-area.ts", "../src/web/primitives/tabs.ts", "../src/web/primitives/segmented-control.ts", "../src/web/primitives/select.ts", "../src/web/primitives/separator.ts", "../src/web/primitives/sheet-chrome.ts", "../src/web/primitives/sheet.ts", "../src/web/primitives/skeleton.ts", "../src/web/primitives/spinner.ts", "../src/web/primitives/switch.ts", "../src/web/primitives/table.ts", "../src/web/primitives/textarea.ts", "../src/web/primitives/tooltip.ts", "../src/web/primitives/truncate.ts", "../src/web/primitives/typeahead-portal.ts"],
4
+ "sourcesContent": [
5
+ "import { cva, type VariantProps } from \"class-variance-authority\"\n\nexport const buttonVariants = cva(\n `inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all duration-fast ease-standard outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,\n {\n variants: {\n variant: {\n default: `bg-primary text-primary-foreground hover:bg-primary/90`,\n destructive: `bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40`,\n outline: `border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50`,\n glass: `border border-glass-stroke-card bg-glass-card text-foreground/70 hover:bg-glass-active hover:text-foreground`,\n secondary: `bg-secondary text-secondary-foreground hover:bg-secondary/80`,\n // EXP-960: a ghost TOGGLE says so with `aria-pressed`, and the pressed\n // state is the hover wash held down (the editor's formatting rail).\n // The `hover` arm names dark's half wash too: a pressed button under\n // the pointer must not fade to it.\n ghost: `hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 aria-pressed:bg-accent aria-pressed:text-accent-foreground dark:aria-pressed:hover:bg-accent`,\n link: `text-primary underline-offset-4 hover:underline`,\n // EXP-962: the TEXT button — muted words that brighten under the\n // pointer and never underline: a fold's \"Show more\"/\"Show less\", a\n // step's \"Back to the current step\". `link` goes SOMEWHERE (it\n // underlines like a link); `text` toggles something in place.\n text: `text-muted-foreground hover:text-foreground`,\n },\n // EXP-1176: a TEXT button is a rounded rectangle at the ladder's MD\n // step (10px, the row corner), the shape desktop `web_md`, iOS\n // `GlassSubmitButton` and Android `GlassSubmitButton` already wear. The\n // base `rounded-md` covers every boxed size; EXP-616's capsule is gone\n // from buttons. The capsule is the `Pill` (chips, header actions, the\n // picker trigger), the tabs, the badge and the phone bars, never a\n // Button with words in it. Icon sizes stay circles (the primary-action\n // rule, EXP-771); the ghost icon button alone sits on the MD corner.\n size: {\n default: `h-9 px-4 py-2 has-[>svg]:px-3`,\n xs: `h-6 gap-1 px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3`,\n sm: `h-8 gap-1.5 px-3 has-[>svg]:px-2.5`,\n lg: `h-10 px-6 has-[>svg]:px-4`,\n icon: `size-9 rounded-full`,\n // EXP-698 — the ONE trailing-action size: every row/header action\n // (play, merge, resume, copy link, the \"…\" menus) is a 32px chromed\n // glass circle.\n \"icon-sm\": `size-8 rounded-full [&_svg:not([class*='size-'])]:size-4`,\n \"icon-xs\": `size-6 rounded-full [&_svg:not([class*='size-'])]:size-3`,\n // EXP-962: INLINE — no box at all: the words sit in the run of text\n // around them at 12px, only the colour (and, for `link`, the\n // underline) says they are a button. For `link` and `text`; the\n // steer feed's \"Show more\", the session bands' \"Continues in a\n // newer run\", the edited-files card's footer.\n inline: `h-auto gap-1 rounded-sm p-0 text-xs has-[>svg]:px-0 [&_svg:not([class*='size-'])]:size-3`,\n },\n },\n // EXP-862: a GHOST icon button is the secondary control (no circle, no\n // border, the row wash on hover), so its hover paints under the MD corner\n // like desktop `controls::ghost_icon_button` and the styleguide's ghost\n // entry, not as a disc.\n compoundVariants: [\n {\n variant: `ghost`,\n size: [`icon`, `icon-sm`, `icon-xs`],\n className: `rounded-md`,\n },\n // EXP-1243: a boxed button presses to `scale.press` (motion-press);\n // the ghost icon button (a row's or toolbar's quiet control) and the\n // words-only link/text buttons do not.\n {\n variant: [`default`, `destructive`, `outline`, `glass`, `secondary`, `ghost`],\n size: [`default`, `xs`, `sm`, `lg`],\n className: `motion-press`,\n },\n {\n variant: [`default`, `destructive`, `outline`, `glass`, `secondary`],\n size: [`icon`, `icon-sm`, `icon-xs`],\n className: `motion-press`,\n },\n ],\n defaultVariants: {\n variant: `default`,\n size: `default`,\n },\n }\n)\n\nexport type ButtonVariantProps = VariantProps<typeof buttonVariants>\n",
6
+ "import { buttonVariants } from \"./button\"\n\n// Round 1: shadcn's AlertDialog on Radix — the confirm-or-cancel modal the\n// catalog's AlertDialog macro also paints (no backdrop dismissal, Escape\n// cancels, focus starts on Cancel).\nexport const ALERT_DIALOG_CLASSES = {\n overlay: `fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:duration-fast data-[state=closed]:ease-accelerate data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:duration-standard data-[state=open]:ease-decelerate`,\n content: `fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg motion-dialog sm:max-w-lg`,\n header: `flex flex-col gap-2 text-center sm:text-left`,\n footer: `flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,\n title: `text-lg font-semibold`,\n description: `text-sm text-muted-foreground`,\n action: buttonVariants(),\n cancel: buttonVariants({ variant: `outline` }),\n} as const\n",
7
+ "import { cva, type VariantProps } from \"class-variance-authority\"\n\n// EXP-941 — the inline banner. The admin console carried two byte-identical\n// copies of the destructive one (`rounded-md border border-destructive/50\n// bg-destructive/10 px-3 py-2 text-sm text-destructive`); this is that recipe\n// as the shadcn `Alert`, so the next error strip is a component and not a\n// third copy. The grid template is shadcn's: a leading glyph gets its own\n// column only when one is present, and the title/description stack in the\n// second.\nexport const alertVariants = cva(\n `relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-md border px-3 py-2 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current`,\n {\n variants: {\n variant: {\n default: `border-glass-stroke-card bg-glass-card text-foreground`,\n destructive: `border-destructive/50 bg-destructive/10 text-destructive`,\n },\n },\n defaultVariants: {\n variant: `default`,\n },\n }\n)\n\nexport type AlertVariantProps = VariantProps<typeof alertVariants>\n\nexport const ALERT_CLASSES = {\n title: `col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight`,\n description: `col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed`,\n} as const\n",
8
+ "// EXP-698 r4 — the avatar fallback hue.\n//\n// A user without a picture gets initials painted on a hue picked from the\n// `avatar` group in `packages/design-tokens/tokens.json` (mirrored as the CSS\n// vars `--avatar-0`..`--avatar-7`). The index is FNV-1a 32-bit over the UTF-8\n// bytes of the user id, modulo the palette size — a byte-identical contract\n// across all four clients, each pinned by the same fixture in\n// `avatar-color.test.ts`. Never reorder the palette: the index is what the\n// hash lands on.\n\nexport const AVATAR_HUE_COUNT = 8\n\nconst FNV_OFFSET_BASIS = 0x811c9dc5\nconst FNV_PRIME = 0x01000193\n\nconst encoder = new TextEncoder()\n\nexport function avatarHueIndex(userId: string | null | undefined): number {\n const bytes = encoder.encode(userId ?? ``)\n let hash = FNV_OFFSET_BASIS\n for (const byte of bytes) {\n hash ^= byte\n hash = Math.imul(hash, FNV_PRIME) >>> 0\n }\n return hash % AVATAR_HUE_COUNT\n}\n",
9
+ "import { avatarHueIndex } from \"./avatar-color\"\n\nexport const AVATAR_CLASSES = {\n root: `relative flex size-8 shrink-0 overflow-hidden rounded-full select-none`,\n image: `aspect-square size-full`,\n fallback: `flex size-full items-center justify-center rounded-full text-sm`,\n /** The fallback without a `userId`: the muted chrome. */\n fallbackMuted: `bg-muted text-muted-foreground`,\n} as const\n\n// EXP-698 r4 — a fallback given the person's `userId` paints their hue: the\n// palette colour at 20% behind initials in the same colour, no stroke. Without\n// an id (a repo, a bot, an unresolved reporter) it keeps the muted chrome. The\n// var is read inline because Tailwind v4 cannot see a computed `bg-avatar-N`.\nexport function avatarFallbackHue(userId: string | null | undefined): string | undefined {\n return userId === undefined || userId === null\n ? undefined\n : `var(--avatar-${avatarHueIndex(userId)})`\n}\n\n/** The inline colours of a hued fallback. */\nexport function avatarFallbackColors(hue: string): { backgroundColor: string; color: string } {\n return {\n backgroundColor: `color-mix(in srgb, ${hue} 20%, transparent)`,\n color: hue,\n }\n}\n",
10
+ "// EXP-962 — the COUNT badge: a 16px capsule carrying a number, the smallest\n// chip there is. `Pill size=\"sm\"` is 24 tall, which is a chip beside a label;\n// this rides a nav entry's corner (the sidebar rail's drafts count) or a\n// row's trailing edge, and says \"how many\", never what. Zero renders NOTHING:\n// a badge is a signal, and an empty signal is noise. Past `max` it reads\n// `99+`. PLACEMENT stays at the call site (the rail positions it absolutely\n// at a row's right edge or an icon's corner) — the badge owns only its shape.\n//\n// tone muted — the resting count (drafts you parked), muted fill\n// primary — the count that wants you (unread), accent fill\nexport type BadgeTone = `muted` | `primary`\n\nexport const BADGE_CLASSES = {\n root: `pointer-events-none inline-flex h-4 min-w-4 shrink-0 items-center justify-center rounded-full px-1 text-[10px] leading-none font-semibold tabular-nums`,\n tones: {\n primary: `bg-primary text-primary-foreground`,\n muted: `bg-muted text-muted-foreground`,\n },\n} as const\n\n/** What the badge prints for `count` (zero and below render nothing). */\nexport function badgeLabel(count: number, max = 99): string {\n return count > max ? `${max}+` : String(count)\n}\n",
11
+ "// Round 1: shadcn's Breadcrumb (the catalog's Breadcrumb macro paints the\n// same trail: links, a separator glyph, the current page last).\nexport const BREADCRUMB_CLASSES = {\n // The SDK sheet ships no preflight: the list resets its own markers.\n list: `flex list-none flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5`,\n item: `inline-flex items-center gap-1.5`,\n link: `transition-colors hover:text-foreground`,\n page: `font-normal text-foreground`,\n separator: `[&>svg]:size-3.5`,\n ellipsis: `flex size-9 items-center justify-center`,\n ellipsisIcon: `size-4`,\n srOnly: `sr-only`,\n} as const\n",
12
+ "// shadcn's Calendar on react-day-picker: `classNames` is DayPicker's part map\n// (its keys are DayPicker's), the rest are the root, the chevrons, the week\n// number cell and the day button.\nexport const CALENDAR_CLASSES = {\n root: [\n `group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent`,\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n ].join(` `),\n classNames: {\n root: `w-fit`,\n months: `relative flex flex-col gap-4 md:flex-row`,\n month: `flex w-full flex-col gap-4`,\n nav: `absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1`,\n button_previous: `size-(--cell-size) p-0 select-none aria-disabled:opacity-50`,\n button_next: `size-(--cell-size) p-0 select-none aria-disabled:opacity-50`,\n month_caption: `flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)`,\n dropdowns: `flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium`,\n dropdown_root: `relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50`,\n dropdown: `absolute inset-0 bg-popover opacity-0`,\n caption_label: `font-medium select-none`,\n table: `w-full border-collapse`,\n weekdays: `flex`,\n weekday: `flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none`,\n week: `mt-2 flex w-full`,\n week_number_header: `w-(--cell-size) select-none`,\n week_number: `text-[0.8rem] text-muted-foreground select-none`,\n day: `group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md`,\n range_start: `rounded-l-md bg-accent`,\n range_middle: `rounded-none`,\n range_end: `rounded-r-md bg-accent`,\n today: `rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none`,\n outside: `text-muted-foreground aria-selected:text-muted-foreground`,\n disabled: `text-muted-foreground opacity-50`,\n hidden: `invisible`,\n },\n /** `caption_label` per `captionLayout`: `label`, else a dropdown. */\n captionLabel: {\n label: `text-sm`,\n dropdown: `flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground`,\n },\n /** The `day` cell's first-selected corner, with or without week numbers. */\n dayFirst: {\n weekNumbers: `[&:nth-child(2)[data-selected=true]_button]:rounded-l-md`,\n plain: `[&:first-child[data-selected=true]_button]:rounded-l-md`,\n },\n chevron: `size-4`,\n weekNumber: `flex size-(--cell-size) items-center justify-center text-center`,\n dayButton: `flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70`,\n} as const\n",
13
+ "// EXP-903 — the ONE glass-card surface recipe.\n//\n// Five web surfaces painted the same translucent card by copy-paste: the\n// comment row, the agent AskCard, the agent usage bar, the mobile issue\n// properties sheet and the repo picker (which had drifted to `rounded-md` and\n// the bare `border` hairline). This is their common core — the XL radius, the\n// card hairline and the glass fill. Everything a card owns on its own (its\n// padding, its dividers, its overflow rule, a blur or a shadow) stays at the\n// call site, because those genuinely differ per surface. `Card` in card.tsx\n// derives its recipe from this constant; the natives already own the\n// primitive (desktop `surface::glass_card`, iOS `GlassCard`, Android\n// `Modifier.glassCard()`). N-12 (owner 2026-10-22): ONE gray ×4: the fill\n// is the opaque card composite (`bg-glass-card-opaque`), never the\n// translucent wash, so every card reads the same tone wherever it sits.\nexport const GLASS_CARD_CLASS = `rounded-xl border border-glass-stroke-card bg-glass-card-opaque`\n\nexport const GLASS_CARD_CLASSES = { root: GLASS_CARD_CLASS } as const\n",
14
+ "import { GLASS_CARD_CLASS } from \"./glass-card\"\n\nexport const CARD_CLASSES = {\n root: `${GLASS_CARD_CLASS} flex flex-col gap-6 backdrop-blur-md py-6 text-card-foreground shadow-sm`,\n header: `@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6`,\n title: `leading-none font-semibold`,\n description: `text-sm text-muted-foreground`,\n action: `col-start-2 row-span-2 row-start-1 self-start justify-self-end`,\n content: `px-6`,\n footer: `flex items-center px-6 [.border-t]:pt-6`,\n} as const\n",
15
+ "export const CHECKBOX_CLASSES = {\n // EXP-616: glass box — the strong stroke keeps a 16px unchecked square\n // legible against the row fill it sits on.\n root: `peer size-4 shrink-0 rounded-sm border border-glass-stroke-strong bg-glass-row shadow-none transition-shadow outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:aria-invalid:ring-destructive/40 dark:data-[state=checked]:bg-primary`,\n indicator: `grid place-content-center text-current transition-none`,\n icon: `size-3.5`,\n} as const\n",
16
+ "// EXP-1280: picture choice tiles. The pure half (the option shape, the\n// pick arithmetic) and the app-token skin of `ChoiceTiles`; the headless\n// frame lives with each renderer.\n\nexport interface ChoiceTileOption {\n value: string\n label: string\n description?: string | null\n /** The picture's url (a relative `/api/attachments/{id}` resolves in the\n * app through `renderImage`). */\n image?: string | null\n disabled?: boolean\n}\n\n/** `columns` clamped to 1–4 (default 2). */\nexport function choiceColumns(columns: unknown): number {\n const n = typeof columns === `number` && Number.isFinite(columns) ? Math.round(columns) : 2\n return Math.min(4, Math.max(1, n))\n}\n\n/** The values a comma-joined eUI `value` picks (single: the whole string). */\nexport function choiceValues(value: unknown, multiple: boolean): string[] {\n if (Array.isArray(value)) return value.map(String).filter(Boolean)\n const raw = value === undefined || value === null ? `` : String(value)\n if (!multiple) return raw ? [raw] : []\n return raw\n .split(`,`)\n .map((s) => s.trim())\n .filter(Boolean)\n}\n\n/** A press on `value`: single picks it; multiple toggles it, the list kept in\n * OPTION order (fixtures/interactions-round1.json `choiceTiles`). */\nexport function choiceToggle(picked: readonly string[], value: string, multiple: boolean, order: readonly string[]): string[] {\n if (!multiple) return [value]\n const next = picked.includes(value) ? picked.filter((v) => v !== value) : [...picked, value]\n const rank = (v: string) => {\n const i = order.indexOf(v)\n return i < 0 ? Number.MAX_SAFE_INTEGER : i\n }\n return next.slice().sort((a, b) => rank(a) - rank(b))\n}\n\nexport interface TileState {\n index: number\n selected: boolean\n disabled: boolean\n}\n\nexport const CHOICE_TILES_CLASSES = {\n root: `gap-[8px]`,\n // The tile in PX, never rem steps (the app's desktop rem is 18.5px, which\n // would inflate them): THE ChoiceTiles recipe = the exponential theme's\n // recipes.ChoiceTiles = packages/domain-contract/fixtures/plan-card.json\n // `tiles` (the SDK imports nothing from the app, so the numbers are copied\n // here): padding 8 (7 when selected, under the 2px `selectedRing`), `gap` 8\n // between tiles, `radius` 10, `pictureRadius` 6 at `pictureAspect` 1.6,\n // `stroke` 1, `placeholderGlyph` 20 at 0.6, `labelGap` 4 picture→label and\n // label→description, `inertOpacity` 0.5. Text stays the sm/xs steps.\n tile: `flex min-w-0 cursor-pointer flex-col gap-[4px] rounded-[10px] border-[1px] border-border bg-card p-[8px] text-start outline-none transition-colors hover:bg-secondary focus-visible:border-ring disabled:cursor-not-allowed disabled:opacity-50`,\n tileSelected: `border-[2px] border-primary bg-accent p-[7px] hover:bg-accent`,\n tileInvalid: `border-destructive`,\n picture: `relative flex aspect-[1.6] w-full shrink-0 items-center justify-center overflow-hidden rounded-[6px] bg-muted text-muted-foreground`,\n image: `absolute inset-0 size-full object-cover`,\n placeholder: `size-[20px] opacity-60`,\n label: `min-w-0 text-sm leading-5 font-medium text-foreground`,\n description: `min-w-0 text-xs leading-4 text-muted-foreground`,\n} as const\n",
17
+ "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\n// The class-name merger every component in this package (and every app that\n// consumes it) styles through: clsx for conditionals, tailwind-merge so a\n// caller's `className` beats the component's own utilities instead of racing\n// it in the cascade.\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport function getInitials(value: string) {\n return value\n .split(` `)\n .map((part) => part[0] ?? ``)\n .join(``)\n .toUpperCase()\n .slice(0, 2)\n}\n",
18
+ "import { cva, type VariantProps } from \"class-variance-authority\"\n\n// EXP-1324 — THE CodeBlock: shadcn's code-block (radix-nova) on our Button,\n// coloured by the catalog's ONE tokenizer (`tokenizeCode`, catalog/code.json\n// — the same tokens every renderer paints; `ansi` = command output, the\n// Terminal pattern). Size `sm` (fixtures/trace.json `geometry.codeBlock`) is\n// tool output inside a Trace line; `destructive` is a failed call's.\n\nexport const codeBlockVariants = cva(\n `group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs`,\n {\n variants: {\n variant: {\n default: `border border-input text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30`,\n destructive: `border border-destructive/30 text-destructive dark:border-destructive/40`,\n },\n },\n defaultVariants: {\n variant: `default`,\n },\n }\n)\n\nexport type CodeBlockVariantProps = VariantProps<typeof codeBlockVariants>\n\n/** The catalog's `codeToken` kinds, painted with the app's code palette\n * (`--hljs-*`, the diff view's and the editor's); a destructive block drops\n * the colours for its own. */\nexport const CODE_TOKEN_CLASS: Record<string, string> = {\n keyword: `text-(--hljs-keyword)`,\n string: `text-(--hljs-string)`,\n number: `text-(--hljs-number)`,\n comment: `text-muted-foreground`,\n type: `text-(--hljs-title)`,\n function: `text-(--hljs-title)`,\n property: `text-(--hljs-variable)`,\n attribute: `text-(--hljs-variable)`,\n tag: `text-(--hljs-tag)`,\n operator: `text-muted-foreground`,\n punctuation: `text-muted-foreground`,\n success: `text-(--hljs-addition)`,\n warning: `text-(--hljs-number)`,\n error: `text-destructive`,\n}\n\nexport const codeBlockLineVariants = cva(\n `relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']`,\n {\n variants: {\n variant: {\n default: ``,\n added: `bg-muted after:content-['+']`,\n removed: `bg-destructive/10 after:text-destructive after:content-['−']`,\n highlighted: `bg-muted`,\n },\n },\n defaultVariants: {\n variant: `default`,\n },\n }\n)\n\nexport type CodeBlockLineVariantProps = VariantProps<typeof codeBlockLineVariants>\n\nexport const CODE_BLOCK_CLASSES = {\n header: `flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0`,\n title: `min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5`,\n actions: `-my-1 ms-auto -me-1 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10`,\n srOnly: `sr-only`,\n content: `min-h-0 min-w-0 scroll-fade-x overflow-auto overscroll-contain px-3 py-3 text-start font-mono leading-relaxed outline-none [--code-block-pad:calc(var(--spacing)*6)] group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-has-data-[slot=code-block-header]/code-block:[--code-block-pad:calc(var(--spacing)*5)] group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:[--code-block-pad:calc(var(--spacing)*5)] group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:[--code-block-pad:calc(var(--spacing)*4)] data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap`,\n code: `grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0`,\n token: `group-data-[variant=destructive]/code-block:text-current`,\n lineContent: `min-w-0`,\n footer: `flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5`,\n} as const\n",
19
+ "import { buttonVariants } from \"./button\"\n\n// FEED-131 — the command menu WITHOUT cmdk: the look of the app's\n// `packages/ui/src/command.tsx` (the inline variant + a trailing clear), and\n// the framework-free engine both renderers share (the React set and its\n// Solid twin wire the SAME store, ordering and keyboard model, so the two\n// paint one DOM): cmdk's `command-score`, the filter, the root store, the\n// DOM ordering pass and the keys.\nexport const COMMAND_CLASSES = {\n // Transparent (EXP-269): the hosts provide the glass surface.\n root: `flex h-full w-full flex-col overflow-hidden rounded-md bg-transparent text-popover-foreground`,\n inputWrapper: `flex h-9 items-center gap-2 border-b border-glass-stroke px-3`,\n inputGlyph: `size-4 shrink-0 opacity-50`,\n input: `flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-foreground/50 disabled:cursor-not-allowed disabled:opacity-50`,\n inputClear: buttonVariants({ variant: `ghost`, size: `icon-xs`, className: `shrink-0 text-muted-foreground` }),\n list: `max-h-[18.75rem] scroll-py-1 overflow-x-hidden overflow-y-auto`,\n empty: `py-6 text-center text-sm`,\n group: `overflow-hidden p-(--menu-surface-padding) text-foreground`,\n groupHeading: `px-(--menu-item-padding-x) py-1.5 text-xs font-medium text-muted-foreground`,\n item: `relative flex min-h-(--menu-item-height) cursor-pointer items-center gap-(--menu-item-gap) rounded-sm px-(--menu-item-padding-x) py-1 text-sm text-foreground/90 outline-hidden select-none data-[disabled=true]:cursor-default data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-glass-active data-[selected=true]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--menu-icon-size) [&_svg:not([class*='text-'])]:text-muted-foreground`,\n separator: `-mx-(--menu-surface-padding) my-(--menu-surface-padding) h-px bg-glass-stroke`,\n shortcut: `ml-auto text-xs tracking-widest text-muted-foreground`,\n} as const\n\n/** cmdk's visually hidden `<label>` (its inline style, in its order). */\nexport const COMMAND_LABEL_STYLE = {\n position: `absolute`,\n width: `1px`,\n height: `1px`,\n padding: `0`,\n margin: `-1px`,\n overflow: `hidden`,\n clip: `rect(0, 0, 0, 0)`,\n whiteSpace: `nowrap`,\n borderWidth: `0`,\n} as const\n\n// ── command-score (cmdk 1.1.1) ──────────────────────────────────────────\n\nconst SCORE_CONTINUE_MATCH = 1\nconst SCORE_SPACE_WORD_JUMP = 0.9\nconst SCORE_NON_SPACE_WORD_JUMP = 0.8\nconst SCORE_CHARACTER_JUMP = 0.17\nconst SCORE_TRANSPOSITION = 0.1\nconst PENALTY_SKIPPED = 0.999\nconst PENALTY_CASE_MISMATCH = 0.9999\nconst PENALTY_NOT_COMPLETE = 0.99\nconst IS_GAP = /[\\\\/_+.#\"@[({&]/\nconst COUNT_GAPS = /[\\\\/_+.#\"@[({&]/g\nconst IS_SPACE = /[\\s-]/\nconst COUNT_SPACE = /[\\s-]/g\n\nfunction scoreFrom(value: string, query: string, lowerValue: string, lowerQuery: string, valueIndex: number, queryIndex: number, memo: Record<string, number>): number {\n if (queryIndex === query.length) return valueIndex === value.length ? SCORE_CONTINUE_MATCH : PENALTY_NOT_COMPLETE\n const key = `${valueIndex},${queryIndex}`\n if (memo[key] !== undefined) return memo[key]\n const queryChar = lowerQuery.charAt(queryIndex)\n let index = lowerValue.indexOf(queryChar, valueIndex)\n let high = 0\n while (index >= 0) {\n let score = scoreFrom(value, query, lowerValue, lowerQuery, index + 1, queryIndex + 1, memo)\n if (score > high) {\n if (index === valueIndex) score *= SCORE_CONTINUE_MATCH\n else if (IS_GAP.test(value.charAt(index - 1))) {\n score *= SCORE_NON_SPACE_WORD_JUMP\n const breaks = value.slice(valueIndex, index - 1).match(COUNT_GAPS)\n if (breaks && valueIndex > 0) score *= Math.pow(PENALTY_SKIPPED, breaks.length)\n } else if (IS_SPACE.test(value.charAt(index - 1))) {\n score *= SCORE_SPACE_WORD_JUMP\n const breaks = value.slice(valueIndex, index - 1).match(COUNT_SPACE)\n if (breaks && valueIndex > 0) score *= Math.pow(PENALTY_SKIPPED, breaks.length)\n } else {\n score *= SCORE_CHARACTER_JUMP\n if (valueIndex > 0) score *= Math.pow(PENALTY_SKIPPED, index - valueIndex)\n }\n if (value.charAt(index) !== query.charAt(queryIndex)) score *= PENALTY_CASE_MISMATCH\n }\n if ((score < SCORE_TRANSPOSITION && lowerValue.charAt(index - 1) === lowerQuery.charAt(queryIndex + 1)) || (lowerQuery.charAt(queryIndex + 1) === lowerQuery.charAt(queryIndex) && lowerValue.charAt(index - 1) !== lowerQuery.charAt(queryIndex))) {\n const transposed = scoreFrom(value, query, lowerValue, lowerQuery, index + 1, queryIndex + 2, memo)\n if (transposed * SCORE_TRANSPOSITION > score) score = transposed * SCORE_TRANSPOSITION\n }\n if (score > high) high = score\n index = lowerValue.indexOf(queryChar, index + 1)\n }\n memo[key] = high\n return high\n}\n\nconst normalize = (s: string) => s.toLowerCase().replace(COUNT_SPACE, ` `)\n\n/** cmdk's `command-score`: 1 = exact, prefix > word boundary > fuzzy,\n * 0 = no match. `keywords` extend the value (`value + \" \" + keywords`). */\nexport function commandScore(value: string, query: string, keywords?: readonly string[]): number {\n const full = keywords && keywords.length > 0 ? `${value} ${keywords.join(` `)}` : value\n return scoreFrom(full, query, normalize(full), normalize(query), 0, 0, {})\n}\n\nexport type CommandFilter = (value: string, query: string, keywords?: readonly string[]) => number\n\n// ── the filter ──────────────────────────────────────────────────────────\n\nexport interface CommandFilterItem {\n id: string\n value: string\n keywords?: readonly string[]\n /** The group's id; none = an ungrouped item. */\n group?: string\n disabled?: boolean\n /** Always visible, never counted (cmdk's `forceMount`). */\n forceMount?: boolean\n}\n\nexport interface CommandFilterResult {\n /** Matching (non-forced) items: 0 = the empty state. */\n count: number\n /** Ungrouped items first, then the groups by their best score; ids by score. */\n groups: { group: string | undefined; ids: string[] }[]\n scores: Map<string, number>\n}\n\n/** The visible ids per group, in display order. An empty query keeps the\n * registration order and shows everything; otherwise score > 0 shows,\n * items sort by score (stable), groups by their best item. */\nexport function filterCommandItems(items: readonly CommandFilterItem[], query: string, filter: CommandFilter = commandScore): CommandFilterResult {\n const scores = new Map<string, number>()\n const order = new Map<string | undefined, { ids: { id: string; score: number; at: number }[]; best: number; at: number }>()\n let count = 0\n items.forEach((item, at) => {\n const score = item.forceMount ? 1 : query ? (item.value ? filter(item.value, query, item.keywords) : 0) : 1\n scores.set(item.id, score)\n if (!item.forceMount && score > 0) count++\n if (score <= 0) return\n let g = order.get(item.group)\n if (!g) order.set(item.group, (g = { ids: [], best: 0, at }))\n g.ids.push({ id: item.id, score, at })\n g.best = Math.max(g.best, score)\n })\n const groups = [...order.entries()].map(([group, g]) => ({ group, ...g }))\n if (query) {\n for (const g of groups) g.ids.sort((a, b) => b.score - a.score || a.at - b.at)\n groups.sort((a, b) => (a.group === undefined ? -1 : b.group === undefined ? 1 : b.best - a.best || a.at - b.at))\n } else groups.sort((a, b) => (a.group === undefined ? -1 : b.group === undefined ? 1 : a.at - b.at))\n return { count, groups: groups.map((g) => ({ group: g.group, ids: g.ids.map((i) => i.id) })), scores }\n}\n\n// ── the root store ──────────────────────────────────────────────────────\n\nexport const COMMAND_SELECT_EVENT = `command-item-select`\nconst ITEM = `[data-slot=\"command-item\"]`\nconst ENABLED_ITEM = `${ITEM}:not([aria-disabled=\"true\"])`\nconst GROUP = `[data-slot=\"command-group\"]`\n\ntype Kind = `item` | `group` | `separator`\ninterface Entry {\n id: string\n kind: Kind\n seq: number\n el: HTMLElement | null\n value: string\n keywords?: string[]\n group?: string\n disabled?: boolean\n forceMount?: boolean\n}\n\nexport interface CommandStoreOptions {\n /** The root's live props. */\n props: () => { value?: string; onValueChange?: (value: string) => void; filter?: CommandFilter; shouldFilter?: boolean; loop?: boolean }\n /** Ask the renderer for a flush after the DOM caught up (React: a root\n * re-render + layout effect; Solid: a microtask). */\n schedule: () => void\n}\n\n/** The command root's state (cmdk's store), framework-free: the query, the\n * selected value, the registry (items, groups, separators in creation\n * order) and the post-render pass (`flush`: DOM order, first-item\n * selection, the active descendant, scroll). Renderers subscribe and\n * re-render on `emit`. */\nexport function createCommandStore(o: CommandStoreOptions) {\n let search = ``\n let value = o.props().value?.trim() ?? ``\n let selectedId: string | undefined\n let seq = 0\n let version = 0\n const entries = new Map<string, Entry>()\n const byEl = new WeakMap<Element, Entry>()\n const listeners = new Set<() => void>()\n let sizer: HTMLElement | null = null\n let dirtyOrder = false\n let selectFirst = false\n let scroll = false\n let selectionChanged = false\n\n const filter = () => o.props().filter ?? commandScore\n const filtering = () => search !== `` && o.props().shouldFilter !== false\n const emit = () => {\n version++\n listeners.forEach((l) => l())\n }\n const touch = () => {\n o.schedule()\n }\n const items = () => [...entries.values()].filter((e) => e.kind === `item`).sort((a, b) => a.seq - b.seq)\n const result = () => filterCommandItems(items(), filtering() ? search : ``, filter())\n\n const setValue = (next: string, opts: { pointer?: boolean } = {}) => {\n const p = o.props()\n if (next === (p.value !== undefined ? p.value.trim() : value)) return\n if (p.value === undefined) value = next\n p.onValueChange?.(next)\n if (!opts.pointer) scroll = true\n selectionChanged = true\n emit()\n touch()\n }\n\n const enabledItems = () => Array.from(sizer?.querySelectorAll<HTMLElement>(ENABLED_ITEM) ?? [])\n const selectedEl = () => sizer?.querySelector<HTMLElement>(`${ITEM}[aria-selected=\"true\"]`) ?? null\n\n /** Registered children of one container, in the display order. */\n const reorder = (container: Element, scores: Map<string, number>) => {\n const kids = Array.from(container.children)\n .map((el) => byEl.get(el))\n .filter((e): e is Entry => e !== undefined)\n if (kids.length === 0) return\n const groupScore = (g: Entry) => Math.max(0, ...items().filter((i) => i.group === g.id).map((i) => scores.get(i.id) ?? 0))\n let want: Entry[]\n if (!filtering()) want = [...kids].sort((a, b) => a.seq - b.seq)\n else {\n const rank = (e: Entry) => (e.kind === `item` ? 1 : e.kind === `group` ? 2 : 0)\n const score = (e: Entry) => (e.kind === `item` ? (scores.get(e.id) ?? 0) : e.kind === `group` ? groupScore(e) : 0)\n want = [...kids].sort((a, b) => rank(a) - rank(b) || score(b) - score(a) || a.seq - b.seq)\n }\n if (want.every((e, i) => e === kids[i])) return\n for (const e of want) if (e.el) container.appendChild(e.el)\n }\n\n return {\n get version() {\n return version\n },\n get search() {\n return search\n },\n get value() {\n const p = o.props().value\n return p !== undefined ? p.trim() : value\n },\n get selectedId() {\n return selectedId\n },\n subscribe(listener: () => void) {\n listeners.add(listener)\n return () => void listeners.delete(listener)\n },\n nextSeq: () => seq++,\n /** The query (the input); `silent` = during the first render. */\n setSearch(next: string, silent = false) {\n if (next === search) return\n search = next\n dirtyOrder = true\n selectFirst = true\n if (silent) return\n emit()\n touch()\n },\n setValue,\n /** Re-read the controlled `value` prop (no callback). */\n syncValue() {\n const p = o.props().value\n if (p === undefined || p.trim() === value) return false\n value = p.trim()\n selectionChanged = true\n scroll = true\n emit()\n touch()\n return true\n },\n setSizer(el: HTMLElement | null) {\n sizer = el\n },\n filtering,\n /** An item's score now (1 when nothing filters). */\n score(itemValue: string, keywords?: readonly string[]) {\n if (!filtering()) return 1\n return itemValue ? filter()(itemValue, search, keywords) : 0\n },\n /** Whether a group shows (some registered item of it matches). */\n groupVisible(groupId: string) {\n if (!filtering()) return true\n return items().some((i) => i.group === groupId && this.score(i.value, i.keywords) > 0)\n },\n /** The empty state: no matching (non-forced) item. */\n empty() {\n return result().count === 0\n },\n register(entry: { id: string; kind: Kind; seq: number; value?: string; keywords?: string[]; group?: string; disabled?: boolean; forceMount?: boolean }) {\n const e: Entry = { el: null, value: ``, ...entry }\n entries.set(e.id, e)\n dirtyOrder = true\n if (e.kind === `item` && !this.value) selectFirst = true\n emit()\n touch()\n return () => {\n entries.delete(e.id)\n if (e.el) byEl.delete(e.el)\n dirtyOrder = true\n if (e.kind === `item` && selectedId === e.id) selectFirst = true\n emit()\n touch()\n }\n },\n /** An entry's element (null = not rendered) or item fields. */\n update(id: string, patch: Partial<Pick<Entry, `el` | `value` | `keywords` | `disabled`>>) {\n const e = entries.get(id)\n if (!e) return\n let changed = false\n if (`el` in patch && patch.el !== e.el) {\n if (e.el) byEl.delete(e.el)\n e.el = patch.el ?? null\n if (e.el) byEl.set(e.el, e)\n dirtyOrder = true\n changed = true\n }\n if (patch.value !== undefined && patch.value !== e.value) {\n e.value = patch.value\n dirtyOrder = true\n if (!this.value) selectFirst = true\n changed = true\n }\n if (`keywords` in patch && (patch.keywords ?? []).join(`\\u0000`) !== (e.keywords ?? []).join(`\\u0000`)) {\n e.keywords = patch.keywords\n dirtyOrder = true\n changed = true\n }\n if (`disabled` in patch && patch.disabled !== e.disabled) {\n e.disabled = patch.disabled\n changed = true\n }\n if (!changed) return\n emit()\n touch()\n },\n /** The post-render pass: DOM order, the first item selected (after a\n * query change or when nothing is selected), the active descendant,\n * the selected item scrolled into view. Idempotent. */\n flush() {\n if (!sizer) return\n if (dirtyOrder) {\n dirtyOrder = false\n const { scores } = result()\n reorder(sizer, scores)\n for (const items of Array.from(sizer.querySelectorAll(`[data-slot=\"command-group-items\"]`))) reorder(items, scores)\n }\n if (selectFirst) {\n selectFirst = false\n const first = enabledItems()[0]\n const next = first?.getAttribute(`data-value`) ?? ``\n if (next !== this.value) {\n setValue(next)\n return\n }\n }\n const sel = selectedEl()\n const id = sel?.id || undefined\n if (id !== selectedId) {\n selectedId = id\n emit()\n }\n if (selectionChanged) {\n selectionChanged = false\n if (scroll && sel) {\n if (sel.parentElement?.firstElementChild === sel) sel.closest(GROUP)?.querySelector(`[data-slot=\"command-group-heading\"]`)?.scrollIntoView({ block: `nearest` })\n sel.scrollIntoView({ block: `nearest` })\n }\n scroll = false\n }\n },\n /** cmdk's root keys. */\n onKeyDown(e: KeyboardEvent) {\n if (e.defaultPrevented || e.isComposing || e.keyCode === 229) return\n const loop = Boolean(o.props().loop)\n const pick = (el: HTMLElement | undefined) => {\n if (el) setValue(el.getAttribute(`data-value`) ?? ``)\n }\n const at = (i: number) => pick(enabledItems()[i])\n const last = () => at(enabledItems().length - 1)\n const step = (delta: number) => {\n const list = enabledItems()\n const i = list.findIndex((el) => el === selectedEl())\n let next = list[i + delta]\n if (loop) next = i + delta < 0 ? list[list.length - 1] : i + delta === list.length ? list[0] : list[i + delta]\n pick(next)\n }\n const group = (delta: number) => {\n let g: Element | null | undefined = selectedEl()?.closest(GROUP)\n let found: HTMLElement | null | undefined\n while (g && !found) {\n g = delta > 0 ? nextMatching(g, GROUP, 1) : nextMatching(g, GROUP, -1)\n found = g?.querySelector<HTMLElement>(ENABLED_ITEM)\n }\n if (found) pick(found)\n else step(delta)\n }\n const down = () => {\n e.preventDefault()\n if (e.metaKey) last()\n else if (e.altKey) group(1)\n else step(1)\n }\n const up = () => {\n e.preventDefault()\n if (e.metaKey) at(0)\n else if (e.altKey) group(-1)\n else step(-1)\n }\n switch (e.key) {\n case `n`:\n case `j`:\n if (e.ctrlKey) down()\n break\n case `ArrowDown`:\n down()\n break\n case `p`:\n case `k`:\n if (e.ctrlKey) up()\n break\n case `ArrowUp`:\n up()\n break\n case `Home`:\n e.preventDefault()\n at(0)\n break\n case `End`:\n e.preventDefault()\n last()\n break\n case `Enter`: {\n e.preventDefault()\n selectedEl()?.dispatchEvent(new Event(COMMAND_SELECT_EVENT))\n break\n }\n }\n },\n }\n}\n\nexport type CommandStore = ReturnType<typeof createCommandStore>\n\nfunction nextMatching(el: Element, selector: string, dir: 1 | -1): Element | null {\n let n = dir > 0 ? el.nextElementSibling : el.previousElementSibling\n while (n) {\n if (n.matches(selector)) return n\n n = dir > 0 ? n.nextElementSibling : n.previousElementSibling\n }\n return null\n}\n\n/** An item's value: the `value` prop, else string children, else the\n * rendered text (trimmed), else the last known one. */\nexport function commandItemValue(value: string | undefined, children: unknown, el: Element | null | undefined, known: string): string {\n if (value !== undefined) return value.trim()\n if (typeof children === `string`) return children.trim()\n if (el) return (el.textContent ?? ``).trim()\n return known\n}\n\n/** CommandList's `--cmdk-list-height` (cmdk: the sizer's offsetHeight,\n * ResizeObserver → rAF). Returns the disposer. */\nexport function observeCommandListHeight(list: HTMLElement, sizer: HTMLElement): () => void {\n if (typeof ResizeObserver === `undefined`) return () => {}\n let raf = 0\n const ro = new ResizeObserver(() => {\n raf = requestAnimationFrame(() => list.style.setProperty(`--cmdk-list-height`, `${sizer.offsetHeight.toFixed(1)}px`))\n })\n ro.observe(sizer)\n return () => {\n cancelAnimationFrame(raf)\n ro.unobserve(sizer)\n }\n}\n",
20
+ "// EXP-877: the composer footer's CONTEXT RING — a 16px radial where the\n// context pill used to be, and the trigger of the usage overlay the session\n// already had. The number and the tone are the SESSION's, so both come in as\n// props (`lib/context-ring.ts` in the app derives them from the engine's\n// usage); this only draws them. It forwards its ref so a `PopoverTrigger\n// asChild` can own it.\n\n/** The ring's box, in px — a footer glyph, the size of a small icon. */\nexport const RING_SIZE = 16\n/** Stroke width of both the track and the progress arc. */\nexport const RING_STROKE = 2\n/** Radius of the stroked circle: the box minus one stroke, halved, so the\n * stroke sits fully inside the box (`(16 - 2) / 2 = 7`… minus a hair, so the\n * arc's round join never clips). */\nexport const RING_RADIUS = 6\n\nexport interface RingGeometry {\n /** The full circle's length — the dash array. */\n circumference: number\n /** How much of it to hide: the UNfilled remainder. */\n dashOffset: number\n}\n\n/** The arc for `percent`, clamped to 0..100 (a NaN reads as empty). */\nexport function ringGeometry(percent: number): RingGeometry {\n const circumference = 2 * Math.PI * RING_RADIUS\n const clamped = Number.isFinite(percent)\n ? Math.min(100, Math.max(0, percent))\n : 0\n return {\n circumference,\n dashOffset: circumference * (1 - clamped / 100),\n }\n}\n\n/** The three tones every usage surface shares — the app maps its thresholds\n * (`severity`, lib/agent-usage.ts) onto them, never the other way round. */\nexport type RingTone = `normal` | `warning` | `danger`\n\nexport const RING_TONE_CLASS: Record<RingTone, string> = {\n normal: `text-muted-foreground`,\n warning: `text-amber-500`,\n danger: `text-destructive`,\n}\n\nexport const CONTEXT_RING_CLASSES = {\n root: `shrink-0`,\n svg: `-rotate-90`,\n} as const\n",
21
+ "// EXP-687 — the four `< sm` presentations a Dialog can take. Kept in their\n// own module because the strings ARE the spec: one bottom sheet, one opaque #18181B\n// surface, one 24px top radius, everywhere.\n//\n// Each arm carries its OWN mobile-only classes so nothing leaks between them,\n// and re-states the `sm:` padding the shared base leaves to the arm — so\n// from `sm` up all four are the identical centered glass panel and DESKTOP\n// PRESENTATION IS UNCHANGED by anything here.\n//\n// Since the UI cleanup batch the two sheet arms render THROUGH `SheetContent`\n// below `sm` (dialog.tsx), so the classes below are the fallback for the\n// first paint and static markup; the sheet's own chrome is the one phone\n// sheet.\n//\n// `sheet` is the default (EXP-687 flipped it from the EXP-255 full-screen\n// page): content-fitted up to 90dvh, matching the native \"fitted\" detent.\n// `sheet-full` is the fixed 94dvh detent EXP-616 introduced for the tall\n// forms (Start coding, New action, Device settings) whose content-sized\n// height read as a cut-off page. `alert` is the compact centered card the\n// `Prompt` (EXP-1215) opens in on every width, deliberately NOT a sheet. `page` is the\n// full-screen arm, only for the image lightbox.\n//\n// EXP-1243: the panel's `motion-dialog` recipe (scale from 0.96 + fade) is the\n// animation for every arm but the sheets, which slide up on `motion-sheet`.\n\n/** Shared by `sheet` and `sheet-full`. Opaque, no blur: it fills the screen\n * edge to edge below `sm`, so there is nothing to see through. */\nconst MOBILE_SHEET_BASE = `max-sm:inset-x-0 max-sm:bottom-0 max-sm:w-full max-sm:rounded-t-3xl max-sm:border-t max-sm:border-glass-stroke-card max-sm:bg-glass-bottom max-sm:px-4 max-sm:pt-0 max-sm:pb-[max(1rem,env(safe-area-inset-bottom))] max-sm:motion-sheet max-sm:data-[state=closed]:slide-out-to-bottom max-sm:data-[state=open]:slide-in-from-bottom sm:p-6`\n\nexport const MOBILE_SHEET = `${MOBILE_SHEET_BASE} max-sm:h-auto max-sm:max-h-[90dvh]`\n\nexport const MOBILE_SHEET_FULL = `${MOBILE_SHEET_BASE} max-sm:h-[94dvh]`\n\nexport const MOBILE_ALERT = `max-sm:top-1/2 max-sm:left-1/2 max-sm:w-[calc(100%-3rem)] max-sm:max-w-sm max-sm:max-h-[calc(100dvh-3rem)] max-sm:-translate-x-1/2 max-sm:-translate-y-1/2 max-sm:rounded-2xl max-sm:border max-sm:border-glass-stroke-card max-sm:bg-glass-bottom max-sm:p-5 sm:p-6`\n\nexport const MOBILE_PAGE = `max-sm:inset-0 max-sm:w-full max-sm:bg-background max-sm:p-6 sm:p-6`\n\nexport type DialogMobileArm = `sheet` | `sheet-full` | `alert` | `page`\n\nexport const MOBILE_ARMS: Record<DialogMobileArm, string> = {\n sheet: MOBILE_SHEET,\n [`sheet-full`]: MOBILE_SHEET_FULL,\n alert: MOBILE_ALERT,\n page: MOBILE_PAGE,\n}\n",
22
+ "/** Below `sm` a sheet-arm dialog IS the bottom sheet (EXP-687 → the UI\n * cleanup batch's \"one phone sheet\"). */\nexport const DIALOG_PHONE_QUERY = `(max-width: 639px)`\n\nexport const DIALOG_CLASSES = {\n overlay: `fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:duration-fast data-[state=closed]:ease-accelerate data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:duration-standard data-[state=open]:ease-decelerate`,\n // ONE phone sheet: a sheet arm below `sm` renders THROUGH `SheetContent`\n // (its grabber, drag-to-dismiss, overlay-tap close and opaque surface)\n // with these on top; `phoneSheetFull` is the `sheet-full` detent.\n phoneSheet: `gap-4 overflow-hidden px-4 pt-0 pb-[max(1rem,env(safe-area-inset-bottom))] outline-none`,\n phoneSheetFull: `h-[94dvh] max-h-[94dvh]`,\n // The panel is a flex COLUMN that never scrolls itself (EXP-369):\n // header and footer stay pinned and the scrolling happens inside\n // `DialogBody` (`flex-1 min-h-0 overflow-y-auto`). Any dialog whose\n // content can outgrow the viewport MUST wrap that content in a\n // DialogBody — without one, tall content is clipped rather than\n // scrolled (short confirm dialogs only hit that below ~200px of\n // viewport height).\n // Below `sm` the presentation is one of the four arms in\n // ui/dialog-arms.ts, `sheet` by default (EXP-687): a bottom sheet\n // with a grabber and no ✕, dismissed by dragging it down or tapping\n // outside. From `sm` up it is the centered frosted panel (EXP-269),\n // capped to the viewport — THE SAME for every arm, which is why the\n // arms own all the padding; the enter is `motion-dialog` (EXP-1243),\n // the sheet arms swap it for `motion-sheet` below `sm`. Callers that reposition or\n // re-cap the panel must sm:-prefix those classes so they compose\n // with (and tailwind-merge away) the sm: base here.\n // A column flex container also fixes EXP-178 for free: items take\n // the container's definite width and long nowrap lines (e.g. an\n // issue title in a picker row) overflow their item instead of\n // inflating the panel the way a grid track's min-content did.\n // sm:w-[calc(100%-2rem)] keeps the 1rem side gutter the old\n // unprefixed max-w-[calc(100%-2rem)] used to give, without sitting in\n // the max-w-* tailwind-merge group — so a caller's sm:max-w-* still\n // caps the panel instead of dropping the gutter.\n content: `fixed z-50 flex flex-col gap-4 overflow-hidden shadow-lg outline-none motion-dialog sm:inset-auto sm:top-[50%] sm:left-[50%] sm:max-h-[calc(100dvh-2rem)] sm:w-[calc(100%-2rem)] sm:max-w-lg sm:translate-x-[-50%] sm:translate-y-[-50%] sm:rounded-2xl sm:border sm:border-glass-stroke-card sm:bg-card/85 sm:shadow-2xl sm:shadow-black/40 sm:backdrop-blur-2xl`,\n /** The sheet arms' grabber on the centred panel: a phone only. */\n grabber: `hidden max-sm:block`,\n /** The hidden Close a drag-to-dismiss clicks. */\n dragClose: `hidden`,\n close: `absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,\n // Sheets and alerts carry no ✕ on a phone (EXP-687); the\n // full-screen page arm is the one that still needs it.\n closePhoneHidden: `max-sm:hidden`,\n srOnly: `sr-only`,\n // Left-aligned on every viewport (EXP-687): a centered mobile title\n // reads as an alert, and sheets are not alerts.\n header: `flex flex-col gap-2 text-left`,\n // The one scrolling region of a dialog. Everything that can grow — a form's\n // fields, a long list, a wall of explanatory copy — goes in here so the header\n // above it and the footer below it stay pinned to the panel edges. Short\n // content just doesn't scroll: flex-1 only claims free space when the panel is\n // actually height-capped.\n body: `min-h-0 flex-1 overflow-y-auto`,\n // On a phone every action is the full-width `lg` capsule pinned to\n // the bottom of the sheet (EXP-687) — one button shape across web,\n // iOS `GlassSubmitButton` and Android `GlassSubmitButton`.\n footer: `flex flex-col-reverse gap-2 max-sm:[&>[data-slot=button]]:h-10 max-sm:[&>[data-slot=button]]:w-full max-sm:[&>[data-slot=button]]:px-6 sm:flex-row sm:justify-end`,\n /** The Cancel of a sheet arm on a phone (EXP-687): hidden, a sheet is\n * dismissed by dragging it down or tapping outside; `alert`/`page` keep it. */\n cancelPhoneHidden: `max-sm:hidden`,\n title: `text-lg leading-none font-semibold`,\n description: `text-sm text-muted-foreground`,\n} as const\n",
23
+ "// EXP-962 — the DISCLOSURE header: the one-line fold toggle a feed row,\n// a subagent lane, a tool group or a workflow agent opens and closes with.\n// Muted at rest and brightening on hover, a 12px chevron that points right\n// when folded and down when open, `aria-expanded` stating the fold, the\n// whole line the click target. Eight call sites in the steer feed and the\n// workflow card drew it by hand before this.\n//\n// It is NOT the group band: `GlassSectionHeader foldable` / `IssueGroupBand`\n// is a filled strip heading a LIST; this is bare text heading a fold INSIDE\n// a row. Chevron placement: `leading` (the default) sits before the label,\n// the way a tree folds; `trailing` parks it at the far edge after a spacer\n// — a row whose siblings carry no chevron must not indent out of line\n// with them (the tool row's output fold, iOS/Android parity).\n//\n// The header may NOT contain another button: a fold's own action (a\n// group's \"+\", a row's menu) renders beside it, not inside it.\nexport const DISCLOSURE_HEADER_CLASSES = {\n root: `flex w-full min-w-0 cursor-pointer items-center gap-2 rounded-sm text-left text-muted-foreground transition-colors duration-fast outline-none hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50`,\n chevron: `size-3 shrink-0`,\n // EXP-1191: a trailing glyph parks itself with `ml-auto` — a flex-1\n // spacer split the free space with a row's own `flex-1` label and left its\n // trailing count mid-row.\n chevronTrailing: `ml-auto`,\n} as const\n",
24
+ "// FEED-131: THE toast of the primitive sets, sonner-free: the class recipe\n// (the Exponential app's `TOAST_*_CLASS` look, packages/ui/src/toast.tsx,\n// minus sonner's overrides) and the framework-free engine both renderers\n// bind: the store (per-toast clocks that pause while the stack is expanded)\n// and the stack geometry of fixtures/toast-stack.json (a copy of the app's\n// contract, drift-tested from packages/ui).\n//\n// VAPP-106: the constants are WRITTEN here, not imported from the fixture:\n// a renderer entry (`@exponential-at/ui/web/primitives`) ships no fixture\n// (release/size.ts gates it); toast.test.ts holds them equal to\n// fixtures/toast-stack.json `constants`.\n\nexport const TOAST_CONSTANTS = {\n width: 356,\n gap: 14,\n peek: 14,\n scaleStep: 0.05,\n visible: 3,\n durationMs: 4000,\n swipeThreshold: 45,\n viewportOffset: 24,\n mobileViewportOffset: 16,\n placement: { pointer: `bottom-right`, touch: `top-center` },\n touchMaxWidth: 600,\n kinds: [`success`, `error`, `info`, `warning`],\n}\n\nexport type ToastKind = `success` | `error` | `info` | `warning`\nexport type ToastPlacement = `bottom-right` | `top-center`\n\nexport const TOAST_KINDS = TOAST_CONSTANTS.kinds as readonly ToastKind[]\n\n/** Touch = up to and including `touchMaxWidth` (the fixture's phone breakpoint). */\nexport const TOAST_TOUCH_QUERY = `(max-width: ${TOAST_CONSTANTS.touchMaxWidth}px)`\n\nexport const TOAST_CLASSES = {\n /** The fixed region (`<section>`), per placement: `viewportOffset` from\n * the corner on a pointer, `mobileViewportOffset` below the status bar\n * on touch. */\n region: `pointer-events-none fixed z-[100] flex`,\n regionPlacement: {\n \"bottom-right\": `right-6 bottom-6`,\n \"top-center\": `inset-x-4 top-[calc(env(safe-area-inset-top,0px)+16px)] justify-center`,\n } satisfies Record<ToastPlacement, string>,\n /** The stack box (`<ol>`): `width` wide, its height = the geometry's. */\n list: `pointer-events-auto relative m-0 w-[356px] max-w-full list-none p-0 transition-[height] duration-standard ease-standard`,\n listPlacement: {\n \"bottom-right\": ``,\n \"top-center\": `w-full`,\n } satisfies Record<ToastPlacement, string>,\n /** The card: the opaque glass card at radius lg, no shadow; placed by its\n * `--offset`/`--scale`. A collapsed back toast hides its contents behind\n * the front one; a toast past `visible` draws nothing. */\n toast: `absolute inset-x-0 top-(--offset) flex items-start gap-3 rounded-lg border border-glass-stroke-card bg-glass-card-opaque p-4 font-sans text-sm text-foreground scale-(--scale) transition-[top,scale,opacity] duration-standard ease-standard data-[expanded=false]:data-[front=false]:*:opacity-0 data-[visible=false]:pointer-events-none data-[visible=false]:opacity-0`,\n /** A back card shrinks about the edge that PEEKS OUT: the top on a bottom\n * stack, the bottom on a top stack. */\n toastOrigin: {\n bottom: `origin-top`,\n top: `origin-bottom`,\n },\n content: `flex min-w-0 flex-1 flex-col gap-0.5`,\n title: `leading-5 font-medium text-foreground`,\n description: `leading-5 text-muted-foreground`,\n action: `inline-flex h-6 shrink-0 cursor-pointer items-center rounded-md border-0 bg-primary px-2 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90`,\n /** The close glyph: last in the row. */\n close: `order-last inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0 text-muted-foreground transition-colors hover:text-foreground [&_svg]:size-3.5`,\n iconSlot: `flex h-5 shrink-0 items-center`,\n icon: `size-4 shrink-0`,\n /** The ONLY place a toast wears its kind. */\n kindIcon: {\n success: `text-green-500`,\n error: `text-red-500`,\n info: `text-blue-500`,\n warning: `text-yellow-500`,\n } satisfies Record<ToastKind, string>,\n} as const\n\n/** The Lucide glyph each kind paints (the app's concept icons\n * `ui-success`/`ui-error`/`ui-info`/`ui-warning`, packages/icons/icons.json). */\nexport const TOAST_KIND_GLYPH = {\n success: `circle-check`,\n error: `circle-x`,\n info: `info`,\n warning: `triangle-alert`,\n} as const satisfies Record<ToastKind, string>\n\n/** The fixture's `placement`: bottom-right on a pointer, top-centre on touch;\n * a bottom stack measures its peek above the front toast. */\nexport function toastPlacement(isTouch: boolean): { placement: ToastPlacement; anchoredBottom: boolean } {\n const placement = (isTouch ? TOAST_CONSTANTS.placement.touch : TOAST_CONSTANTS.placement.pointer) as ToastPlacement\n return { placement, anchoredBottom: placement.startsWith(`bottom`) }\n}\n\nexport interface ToastStackItem {\n /** The item's top inside the stack box. */\n offset: number\n /** Its width factor. */\n scale: number\n /** Whether it draws at all. */\n visible: boolean\n}\n\n/** The numbers a stack is drawn from (the toast's, the Dock pile's). */\nexport interface StackConstants {\n /** How far an older item peeks out behind the one in front of it. */\n peek: number\n /** How much smaller each rank behind the front draws. */\n scaleStep: number\n /** How many items draw at all while collapsed. */\n visible: number\n /** The space between items while expanded. */\n gap: number\n}\n\n/** THE stack geometry ×4 (fixtures/toast-stack.json `geometry`; N-12: the\n * Dock pile draws it too): `heights` oldest first (the newest is in front).\n * Collapsed, the item of rank r (0 = front) sits r × `peek` from the\n * anchoring edge, shrunk by `scaleStep` per rank (clamped at the last\n * visible rank), `visible` of them drawn; expanded, every item at full\n * size, `gap` apart. */\nexport function stackGeometry(\n heights: readonly number[],\n expanded: boolean,\n anchoredBottom: boolean,\n constants: StackConstants\n): { height: number; items: ToastStackItem[] } {\n const { gap, peek, scaleStep, visible } = constants\n const n = heights.length\n if (n === 0) return { height: 0, items: [] }\n const rank = (i: number) => n - 1 - i\n if (expanded) {\n const height = heights.reduce((sum, h) => sum + h, 0) + (n - 1) * gap\n // The distance of each item from the anchoring edge: the newer ones first.\n const fromEdge: number[] = new Array(n)\n let at = 0\n for (let i = n - 1; i >= 0; i--) {\n fromEdge[i] = at\n at += heights[i]! + gap\n }\n return { height, items: heights.map((h, i) => ({ offset: anchoredBottom ? height - fromEdge[i]! - h : fromEdge[i]!, scale: 1, visible: true })) }\n }\n const height = Math.max(...heights.map((h, i) => rank(i) * peek + h))\n const items = heights.map((h, i) => {\n const r = rank(i)\n const scale = Math.round((1 - Math.min(r, visible - 1) * scaleStep) * 100) / 100\n return { offset: anchoredBottom ? height - r * peek - h : r * peek, scale, visible: r < visible }\n })\n return { height, items }\n}\n\n/** The toast's stack (`stackGeometry` with the toast's numbers). */\nexport function toastStackGeometry(heights: readonly number[], expanded: boolean, anchoredBottom: boolean): { height: number; items: ToastStackItem[] } {\n return stackGeometry(heights, expanded, anchoredBottom, TOAST_CONSTANTS)\n}\n\nexport interface ToastAction {\n label: string\n onClick?: (event: Event) => void\n}\n\nexport interface ToastOptions {\n /** A fixed id (else the store generates `toast-<n>`); re-using a live id\n * replaces that toast. */\n id?: string\n kind?: ToastKind\n description?: string\n action?: ToastAction\n /** The auto-dismiss clock in ms (default `durationMs`); `Infinity` = sticky. */\n duration?: number\n /** A fixed height for the stack geometry (else the renderer measures). */\n height?: number\n onDismiss?: (toast: ToastRecord) => void\n}\n\nexport interface ToastRecord {\n id: string\n kind?: ToastKind\n title: string\n description?: string\n action?: ToastAction\n duration: number\n height?: number\n}\n\nexport interface ToastFn {\n (title: string, options?: ToastOptions): string\n (options: ToastOptions & { title: string }): string\n success: (title: string, options?: Omit<ToastOptions, `kind`>) => string\n error: (title: string, options?: Omit<ToastOptions, `kind`>) => string\n info: (title: string, options?: Omit<ToastOptions, `kind`>) => string\n warning: (title: string, options?: Omit<ToastOptions, `kind`>) => string\n}\n\nexport interface ToastStore {\n toast: ToastFn\n /** Removes one toast, or every toast without an id. */\n dismiss: (id?: string) => void\n /** The live toasts, oldest first. */\n toasts: () => readonly ToastRecord[]\n /** Called with the toasts on every change; returns the unsubscribe. */\n subscribe: (listener: (toasts: readonly ToastRecord[]) => void) => () => void\n /** Stops every clock (the stack expanded), keeping what is left of each. */\n pauseAll: () => void\n /** Restarts every clock with its remaining time. */\n resumeAll: () => void\n readonly paused: boolean\n}\n\ninterface Clock {\n remaining: number\n startedAt: number\n timer?: ReturnType<typeof setTimeout>\n}\n\n/** A toast store: the queue, the per-toast clocks and their pause. */\nexport function createToastStore(): ToastStore {\n let list: ToastRecord[] = []\n const options = new Map<string, ToastOptions>()\n const clocks = new Map<string, Clock>()\n const listeners = new Set<(toasts: readonly ToastRecord[]) => void>()\n let paused = false\n let counter = 0\n const emit = () => {\n for (const l of [...listeners]) l(list)\n }\n const stop = (id: string) => {\n const clock = clocks.get(id)\n if (!clock?.timer) return\n clearTimeout(clock.timer)\n clock.timer = undefined\n clock.remaining = Math.max(0, clock.remaining - (Date.now() - clock.startedAt))\n }\n const start = (id: string) => {\n const clock = clocks.get(id)\n if (!clock || clock.timer || !Number.isFinite(clock.remaining)) return\n clock.startedAt = Date.now()\n clock.timer = setTimeout(() => dismiss(id), clock.remaining)\n }\n const dismiss = (id?: string) => {\n const gone = id === undefined ? list : list.filter((t) => t.id === id)\n if (gone.length === 0) return\n for (const t of gone) {\n const clock = clocks.get(t.id)\n if (clock?.timer) clearTimeout(clock.timer)\n clocks.delete(t.id)\n }\n list = id === undefined ? [] : list.filter((t) => t.id !== id)\n emit()\n for (const t of gone) {\n const o = options.get(t.id)\n options.delete(t.id)\n o?.onDismiss?.(t)\n }\n }\n const add = (title: string, o: ToastOptions = {}): string => {\n const id = o.id ?? `toast-${++counter}`\n const record: ToastRecord = { id, kind: o.kind, title, description: o.description, action: o.action, duration: o.duration ?? TOAST_CONSTANTS.durationMs, height: o.height }\n const old = clocks.get(id)\n if (old?.timer) clearTimeout(old.timer)\n options.set(id, o)\n clocks.set(id, { remaining: record.duration, startedAt: 0 })\n const at = list.findIndex((t) => t.id === id)\n list = at >= 0 ? list.map((t, i) => (i === at ? record : t)) : [...list, record]\n if (!paused) start(id)\n emit()\n return id\n }\n const toast = ((first: string | (ToastOptions & { title: string }), o?: ToastOptions) => (typeof first === `string` ? add(first, o) : add(first.title, first))) as ToastFn\n for (const kind of TOAST_KINDS) toast[kind] = (title, o) => add(title, { ...o, kind })\n return {\n toast,\n dismiss,\n toasts: () => list,\n subscribe: (listener) => {\n listeners.add(listener)\n return () => listeners.delete(listener)\n },\n pauseAll: () => {\n if (paused) return\n paused = true\n for (const id of clocks.keys()) stop(id)\n },\n resumeAll: () => {\n if (!paused) return\n paused = false\n for (const id of clocks.keys()) start(id)\n },\n get paused() {\n return paused\n },\n }\n}\n",
25
+ "// N-12: THE DockCard and THE Dock pile of the primitive sets: the class\n// recipes and the pile's geometry both renderers bind (React\n// @exponential-at/ui-react/primitives `DockCard`/`DockPile`, Solid\n// @exponential-at/ui-solid/primitives, the same markup). A DockCard is a\n// one-row floating card: the kind glyph and the tinted label, a muted\n// caption, trailing meta, ONE title line and the open chevron (or a trailing\n// action); several pile like the toasts (`stackGeometry` with the Dock's\n// numbers, anchored at the bottom: the front card last, the older ones\n// peeking out above it, `visible` of them drawn; expanded = fanned `gap`\n// apart). The Exponential app's Dock (packages/ui dock.tsx) paints through\n// these; its sheet is the app's.\n//\n// VAPP-106: the constants are WRITTEN here (a renderer entry ships no\n// fixture); packages/ui's dock test holds them equal to the app's\n// fixtures/dock.json `stack`.\n\nimport { GLASS_CARD_CLASS } from \"./glass-card\"\nimport { stackGeometry, type StackConstants, type ToastStackItem } from \"./toast\"\n\nexport const DOCK_PILE_CONSTANTS: StackConstants = { peek: 14, scaleStep: 0.05, visible: 3, gap: 6 }\n\nexport type DockCardTint = `plan` | `question` | `muted` | `warning`\n\nexport const DOCK_CARD_CLASSES = {\n /** THE card: the glass card (ONE gray: the opaque card fill under the\n * card hairline), padded. */\n root: `${GLASS_CARD_CLASS} block w-full p-3 text-left outline-none`,\n /** A card that opens (a press, Enter or Space). */\n pressable: `cursor-pointer transition-colors duration-fast hover:bg-glass-active focus-visible:ring-[3px] focus-visible:ring-ring/50`,\n /** The glyph + text row; a card behind the front one hides its words. */\n body: `flex items-start gap-2 data-[hidden=true]:opacity-0`,\n icon: `mt-0.5 size-3.5 shrink-0`,\n text: `min-w-0 flex-1`,\n header: `mb-1 flex items-center gap-2`,\n label: `truncate text-xs font-medium`,\n caption: `min-w-0 truncate text-xs text-muted-foreground`,\n meta: `ml-auto shrink-0 text-xs text-muted-foreground`,\n row: `flex min-w-0 items-center gap-2`,\n title: `min-w-0 flex-1 truncate text-sm text-foreground/90`,\n chevron: `size-3.5 shrink-0 text-muted-foreground`,\n trailing: `shrink-0`,\n /** The tint sits on the glyph and the label alone. */\n tint: {\n plan: `text-primary`,\n question: `text-yellow-400`,\n muted: `text-muted-foreground`,\n warning: `text-amber-400`,\n } satisfies Record<DockCardTint, string>,\n} as const\n\nexport const DOCK_PILE_CLASSES = {\n /** The pile box: its height = the geometry's, animated over `slow`. */\n root: `relative transition-[height] duration-slow ease-standard motion-reduce:transition-none`,\n /** One card, placed by `--offset`/`--scale`; it shrinks about the TOP\n * edge (the one that peeks out above the front card). */\n item: `absolute inset-x-0 top-(--offset) origin-top scale-(--scale) transition-[top,scale,opacity] duration-slow ease-standard motion-reduce:transition-none data-[visible=false]:pointer-events-none data-[visible=false]:opacity-0`,\n} as const\n\n/** The pile's geometry: `stackGeometry` with the Dock's numbers, anchored\n * at the bottom (the front card is the LAST height). */\nexport function dockPileGeometry(heights: readonly number[], expanded: boolean): { height: number; items: ToastStackItem[] } {\n return stackGeometry(heights, expanded, true, DOCK_PILE_CONSTANTS)\n}\n",
26
+ "// EXP-887 — the ONE floating-menu surface recipe.\n//\n// Seven contents painted the same glass box by copy-paste: Select, the\n// dropdown menu and its submenu, the context menu and its submenu, Popover\n// and HoverCard. This is their common core — the fill, the hairline, the\n// radius, the text colour and the open/close animation suite. Everything a\n// single surface owns on its own (its Radix transform-origin variable, its\n// height bound, its overflow rule) stays inline at the call site, because\n// those genuinely differ per menu. EXP-1243: the animation is the\n// `motion-popover` recipe (tailwind.css): scale from 0.96 + fade from the\n// trigger's origin, exit fade only.\nexport const MENU_SURFACE_CLASS = `z-50 rounded-lg border border-glass-stroke-card bg-glass-card-opaque text-popover-foreground motion-popover`\n\n// EXP-1074 — and the ONE menu ROW recipe.\n//\n// The GEOMETRY of a menu is not the call site's: every menu-like row (the\n// context and dropdown items, their sub-triggers, check/radio rows, Select\n// items, Command rows, the typeahead rows) reads the --menu-* vars in\n// styles.css, which mirror packages/design-tokens/tokens.json `menu` — the\n// pointer density from md up, the touch density below — so one change moves\n// every web menu. Since the UI cleanup batch every action menu is the ONE\n// `@exp/ui` `Menu` over these constants (dropdown, pointer and phone-sheet\n// presentations alike), and its static `MenuPanel` is what the styleguide\n// draws. Every row carries the pointer cursor; a disabled one the arrow.\nexport const MENU_CONTENT_CLASS = `min-w-(--menu-min-width) max-w-(--menu-max-width) p-(--menu-surface-padding)`\n\nconst MENU_ROW_BASE = `flex min-h-(--menu-item-height) cursor-pointer items-center gap-(--menu-item-gap) rounded-sm px-(--menu-item-padding-x) py-1 text-sm text-foreground/90 outline-hidden select-none focus:bg-glass-active focus:text-foreground data-[disabled]:cursor-default data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--menu-icon-size) [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!`\n\nexport const MENU_ITEM_CLASS = `relative ${MENU_ROW_BASE} data-[disabled]:pointer-events-none data-[disabled]:opacity-50`\n\n/** A submenu's label never wraps: the value beside it truncates instead.\n * The value (a `MENU_VALUE_CLASS` span) and the chevron both push right;\n * with a value present the chevron gives up its auto margin, so every value\n * ends flush against the chevron column instead of floating mid-row. */\nexport const MENU_SUB_TRIGGER_CLASS = `${MENU_ROW_BASE} whitespace-nowrap data-[state=open]:bg-glass-active data-[variant=destructive]:data-[state=open]:bg-destructive/10 data-[variant=destructive]:data-[state=open]:text-destructive [&>span+svg:last-child]:ml-0`\n\n/** The checkbox / radio rows: the indicator sits in the `pl-8` inset. */\nexport const MENU_CHECK_ITEM_CLASS = `relative flex min-h-(--menu-item-height) cursor-pointer items-center gap-(--menu-item-gap) rounded-sm py-1 pr-(--menu-item-padding-x) pl-8 text-sm text-foreground/90 outline-hidden select-none focus:bg-glass-active focus:text-foreground data-[disabled]:cursor-default data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--menu-icon-size)`\n\nexport const MENU_LABEL_CLASS = `px-(--menu-item-padding-x) py-1.5 text-sm font-medium data-[inset]:pl-8`\n\nexport const MENU_SEPARATOR_CLASS = `-mx-(--menu-surface-padding) my-(--menu-surface-padding) h-px bg-glass-stroke`\n\nexport const MENU_SHORTCUT_CLASS = `ml-auto text-xs tracking-widest text-muted-foreground`\n\n/** The current VALUE beside a submenu's label (\"Status Backlog ›\"): takes\n * what is left of the row and truncates, never the label's room. */\nexport const MENU_VALUE_CLASS = `min-w-0 max-w-[7rem] shrink text-right normal-case tracking-normal truncate`\n\nexport const MENU_CHEVRON_CLASS = `ml-auto size-(--menu-icon-size) shrink-0`\n",
27
+ "import {\n MENU_CHECK_ITEM_CLASS,\n MENU_CHEVRON_CLASS,\n MENU_CONTENT_CLASS,\n MENU_ITEM_CLASS,\n MENU_LABEL_CLASS,\n MENU_SEPARATOR_CLASS,\n MENU_SHORTCUT_CLASS,\n MENU_SUB_TRIGGER_CLASS,\n MENU_SURFACE_CLASS,\n} from \"./menu-surface\"\n\nexport const DROPDOWN_MENU_CLASSES = {\n // EXP-698 menu recipe: opaque card composite, 12 radius, NO blur and\n // NO shadow — see `bg-glass-card-opaque` in styles.css.\n content: `${MENU_SURFACE_CLASS} ${MENU_CONTENT_CLASS} max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto`,\n item: MENU_ITEM_CLASS,\n checkItem: MENU_CHECK_ITEM_CLASS,\n itemIndicator: `pointer-events-none absolute left-2 flex size-3.5 items-center justify-center`,\n checkIcon: `size-4`,\n radioIcon: `size-2 fill-current`,\n label: MENU_LABEL_CLASS,\n separator: MENU_SEPARATOR_CLASS,\n shortcut: MENU_SHORTCUT_CLASS,\n subTrigger: MENU_SUB_TRIGGER_CLASS,\n subChevron: MENU_CHEVRON_CLASS,\n // Portaled: un-portaled sub content lives inside the parent content's DOM,\n // and the parent's `glass-panel` backdrop-filter makes it a containing\n // block whose overflow-x-hidden clips the fixed-positioned submenu to\n // invisibility in Safari/WebKit (EXP-305).\n subContent: `${MENU_SURFACE_CLASS} ${MENU_CONTENT_CLASS} origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden`,\n} as const\n",
28
+ "// EXP-1274 — ONE empty state, two sizes (the catalog `EmptyState` macro's\n// `size`; the ×4 contract is `@exp/domain-contract/fixtures/empty-state.json`).\n//\n// `page`: what a whole screen or pane says when it has nothing — the 48px\n// icon disc, a semibold title, an optional muted sentence that TEACHES the\n// next step, and an optional actions row, centred on a column of at most\n// 28rem.\n//\n// `list`: what a list inside a section, a sidebar or a picker says — a bare\n// 20px muted glyph over ONE muted line, centred, 24px of vertical padding.\n// It never carries a description or a button: the section band's trailing\n// pill (or the picker's own field) is the call to action. Without an icon it\n// is the line `CommandEmpty` draws inside a `Command`.\nexport const EMPTY_STATE_SIZES = [`page`, `list`] as const\nexport type EmptyStateSize = (typeof EMPTY_STATE_SIZES)[number]\n\nexport const EMPTY_STATE_CLASSES = {\n list: `flex w-full flex-col items-center gap-1.5 px-3 py-6 text-center text-sm text-muted-foreground`,\n listIcon: `size-5 shrink-0 text-muted-foreground/60`,\n page: `mx-auto flex max-w-md flex-col items-center gap-3 px-6 py-12 text-center`,\n pageTitle: `text-lg font-semibold`,\n pageDescription: `text-sm text-muted-foreground`,\n pageActions: `mt-2 flex flex-wrap items-center justify-center gap-2`,\n // The compact in-list empty line = `EmptyState size=\"list\"` without a glyph\n // (the emoji picker's grid, a filtered admin table). Kept as its own name\n // because a `children` string reads better than `title` at those call sites.\n listEmpty: `px-3 py-6 text-center text-sm text-muted-foreground`,\n // EXP-962: the CLICKABLE empty state — a dashed, full-width nudge standing\n // where the first item will go, that IS the call to action (the actions\n // panel's \"No custom actions yet / Describe one and your agent will build\n // it\"). Dashed because the box is a placeholder for the row it invites; a\n // button because the shortest path to the row is the box itself. `EmptyState`\n // teaches a PAGE or reports a list, this one starts the list. Desktop\n // `actions_view` draws the same dashed strip.\n cta: `flex w-full cursor-pointer flex-col items-start gap-1 rounded-md border border-dashed border-glass-stroke-strong p-3 text-left text-sm text-muted-foreground transition-colors duration-fast outline-none hover:bg-glass-row hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50`,\n ctaTitle: `flex items-center gap-2`,\n ctaIcon: `size-4 shrink-0`,\n ctaDescription: `text-xs`,\n} as const\n",
29
+ "import { MENU_SURFACE_CLASS } from \"./menu-surface\"\n\n// EXP-760: the shadcn HoverCard, wired to the same opaque card composite the\n// Popover uses (EXP-698 menu recipe — 12 radius, no blur, no shadow).\n//\n// The delays are the product's own, not Radix's defaults: 400 ms to open so a\n// pointer crossing a dense list of `#IDENT` chips never flashes a card, 100 ms\n// to close so the pointer can travel from the trigger into the card. The\n// desktop IDE's `IssuePreviewHost` uses the same pair.\n//\n// Hover is a POINTER affordance: Radix only opens on `pointerenter` from a\n// mouse-like device, so a touch tap on a wrapped trigger still just activates\n// the trigger. Callers gate the mount on `useIsMobile` anyway.\nexport const HOVER_CARD_DELAYS = { openDelay: 400, closeDelay: 100 } as const\n\nexport const HOVER_CARD_CLASSES = {\n content: `${MENU_SURFACE_CLASS} w-80 origin-(--radix-hover-card-content-transform-origin) p-3 outline-hidden`,\n} as const\n",
30
+ "// EXP-903 — the ONE icon disc: a 48px circle holding a 24px glyph.\n//\n// Eight web surfaces drew it by hand — the empty state, the onboarding step\n// card and the invite page in the primary tint, the GitHub claim/installed\n// pages in red, emerald and muted. The tone owns BOTH the wash and the glyph\n// colour, so a call site never restates `text-*` on the icon. Placement\n// (`mx-auto`, margins) stays at the call site.\nexport const ICON_DISC_TONES = [`primary`, `success`, `danger`, `muted`] as const\n\nexport type IconDiscTone = (typeof ICON_DISC_TONES)[number]\n\nexport const ICON_DISC_CLASSES = {\n root: `flex size-12 shrink-0 items-center justify-center rounded-full`,\n tones: {\n primary: `bg-primary/10 text-primary`,\n success: `bg-emerald-500/15 text-emerald-500`,\n danger: `bg-red-500/15 text-red-500`,\n muted: `bg-muted text-muted-foreground`,\n } satisfies Record<IconDiscTone, string>,\n icon: `size-6`,\n} as const\n",
31
+ "// EXP-941 — \"undress the field, the row is the chrome\".\n//\n// Seven surfaces (the glass input/search rows here, the board form's title,\n// the action editor's name, the MCP server rows, the support composer, the\n// issue title field) strip an `Input` down to bare text so the row or card\n// AROUND it draws the box. That was one long class string copy-pasted seven\n// times; it is this constant now. Compose with `cn(BARE_FIELD_CLASS, …)` and\n// add only what the surface itself changes (alignment, padding, colour).\nexport const BARE_FIELD_CLASS = `h-auto min-w-0 flex-1 rounded-none border-0 bg-transparent p-0 text-sm shadow-none focus-visible:border-0 focus-visible:ring-0 md:text-sm`\n\n// EXP-616: glass by default — the card fill + card hairline ARE the field, so\n// callers never re-dress an Input locally. EXP-698: 36 tall, 12 radius, and\n// focus is the STROKE stepping to active — the 3px halo ring is gone from\n// every text field. A constant so a field that is not an `Input` (cmdk's own\n// input in `CommandInput`'s `field` variant) wears the same chrome.\nexport const FIELD_CHROME_CLASS = `h-9 w-full min-w-0 rounded-lg border border-glass-stroke-card bg-glass-card px-3 py-1 text-base shadow-none transition-[color,border-color] duration-fast outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-foreground/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm focus-visible:border-glass-stroke-active focus-visible:ring-0`\n\nexport const INPUT_CLASSES = {\n root: `${FIELD_CHROME_CLASS} aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40`,\n} as const\n",
32
+ "// Round 1: shadcn's Kbd (the key-cap hint the catalog's Kbd macro paints the\n// same way) — a single key, or `KbdGroup` for a chord.\nexport const KBD_CLASSES = {\n root: `pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none [&_svg:not([class*='size-'])]:size-3`,\n group: `inline-flex items-center gap-1`,\n} as const\n",
33
+ "export const LABEL_CLASSES = {\n root: `flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,\n} as const\n",
34
+ "/** EXP-909: the ONE bar every usage surface draws — the rate-limit windows,\n * the run's context, and the tiny three-bar mini line. Before this there were\n * two: a bare `Progress` (primary fill, no tone) under the Context block and a\n * hand-rolled `<span>` track with its own tone map inside the usage cards, so\n * the same 67% was two different colours two rows apart.\n *\n * It IS `Progress` — the Radix root, its track and its indicator — with the\n * severity tone painted on the indicator (`lib/agent-usage.ts` `severity`,\n * hand-mirrored ×4 with the desktop's `usage_bar::meter`, iOS `AgentUsageTrack`\n * and Android `UsageTrack`). Height comes from `className` (`h-1` for the mini\n * line, `h-1.5` for a full window), never from a prop: the tone is the only\n * thing a caller has to think about. */\nexport type MeterTone = `normal` | `warning` | `danger`\n\nexport const METER_CLASSES = {\n root: `h-1.5 bg-glass-stroke-strong`,\n tones: {\n normal: `[&_[data-slot=progress-indicator]]:bg-foreground/30`,\n warning: `[&_[data-slot=progress-indicator]]:bg-amber-500`,\n danger: `[&_[data-slot=progress-indicator]]:bg-destructive`,\n } satisfies Record<MeterTone, string>,\n} as const\n",
35
+ "import { MENU_SURFACE_CLASS } from \"./menu-surface\"\n\nexport const POPOVER_CLASSES = {\n // EXP-698 menu recipe: opaque card composite, 12 radius, NO blur and\n // NO shadow. A popover keeps its `p-4` form padding; menu-shaped\n // hosts (Command lists) pass `p-0` as they always have.\n content: `${MENU_SURFACE_CLASS} w-72 origin-(--radix-popover-content-transform-origin) p-4 outline-hidden`,\n} as const\n",
36
+ "// EXP-1097 — the sub-issue COMPLETION ring that leads the issue detail's\n// \"Sub-issues\" band: `done` of `total` as an arc over a 20% track. The same\n// 16-unit box, 2-unit stroke and track as `ContextRing` (`ringGeometry`), so\n// the two rings read as one family; drawn at icon size (14px by default) and\n// painted in the team's COMPLETED status colour, handed in exactly like a\n// `StatusGlyph`'s (a token class for builtins, a hex for custom rows).\n\n/** The filled share of the ring, 0..100 (an empty or nonsensical total = 0). */\nexport function progressRingPercent(done: number, total: number): number {\n if (!Number.isFinite(done) || !Number.isFinite(total) || total <= 0) return 0\n return (Math.min(Math.max(done, 0), total) / total) * 100\n}\n\nexport const PROGRESS_RING_CLASSES = {\n root: `shrink-0 -rotate-90`,\n} as const\n",
37
+ "export const PROGRESS_CLASSES = {\n root: `bg-primary/20 relative h-2 w-full overflow-hidden rounded-full`,\n indicator: `bg-primary h-full flex-1 transition-all`,\n // EXP-724: no value = INDETERMINATE (Radix's own `null` state) — a short bar\n // sweeping the track, for work with a real duration but no measurable\n // progress (the steering compaction strip). Under reduced motion it parks\n // at the left as a static, dimmed segment rather than animating.\n indicatorIndeterminate: `w-1/3 motion-safe:animate-progress-indeterminate motion-reduce:opacity-60`,\n indicatorDeterminate: `w-full`,\n} as const\n\n/** The determinate indicator's offset for `value` (0-100). */\nexport function progressIndicatorTransform(value: number | null | undefined): string {\n return `translateX(-${100 - (value || 0)}%)`\n}\n",
38
+ "// Round 1: shadcn's ScrollArea on Radix (the catalog's ScrollArea macro is a\n// Box with overflowX/Y; this is the app-side primitive with styled bars).\nexport const SCROLL_AREA_CLASSES = {\n root: `relative`,\n viewport: `size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1`,\n scrollbar: `flex touch-none p-px transition-colors select-none`,\n orientations: {\n vertical: `h-full w-2.5 border-l border-l-transparent`,\n horizontal: `h-2.5 flex-col border-t border-t-transparent`,\n },\n thumb: `relative flex-1 rounded-full bg-border`,\n} as const\n\n// FEED-131 — Radix ScrollArea's framework-free half for the Solid twin (React's\n// Radix writes the same itself): the inline styles in Radix's order, the\n// `type=\"scroll\"` state machine and the thumb maths.\n\nexport type ScrollAreaDir = `ltr` | `rtl`\nexport type ScrollAreaOrientation = `vertical` | `horizontal`\n\n/** Radix's viewport <style>: the native scrollbar hidden. */\nexport const SCROLL_AREA_VIEWPORT_CSS = `[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}`\n\nexport function scrollAreaRootStyle(cornerWidth: number, cornerHeight: number): Record<string, string> {\n return { position: `relative`, \"--radix-scroll-area-corner-width\": `${cornerWidth}px`, \"--radix-scroll-area-corner-height\": `${cornerHeight}px` }\n}\n\nexport function scrollAreaViewportStyle(xEnabled: boolean, yEnabled: boolean): Record<string, string> {\n return { \"overflow-x\": xEnabled ? `scroll` : `hidden`, \"overflow-y\": yEnabled ? `scroll` : `hidden` }\n}\n\n/** The viewport's `display: table` sizer. */\nexport const SCROLL_AREA_CONTENT_STYLE = { \"min-width\": `100%`, display: `table` } as const\n\nexport function scrollAreaScrollbarStyle(orientation: ScrollAreaOrientation, dir: ScrollAreaDir, thumbSize: number): Record<string, string> {\n if (orientation === `horizontal`) {\n return { position: `absolute`, bottom: `0`, left: dir === `rtl` ? `var(--radix-scroll-area-corner-width)` : `0`, right: dir === `ltr` ? `var(--radix-scroll-area-corner-width)` : `0`, \"--radix-scroll-area-thumb-width\": `${thumbSize}px` }\n }\n const s: Record<string, string> = { position: `absolute`, top: `0` }\n if (dir === `ltr`) s.right = `0`\n if (dir === `rtl`) s.left = `0`\n s.bottom = `var(--radix-scroll-area-corner-height)`\n s[`--radix-scroll-area-thumb-height`] = `${thumbSize}px`\n return s\n}\n\nexport const SCROLL_AREA_THUMB_STYLE = { width: `var(--radix-scroll-area-thumb-width)`, height: `var(--radix-scroll-area-thumb-height)` } as const\n\nexport function scrollAreaCornerStyle(width: number, height: number, dir: ScrollAreaDir): Record<string, string> {\n const s: Record<string, string> = { width: `${width}px`, height: `${height}px`, position: `absolute` }\n if (dir === `ltr`) s.right = `0`\n if (dir === `rtl`) s.left = `0`\n s.bottom = `0`\n return s\n}\n\n/** A scrollbar's / thumb's `data-state`. */\nexport const scrollAreaVisibility = (visible: boolean): `visible` | `hidden` => (visible ? `visible` : `hidden`)\n\nexport type ScrollAreaScrollState = `hidden` | `scrolling` | `interacting` | `idle`\n/** Radix's `type=\"scroll\"` machine. */\nexport const SCROLL_AREA_SCROLL_MACHINE: Record<ScrollAreaScrollState, Partial<Record<string, ScrollAreaScrollState>>> = {\n hidden: { SCROLL: `scrolling` },\n scrolling: { SCROLL_END: `idle`, POINTER_ENTER: `interacting` },\n interacting: { SCROLL: `interacting`, POINTER_LEAVE: `idle` },\n idle: { HIDE: `hidden`, SCROLL: `scrolling`, POINTER_ENTER: `interacting` },\n}\nexport const SCROLL_AREA_SCROLL_INITIAL: ScrollAreaScrollState = `hidden`\n\nexport interface ScrollAreaSizes {\n content: number\n viewport: number\n scrollbar: { size: number; paddingStart: number; paddingEnd: number }\n}\n\nexport const scrollAreaThumbRatio = (viewport: number, content: number): number => {\n const ratio = viewport / content\n return isNaN(ratio) ? 0 : ratio\n}\n\n/** Radix's `getThumbSize`: the ratio of the track, at least 18px. */\nexport function scrollAreaThumbSize(sizes: ScrollAreaSizes): number {\n const padding = sizes.scrollbar.paddingStart + sizes.scrollbar.paddingEnd\n return Math.max((sizes.scrollbar.size - padding) * scrollAreaThumbRatio(sizes.viewport, sizes.content), 18)\n}\n\nconst linearScale = (input: [number, number], output: [number, number]) => (value: number) => {\n if (input[0] === input[1] || output[0] === output[1]) return output[0]\n return output[0] + ((output[1] - output[0]) / (input[1] - input[0])) * (value - input[0])\n}\n\n/** Radix's `getScrollPositionFromPointer`. */\nexport function scrollAreaScrollFromPointer(pointer: number, pointerOffset: number, sizes: ScrollAreaSizes, dir: ScrollAreaDir = `ltr`): number {\n const size = scrollAreaThumbSize(sizes)\n const offset = pointerOffset || size / 2\n const min = sizes.scrollbar.paddingStart + offset\n const max = sizes.scrollbar.size - sizes.scrollbar.paddingEnd - (size - offset)\n const maxScroll = sizes.content - sizes.viewport\n return linearScale([min, max], dir === `ltr` ? [0, maxScroll] : [maxScroll * -1, 0])(pointer)\n}\n\n/** Radix's `getThumbOffsetFromScroll`. */\nexport function scrollAreaThumbOffset(scroll: number, sizes: ScrollAreaSizes, dir: ScrollAreaDir = `ltr`): number {\n const size = scrollAreaThumbSize(sizes)\n const bar = sizes.scrollbar.size - sizes.scrollbar.paddingStart - sizes.scrollbar.paddingEnd\n const maxScroll = sizes.content - sizes.viewport\n const [lo, hi] = dir === `ltr` ? [0, maxScroll] : [maxScroll * -1, 0]\n const clamped = Math.min(hi, Math.max(lo, scroll))\n return linearScale([0, maxScroll], [0, bar - size])(clamped)\n}\n",
39
+ "// EXP-698 — the ONE segmented control on the web. The Radix tabs below and\n// the route-link strips that can't use Radix semantics (team settings nav,\n// admin nav) all read these two strings, so the capsule can't drift into\n// three hand-mirrored copies again. The strips supply their own active /\n// inactive link colours (`activeProps`), which is the only part Radix owns\n// through `data-[state=active]` instead.\nexport const SEGMENTED_LIST = `inline-flex h-9 w-fit items-center justify-center rounded-full border border-glass-stroke-section bg-glass-section p-[3px] text-muted-foreground`\n\n// EXP-851: the strip's ROW. The Inbox / My issues strip and the Support\n// Open / Resolved strip are ONE control at ONE size — same trigger padding\n// (`SEGMENTED_TAB`), same row padding — in the big list views…\nexport const SEGMENTED_ROW = `flex shrink-0 items-center justify-between gap-2 px-4 pt-3 pb-2 md:px-6`\n\n// …and in the sidebar's list nav, where the 17rem slot is the only thing that\n// changes (the strip itself is identical).\nexport const SEGMENTED_ROW_COMPACT = `flex shrink-0 items-center justify-between gap-2 px-2 pt-2 pb-2`\n\n/** The ONE trigger sizing both strips use — no per-surface `h-8`/`text-xs`\n * overrides, or the two drift by a pixel again. */\nexport const SEGMENTED_TAB = `px-3`\n\nexport const SEGMENTED_ITEM = `inline-flex shrink-0 items-center justify-center gap-1.5 rounded-full border border-transparent px-3 py-1 text-sm font-medium whitespace-nowrap transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`\n\nexport const TABS_CLASSES = {\n root: `flex flex-col gap-2`,\n list: SEGMENTED_LIST,\n trigger: `${SEGMENTED_ITEM} h-[calc(100%-1px)] flex-1 text-foreground dark:text-muted-foreground dark:data-[state=active]:border-glass-stroke-active dark:data-[state=active]:bg-glass-active dark:data-[state=active]:text-foreground disabled:pointer-events-none disabled:opacity-50`,\n content: `flex-1 outline-none`,\n} as const\n",
40
+ "import { SEGMENTED_TAB } from \"./tabs\"\n\n// EXP-941 — the segmented capsule as a COMPONENT.\n//\n// `tabs.tsx` has owned the class recipe for a while, but the eight strips that\n// use it each wired their own `Tabs` + `TabsList` + N `TabsTrigger`s by hand,\n// so the triggers drifted in padding and in whether they carried a glyph. This\n// renders the strip from an option array instead. It changes no string in\n// `tabs.tsx`: the constants stay exactly as they are (other surfaces, and\n// `mobile-detail-header.test.ts`, read them directly).\n//\n// `embedded` swaps the free-floating capsule for `GlassTabsRow` — the strip as\n// the FIRST ROW of a glass group (EXP-694), which is what the settings sheets\n// and the natives' `GlassSegmentedControl(embedded:)` draw.\nexport const SEGMENTED_CONTROL_CLASSES = {\n trigger: SEGMENTED_TAB,\n /** `fill`: span the container instead of the capsule's natural `w-fit`. */\n fill: `w-full`,\n} as const\n",
41
+ "import { MENU_SURFACE_CLASS } from \"./menu-surface\"\n\nexport const SELECT_CLASSES = {\n // EXP-616: glass by default, matching Input/Textarea. EXP-698: 12\n // radius, card fill + card hairline, focus on the stroke, no ring.\n trigger: `flex w-fit items-center justify-between gap-2 rounded-lg border border-glass-stroke-card bg-glass-card px-3 py-2 text-sm whitespace-nowrap shadow-none transition-[color,border-color] duration-fast outline-none hover:bg-glass-active/50 focus-visible:border-glass-stroke-active focus-visible:ring-0 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-foreground/50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--menu-icon-size) [&_svg:not([class*='text-'])]:text-muted-foreground`,\n triggerIcon: `size-4 opacity-50`,\n // EXP-698 menu recipe: opaque card composite, 12 radius, NO blur and\n // NO shadow — see `bg-glass-card-opaque` in styles.css.\n content: `${MENU_SURFACE_CLASS} relative max-h-(--radix-select-content-available-height) min-w-(--menu-min-width) max-w-(--menu-max-width) origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto`,\n /** `position=\"popper\"` only. */\n contentPopper: `data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1`,\n viewport: `p-(--menu-surface-padding)`,\n /** `position=\"popper\"` only. */\n viewportPopper: `h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1`,\n label: `px-(--menu-item-padding-x) py-1.5 text-xs text-muted-foreground`,\n item: `relative flex min-h-(--menu-item-height) w-full cursor-pointer items-center gap-(--menu-item-gap) rounded-sm py-1 pr-8 pl-(--menu-item-padding-x) text-sm text-foreground/90 outline-hidden select-none focus:bg-glass-active focus:text-foreground data-[disabled]:cursor-default data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-(--menu-icon-size) [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2`,\n itemIndicator: `absolute right-2 flex size-3.5 items-center justify-center`,\n itemCheck: `size-4`,\n separator: `pointer-events-none -mx-1 my-1 h-px bg-glass-stroke`,\n scrollButton: `flex cursor-default items-center justify-center py-1`,\n scrollIcon: `size-4`,\n} as const\n\n// FEED-131 — Radix Select's INLINE styles, in the order Radix writes them\n// (kebab-case keys): the Solid twin paints Radix's DOM by hand and the\n// web-parity gate diffs the `style` attribute strings.\nexport const SELECT_INLINE = {\n value: { \"pointer-events\": `none` },\n /** The item-aligned position's fixed wrapper (before `position()` runs). */\n wrapper: { display: `flex`, \"flex-direction\": `column`, position: `fixed` },\n viewport: { position: `relative`, flex: `1`, overflow: `hidden auto` },\n scrollButton: { \"flex-shrink\": `0` },\n /** The wrapper's `justify-content` once an expand-on-scroll pinned it to the bottom. */\n expandEnd: `flex-end`,\n} as const\n\nexport const SELECT_VIEWPORT_ATTR = `data-radix-select-viewport`\n/** Radix Select's viewport sheet (the native scrollbar hidden). */\nexport const SELECT_VIEWPORT_CSS = `[${SELECT_VIEWPORT_ATTR}]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[${SELECT_VIEWPORT_ATTR}]::-webkit-scrollbar{display:none}`\n\n/** The content's style, `item-aligned`: box sizing + max height, the\n * dismissable layer's pointer events, the flex column, no outline. */\nexport function selectItemAlignedContentStyle(pointerEvents: string | undefined): Record<string, string | undefined> {\n return { \"box-sizing\": `border-box`, \"max-height\": `100%`, \"pointer-events\": pointerEvents, display: `flex`, \"flex-direction\": `column`, outline: `none` }\n}\n\n/** The content's style, `popper`: Radix's PopperContent order (its\n * `--radix-select-*` aliases, `animation: none` until placed). */\nexport function selectPopperContentStyle(pointerEvents: string | undefined, positioned: boolean): Record<string, string | undefined> {\n return {\n \"box-sizing\": `border-box`,\n \"pointer-events\": pointerEvents,\n display: `flex`,\n \"flex-direction\": `column`,\n outline: `none`,\n \"--radix-select-content-transform-origin\": `var(--radix-popper-transform-origin)`,\n \"--radix-select-content-available-width\": `var(--radix-popper-available-width)`,\n \"--radix-select-content-available-height\": `var(--radix-popper-available-height)`,\n \"--radix-select-trigger-width\": `var(--radix-popper-anchor-width)`,\n \"--radix-select-trigger-height\": `var(--radix-popper-anchor-height)`,\n animation: positioned ? undefined : `none`,\n }\n}\n",
42
+ "export const SEPARATOR_CLASSES = {\n root: `shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,\n} as const\n",
43
+ "// EXP-687 — the shared chrome of every mobile bottom sheet, whether it was\n// painted by ui/dialog.tsx's `sheet` arm or by ui/sheet.tsx's `bottom` side.\n// One grabber, one drag gesture, no ✕: the sheet closes by tapping outside or\n// by dragging it down (native parity across iOS/Android/web).\nexport const SHEET_CHROME_CLASSES = {\n /** The pill at the top edge of a sheet. Purely decorative, but it drags. */\n grabber: `mx-auto mt-2 -mb-1 h-1 w-9 shrink-0 rounded-full bg-foreground/30`,\n} as const\n",
44
+ "export type SheetSide = `top` | `right` | `bottom` | `left`\n\nexport const SHEET_CLASSES = {\n overlay: `fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:duration-standard data-[state=closed]:ease-accelerate data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:duration-slow data-[state=open]:ease-decelerate`,\n // The mobile sheet radius (24px = rounded-*-3xl) on the leading\n // edge. Full-screen consumers (e.g. the search sheet) pass\n // rounded-none.\n content: `group/sheet fixed z-50 flex flex-col gap-4 border-glass-stroke-card shadow-lg motion-sheet`,\n // Side/top drawers stay frosted glass (EXP-269); the BOTTOM sheet\n // is the opaque #18181B surface every client shares (EXP-687) — it\n // covers the screen edge to edge, so there is nothing to blur.\n sides: {\n right: `inset-y-0 right-0 h-full w-3/4 rounded-l-3xl border-l bg-card/85 backdrop-blur-2xl data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm`,\n left: `inset-y-0 left-0 h-full w-3/4 rounded-r-3xl border-r bg-card/85 backdrop-blur-2xl data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm`,\n top: `inset-x-0 top-0 h-auto rounded-b-3xl border-b bg-card/85 backdrop-blur-2xl data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top`,\n bottom: `inset-x-0 bottom-0 h-auto max-h-[90dvh] rounded-t-3xl border-t bg-glass-bottom data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom`,\n } satisfies Record<SheetSide, string>,\n /** The hidden Close a drag-to-dismiss clicks. */\n dragClose: `hidden`,\n close: `absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary`,\n closeIcon: `size-4`,\n srOnly: `sr-only`,\n header: `flex flex-col gap-1.5 p-4 text-left`,\n footer: `mt-auto flex flex-col gap-2 p-4`,\n // Headline weight and size on a phone (EXP-687): the same left-aligned\n // sheet title on web, iOS (`.headline`) and Android (`titleMedium`).\n title: `font-semibold text-foreground max-sm:group-data-[side=bottom]/sheet:text-lg max-sm:group-data-[side=bottom]/sheet:leading-none`,\n description: `text-sm text-muted-foreground`,\n} as const\n",
45
+ "export const SKELETON_CLASSES = {\n root: `animate-pulse rounded-md bg-accent`,\n} as const\n",
46
+ "// EXP-1275 (EXP-1259 D8.1): THE inline spinner, feedback-states.json\n// `inline.spinner` (10px) by default. The EXP-1274 list-head glyph (the\n// GlassSectionHeader `loading` arm) IS this primitive; a pending Button swaps\n// its icon slot for it at `pending.spinner` (12px). ×4: desktop\n// `feedback::spinner`, iOS `ExpSpinner`, Android `Spinner`.\nexport const SPINNER_CLASSES = {\n root: `shrink-0 animate-spin text-muted-foreground`,\n} as const\n",
47
+ "export const SWITCH_CLASSES = {\n // EXP-616: the default track grows one notch toward the iOS toggle\n // (20×36 with a 16px thumb); size=sm stays untouched for dense rows.\n root: `peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-none transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-5 data-[size=default]:w-9 data-[size=sm]:h-3.5 data-[size=sm]:w-6 data-[state=checked]:bg-primary data-[state=unchecked]:bg-glass-active`,\n // The checked offset is (track width - 2px of border - thumb width),\n // written relative to the thumb's own width: sm is 24-2-12 = 10px =\n // calc(100% - 2px); the widened default is 36-2-16 = 18px =\n // calc(100% + 2px).\n thumb: `pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 group-data-[size=default]/switch:data-[state=checked]:translate-x-[calc(100%+2px)] dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground`,\n} as const\n",
48
+ "// FEED-131: shadcn's Table (`table-container` > `table` > header/body/footer\n// rows) at the LOOK of the renderer's Table native: a muted 12px/medium\n// header, hairline row dividers on `--border`, the glass row wash under the\n// pointer, the selected row (`data-state=\"selected\"`) on the active wash,\n// cells 8px/12px at 14px, no outer border. The sheet ships no preflight,\n// so the root collapses its borders itself (row hairlines need it).\nexport const TABLE_CLASSES = {\n container: `relative w-full overflow-x-auto`,\n root: `w-full caption-bottom border-collapse text-sm`,\n header: `[&_tr]:hover:bg-transparent`,\n body: `[&_tr:last-child]:border-0`,\n footer: `border-t border-border font-medium [&>tr]:last:border-b-0`,\n row: `border-b border-border transition-colors duration-fast hover:bg-glass-row data-[state=selected]:bg-glass-active`,\n head: `px-3 py-2 text-left align-middle text-xs font-medium whitespace-nowrap text-muted-foreground [&:has([role=checkbox])]:pr-0`,\n cell: `px-3 py-2 align-middle text-sm whitespace-nowrap [&:has([role=checkbox])]:pr-0`,\n caption: `mt-4 text-sm text-muted-foreground`,\n} as const\n",
49
+ "export const TEXTAREA_CLASSES = {\n // EXP-616: glass by default, matching Input. EXP-698: the same 12\n // radius / card fill / card hairline recipe, focus on the stroke and\n // no ring. `resize-none` is part of it — every field here auto-grows\n // through `field-sizing-content`, so the native grip only ever landed\n // mid-card over a tool row. Browsers without `field-sizing`\n // (Firefox, Safari) keep a vertical grip so the field can still grow.\n root: `flex field-sizing-content min-h-16 w-full resize-y [@supports(field-sizing:content)]:resize-none rounded-lg border border-glass-stroke-card bg-glass-card px-3 py-2 text-base shadow-none transition-[color,border-color] duration-fast outline-none placeholder:text-foreground/50 focus-visible:border-glass-stroke-active focus-visible:ring-0 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:ring-destructive/40`,\n} as const\n",
50
+ "export const TOOLTIP_CLASSES = {\n // Glass tooltip (EXP-269) — no Arrow: a translucent arrow\n // double-renders against the blurred panel behind it. EXP-277:\n // on the shared glass-panel recipe (same 95% step it already sat\n // on; unifies blur radius + shadow).\n content: `glass-panel z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-lg px-3 py-1.5 text-xs text-balance text-popover-foreground motion-popover`,\n} as const\n",
51
+ "// EXP-698 — string shaping shared by the surfaces that print paths. Moved into\n// the package with the diff view (EXP-895), its only caller.\n//\n// A diff's file paths are the one place where `truncate` (a trailing ellipsis)\n// destroys the only part a reader needs: the FILENAME. Middle-truncation drops\n// the middle of the path instead, so `apps/web/src/…/file-diff-card.tsx` still\n// names the file. CSS can't do this, so it is a string transform.\n/**\n * Shorten `value` to at most `max` characters by replacing its middle with an\n * ellipsis, keeping both ends visible (the tail slightly longer, since that is\n * where the filename lives). Shorter values, and any `max` too small to hold a\n * character on each side of the ellipsis, are returned unchanged.\n */\nexport function middleTruncate(value: string, max: number): string {\n if (max <= 0) return value\n // `[...value]` so astral characters (emoji in a path) are never cut in half.\n const chars = [...value]\n if (chars.length <= max) return value\n // 1 for the ellipsis itself, and a character on each side of it.\n if (max < 3) return value\n const keep = max - 1\n const head = Math.floor(keep / 2)\n const tail = keep - head\n return `${chars.slice(0, head).join(``)}…${chars.slice(chars.length - tail).join(``)}`\n}\n",
52
+ "/** The attribute the anchored arm stamps on its portal. It lives outside the\n * host's subtree, so a Radix modal would take a click on it as an OUTSIDE\n * interaction and close: dialog hosts whitelist this selector in their\n * `onInteractOutside`, and treat a mounted one as \"a menu is open\" when\n * routing Escape. */\nexport const TYPEAHEAD_PORTAL_SELECTOR = `[data-editor-autocomplete]`\n\n/** Whether a Radix outside-interaction (its `target` is the pointed-at\n * node) landed inside the anchored arm's portal. `DialogContent` and\n * `SheetContent` ignore that one by default. */\nexport function isTypeaheadPortalInteraction(event: {\n target: EventTarget | null\n}): boolean {\n return (\n event.target instanceof Element &&\n event.target.closest(TYPEAHEAD_PORTAL_SELECTOR) !== null\n )\n}\n"
53
+ ],
54
+ "mappings": ";AAAA;AAEO,IAAM,iBAAiB,IAC5B,2dACA;AAAA,EACE,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,SAAS;AAAA,MACT,OAAO;AAAA,MACP,WAAW;AAAA,MAKX,OAAO;AAAA,MACP,MAAM;AAAA,MAKN,MAAM;AAAA,IACR;AAAA,IASA,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MAIN,WAAW;AAAA,MACX,WAAW;AAAA,MAMX,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAKA,kBAAkB;AAAA,IAChB;AAAA,MACE,SAAS;AAAA,MACT,MAAM,CAAC,QAAQ,WAAW,SAAS;AAAA,MACnC,WAAW;AAAA,IACb;AAAA,IAIA;AAAA,MACE,SAAS,CAAC,WAAW,eAAe,WAAW,SAAS,aAAa,OAAO;AAAA,MAC5E,MAAM,CAAC,WAAW,MAAM,MAAM,IAAI;AAAA,MAClC,WAAW;AAAA,IACb;AAAA,IACA;AAAA,MACE,SAAS,CAAC,WAAW,eAAe,WAAW,SAAS,WAAW;AAAA,MACnE,MAAM,CAAC,QAAQ,WAAW,SAAS;AAAA,MACnC,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AACF,CACF;;;AC3EO,IAAM,uBAAuB;AAAA,EAClC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ,eAAe;AAAA,EACvB,QAAQ,eAAe,EAAE,SAAS,UAAU,CAAC;AAC/C;;ACdA,gBAAS;AASF,IAAM,gBAAgB,KAC3B,qOACA;AAAA,EACE,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,EACX;AACF,CACF;AAIO,IAAM,gBAAgB;AAAA,EAC3B,OAAO;AAAA,EACP,aAAa;AACf;;ACnBO,IAAM,mBAAmB;AAEhC,IAAM,mBAAmB;AACzB,IAAM,YAAY;AAElB,IAAM,UAAU,IAAI;AAEb,SAAS,cAAc,CAAC,QAA2C;AAAA,EACxE,MAAM,QAAQ,QAAQ,OAAO,UAAU,EAAE;AAAA,EACzC,IAAI,OAAO;AAAA,EACX,WAAW,QAAQ,OAAO;AAAA,IACxB,QAAQ;AAAA,IACR,OAAO,KAAK,KAAK,MAAM,SAAS,MAAM;AAAA,EACxC;AAAA,EACA,OAAO,OAAO;AAAA;;ACtBT,IAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EAEV,eAAe;AACjB;AAMO,SAAS,iBAAiB,CAAC,QAAuD;AAAA,EACvF,OAAO,WAAW,aAAa,WAAW,OACtC,YACA,gBAAgB,eAAe,MAAM;AAAA;AAIpC,SAAS,oBAAoB,CAAC,KAAyD;AAAA,EAC5F,OAAO;AAAA,IACL,iBAAiB,sBAAsB;AAAA,IACvC,OAAO;AAAA,EACT;AAAA;;ACbK,IAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AACF;AAGO,SAAS,UAAU,CAAC,OAAe,MAAM,IAAY;AAAA,EAC1D,OAAO,QAAQ,MAAM,GAAG,SAAS,OAAO,KAAK;AAAA;;ACpBxC,IAAM,qBAAqB;AAAA,EAEhC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AAAA,EACV,cAAc;AAAA,EACd,QAAQ;AACV;;ACTO,IAAM,mBAAmB;AAAA,EAC9B,MAAM;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,EACT,EAAE,KAAK,GAAG;AAAA,EACV,YAAY;AAAA,IACV,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,KAAK;AAAA,IACL,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,eAAe;AAAA,IACf,WAAW;AAAA,IACX,eAAe;AAAA,IACf,UAAU;AAAA,IACV,eAAe;AAAA,IACf,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,MAAM;AAAA,IACN,oBAAoB;AAAA,IACpB,aAAa;AAAA,IACb,KAAK;AAAA,IACL,aAAa;AAAA,IACb,cAAc;AAAA,IACd,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EAEA,cAAc;AAAA,IACZ,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EAEA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AAAA,EACA,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,WAAW;AACb;;ACnCO,IAAM,mBAAmB;AAEzB,IAAM,qBAAqB,EAAE,MAAM,iBAAiB;;;ACdpD,IAAM,eAAe;AAAA,EAC1B,MAAM,GAAG;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AACV;;ACVO,IAAM,mBAAmB;AAAA,EAG9B,MAAM;AAAA,EACN,WAAW;AAAA,EACX,MAAM;AACR;;ACSO,SAAS,aAAa,CAAC,SAA0B;AAAA,EACtD,MAAM,IAAI,OAAO,YAAY,YAAY,OAAO,SAAS,OAAO,IAAI,KAAK,MAAM,OAAO,IAAI;AAAA,EAC1F,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAAA;AAI5B,SAAS,YAAY,CAAC,OAAgB,UAA6B;AAAA,EACxE,IAAI,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO,MAAM,IAAI,MAAM,EAAE,OAAO,OAAO;AAAA,EACjE,MAAM,MAAM,UAAU,aAAa,UAAU,OAAO,KAAK,OAAO,KAAK;AAAA,EACrE,IAAI,CAAC;AAAA,IAAU,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AAAA,EACrC,OAAO,IACJ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AAAA;AAKZ,SAAS,YAAY,CAAC,QAA2B,OAAe,UAAmB,OAAoC;AAAA,EAC5H,IAAI,CAAC;AAAA,IAAU,OAAO,CAAC,KAAK;AAAA,EAC5B,MAAM,OAAO,OAAO,SAAS,KAAK,IAAI,OAAO,OAAO,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,GAAG,QAAQ,KAAK;AAAA,EAC3F,MAAM,OAAO,CAAC,MAAc;AAAA,IAC1B,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,IACzB,OAAO,IAAI,IAAI,OAAO,mBAAmB;AAAA;AAAA,EAE3C,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;AAAA;AAS/C,IAAM,uBAAuB;AAAA,EAClC,MAAM;AAAA,EASN,MAAM;AAAA,EACN,cAAc;AAAA,EACd,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO;AAAA,EACP,aAAa;AAAA,EACb,OAAO;AAAA,EACP,aAAa;AACf;;ACnEA;AACA;AAMO,SAAS,EAAE,IAAI,QAAsB;AAAA,EAC1C,OAAO,QAAQ,KAAK,MAAM,CAAC;AAAA;AAGtB,SAAS,WAAW,CAAC,OAAe;AAAA,EACzC,OAAO,MACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,EAC3B,KAAK,EAAE,EACP,YAAY,EACZ,MAAM,GAAG,CAAC;AAAA;;ACjBf,gBAAS;AAQF,IAAM,oBAAoB,KAC/B,gPACA;AAAA,EACE,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,EACX;AACF,CACF;AAOO,IAAM,mBAA2C;AAAA,EACtD,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AAAA,EACX,KAAK;AAAA,EACL,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAEO,IAAM,wBAAwB,KACnC,+kBACA;AAAA,EACE,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,SAAS;AAAA,EACX;AACF,CACF;AAIO,IAAM,qBAAqB;AAAA,EAChC,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AACV;;AClEO,IAAM,kBAAkB;AAAA,EAE7B,MAAM;AAAA,EACN,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,YAAY,eAAe,EAAE,SAAS,SAAS,MAAM,WAAW,WAAW,iCAAiC,CAAC;AAAA,EAC7G,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,cAAc;AAAA,EACd,MAAM;AAAA,EACN,WAAW;AAAA,EACX,UAAU;AACZ;AAGO,IAAM,sBAAsB;AAAA,EACjC,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AACf;AAIA,IAAM,uBAAuB;AAC7B,IAAM,wBAAwB;AAC9B,IAAM,4BAA4B;AAClC,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,kBAAkB;AACxB,IAAM,wBAAwB;AAC9B,IAAM,uBAAuB;AAC7B,IAAM,SAAS;AACf,IAAM,aAAa;AACnB,IAAM,WAAW;AACjB,IAAM,cAAc;AAEpB,SAAS,SAAS,CAAC,OAAe,OAAe,YAAoB,YAAoB,YAAoB,YAAoB,MAAsC;AAAA,EACrK,IAAI,eAAe,MAAM;AAAA,IAAQ,OAAO,eAAe,MAAM,SAAS,uBAAuB;AAAA,EAC7F,MAAM,MAAM,GAAG,cAAc;AAAA,EAC7B,IAAI,KAAK,SAAS;AAAA,IAAW,OAAO,KAAK;AAAA,EACzC,MAAM,YAAY,WAAW,OAAO,UAAU;AAAA,EAC9C,IAAI,QAAQ,WAAW,QAAQ,WAAW,UAAU;AAAA,EACpD,IAAI,OAAO;AAAA,EACX,OAAO,SAAS,GAAG;AAAA,IACjB,IAAI,QAAQ,UAAU,OAAO,OAAO,YAAY,YAAY,QAAQ,GAAG,aAAa,GAAG,IAAI;AAAA,IAC3F,IAAI,QAAQ,MAAM;AAAA,MAChB,IAAI,UAAU;AAAA,QAAY,SAAS;AAAA,MACnC,KAAK,IAAI,OAAO,KAAK,MAAM,OAAO,QAAQ,CAAC,CAAC,GAAG;AAAA,QAC7C,SAAS;AAAA,QACT,MAAM,SAAS,MAAM,MAAM,YAAY,QAAQ,CAAC,EAAE,MAAM,UAAU;AAAA,QAClE,IAAI,UAAU,aAAa;AAAA,UAAG,SAAS,KAAK,IAAI,iBAAiB,OAAO,MAAM;AAAA,MAChF,EAAE,KAAK,IAAI,SAAS,KAAK,MAAM,OAAO,QAAQ,CAAC,CAAC,GAAG;AAAA,QACjD,SAAS;AAAA,QACT,MAAM,SAAS,MAAM,MAAM,YAAY,QAAQ,CAAC,EAAE,MAAM,WAAW;AAAA,QACnE,IAAI,UAAU,aAAa;AAAA,UAAG,SAAS,KAAK,IAAI,iBAAiB,OAAO,MAAM;AAAA,MAChF,EAAE,KAAK;AAAA,QACL,SAAS;AAAA,QACT,IAAI,aAAa;AAAA,UAAG,SAAS,KAAK,IAAI,iBAAiB,QAAQ,UAAU;AAAA;AAAA,MAE3E,IAAI,MAAM,OAAO,KAAK,MAAM,MAAM,OAAO,UAAU;AAAA,QAAG,SAAS;AAAA,IACjE;AAAA,IACA,IAAK,QAAQ,uBAAuB,WAAW,OAAO,QAAQ,CAAC,MAAM,WAAW,OAAO,aAAa,CAAC,KAAO,WAAW,OAAO,aAAa,CAAC,MAAM,WAAW,OAAO,UAAU,KAAK,WAAW,OAAO,QAAQ,CAAC,MAAM,WAAW,OAAO,UAAU,GAAI;AAAA,MAClP,MAAM,aAAa,UAAU,OAAO,OAAO,YAAY,YAAY,QAAQ,GAAG,aAAa,GAAG,IAAI;AAAA,MAClG,IAAI,aAAa,sBAAsB;AAAA,QAAO,QAAQ,aAAa;AAAA,IACrE;AAAA,IACA,IAAI,QAAQ;AAAA,MAAM,OAAO;AAAA,IACzB,QAAQ,WAAW,QAAQ,WAAW,QAAQ,CAAC;AAAA,EACjD;AAAA,EACA,KAAK,OAAO;AAAA,EACZ,OAAO;AAAA;AAGT,IAAM,YAAY,CAAC,MAAc,EAAE,YAAY,EAAE,QAAQ,aAAa,GAAG;AAIlE,SAAS,YAAY,CAAC,OAAe,OAAe,UAAsC;AAAA,EAC/F,MAAM,OAAO,YAAY,SAAS,SAAS,IAAI,GAAG,SAAS,SAAS,KAAK,GAAG,MAAM;AAAA,EAClF,OAAO,UAAU,MAAM,OAAO,UAAU,IAAI,GAAG,UAAU,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA;AA6BpE,SAAS,kBAAkB,CAAC,OAAqC,OAAe,SAAwB,cAAmC;AAAA,EAChJ,MAAM,SAAS,IAAI;AAAA,EACnB,MAAM,QAAQ,IAAI;AAAA,EAClB,IAAI,QAAQ;AAAA,EACZ,MAAM,QAAQ,CAAC,MAAM,OAAO;AAAA,IAC1B,MAAM,QAAQ,KAAK,aAAa,IAAI,QAAS,KAAK,QAAQ,OAAO,KAAK,OAAO,OAAO,KAAK,QAAQ,IAAI,IAAK;AAAA,IAC1G,OAAO,IAAI,KAAK,IAAI,KAAK;AAAA,IACzB,IAAI,CAAC,KAAK,cAAc,QAAQ;AAAA,MAAG;AAAA,IACnC,IAAI,SAAS;AAAA,MAAG;AAAA,IAChB,IAAI,IAAI,MAAM,IAAI,KAAK,KAAK;AAAA,IAC5B,IAAI,CAAC;AAAA,MAAG,MAAM,IAAI,KAAK,OAAQ,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,GAAG,GAAG,CAAE;AAAA,IAC5D,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,OAAO,GAAG,CAAC;AAAA,IACrC,EAAE,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK;AAAA,GAChC;AAAA,EACD,MAAM,SAAS,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,QAAQ,EAAE,UAAU,EAAE,EAAE;AAAA,EACzE,IAAI,OAAO;AAAA,IACT,WAAW,KAAK;AAAA,MAAQ,EAAE,IAAI,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;AAAA,IAC7E,OAAO,KAAK,CAAC,GAAG,MAAO,EAAE,UAAU,YAAY,KAAK,EAAE,UAAU,YAAY,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAG;AAAA,EACjH,EAAE;AAAA,IAAK,OAAO,KAAK,CAAC,GAAG,MAAO,EAAE,UAAU,YAAY,KAAK,EAAE,UAAU,YAAY,IAAI,EAAE,KAAK,EAAE,EAAG;AAAA,EACnG,OAAO,EAAE,OAAO,QAAQ,OAAO,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO;AAAA;AAKhG,IAAM,uBAAuB;AACpC,IAAM,OAAO;AACb,IAAM,eAAe,GAAG;AACxB,IAAM,QAAQ;AA4BP,SAAS,kBAAkB,CAAC,GAAwB;AAAA,EACzD,IAAI,SAAS;AAAA,EACb,IAAI,QAAQ,EAAE,MAAM,EAAE,OAAO,KAAK,KAAK;AAAA,EACvC,IAAI;AAAA,EACJ,IAAI,MAAM;AAAA,EACV,IAAI,UAAU;AAAA,EACd,MAAM,UAAU,IAAI;AAAA,EACpB,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,YAAY,IAAI;AAAA,EACtB,IAAI,QAA4B;AAAA,EAChC,IAAI,aAAa;AAAA,EACjB,IAAI,cAAc;AAAA,EAClB,IAAI,SAAS;AAAA,EACb,IAAI,mBAAmB;AAAA,EAEvB,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU;AAAA,EACzC,MAAM,YAAY,MAAM,WAAW,MAAM,EAAE,MAAM,EAAE,iBAAiB;AAAA,EACpE,MAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA,UAAU,QAAQ,CAAC,MAAM,EAAE,CAAC;AAAA;AAAA,EAE9B,MAAM,QAAQ,MAAM;AAAA,IAClB,EAAE,SAAS;AAAA;AAAA,EAEb,MAAM,QAAQ,MAAM,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;AAAA,EACvG,MAAM,SAAS,MAAM,mBAAmB,MAAM,GAAG,UAAU,IAAI,SAAS,IAAI,OAAO,CAAC;AAAA,EAEpF,MAAM,WAAW,CAAC,MAAc,OAA8B,CAAC,MAAM;AAAA,IACnE,MAAM,IAAI,EAAE,MAAM;AAAA,IAClB,IAAI,UAAU,EAAE,UAAU,YAAY,EAAE,MAAM,KAAK,IAAI;AAAA,MAAQ;AAAA,IAC/D,IAAI,EAAE,UAAU;AAAA,MAAW,QAAQ;AAAA,IACnC,EAAE,gBAAgB,IAAI;AAAA,IACtB,IAAI,CAAC,KAAK;AAAA,MAAS,SAAS;AAAA,IAC5B,mBAAmB;AAAA,IACnB,KAAK;AAAA,IACL,MAAM;AAAA;AAAA,EAGR,MAAM,eAAe,MAAM,MAAM,KAAK,OAAO,iBAA8B,YAAY,KAAK,CAAC,CAAC;AAAA,EAC9F,MAAM,aAAa,MAAM,OAAO,cAA2B,GAAG,4BAA4B,KAAK;AAAA,EAG/F,MAAM,UAAU,CAAC,WAAoB,WAAgC;AAAA,IACnE,MAAM,OAAO,MAAM,KAAK,UAAU,QAAQ,EACvC,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC,EACxB,OAAO,CAAC,MAAkB,MAAM,SAAS;AAAA,IAC5C,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,MAAM,aAAa,CAAC,MAAa,KAAK,IAAI,GAAG,GAAG,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,OAAO,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;AAAA,IACzH,IAAI;AAAA,IACJ,IAAI,CAAC,UAAU;AAAA,MAAG,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;AAAA,IAC/D,KAAK;AAAA,MACH,MAAM,OAAO,CAAC,MAAc,EAAE,SAAS,SAAS,IAAI,EAAE,SAAS,UAAU,IAAI;AAAA,MAC7E,MAAM,QAAQ,CAAC,MAAc,EAAE,SAAS,SAAU,OAAO,IAAI,EAAE,EAAE,KAAK,IAAK,EAAE,SAAS,UAAU,WAAW,CAAC,IAAI;AAAA,MAChH,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG;AAAA;AAAA,IAE3F,IAAI,KAAK,MAAM,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE;AAAA,MAAG;AAAA,IACzC,WAAW,KAAK;AAAA,MAAM,IAAI,EAAE;AAAA,QAAI,UAAU,YAAY,EAAE,EAAE;AAAA;AAAA,EAG5D,OAAO;AAAA,QACD,OAAO,GAAG;AAAA,MACZ,OAAO;AAAA;AAAA,QAEL,MAAM,GAAG;AAAA,MACX,OAAO;AAAA;AAAA,QAEL,KAAK,GAAG;AAAA,MACV,MAAM,IAAI,EAAE,MAAM,EAAE;AAAA,MACpB,OAAO,MAAM,YAAY,EAAE,KAAK,IAAI;AAAA;AAAA,QAElC,UAAU,GAAG;AAAA,MACf,OAAO;AAAA;AAAA,IAET,SAAS,CAAC,UAAsB;AAAA,MAC9B,UAAU,IAAI,QAAQ;AAAA,MACtB,OAAO,MAAM,KAAK,UAAU,OAAO,QAAQ;AAAA;AAAA,IAE7C,SAAS,MAAM;AAAA,IAEf,SAAS,CAAC,MAAc,SAAS,OAAO;AAAA,MACtC,IAAI,SAAS;AAAA,QAAQ;AAAA,MACrB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,cAAc;AAAA,MACd,IAAI;AAAA,QAAQ;AAAA,MACZ,KAAK;AAAA,MACL,MAAM;AAAA;AAAA,IAER;AAAA,IAEA,SAAS,GAAG;AAAA,MACV,MAAM,IAAI,EAAE,MAAM,EAAE;AAAA,MACpB,IAAI,MAAM,aAAa,EAAE,KAAK,MAAM;AAAA,QAAO,OAAO;AAAA,MAClD,QAAQ,EAAE,KAAK;AAAA,MACf,mBAAmB;AAAA,MACnB,SAAS;AAAA,MACT,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA;AAAA,IAET,QAAQ,CAAC,IAAwB;AAAA,MAC/B,QAAQ;AAAA;AAAA,IAEV;AAAA,IAEA,KAAK,CAAC,WAAmB,UAA8B;AAAA,MACrD,IAAI,CAAC,UAAU;AAAA,QAAG,OAAO;AAAA,MACzB,OAAO,YAAY,OAAO,EAAE,WAAW,QAAQ,QAAQ,IAAI;AAAA;AAAA,IAG7D,YAAY,CAAC,SAAiB;AAAA,MAC5B,IAAI,CAAC,UAAU;AAAA,QAAG,OAAO;AAAA,MACzB,OAAO,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW,KAAK,MAAM,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA,IAGvF,KAAK,GAAG;AAAA,MACN,OAAO,OAAO,EAAE,UAAU;AAAA;AAAA,IAE5B,QAAQ,CAAC,OAA+I;AAAA,MACtJ,MAAM,IAAW,EAAE,IAAI,MAAM,OAAO,OAAO,MAAM;AAAA,MACjD,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,MACnB,aAAa;AAAA,MACb,IAAI,EAAE,SAAS,UAAU,CAAC,KAAK;AAAA,QAAO,cAAc;AAAA,MACpD,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO,MAAM;AAAA,QACX,QAAQ,OAAO,EAAE,EAAE;AAAA,QACnB,IAAI,EAAE;AAAA,UAAI,KAAK,OAAO,EAAE,EAAE;AAAA,QAC1B,aAAa;AAAA,QACb,IAAI,EAAE,SAAS,UAAU,eAAe,EAAE;AAAA,UAAI,cAAc;AAAA,QAC5D,KAAK;AAAA,QACL,MAAM;AAAA;AAAA;AAAA,IAIV,MAAM,CAAC,IAAY,OAAuE;AAAA,MACxF,MAAM,IAAI,QAAQ,IAAI,EAAE;AAAA,MACxB,IAAI,CAAC;AAAA,QAAG;AAAA,MACR,IAAI,UAAU;AAAA,MACd,IAAI,QAAQ,SAAS,MAAM,OAAO,EAAE,IAAI;AAAA,QACtC,IAAI,EAAE;AAAA,UAAI,KAAK,OAAO,EAAE,EAAE;AAAA,QAC1B,EAAE,KAAK,MAAM,MAAM;AAAA,QACnB,IAAI,EAAE;AAAA,UAAI,KAAK,IAAI,EAAE,IAAI,CAAC;AAAA,QAC1B,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,IAAI,MAAM,UAAU,aAAa,MAAM,UAAU,EAAE,OAAO;AAAA,QACxD,EAAE,QAAQ,MAAM;AAAA,QAChB,aAAa;AAAA,QACb,IAAI,CAAC,KAAK;AAAA,UAAO,cAAc;AAAA,QAC/B,UAAU;AAAA,MACZ;AAAA,MACA,IAAI,cAAc,UAAU,MAAM,YAAY,CAAC,GAAG,KAAK,MAAQ,OAAO,EAAE,YAAY,CAAC,GAAG,KAAK,MAAQ,GAAG;AAAA,QACtG,EAAE,WAAW,MAAM;AAAA,QACnB,aAAa;AAAA,QACb,UAAU;AAAA,MACZ;AAAA,MACA,IAAI,cAAc,SAAS,MAAM,aAAa,EAAE,UAAU;AAAA,QACxD,EAAE,WAAW,MAAM;AAAA,QACnB,UAAU;AAAA,MACZ;AAAA,MACA,IAAI,CAAC;AAAA,QAAS;AAAA,MACd,KAAK;AAAA,MACL,MAAM;AAAA;AAAA,IAKR,KAAK,GAAG;AAAA,MACN,IAAI,CAAC;AAAA,QAAO;AAAA,MACZ,IAAI,YAAY;AAAA,QACd,aAAa;AAAA,QACb,QAAQ,WAAW,OAAO;AAAA,QAC1B,QAAQ,OAAO,MAAM;AAAA,QACrB,WAAW,SAAS,MAAM,KAAK,MAAM,iBAAiB,mCAAmC,CAAC;AAAA,UAAG,QAAQ,OAAO,MAAM;AAAA,MACpH;AAAA,MACA,IAAI,aAAa;AAAA,QACf,cAAc;AAAA,QACd,MAAM,QAAQ,aAAa,EAAE;AAAA,QAC7B,MAAM,OAAO,OAAO,aAAa,YAAY,KAAK;AAAA,QAClD,IAAI,SAAS,KAAK,OAAO;AAAA,UACvB,SAAS,IAAI;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,MAAM,WAAW;AAAA,MACvB,MAAM,KAAK,KAAK,MAAM;AAAA,MACtB,IAAI,OAAO,YAAY;AAAA,QACrB,aAAa;AAAA,QACb,KAAK;AAAA,MACP;AAAA,MACA,IAAI,kBAAkB;AAAA,QACpB,mBAAmB;AAAA,QACnB,IAAI,UAAU,KAAK;AAAA,UACjB,IAAI,IAAI,eAAe,sBAAsB;AAAA,YAAK,IAAI,QAAQ,KAAK,GAAG,cAAc,qCAAqC,GAAG,eAAe,EAAE,OAAO,UAAU,CAAC;AAAA,UAC/J,IAAI,eAAe,EAAE,OAAO,UAAU,CAAC;AAAA,QACzC;AAAA,QACA,SAAS;AAAA,MACX;AAAA;AAAA,IAGF,SAAS,CAAC,GAAkB;AAAA,MAC1B,IAAI,EAAE,oBAAoB,EAAE,eAAe,EAAE,YAAY;AAAA,QAAK;AAAA,MAC9D,MAAM,OAAO,QAAQ,EAAE,MAAM,EAAE,IAAI;AAAA,MACnC,MAAM,OAAO,CAAC,OAAgC;AAAA,QAC5C,IAAI;AAAA,UAAI,SAAS,GAAG,aAAa,YAAY,KAAK,EAAE;AAAA;AAAA,MAEtD,MAAM,KAAK,CAAC,MAAc,KAAK,aAAa,EAAE,EAAE;AAAA,MAChD,MAAM,OAAO,MAAM,GAAG,aAAa,EAAE,SAAS,CAAC;AAAA,MAC/C,MAAM,OAAO,CAAC,UAAkB;AAAA,QAC9B,MAAM,OAAO,aAAa;AAAA,QAC1B,MAAM,IAAI,KAAK,UAAU,CAAC,OAAO,OAAO,WAAW,CAAC;AAAA,QACpD,IAAI,OAAO,KAAK,IAAI;AAAA,QACpB,IAAI;AAAA,UAAM,OAAO,IAAI,QAAQ,IAAI,KAAK,KAAK,SAAS,KAAK,IAAI,UAAU,KAAK,SAAS,KAAK,KAAK,KAAK,IAAI;AAAA,QACxG,KAAK,IAAI;AAAA;AAAA,MAEX,MAAM,QAAQ,CAAC,UAAkB;AAAA,QAC/B,IAAI,IAAgC,WAAW,GAAG,QAAQ,KAAK;AAAA,QAC/D,IAAI;AAAA,QACJ,OAAO,KAAK,CAAC,OAAO;AAAA,UAClB,IAAI,QAAQ,IAAI,aAAa,GAAG,OAAO,CAAC,IAAI,aAAa,GAAG,OAAO,EAAE;AAAA,UACrE,QAAQ,GAAG,cAA2B,YAAY;AAAA,QACpD;AAAA,QACA,IAAI;AAAA,UAAO,KAAK,KAAK;AAAA,QACrB;AAAA,UAAK,KAAK,KAAK;AAAA;AAAA,MAEjB,MAAM,OAAO,MAAM;AAAA,QACjB,EAAE,eAAe;AAAA,QACjB,IAAI,EAAE;AAAA,UAAS,KAAK;AAAA,QACpB,KAAK,IAAI,EAAE;AAAA,UAAQ,MAAM,CAAC;AAAA,QAC1B;AAAA,UAAK,KAAK,CAAC;AAAA;AAAA,MAEb,MAAM,KAAK,MAAM;AAAA,QACf,EAAE,eAAe;AAAA,QACjB,IAAI,EAAE;AAAA,UAAS,GAAG,CAAC;AAAA,QACnB,KAAK,IAAI,EAAE;AAAA,UAAQ,MAAM,EAAE;AAAA,QAC3B;AAAA,UAAK,KAAK,EAAE;AAAA;AAAA,MAEd,QAAQ,EAAE;AAAA,QACR,KAAK;AAAA,QACL,KAAK;AAAA,UACH,IAAI,EAAE;AAAA,YAAS,KAAK;AAAA,UACpB;AAAA,QACF,KAAK;AAAA,UACH,KAAK;AAAA,UACL;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAAA,UACH,IAAI,EAAE;AAAA,YAAS,GAAG;AAAA,UAClB;AAAA,QACF,KAAK;AAAA,UACH,GAAG;AAAA,UACH;AAAA,QACF,KAAK;AAAA,UACH,EAAE,eAAe;AAAA,UACjB,GAAG,CAAC;AAAA,UACJ;AAAA,QACF,KAAK;AAAA,UACH,EAAE,eAAe;AAAA,UACjB,KAAK;AAAA,UACL;AAAA,QACF,KAAK,SAAS;AAAA,UACZ,EAAE,eAAe;AAAA,UACjB,WAAW,GAAG,cAAc,IAAI,MAAM,oBAAoB,CAAC;AAAA,UAC3D;AAAA,QACF;AAAA;AAAA;AAAA,EAGN;AAAA;AAKF,SAAS,YAAY,CAAC,IAAa,UAAkB,KAA6B;AAAA,EAChF,IAAI,IAAI,MAAM,IAAI,GAAG,qBAAqB,GAAG;AAAA,EAC7C,OAAO,GAAG;AAAA,IACR,IAAI,EAAE,QAAQ,QAAQ;AAAA,MAAG,OAAO;AAAA,IAChC,IAAI,MAAM,IAAI,EAAE,qBAAqB,EAAE;AAAA,EACzC;AAAA,EACA,OAAO;AAAA;AAKF,SAAS,gBAAgB,CAAC,OAA2B,UAAmB,IAAgC,OAAuB;AAAA,EACpI,IAAI,UAAU;AAAA,IAAW,OAAO,MAAM,KAAK;AAAA,EAC3C,IAAI,OAAO,aAAa;AAAA,IAAU,OAAO,SAAS,KAAK;AAAA,EACvD,IAAI;AAAA,IAAI,QAAQ,GAAG,eAAe,IAAI,KAAK;AAAA,EAC3C,OAAO;AAAA;AAKF,SAAS,wBAAwB,CAAC,MAAmB,OAAgC;AAAA,EAC1F,IAAI,OAAO,mBAAmB;AAAA,IAAa,OAAO,MAAM;AAAA,EACxD,IAAI,MAAM;AAAA,EACV,MAAM,KAAK,IAAI,eAAe,MAAM;AAAA,IAClC,MAAM,sBAAsB,MAAM,KAAK,MAAM,YAAY,sBAAsB,GAAG,MAAM,aAAa,QAAQ,CAAC,KAAK,CAAC;AAAA,GACrH;AAAA,EACD,GAAG,QAAQ,KAAK;AAAA,EAChB,OAAO,MAAM;AAAA,IACX,qBAAqB,GAAG;AAAA,IACxB,GAAG,UAAU,KAAK;AAAA;AAAA;;ACxdf,IAAM,YAAY;AAElB,IAAM,cAAc;AAIpB,IAAM,cAAc;AAUpB,SAAS,YAAY,CAAC,SAA+B;AAAA,EAC1D,MAAM,gBAAgB,IAAI,KAAK,KAAK;AAAA,EACpC,MAAM,UAAU,OAAO,SAAS,OAAO,IACnC,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAClC;AAAA,EACJ,OAAO;AAAA,IACL;AAAA,IACA,YAAY,iBAAiB,IAAI,UAAU;AAAA,EAC7C;AAAA;AAOK,IAAM,kBAA4C;AAAA,EACvD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AACV;AAEO,IAAM,uBAAuB;AAAA,EAClC,MAAM;AAAA,EACN,KAAK;AACP;;ACrBA,IAAM,oBAAoB;AAEnB,IAAM,eAAe,GAAG;AAExB,IAAM,oBAAoB,GAAG;AAE7B,IAAM,eAAe;AAErB,IAAM,cAAc;AAIpB,IAAM,cAA+C;AAAA,EAC1D,OAAO;AAAA,GACN,eAAe;AAAA,EAChB,OAAO;AAAA,EACP,MAAM;AACR;;AC1CO,IAAM,qBAAqB;AAE3B,IAAM,iBAAiB;AAAA,EAC5B,SAAS;AAAA,EAIT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAyBhB,SAAS;AAAA,EAET,SAAS;AAAA,EAET,WAAW;AAAA,EACX,OAAO;AAAA,EAGP,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EAGR,QAAQ;AAAA,EAMR,MAAM;AAAA,EAIN,QAAQ;AAAA,EAGR,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,aAAa;AACf;;AC/CO,IAAM,4BAA4B;AAAA,EACvC,MAAM;AAAA,EACN,SAAS;AAAA,EAIT,iBAAiB;AACnB;;ACXO,IAAM,kBAAkB;AAAA,EAC7B,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,WAAW,EAAE,SAAS,gBAAgB,OAAO,aAAa;AAAA,EAC1D,eAAe;AAAA,EACf,OAAO,CAAC,WAAW,SAAS,QAAQ,SAAS;AAC/C;AAKO,IAAM,cAAc,gBAAgB;AAGpC,IAAM,oBAAoB,eAAe,gBAAgB;AAEzD,IAAM,gBAAgB;AAAA,EAI3B,QAAQ;AAAA,EACR,iBAAiB;AAAA,IACf,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AAAA,EAEA,MAAM;AAAA,EACN,eAAe;AAAA,IACb,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AAAA,EAIA,OAAO;AAAA,EAGP,aAAa;AAAA,IACX,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,SAAS;AAAA,EACT,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EAER,OAAO;AAAA,EACP,UAAU;AAAA,EACV,MAAM;AAAA,EAEN,UAAU;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAIO,IAAM,mBAAmB;AAAA,EAC9B,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AACX;AAIO,SAAS,cAAc,CAAC,SAA0E;AAAA,EACvG,MAAM,YAAa,UAAU,gBAAgB,UAAU,QAAQ,gBAAgB,UAAU;AAAA,EACzF,OAAO,EAAE,WAAW,gBAAgB,UAAU,WAAW,QAAQ,EAAE;AAAA;AA8B9D,SAAS,aAAa,CAC3B,SACA,UACA,gBACA,WAC6C;AAAA,EAC7C,QAAQ,KAAK,MAAM,WAAW,YAAY;AAAA,EAC1C,MAAM,IAAI,QAAQ;AAAA,EAClB,IAAI,MAAM;AAAA,IAAG,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE;AAAA,EAC3C,MAAM,OAAO,CAAC,MAAc,IAAI,IAAI;AAAA,EACpC,IAAI,UAAU;AAAA,IACZ,MAAM,SAAS,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,KAAK;AAAA,IAElE,MAAM,WAAqB,IAAI,MAAM,CAAC;AAAA,IACtC,IAAI,KAAK;AAAA,IACT,SAAS,IAAI,IAAI,EAAG,KAAK,GAAG,KAAK;AAAA,MAC/B,SAAS,KAAK;AAAA,MACd,MAAM,QAAQ,KAAM;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,QAAQ,OAAO,QAAQ,IAAI,CAAC,GAAG,OAAO,EAAE,QAAQ,iBAAiB,SAAS,SAAS,KAAM,IAAI,SAAS,IAAK,OAAO,GAAG,SAAS,KAAK,EAAE,EAAE;AAAA,EAClJ;AAAA,EACA,MAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC;AAAA,EACpE,MAAM,QAAQ,QAAQ,IAAI,CAAC,GAAG,MAAM;AAAA,IAClC,MAAM,IAAI,KAAK,CAAC;AAAA,IAChB,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,IAAI,GAAG,UAAU,CAAC,IAAI,aAAa,GAAG,IAAI;AAAA,IAC7E,OAAO,EAAE,QAAQ,iBAAiB,SAAS,IAAI,OAAO,IAAI,IAAI,MAAM,OAAO,SAAS,IAAI,QAAQ;AAAA,GACjG;AAAA,EACD,OAAO,EAAE,QAAQ,MAAM;AAAA;AAIlB,SAAS,kBAAkB,CAAC,SAA4B,UAAmB,gBAAsE;AAAA,EACtJ,OAAO,cAAc,SAAS,UAAU,gBAAgB,eAAe;AAAA;AA+DlE,SAAS,gBAAgB,GAAe;AAAA,EAC7C,IAAI,OAAsB,CAAC;AAAA,EAC3B,MAAM,UAAU,IAAI;AAAA,EACpB,MAAM,SAAS,IAAI;AAAA,EACnB,MAAM,YAAY,IAAI;AAAA,EACtB,IAAI,SAAS;AAAA,EACb,IAAI,UAAU;AAAA,EACd,MAAM,OAAO,MAAM;AAAA,IACjB,WAAW,KAAK,CAAC,GAAG,SAAS;AAAA,MAAG,EAAE,IAAI;AAAA;AAAA,EAExC,MAAM,OAAO,CAAC,OAAe;AAAA,IAC3B,MAAM,QAAQ,OAAO,IAAI,EAAE;AAAA,IAC3B,IAAI,CAAC,OAAO;AAAA,MAAO;AAAA,IACnB,aAAa,MAAM,KAAK;AAAA,IACxB,MAAM,QAAQ;AAAA,IACd,MAAM,YAAY,KAAK,IAAI,GAAG,MAAM,aAAa,KAAK,IAAI,IAAI,MAAM,UAAU;AAAA;AAAA,EAEhF,MAAM,QAAQ,CAAC,OAAe;AAAA,IAC5B,MAAM,QAAQ,OAAO,IAAI,EAAE;AAAA,IAC3B,IAAI,CAAC,SAAS,MAAM,SAAS,CAAC,OAAO,SAAS,MAAM,SAAS;AAAA,MAAG;AAAA,IAChE,MAAM,YAAY,KAAK,IAAI;AAAA,IAC3B,MAAM,QAAQ,WAAW,MAAM,QAAQ,EAAE,GAAG,MAAM,SAAS;AAAA;AAAA,EAE7D,MAAM,UAAU,CAAC,OAAgB;AAAA,IAC/B,MAAM,OAAO,OAAO,YAAY,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,IACrE,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,WAAW,KAAK,MAAM;AAAA,MACpB,MAAM,QAAQ,OAAO,IAAI,EAAE,EAAE;AAAA,MAC7B,IAAI,OAAO;AAAA,QAAO,aAAa,MAAM,KAAK;AAAA,MAC1C,OAAO,OAAO,EAAE,EAAE;AAAA,IACpB;AAAA,IACA,OAAO,OAAO,YAAY,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,IAC7D,KAAK;AAAA,IACL,WAAW,KAAK,MAAM;AAAA,MACpB,MAAM,IAAI,QAAQ,IAAI,EAAE,EAAE;AAAA,MAC1B,QAAQ,OAAO,EAAE,EAAE;AAAA,MACnB,GAAG,YAAY,CAAC;AAAA,IAClB;AAAA;AAAA,EAEF,MAAM,MAAM,CAAC,OAAe,IAAkB,CAAC,MAAc;AAAA,IAC3D,MAAM,KAAK,EAAE,MAAM,SAAS,EAAE;AAAA,IAC9B,MAAM,SAAsB,EAAE,IAAI,MAAM,EAAE,MAAM,OAAO,aAAa,EAAE,aAAa,QAAQ,EAAE,QAAQ,UAAU,EAAE,YAAY,gBAAgB,YAAY,QAAQ,EAAE,OAAO;AAAA,IAC1K,MAAM,MAAM,OAAO,IAAI,EAAE;AAAA,IACzB,IAAI,KAAK;AAAA,MAAO,aAAa,IAAI,KAAK;AAAA,IACtC,QAAQ,IAAI,IAAI,CAAC;AAAA,IACjB,OAAO,IAAI,IAAI,EAAE,WAAW,OAAO,UAAU,WAAW,EAAE,CAAC;AAAA,IAC3D,MAAM,KAAK,KAAK,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,IAC5C,OAAO,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,MAAO,MAAM,KAAK,SAAS,CAAE,IAAI,CAAC,GAAG,MAAM,MAAM;AAAA,IAC/E,IAAI,CAAC;AAAA,MAAQ,MAAM,EAAE;AAAA,IACrB,KAAK;AAAA,IACL,OAAO;AAAA;AAAA,EAET,MAAM,QAAS,CAAC,OAAoD,MAAsB,OAAO,UAAU,WAAW,IAAI,OAAO,CAAC,IAAI,IAAI,MAAM,OAAO,KAAK;AAAA,EAC5J,WAAW,QAAQ;AAAA,IAAa,MAAM,QAAQ,CAAC,OAAO,MAAM,IAAI,OAAO,KAAK,GAAG,KAAK,CAAC;AAAA,EACrF,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,MAAM;AAAA,IACd,WAAW,CAAC,aAAa;AAAA,MACvB,UAAU,IAAI,QAAQ;AAAA,MACtB,OAAO,MAAM,UAAU,OAAO,QAAQ;AAAA;AAAA,IAExC,UAAU,MAAM;AAAA,MACd,IAAI;AAAA,QAAQ;AAAA,MACZ,SAAS;AAAA,MACT,WAAW,MAAM,OAAO,KAAK;AAAA,QAAG,KAAK,EAAE;AAAA;AAAA,IAEzC,WAAW,MAAM;AAAA,MACf,IAAI,CAAC;AAAA,QAAQ;AAAA,MACb,SAAS;AAAA,MACT,WAAW,MAAM,OAAO,KAAK;AAAA,QAAG,MAAM,EAAE;AAAA;AAAA,QAEtC,MAAM,GAAG;AAAA,MACX,OAAO;AAAA;AAAA,EAEX;AAAA;;;AC/QK,IAAM,sBAAsC,EAAE,MAAM,IAAI,WAAW,MAAM,SAAS,GAAG,KAAK,EAAE;AAI5F,IAAM,oBAAoB;AAAA,EAG/B,MAAM,GAAG;AAAA,EAET,WAAW;AAAA,EAEX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AAAA,EAEV,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AACF;AAEO,IAAM,oBAAoB;AAAA,EAE/B,MAAM;AAAA,EAGN,MAAM;AACR;AAIO,SAAS,gBAAgB,CAAC,SAA4B,UAAgE;AAAA,EAC3H,OAAO,cAAc,SAAS,UAAU,MAAM,mBAAmB;AAAA;;AClD5D,IAAM,qBAAqB;AAa3B,IAAM,qBAAqB;AAElC,IAAM,gBAAgB;AAEf,IAAM,kBAAkB,YAAY;AAMpC,IAAM,yBAAyB,GAAG;AAGlC,IAAM,wBAAwB;AAE9B,IAAM,mBAAmB;AAEzB,IAAM,uBAAuB;AAE7B,IAAM,sBAAsB;AAI5B,IAAM,mBAAmB;AAEzB,IAAM,qBAAqB;;;ACrC3B,IAAM,wBAAwB;AAAA,EAGnC,SAAS,GAAG,sBAAsB;AAAA,EAClC,MAAM;AAAA,EACN,WAAW;AAAA,EACX,eAAe;AAAA,EACf,WAAW;AAAA,EACX,WAAW;AAAA,EACX,OAAO;AAAA,EACP,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EAKZ,YAAY,GAAG,sBAAsB;AACvC;;AClBO,IAAM,oBAAoB,CAAC,QAAQ,MAAM;AAGzC,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,aAAa;AAAA,EAIb,WAAW;AAAA,EAQX,KAAK;AAAA,EACL,UAAU;AAAA,EACV,SAAS;AAAA,EACT,gBAAgB;AAClB;;ACzBO,IAAM,oBAAoB,EAAE,WAAW,KAAK,YAAY,IAAI;AAE5D,IAAM,qBAAqB;AAAA,EAChC,SAAS,GAAG;AACd;;ACVO,IAAM,kBAAkB,CAAC,WAAW,WAAW,UAAU,OAAO;AAIhE,IAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,OAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AAAA,EACA,MAAM;AACR;;ACZO,IAAM,mBAAmB;AAOzB,IAAM,qBAAqB;AAE3B,IAAM,gBAAgB;AAAA,EAC3B,MAAM,GAAG;AACX;;ACjBO,IAAM,cAAc;AAAA,EACzB,MAAM;AAAA,EACN,OAAO;AACT;;ACLO,IAAM,gBAAgB;AAAA,EAC3B,MAAM;AACR;;ACYO,IAAM,gBAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AACF;;ACnBO,IAAM,kBAAkB;AAAA,EAI7B,SAAS,GAAG;AACd;;ACCO,SAAS,mBAAmB,CAAC,MAAc,OAAuB;AAAA,EACvE,IAAI,CAAC,OAAO,SAAS,IAAI,KAAK,CAAC,OAAO,SAAS,KAAK,KAAK,SAAS;AAAA,IAAG,OAAO;AAAA,EAC5E,OAAQ,KAAK,IAAI,KAAK,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,QAAS;AAAA;AAGjD,IAAM,wBAAwB;AAAA,EACnC,MAAM;AACR;;ACfO,IAAM,mBAAmB;AAAA,EAC9B,MAAM;AAAA,EACN,WAAW;AAAA,EAKX,wBAAwB;AAAA,EACxB,sBAAsB;AACxB;AAGO,SAAS,0BAA0B,CAAC,OAA0C;AAAA,EACnF,OAAO,eAAe,OAAO,SAAS;AAAA;;ACXjC,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,IACZ,UAAU;AAAA,IACV,YAAY;AAAA,EACd;AAAA,EACA,OAAO;AACT;AAUO,IAAM,2BAA2B;AAEjC,SAAS,mBAAmB,CAAC,aAAqB,cAA8C;AAAA,EACrG,OAAO,EAAE,UAAU,YAAY,oCAAoC,GAAG,iBAAiB,qCAAqC,GAAG,iBAAiB;AAAA;AAG3I,SAAS,uBAAuB,CAAC,UAAmB,UAA2C;AAAA,EACpG,OAAO,EAAE,cAAc,WAAW,WAAW,UAAU,cAAc,WAAW,WAAW,SAAS;AAAA;AAI/F,IAAM,4BAA4B,EAAE,aAAa,QAAQ,SAAS,QAAQ;AAE1E,SAAS,wBAAwB,CAAC,aAAoC,KAAoB,WAA2C;AAAA,EAC1I,IAAI,gBAAgB,cAAc;AAAA,IAChC,OAAO,EAAE,UAAU,YAAY,QAAQ,KAAK,MAAM,QAAQ,QAAQ,0CAA0C,KAAK,OAAO,QAAQ,QAAQ,0CAA0C,KAAK,mCAAmC,GAAG,cAAc;AAAA,EAC7O;AAAA,EACA,MAAM,IAA4B,EAAE,UAAU,YAAY,KAAK,IAAI;AAAA,EACnE,IAAI,QAAQ;AAAA,IAAO,EAAE,QAAQ;AAAA,EAC7B,IAAI,QAAQ;AAAA,IAAO,EAAE,OAAO;AAAA,EAC5B,EAAE,SAAS;AAAA,EACX,EAAE,sCAAsC,GAAG;AAAA,EAC3C,OAAO;AAAA;AAGF,IAAM,0BAA0B,EAAE,OAAO,wCAAwC,QAAQ,wCAAwC;AAEjI,SAAS,qBAAqB,CAAC,OAAe,QAAgB,KAA4C;AAAA,EAC/G,MAAM,IAA4B,EAAE,OAAO,GAAG,WAAW,QAAQ,GAAG,YAAY,UAAU,WAAW;AAAA,EACrG,IAAI,QAAQ;AAAA,IAAO,EAAE,QAAQ;AAAA,EAC7B,IAAI,QAAQ;AAAA,IAAO,EAAE,OAAO;AAAA,EAC5B,EAAE,SAAS;AAAA,EACX,OAAO;AAAA;AAIF,IAAM,uBAAuB,CAAC,YAA4C,UAAU,YAAY;AAIhG,IAAM,6BAA4G;AAAA,EACvH,QAAQ,EAAE,QAAQ,YAAY;AAAA,EAC9B,WAAW,EAAE,YAAY,QAAQ,eAAe,cAAc;AAAA,EAC9D,aAAa,EAAE,QAAQ,eAAe,eAAe,OAAO;AAAA,EAC5D,MAAM,EAAE,MAAM,UAAU,QAAQ,aAAa,eAAe,cAAc;AAC5E;AACO,IAAM,6BAAoD;AAQ1D,IAAM,uBAAuB,CAAC,UAAkB,YAA4B;AAAA,EACjF,MAAM,QAAQ,WAAW;AAAA,EACzB,OAAO,MAAM,KAAK,IAAI,IAAI;AAAA;AAIrB,SAAS,mBAAmB,CAAC,OAAgC;AAAA,EAClE,MAAM,UAAU,MAAM,UAAU,eAAe,MAAM,UAAU;AAAA,EAC/D,OAAO,KAAK,KAAK,MAAM,UAAU,OAAO,WAAW,qBAAqB,MAAM,UAAU,MAAM,OAAO,GAAG,EAAE;AAAA;AAG5G,IAAM,cAAc,CAAC,OAAyB,WAA6B,CAAC,UAAkB;AAAA,EAC5F,IAAI,MAAM,OAAO,MAAM,MAAM,OAAO,OAAO,OAAO;AAAA,IAAI,OAAO,OAAO;AAAA,EACpE,OAAO,OAAO,MAAO,OAAO,KAAK,OAAO,OAAO,MAAM,KAAK,MAAM,OAAQ,QAAQ,MAAM;AAAA;AAIjF,SAAS,2BAA2B,CAAC,SAAiB,eAAuB,OAAwB,MAAqB,OAAe;AAAA,EAC9I,MAAM,OAAO,oBAAoB,KAAK;AAAA,EACtC,MAAM,SAAS,iBAAiB,OAAO;AAAA,EACvC,MAAM,MAAM,MAAM,UAAU,eAAe;AAAA,EAC3C,MAAM,MAAM,MAAM,UAAU,OAAO,MAAM,UAAU,cAAc,OAAO;AAAA,EACxE,MAAM,YAAY,MAAM,UAAU,MAAM;AAAA,EACxC,OAAO,YAAY,CAAC,KAAK,GAAG,GAAG,QAAQ,QAAQ,CAAC,GAAG,SAAS,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,EAAE,OAAO;AAAA;AAIvF,SAAS,qBAAqB,CAAC,QAAgB,OAAwB,MAAqB,OAAe;AAAA,EAChH,MAAM,OAAO,oBAAoB,KAAK;AAAA,EACtC,MAAM,MAAM,MAAM,UAAU,OAAO,MAAM,UAAU,eAAe,MAAM,UAAU;AAAA,EAClF,MAAM,YAAY,MAAM,UAAU,MAAM;AAAA,EACxC,OAAO,IAAI,MAAM,QAAQ,QAAQ,CAAC,GAAG,SAAS,IAAI,CAAC,YAAY,IAAI,CAAC;AAAA,EACpE,MAAM,UAAU,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC;AAAA,EACjD,OAAO,YAAY,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,OAAO;AAAA;;ACtGtD,IAAM,iBAAiB;AAKvB,IAAM,gBAAgB;AAItB,IAAM,wBAAwB;AAI9B,IAAM,gBAAgB;AAEtB,IAAM,iBAAiB;AAEvB,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,GAAG;AAAA,EACZ,SAAS;AACX;;;ACdO,IAAM,4BAA4B;AAAA,EACvC,SAAS;AAAA,EAET,MAAM;AACR;;AChBO,IAAM,iBAAiB;AAAA,EAG5B,SAAS;AAAA,EACT,aAAa;AAAA,EAGb,SAAS,GAAG;AAAA,EAEZ,eAAe;AAAA,EACf,UAAU;AAAA,EAEV,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,eAAe;AAAA,EACf,WAAW;AAAA,EACX,WAAW;AAAA,EACX,cAAc;AAAA,EACd,YAAY;AACd;AAKO,IAAM,gBAAgB;AAAA,EAC3B,OAAO,EAAE,kBAAkB,OAAO;AAAA,EAElC,SAAS,EAAE,SAAS,QAAQ,kBAAkB,UAAU,UAAU,QAAQ;AAAA,EAC1E,UAAU,EAAE,UAAU,YAAY,MAAM,KAAK,UAAU,cAAc;AAAA,EACrE,cAAc,EAAE,eAAe,IAAI;AAAA,EAEnC,WAAW;AACb;AAEO,IAAM,uBAAuB;AAE7B,IAAM,sBAAsB,IAAI,yGAAyG;AAIzI,SAAS,6BAA6B,CAAC,eAAuE;AAAA,EACnH,OAAO,EAAE,cAAc,cAAc,cAAc,QAAQ,kBAAkB,eAAe,SAAS,QAAQ,kBAAkB,UAAU,SAAS,OAAO;AAAA;AAKpJ,SAAS,wBAAwB,CAAC,eAAmC,YAAyD;AAAA,EACnI,OAAO;AAAA,IACL,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,SAAS;AAAA,IACT,kBAAkB;AAAA,IAClB,SAAS;AAAA,IACT,2CAA2C;AAAA,IAC3C,0CAA0C;AAAA,IAC1C,2CAA2C;AAAA,IAC3C,gCAAgC;AAAA,IAChC,iCAAiC;AAAA,IACjC,WAAW,aAAa,YAAY;AAAA,EACtC;AAAA;;AC9DK,IAAM,oBAAoB;AAAA,EAC/B,MAAM;AACR;;ACEO,IAAM,uBAAuB;AAAA,EAElC,SAAS;AACX;;ACLO,IAAM,gBAAgB;AAAA,EAC3B,SAAS;AAAA,EAIT,SAAS;AAAA,EAIT,OAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,QAAQ;AAAA,EACV;AAAA,EAEA,WAAW;AAAA,EACX,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EAGR,OAAO;AAAA,EACP,aAAa;AACf;;AC5BO,IAAM,mBAAmB;AAAA,EAC9B,MAAM;AACR;;ACGO,IAAM,kBAAkB;AAAA,EAC7B,MAAM;AACR;;ACPO,IAAM,iBAAiB;AAAA,EAG5B,MAAM;AAAA,EAKN,OAAO;AACT;;ACHO,IAAM,gBAAgB;AAAA,EAC3B,WAAW;AAAA,EACX,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AACX;;AChBO,IAAM,mBAAmB;AAAA,EAO9B,MAAM;AACR;;ACRO,IAAM,kBAAkB;AAAA,EAK7B,SAAS;AACX;;ACOO,SAAS,cAAc,CAAC,OAAe,KAAqB;AAAA,EACjE,IAAI,OAAO;AAAA,IAAG,OAAO;AAAA,EAErB,MAAM,QAAQ,CAAC,GAAG,KAAK;AAAA,EACvB,IAAI,MAAM,UAAU;AAAA,IAAK,OAAO;AAAA,EAEhC,IAAI,MAAM;AAAA,IAAG,OAAO;AAAA,EACpB,MAAM,OAAO,MAAM;AAAA,EACnB,MAAM,OAAO,KAAK,MAAM,OAAO,CAAC;AAAA,EAChC,MAAM,OAAO,OAAO;AAAA,EACpB,OAAO,GAAG,MAAM,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,MAAM,MAAM,MAAM,SAAS,IAAI,EAAE,KAAK,EAAE;AAAA;;AClB9E,IAAM,4BAA4B;AAKlC,SAAS,4BAA4B,CAAC,OAEjC;AAAA,EACV,OACE,MAAM,kBAAkB,WACxB,MAAM,OAAO,QAAQ,yBAAyB,MAAM;AAAA;",
55
+ "debugId": "CD543CBDC0BE10E764756E2164756E21",
56
+ "names": []
57
+ }