@aglyn/besigner-ui 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +73 -0
  4. package/src/besigner.d.ts +88 -0
  5. package/src/besigner.js +89 -0
  6. package/src/besigner.js.map +1 -0
  7. package/src/index.d.ts +17 -0
  8. package/src/index.js +18 -0
  9. package/src/index.js.map +1 -0
  10. package/src/lib/box-styler/box-styler.d.ts +57 -0
  11. package/src/lib/box-styler/box-styler.js +240 -0
  12. package/src/lib/box-styler/box-styler.js.map +1 -0
  13. package/src/lib/box-styler/components/box-diagram.d.ts +89 -0
  14. package/src/lib/box-styler/components/box-diagram.js +661 -0
  15. package/src/lib/box-styler/components/box-diagram.js.map +1 -0
  16. package/src/lib/box-styler/components/legend.d.ts +56 -0
  17. package/src/lib/box-styler/components/legend.js +130 -0
  18. package/src/lib/box-styler/components/legend.js.map +1 -0
  19. package/src/lib/box-styler/components/spacing-editor.d.ts +55 -0
  20. package/src/lib/box-styler/components/spacing-editor.js +347 -0
  21. package/src/lib/box-styler/components/spacing-editor.js.map +1 -0
  22. package/src/lib/box-styler/constants.d.ts +17 -0
  23. package/src/lib/box-styler/constants.js +30 -0
  24. package/src/lib/box-styler/constants.js.map +1 -0
  25. package/src/lib/box-styler/index.d.ts +2 -0
  26. package/src/lib/box-styler/index.js +4 -0
  27. package/src/lib/box-styler/index.js.map +1 -0
  28. package/src/lib/box-styler/region-fills.d.ts +107 -0
  29. package/src/lib/box-styler/region-fills.js +139 -0
  30. package/src/lib/box-styler/region-fills.js.map +1 -0
  31. package/src/lib/box-styler/spacing-value.d.ts +104 -0
  32. package/src/lib/box-styler/spacing-value.js +223 -0
  33. package/src/lib/box-styler/spacing-value.js.map +1 -0
  34. package/src/lib/box-styler/types.d.ts +29 -0
  35. package/src/lib/box-styler/types.js +18 -0
  36. package/src/lib/box-styler/types.js.map +1 -0
  37. package/src/lib/components/accordion-list.component.d.ts +50 -0
  38. package/src/lib/components/accordion-list.component.js +228 -0
  39. package/src/lib/components/accordion-list.component.js.map +1 -0
  40. package/src/lib/components/add-controls.component.d.ts +22 -0
  41. package/src/lib/components/add-controls.component.js +50 -0
  42. package/src/lib/components/add-controls.component.js.map +1 -0
  43. package/src/lib/components/app-bar-breadcrumbs.component.d.ts +29 -0
  44. package/src/lib/components/app-bar-breadcrumbs.component.js +279 -0
  45. package/src/lib/components/app-bar-breadcrumbs.component.js.map +1 -0
  46. package/src/lib/components/app-bar-primary.component.d.ts +21 -0
  47. package/src/lib/components/app-bar-primary.component.js +108 -0
  48. package/src/lib/components/app-bar-primary.component.js.map +1 -0
  49. package/src/lib/components/app-bar-secondary.component.d.ts +21 -0
  50. package/src/lib/components/app-bar-secondary.component.js +94 -0
  51. package/src/lib/components/app-bar-secondary.component.js.map +1 -0
  52. package/src/lib/components/aside-panel.component.d.ts +23 -0
  53. package/src/lib/components/aside-panel.component.js +505 -0
  54. package/src/lib/components/aside-panel.component.js.map +1 -0
  55. package/src/lib/components/besigner-conflict-alert.component.d.ts +36 -0
  56. package/src/lib/components/besigner-conflict-alert.component.js +51 -0
  57. package/src/lib/components/besigner-conflict-alert.component.js.map +1 -0
  58. package/src/lib/components/besigner-dnd-context.component.d.ts +32 -0
  59. package/src/lib/components/besigner-dnd-context.component.js +75 -0
  60. package/src/lib/components/besigner-dnd-context.component.js.map +1 -0
  61. package/src/lib/components/besigner-draft-alert.component.d.ts +70 -0
  62. package/src/lib/components/besigner-draft-alert.component.js +155 -0
  63. package/src/lib/components/besigner-draft-alert.component.js.map +1 -0
  64. package/src/lib/components/besigner-root-provider.component.d.ts +33 -0
  65. package/src/lib/components/besigner-root-provider.component.js +68 -0
  66. package/src/lib/components/besigner-root-provider.component.js.map +1 -0
  67. package/src/lib/components/binding-preview-controls.component.d.ts +28 -0
  68. package/src/lib/components/binding-preview-controls.component.js +63 -0
  69. package/src/lib/components/binding-preview-controls.component.js.map +1 -0
  70. package/src/lib/components/closeable-drawer.component.d.ts +32 -0
  71. package/src/lib/components/closeable-drawer.component.js +134 -0
  72. package/src/lib/components/closeable-drawer.component.js.map +1 -0
  73. package/src/lib/components/component-accordion-list.d.ts +28 -0
  74. package/src/lib/components/component-accordion-list.js +205 -0
  75. package/src/lib/components/component-accordion-list.js.map +1 -0
  76. package/src/lib/components/component-icon.component.d.ts +32 -0
  77. package/src/lib/components/component-icon.component.js +51 -0
  78. package/src/lib/components/component-icon.component.js.map +1 -0
  79. package/src/lib/components/component-picker.d.ts +27 -0
  80. package/src/lib/components/component-picker.js +368 -0
  81. package/src/lib/components/component-picker.js.map +1 -0
  82. package/src/lib/components/components-grid-list.component.d.ts +31 -0
  83. package/src/lib/components/components-grid-list.component.js +162 -0
  84. package/src/lib/components/components-grid-list.component.js.map +1 -0
  85. package/src/lib/components/custom-css-form.component.d.ts +115 -0
  86. package/src/lib/components/custom-css-form.component.js +699 -0
  87. package/src/lib/components/custom-css-form.component.js.map +1 -0
  88. package/src/lib/components/device-preview-controls.component.d.ts +22 -0
  89. package/src/lib/components/device-preview-controls.component.js +150 -0
  90. package/src/lib/components/device-preview-controls.component.js.map +1 -0
  91. package/src/lib/components/dnd/canvas-drop-indicator.d.ts +20 -0
  92. package/src/lib/components/dnd/canvas-drop-indicator.js +61 -0
  93. package/src/lib/components/dnd/canvas-drop-indicator.js.map +1 -0
  94. package/src/lib/components/dnd/draggable-droppable.d.ts +31 -0
  95. package/src/lib/components/dnd/draggable-droppable.js +383 -0
  96. package/src/lib/components/dnd/draggable-droppable.js.map +1 -0
  97. package/src/lib/components/dnd/draggable.d.ts +42 -0
  98. package/src/lib/components/dnd/draggable.js +66 -0
  99. package/src/lib/components/dnd/draggable.js.map +1 -0
  100. package/src/lib/components/dnd/drop-indicator.d.ts +31 -0
  101. package/src/lib/components/dnd/drop-indicator.js +139 -0
  102. package/src/lib/components/dnd/drop-indicator.js.map +1 -0
  103. package/src/lib/components/dnd/droppable.d.ts +43 -0
  104. package/src/lib/components/dnd/droppable.js +63 -0
  105. package/src/lib/components/dnd/droppable.js.map +1 -0
  106. package/src/lib/components/element-card.component.d.ts +23 -0
  107. package/src/lib/components/element-card.component.js +49 -0
  108. package/src/lib/components/element-card.component.js.map +1 -0
  109. package/src/lib/components/element-classes-field.component.d.ts +41 -0
  110. package/src/lib/components/element-classes-field.component.js +140 -0
  111. package/src/lib/components/element-classes-field.component.js.map +1 -0
  112. package/src/lib/components/element-detail-overlay.component.d.ts +55 -0
  113. package/src/lib/components/element-detail-overlay.component.js +157 -0
  114. package/src/lib/components/element-detail-overlay.component.js.map +1 -0
  115. package/src/lib/components/element-detail.component.d.ts +56 -0
  116. package/src/lib/components/element-detail.component.js +171 -0
  117. package/src/lib/components/element-detail.component.js.map +1 -0
  118. package/src/lib/components/element-info-details.component.d.ts +18 -0
  119. package/src/lib/components/element-info-details.component.js +169 -0
  120. package/src/lib/components/element-info-details.component.js.map +1 -0
  121. package/src/lib/components/element-interactions-form.component.d.ts +21 -0
  122. package/src/lib/components/element-interactions-form.component.js +199 -0
  123. package/src/lib/components/element-interactions-form.component.js.map +1 -0
  124. package/src/lib/components/element-preview.component.d.ts +75 -0
  125. package/src/lib/components/element-preview.component.js +346 -0
  126. package/src/lib/components/element-preview.component.js.map +1 -0
  127. package/src/lib/components/element-props-form.component.d.ts +565 -0
  128. package/src/lib/components/element-props-form.component.js +2392 -0
  129. package/src/lib/components/element-props-form.component.js.map +1 -0
  130. package/src/lib/components/element-styles-form-template.component.d.ts +27 -0
  131. package/src/lib/components/element-styles-form-template.component.js +89 -0
  132. package/src/lib/components/element-styles-form-template.component.js.map +1 -0
  133. package/src/lib/components/element-styles-form.component.d.ts +52 -0
  134. package/src/lib/components/element-styles-form.component.js +1350 -0
  135. package/src/lib/components/element-styles-form.component.js.map +1 -0
  136. package/src/lib/components/empty-document-slot.d.ts +39 -0
  137. package/src/lib/components/empty-document-slot.js +121 -0
  138. package/src/lib/components/empty-document-slot.js.map +1 -0
  139. package/src/lib/components/empty-results.d.ts +22 -0
  140. package/src/lib/components/empty-results.js +131 -0
  141. package/src/lib/components/empty-results.js.map +1 -0
  142. package/src/lib/components/history-controls.component.d.ts +21 -0
  143. package/src/lib/components/history-controls.component.js +67 -0
  144. package/src/lib/components/history-controls.component.js.map +1 -0
  145. package/src/lib/components/inline-markdown-editor.component.d.ts +17 -0
  146. package/src/lib/components/inline-markdown-editor.component.js +220 -0
  147. package/src/lib/components/inline-markdown-editor.component.js.map +1 -0
  148. package/src/lib/components/inline-text-editor.component.d.ts +48 -0
  149. package/src/lib/components/inline-text-editor.component.js +905 -0
  150. package/src/lib/components/inline-text-editor.component.js.map +1 -0
  151. package/src/lib/components/insert-token-menu.component.d.ts +86 -0
  152. package/src/lib/components/insert-token-menu.component.js +232 -0
  153. package/src/lib/components/insert-token-menu.component.js.map +1 -0
  154. package/src/lib/components/instance-attr-overrides.component.d.ts +50 -0
  155. package/src/lib/components/instance-attr-overrides.component.js +298 -0
  156. package/src/lib/components/instance-attr-overrides.component.js.map +1 -0
  157. package/src/lib/components/interact-controls.component.d.ts +22 -0
  158. package/src/lib/components/interact-controls.component.js +74 -0
  159. package/src/lib/components/interact-controls.component.js.map +1 -0
  160. package/src/lib/components/markdown-attribute-field.component.d.ts +40 -0
  161. package/src/lib/components/markdown-attribute-field.component.js +103 -0
  162. package/src/lib/components/markdown-attribute-field.component.js.map +1 -0
  163. package/src/lib/components/node-card.d.ts +24 -0
  164. package/src/lib/components/node-card.js +86 -0
  165. package/src/lib/components/node-card.js.map +1 -0
  166. package/src/lib/components/node-context-menu.d.ts +25 -0
  167. package/src/lib/components/node-context-menu.js +558 -0
  168. package/src/lib/components/node-context-menu.js.map +1 -0
  169. package/src/lib/components/node-leaf.d.ts +39 -0
  170. package/src/lib/components/node-leaf.js +628 -0
  171. package/src/lib/components/node-leaf.js.map +1 -0
  172. package/src/lib/components/node-outline.d.ts +24 -0
  173. package/src/lib/components/node-outline.js +156 -0
  174. package/src/lib/components/node-outline.js.map +1 -0
  175. package/src/lib/components/node-overlay.d.ts +23 -0
  176. package/src/lib/components/node-overlay.js +299 -0
  177. package/src/lib/components/node-overlay.js.map +1 -0
  178. package/src/lib/components/node-quick-actions.d.ts +24 -0
  179. package/src/lib/components/node-quick-actions.js +284 -0
  180. package/src/lib/components/node-quick-actions.js.map +1 -0
  181. package/src/lib/components/node-tree-view.d.ts +106 -0
  182. package/src/lib/components/node-tree-view.js +820 -0
  183. package/src/lib/components/node-tree-view.js.map +1 -0
  184. package/src/lib/components/panel-controls.component.d.ts +22 -0
  185. package/src/lib/components/panel-controls.component.js +76 -0
  186. package/src/lib/components/panel-controls.component.js.map +1 -0
  187. package/src/lib/components/picker-search-field.d.ts +38 -0
  188. package/src/lib/components/picker-search-field.js +79 -0
  189. package/src/lib/components/picker-search-field.js.map +1 -0
  190. package/src/lib/components/plugin-settings-field.component.d.ts +38 -0
  191. package/src/lib/components/plugin-settings-field.component.js +264 -0
  192. package/src/lib/components/plugin-settings-field.component.js.map +1 -0
  193. package/src/lib/components/properties-dialog.component.d.ts +22 -0
  194. package/src/lib/components/properties-dialog.component.js +40 -0
  195. package/src/lib/components/properties-dialog.component.js.map +1 -0
  196. package/src/lib/components/property-binding-field.component.d.ts +142 -0
  197. package/src/lib/components/property-binding-field.component.js +325 -0
  198. package/src/lib/components/property-binding-field.component.js.map +1 -0
  199. package/src/lib/components/property-values-form.component.d.ts +43 -0
  200. package/src/lib/components/property-values-form.component.js +223 -0
  201. package/src/lib/components/property-values-form.component.js.map +1 -0
  202. package/src/lib/components/scheme-preview-controls.component.d.ts +26 -0
  203. package/src/lib/components/scheme-preview-controls.component.js +56 -0
  204. package/src/lib/components/scheme-preview-controls.component.js.map +1 -0
  205. package/src/lib/components/screen-link-field.component.d.ts +118 -0
  206. package/src/lib/components/screen-link-field.component.js +282 -0
  207. package/src/lib/components/screen-link-field.component.js.map +1 -0
  208. package/src/lib/components/site-theme-color-tokens-provider.component.d.ts +33 -0
  209. package/src/lib/components/site-theme-color-tokens-provider.component.js +53 -0
  210. package/src/lib/components/site-theme-color-tokens-provider.component.js.map +1 -0
  211. package/src/lib/components/subtree-json-dialog.component.d.ts +46 -0
  212. package/src/lib/components/subtree-json-dialog.component.js +125 -0
  213. package/src/lib/components/subtree-json-dialog.component.js.map +1 -0
  214. package/src/lib/components/token-pill.component.d.ts +51 -0
  215. package/src/lib/components/token-pill.component.js +164 -0
  216. package/src/lib/components/token-pill.component.js.map +1 -0
  217. package/src/lib/components/token-text-field.component.d.ts +146 -0
  218. package/src/lib/components/token-text-field.component.js +603 -0
  219. package/src/lib/components/token-text-field.component.js.map +1 -0
  220. package/src/lib/components/tree/tree-list.d.ts +6 -0
  221. package/src/lib/components/tree/tree-list.js +108 -0
  222. package/src/lib/components/tree/tree-list.js.map +1 -0
  223. package/src/lib/components/viewport-canvas.component.d.ts +23 -0
  224. package/src/lib/components/viewport-canvas.component.js +128 -0
  225. package/src/lib/components/viewport-canvas.component.js.map +1 -0
  226. package/src/lib/components/viewport-frame.component.d.ts +47 -0
  227. package/src/lib/components/viewport-frame.component.js +332 -0
  228. package/src/lib/components/viewport-frame.component.js.map +1 -0
  229. package/src/lib/components/viewport-root.component.d.ts +22 -0
  230. package/src/lib/components/viewport-root.component.js +112 -0
  231. package/src/lib/components/viewport-root.component.js.map +1 -0
  232. package/src/lib/components/viewport-zoom-controls.d.ts +29 -0
  233. package/src/lib/components/viewport-zoom-controls.js +147 -0
  234. package/src/lib/components/viewport-zoom-controls.js.map +1 -0
  235. package/src/lib/components/workspace-editor.component.d.ts +23 -0
  236. package/src/lib/components/workspace-editor.component.js +191 -0
  237. package/src/lib/components/workspace-editor.component.js.map +1 -0
  238. package/src/lib/components/workspace-panel.component.d.ts +28 -0
  239. package/src/lib/components/workspace-panel.component.js +147 -0
  240. package/src/lib/components/workspace-panel.component.js.map +1 -0
  241. package/src/lib/constants/sample-data.d.ts +18 -0
  242. package/src/lib/constants/sample-data.js +106 -0
  243. package/src/lib/constants/sample-data.js.map +1 -0
  244. package/src/lib/constants/shared.d.ts +17 -0
  245. package/src/lib/constants/shared.js +18 -0
  246. package/src/lib/constants/shared.js.map +1 -0
  247. package/src/lib/contexts/besigner-app-context.d.ts +30 -0
  248. package/src/lib/contexts/besigner-app-context.js +41 -0
  249. package/src/lib/contexts/besigner-app-context.js.map +1 -0
  250. package/src/lib/contexts/binding-picker-context.d.ts +78 -0
  251. package/src/lib/contexts/binding-picker-context.js +21 -0
  252. package/src/lib/contexts/binding-picker-context.js.map +1 -0
  253. package/src/lib/contexts/canvas-host-tokens-context.d.ts +49 -0
  254. package/src/lib/contexts/canvas-host-tokens-context.js +63 -0
  255. package/src/lib/contexts/canvas-host-tokens-context.js.map +1 -0
  256. package/src/lib/contexts/canvas-reveal-context.d.ts +32 -0
  257. package/src/lib/contexts/canvas-reveal-context.js +34 -0
  258. package/src/lib/contexts/canvas-reveal-context.js.map +1 -0
  259. package/src/lib/contexts/component-promotion-context.d.ts +89 -0
  260. package/src/lib/contexts/component-promotion-context.js +21 -0
  261. package/src/lib/contexts/component-promotion-context.js.map +1 -0
  262. package/src/lib/contexts/components-drawer-context.provider.d.ts +32 -0
  263. package/src/lib/contexts/components-drawer-context.provider.js +80 -0
  264. package/src/lib/contexts/components-drawer-context.provider.js.map +1 -0
  265. package/src/lib/contexts/element-drawer-context.d.ts +1005 -0
  266. package/src/lib/contexts/element-drawer-context.js +45 -0
  267. package/src/lib/contexts/element-drawer-context.js.map +1 -0
  268. package/src/lib/contexts/inspected-selection.d.ts +32 -0
  269. package/src/lib/contexts/inspected-selection.js +38 -0
  270. package/src/lib/contexts/inspected-selection.js.map +1 -0
  271. package/src/lib/contexts/inspector-extras-context.d.ts +56 -0
  272. package/src/lib/contexts/inspector-extras-context.js +35 -0
  273. package/src/lib/contexts/inspector-extras-context.js.map +1 -0
  274. package/src/lib/contexts/interactions-context.d.ts +99 -0
  275. package/src/lib/contexts/interactions-context.js +22 -0
  276. package/src/lib/contexts/interactions-context.js.map +1 -0
  277. package/src/lib/contexts/layout-chrome-context.d.ts +37 -0
  278. package/src/lib/contexts/layout-chrome-context.js +75 -0
  279. package/src/lib/contexts/layout-chrome-context.js.map +1 -0
  280. package/src/lib/contexts/media-asset-facts-context.d.ts +74 -0
  281. package/src/lib/contexts/media-asset-facts-context.js +27 -0
  282. package/src/lib/contexts/media-asset-facts-context.js.map +1 -0
  283. package/src/lib/contexts/media-picker-context.d.ts +88 -0
  284. package/src/lib/contexts/media-picker-context.js +21 -0
  285. package/src/lib/contexts/media-picker-context.js.map +1 -0
  286. package/src/lib/contexts/rendered-canvas-elements.d.ts +42 -0
  287. package/src/lib/contexts/rendered-canvas-elements.js +79 -0
  288. package/src/lib/contexts/rendered-canvas-elements.js.map +1 -0
  289. package/src/lib/contexts/repeat-record-context.d.ts +38 -0
  290. package/src/lib/contexts/repeat-record-context.js +21 -0
  291. package/src/lib/contexts/repeat-record-context.js.map +1 -0
  292. package/src/lib/contexts/repeat-rows-context.d.ts +53 -0
  293. package/src/lib/contexts/repeat-rows-context.js +38 -0
  294. package/src/lib/contexts/repeat-rows-context.js.map +1 -0
  295. package/src/lib/contexts/toolbar-extras-context.d.ts +31 -0
  296. package/src/lib/contexts/toolbar-extras-context.js +33 -0
  297. package/src/lib/contexts/toolbar-extras-context.js.map +1 -0
  298. package/src/lib/drafts/besigner-draft-store.d.ts +110 -0
  299. package/src/lib/drafts/besigner-draft-store.js +125 -0
  300. package/src/lib/drafts/besigner-draft-store.js.map +1 -0
  301. package/src/lib/drafts/besigner-server-draft.d.ts +130 -0
  302. package/src/lib/drafts/besigner-server-draft.js +211 -0
  303. package/src/lib/drafts/besigner-server-draft.js.map +1 -0
  304. package/src/lib/form-fields/components/shared/inline-form-control.d.ts +32 -0
  305. package/src/lib/form-fields/components/shared/inline-form-control.js +85 -0
  306. package/src/lib/form-fields/components/shared/inline-form-control.js.map +1 -0
  307. package/src/lib/form-fields/components/shared/toggle-button-form-control.d.ts +33 -0
  308. package/src/lib/form-fields/components/shared/toggle-button-form-control.js +83 -0
  309. package/src/lib/form-fields/components/shared/toggle-button-form-control.js.map +1 -0
  310. package/src/lib/form-fields/form-fields.d.ts +20 -0
  311. package/src/lib/form-fields/form-fields.js +21 -0
  312. package/src/lib/form-fields/form-fields.js.map +1 -0
  313. package/src/lib/form-fields/index.d.ts +1 -0
  314. package/src/lib/form-fields/index.js +3 -0
  315. package/src/lib/form-fields/index.js.map +1 -0
  316. package/src/lib/hooks/use-add-element-drawer-callback.d.ts +28 -0
  317. package/src/lib/hooks/use-add-element-drawer-callback.js +112 -0
  318. package/src/lib/hooks/use-add-element-drawer-callback.js.map +1 -0
  319. package/src/lib/hooks/use-aglyn-besigner-flag.d.ts +23 -0
  320. package/src/lib/hooks/use-aglyn-besigner-flag.js +47 -0
  321. package/src/lib/hooks/use-aglyn-besigner-flag.js.map +1 -0
  322. package/src/lib/hooks/use-aglyn-besigner-panel-value.d.ts +23 -0
  323. package/src/lib/hooks/use-aglyn-besigner-panel-value.js +54 -0
  324. package/src/lib/hooks/use-aglyn-besigner-panel-value.js.map +1 -0
  325. package/src/lib/hooks/use-aglyn-besigner-panel.d.ts +23 -0
  326. package/src/lib/hooks/use-aglyn-besigner-panel.js +47 -0
  327. package/src/lib/hooks/use-aglyn-besigner-panel.js.map +1 -0
  328. package/src/lib/hooks/use-anchored-rect.d.ts +68 -0
  329. package/src/lib/hooks/use-anchored-rect.js +131 -0
  330. package/src/lib/hooks/use-anchored-rect.js.map +1 -0
  331. package/src/lib/hooks/use-besigner-app-context.d.ts +18 -0
  332. package/src/lib/hooks/use-besigner-app-context.js +19 -0
  333. package/src/lib/hooks/use-besigner-app-context.js.map +1 -0
  334. package/src/lib/hooks/use-besigner-document.d.ts +309 -0
  335. package/src/lib/hooks/use-besigner-document.js +500 -0
  336. package/src/lib/hooks/use-besigner-document.js.map +1 -0
  337. package/src/lib/hooks/use-besigner-draft.d.ts +209 -0
  338. package/src/lib/hooks/use-besigner-draft.js +429 -0
  339. package/src/lib/hooks/use-besigner-draft.js.map +1 -0
  340. package/src/lib/hooks/use-clipboard-callbacks.d.ts +29 -0
  341. package/src/lib/hooks/use-clipboard-callbacks.js +82 -0
  342. package/src/lib/hooks/use-clipboard-callbacks.js.map +1 -0
  343. package/src/lib/hooks/use-clipboard-shortcuts.d.ts +52 -0
  344. package/src/lib/hooks/use-clipboard-shortcuts.js +102 -0
  345. package/src/lib/hooks/use-clipboard-shortcuts.js.map +1 -0
  346. package/src/lib/hooks/use-component-propagation-notice.d.ts +96 -0
  347. package/src/lib/hooks/use-component-propagation-notice.js +177 -0
  348. package/src/lib/hooks/use-component-propagation-notice.js.map +1 -0
  349. package/src/lib/hooks/use-debounced-commit.d.ts +43 -0
  350. package/src/lib/hooks/use-debounced-commit.js +88 -0
  351. package/src/lib/hooks/use-debounced-commit.js.map +1 -0
  352. package/src/lib/hooks/use-delete-element-callback.d.ts +24 -0
  353. package/src/lib/hooks/use-delete-element-callback.js +82 -0
  354. package/src/lib/hooks/use-delete-element-callback.js.map +1 -0
  355. package/src/lib/hooks/use-detail-hover-intent.d.ts +76 -0
  356. package/src/lib/hooks/use-detail-hover-intent.js +123 -0
  357. package/src/lib/hooks/use-detail-hover-intent.js.map +1 -0
  358. package/src/lib/hooks/use-document-repair-callbacks.d.ts +50 -0
  359. package/src/lib/hooks/use-document-repair-callbacks.js +237 -0
  360. package/src/lib/hooks/use-document-repair-callbacks.js.map +1 -0
  361. package/src/lib/hooks/use-insert-token-options.d.ts +52 -0
  362. package/src/lib/hooks/use-insert-token-options.js +230 -0
  363. package/src/lib/hooks/use-insert-token-options.js.map +1 -0
  364. package/src/lib/hooks/use-leaf-drag.d.ts +24 -0
  365. package/src/lib/hooks/use-leaf-drag.js +28 -0
  366. package/src/lib/hooks/use-leaf-drag.js.map +1 -0
  367. package/src/lib/hooks/use-leaf-drop.d.ts +31 -0
  368. package/src/lib/hooks/use-leaf-drop.js +43 -0
  369. package/src/lib/hooks/use-leaf-drop.js.map +1 -0
  370. package/src/lib/hooks/use-markdown-media-picker.d.ts +63 -0
  371. package/src/lib/hooks/use-markdown-media-picker.js +110 -0
  372. package/src/lib/hooks/use-markdown-media-picker.js.map +1 -0
  373. package/src/lib/hooks/use-media-asset-facts-overlay.d.ts +43 -0
  374. package/src/lib/hooks/use-media-asset-facts-overlay.js +133 -0
  375. package/src/lib/hooks/use-media-asset-facts-overlay.js.map +1 -0
  376. package/src/lib/hooks/use-move-node-callbacks.d.ts +22 -0
  377. package/src/lib/hooks/use-move-node-callbacks.js +57 -0
  378. package/src/lib/hooks/use-move-node-callbacks.js.map +1 -0
  379. package/src/lib/hooks/use-node-with-host-tokens.d.ts +42 -0
  380. package/src/lib/hooks/use-node-with-host-tokens.js +59 -0
  381. package/src/lib/hooks/use-node-with-host-tokens.js.map +1 -0
  382. package/src/lib/hooks/use-picker-filter.d.ts +61 -0
  383. package/src/lib/hooks/use-picker-filter.js +122 -0
  384. package/src/lib/hooks/use-picker-filter.js.map +1 -0
  385. package/src/lib/hooks/use-repeat-preview.d.ts +64 -0
  386. package/src/lib/hooks/use-repeat-preview.js +214 -0
  387. package/src/lib/hooks/use-repeat-preview.js.map +1 -0
  388. package/src/lib/hooks/use-repeat-sources.d.ts +17 -0
  389. package/src/lib/hooks/use-repeat-sources.js +41 -0
  390. package/src/lib/hooks/use-repeat-sources.js.map +1 -0
  391. package/src/lib/hooks/use-visible-component-categories.d.ts +37 -0
  392. package/src/lib/hooks/use-visible-component-categories.js +79 -0
  393. package/src/lib/hooks/use-visible-component-categories.js.map +1 -0
  394. package/src/lib/utils/active-host-theme.d.ts +28 -0
  395. package/src/lib/utils/active-host-theme.js +77 -0
  396. package/src/lib/utils/active-host-theme.js.map +1 -0
  397. package/src/lib/utils/attr-target.d.ts +170 -0
  398. package/src/lib/utils/attr-target.js +229 -0
  399. package/src/lib/utils/attr-target.js.map +1 -0
  400. package/src/lib/utils/attribute-field-value.d.ts +21 -0
  401. package/src/lib/utils/attribute-field-value.js +28 -0
  402. package/src/lib/utils/attribute-field-value.js.map +1 -0
  403. package/src/lib/utils/canvas-context-menu.d.ts +28 -0
  404. package/src/lib/utils/canvas-context-menu.js +56 -0
  405. package/src/lib/utils/canvas-context-menu.js.map +1 -0
  406. package/src/lib/utils/canvas-reveal.d.ts +115 -0
  407. package/src/lib/utils/canvas-reveal.js +165 -0
  408. package/src/lib/utils/canvas-reveal.js.map +1 -0
  409. package/src/lib/utils/describe-element.d.ts +72 -0
  410. package/src/lib/utils/describe-element.js +159 -0
  411. package/src/lib/utils/describe-element.js.map +1 -0
  412. package/src/lib/utils/device-preview-styles.d.ts +89 -0
  413. package/src/lib/utils/device-preview-styles.js +228 -0
  414. package/src/lib/utils/device-preview-styles.js.map +1 -0
  415. package/src/lib/utils/docs-help.d.ts +22 -0
  416. package/src/lib/utils/docs-help.generated.d.ts +47 -0
  417. package/src/lib/utils/docs-help.generated.js +229 -0
  418. package/src/lib/utils/docs-help.generated.js.map +1 -0
  419. package/src/lib/utils/docs-help.js +37 -0
  420. package/src/lib/utils/docs-help.js.map +1 -0
  421. package/src/lib/utils/held-answers-store.d.ts +59 -0
  422. package/src/lib/utils/held-answers-store.js +94 -0
  423. package/src/lib/utils/held-answers-store.js.map +1 -0
  424. package/src/lib/utils/in-place-edit-surface.d.ts +118 -0
  425. package/src/lib/utils/in-place-edit-surface.js +164 -0
  426. package/src/lib/utils/in-place-edit-surface.js.map +1 -0
  427. package/src/lib/utils/inline-markdown-edit.store.d.ts +71 -0
  428. package/src/lib/utils/inline-markdown-edit.store.js +90 -0
  429. package/src/lib/utils/inline-markdown-edit.store.js.map +1 -0
  430. package/src/lib/utils/inline-text-edit.store.d.ts +85 -0
  431. package/src/lib/utils/inline-text-edit.store.js +78 -0
  432. package/src/lib/utils/inline-text-edit.store.js.map +1 -0
  433. package/src/lib/utils/instance-leaf-hit.d.ts +39 -0
  434. package/src/lib/utils/instance-leaf-hit.js +56 -0
  435. package/src/lib/utils/instance-leaf-hit.js.map +1 -0
  436. package/src/lib/utils/muted-classes.d.ts +76 -0
  437. package/src/lib/utils/muted-classes.js +108 -0
  438. package/src/lib/utils/muted-classes.js.map +1 -0
  439. package/src/lib/utils/muted-styles.d.ts +125 -0
  440. package/src/lib/utils/muted-styles.js +193 -0
  441. package/src/lib/utils/muted-styles.js.map +1 -0
  442. package/src/lib/utils/numeric-text-value.d.ts +42 -0
  443. package/src/lib/utils/numeric-text-value.js +47 -0
  444. package/src/lib/utils/numeric-text-value.js.map +1 -0
  445. package/src/lib/utils/preset-interactions.d.ts +37 -0
  446. package/src/lib/utils/preset-interactions.js +87 -0
  447. package/src/lib/utils/preset-interactions.js.map +1 -0
  448. package/src/lib/utils/publish-failure-message.d.ts +35 -0
  449. package/src/lib/utils/publish-failure-message.js +51 -0
  450. package/src/lib/utils/publish-failure-message.js.map +1 -0
  451. package/src/lib/utils/rank-picker-results.d.ts +45 -0
  452. package/src/lib/utils/rank-picker-results.js +136 -0
  453. package/src/lib/utils/rank-picker-results.js.map +1 -0
  454. package/src/lib/utils/responsive-sx.d.ts +65 -0
  455. package/src/lib/utils/responsive-sx.js +129 -0
  456. package/src/lib/utils/responsive-sx.js.map +1 -0
  457. package/src/lib/utils/rich-text-commands.d.ts +28 -0
  458. package/src/lib/utils/rich-text-commands.js +43 -0
  459. package/src/lib/utils/rich-text-commands.js.map +1 -0
  460. package/src/lib/utils/sanitize-rich-text.d.ts +52 -0
  461. package/src/lib/utils/sanitize-rich-text.js +173 -0
  462. package/src/lib/utils/sanitize-rich-text.js.map +1 -0
  463. package/src/lib/utils/state-sx.d.ts +255 -0
  464. package/src/lib/utils/state-sx.js +338 -0
  465. package/src/lib/utils/state-sx.js.map +1 -0
  466. package/src/lib/utils/style-field-groups.d.ts +136 -0
  467. package/src/lib/utils/style-field-groups.js +874 -0
  468. package/src/lib/utils/style-field-groups.js.map +1 -0
  469. package/src/lib/utils/style-field-search.d.ts +84 -0
  470. package/src/lib/utils/style-field-search.js +505 -0
  471. package/src/lib/utils/style-field-search.js.map +1 -0
  472. package/src/lib/utils/style-target.d.ts +69 -0
  473. package/src/lib/utils/style-target.js +203 -0
  474. package/src/lib/utils/style-target.js.map +1 -0
  475. package/src/lib/utils/theme-scale-options.d.ts +169 -0
  476. package/src/lib/utils/theme-scale-options.js +702 -0
  477. package/src/lib/utils/theme-scale-options.js.map +1 -0
  478. package/src/lib/utils/token-editable-dom.d.ts +82 -0
  479. package/src/lib/utils/token-editable-dom.js +280 -0
  480. package/src/lib/utils/token-editable-dom.js.map +1 -0
  481. package/src/lib/utils/token-segments.d.ts +111 -0
  482. package/src/lib/utils/token-segments.js +246 -0
  483. package/src/lib/utils/token-segments.js.map +1 -0
  484. package/src/lib/utils/visibility-styles.d.ts +38 -0
  485. package/src/lib/utils/visibility-styles.js +54 -0
  486. package/src/lib/utils/visibility-styles.js.map +1 -0
@@ -0,0 +1,125 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { pruneLocalStorageByAge, writeLocalStorageWithBudget } from "@aglyn/aglyn";
18
+ /**
19
+ * Local crash net for unsaved besigner work (AGL-1256).
20
+ *
21
+ * ## What this is not
22
+ *
23
+ * It is deliberately **not** version history. Versioning is a paid feature
24
+ * (`versioning`, Pro and above): named snapshots of the *saved* document that
25
+ * you can list, reopen, publish and schedule. A store of dated snapshots in
26
+ * the browser is one careless design decision away from being a free
27
+ * imitation of exactly that, so three rules hold the line, and every one of
28
+ * them is load-bearing rather than incidental:
29
+ *
30
+ * 1. **One draft per document, latest wins.** No list, no names, no history.
31
+ * There is nothing to browse and nothing to choose between.
32
+ * 2. **A draft only ever holds work that was never saved.** It is cleared the
33
+ * moment a save succeeds, so it can never act as "restore the document to
34
+ * how it was before" — that is rollback, and rollback is what versions
35
+ * sell. The only thing a draft can give back is the thing that would
36
+ * otherwise be gone forever.
37
+ * 3. **A draft expires.** {@link DRAFT_MAX_AGE_MS} keeps it a recovery window
38
+ * rather than an archive.
39
+ *
40
+ * Because of those, drafts are ungated: this is data-loss prevention, and
41
+ * gating it would mean a free org's crash still costs them their afternoon.
42
+ * A free org gets back exactly what they had in the canvas and not one
43
+ * revision more.
44
+ */ /** Every key this module owns; also the set it may evict from. */ export const BESIGNER_DRAFT_KEY_PREFIX = 'aglyn:draft:';
45
+ /**
46
+ * A week. Long enough to cover "my laptop died on Friday", short enough that
47
+ * the store never becomes an accumulating pile of restore points.
48
+ */ export const DRAFT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
49
+ export function besignerDraftKey(ids) {
50
+ var _ids_versionId;
51
+ const version = (_ids_versionId = ids.versionId) != null ? _ids_versionId : 'current';
52
+ return `${BESIGNER_DRAFT_KEY_PREFIX}${ids.kind}:` + `${ids.scope}:${ids.docId}:${version}`;
53
+ }
54
+ function storageOrNull() {
55
+ try {
56
+ return typeof window === 'undefined' ? null : window.localStorage;
57
+ } catch (unused) {
58
+ return null;
59
+ }
60
+ }
61
+ /**
62
+ * Writes the draft, replacing any previous one for this document.
63
+ *
64
+ * Returns false when storage refused it — the caller carries on editing
65
+ * either way. Preview snapshots are spent first when the origin is full
66
+ * (they regenerate on the next Preview click); other documents' drafts only
67
+ * after that, oldest first.
68
+ */ export function writeBesignerDraft(ids, draft, now = Date.now()) {
69
+ const value = _extends({}, draft, {
70
+ updatedAt: now
71
+ });
72
+ return writeLocalStorageWithBudget({
73
+ key: besignerDraftKey(ids),
74
+ value: JSON.stringify(value),
75
+ evictPrefixes: [
76
+ 'aglyn:preview:',
77
+ BESIGNER_DRAFT_KEY_PREFIX
78
+ ]
79
+ }).ok;
80
+ }
81
+ /**
82
+ * Reads this document's draft, or null when there is none, it is unreadable,
83
+ * or it has aged out. An expired draft is removed on the way past, so the
84
+ * store self-prunes on the path everyone takes.
85
+ */ export function readBesignerDraft(ids, now = Date.now()) {
86
+ var _draft_updatedAt;
87
+ const storage = storageOrNull();
88
+ if (!storage) return null;
89
+ const key = besignerDraftKey(ids);
90
+ const raw = storage.getItem(key);
91
+ if (!raw) return null;
92
+ let draft;
93
+ try {
94
+ const parsed = JSON.parse(raw);
95
+ draft = (parsed == null ? void 0 : parsed.nodes) ? parsed : null;
96
+ } catch (unused) {
97
+ draft = null;
98
+ }
99
+ if (!draft) {
100
+ clearBesignerDraft(ids);
101
+ return null;
102
+ }
103
+ if (now - ((_draft_updatedAt = draft.updatedAt) != null ? _draft_updatedAt : 0) > DRAFT_MAX_AGE_MS) {
104
+ clearBesignerDraft(ids);
105
+ return null;
106
+ }
107
+ return draft;
108
+ }
109
+ export function clearBesignerDraft(ids) {
110
+ try {
111
+ var _storageOrNull;
112
+ (_storageOrNull = storageOrNull()) == null ? void 0 : _storageOrNull.removeItem(besignerDraftKey(ids));
113
+ } catch (unused) {
114
+ // Nothing to do and nothing worth interrupting an edit for.
115
+ }
116
+ }
117
+ /** Drops every expired draft, whichever document it belongs to. */ export function pruneBesignerDrafts(now = Date.now()) {
118
+ return pruneLocalStorageByAge({
119
+ prefix: BESIGNER_DRAFT_KEY_PREFIX,
120
+ maxAgeMs: DRAFT_MAX_AGE_MS,
121
+ now
122
+ });
123
+ }
124
+
125
+ //# sourceMappingURL=besigner-draft-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/drafts/besigner-draft-store.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type ProcessableNodes,\n pruneLocalStorageByAge,\n writeLocalStorageWithBudget,\n} from '@aglyn/aglyn'\n\n/**\n * Local crash net for unsaved besigner work (AGL-1256).\n *\n * ## What this is not\n *\n * It is deliberately **not** version history. Versioning is a paid feature\n * (`versioning`, Pro and above): named snapshots of the *saved* document that\n * you can list, reopen, publish and schedule. A store of dated snapshots in\n * the browser is one careless design decision away from being a free\n * imitation of exactly that, so three rules hold the line, and every one of\n * them is load-bearing rather than incidental:\n *\n * 1. **One draft per document, latest wins.** No list, no names, no history.\n * There is nothing to browse and nothing to choose between.\n * 2. **A draft only ever holds work that was never saved.** It is cleared the\n * moment a save succeeds, so it can never act as \"restore the document to\n * how it was before\" — that is rollback, and rollback is what versions\n * sell. The only thing a draft can give back is the thing that would\n * otherwise be gone forever.\n * 3. **A draft expires.** {@link DRAFT_MAX_AGE_MS} keeps it a recovery window\n * rather than an archive.\n *\n * Because of those, drafts are ungated: this is data-loss prevention, and\n * gating it would mean a free org's crash still costs them their afternoon.\n * A free org gets back exactly what they had in the canvas and not one\n * revision more.\n */\n\n/** Every key this module owns; also the set it may evict from. */\nexport const BESIGNER_DRAFT_KEY_PREFIX = 'aglyn:draft:'\n\n/**\n * A week. Long enough to cover \"my laptop died on Friday\", short enough that\n * the store never becomes an accumulating pile of restore points.\n */\nexport const DRAFT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000\n\n/**\n * Which besigner document a draft belongs to.\n *\n * Every field is part of the key on purpose. `useBesignerDocument`'s\n * `documentKey` looks like the natural choice and is not safe as one: both\n * email editors build it as `${templateKey}:${versionId}`, so a platform\n * email template and a host's override of the same key — and two different\n * hosts overriding it — all collide. This is the same trap AGL-1203 hit with\n * preview snapshots, where screen, layout, component and template ids come\n * from one generator and live in sibling collections.\n */\nexport interface BesignerDraftIds {\n /**\n * Owning host id, or `'platform'` for the staff-owned system documents\n * that have no host.\n */\n scope: string\n kind: 'screen' | 'layout' | 'component' | 'template' | 'email' | 'form'\n docId: string\n /**\n * Which version of the document is open. Keeping this in the key is what\n * stops a draft taken against version A being offered on version B —\n * versions are meant to be independent, and a draft that leaked across\n * them would corrupt the paid feature rather than merely duplicate it.\n * Templates version but never publish, so they have none.\n */\n versionId?: string\n}\n\nexport interface BesignerDraft {\n nodes: ProcessableNodes\n /**\n * The stored document's version stamp when this draft was taken, in\n * `Aglyn.versionStamp` form. Null when the document had not stamped yet.\n * This is what makes the restore prompt honest about a colleague having\n * saved in the meantime (AGL-674).\n */\n baseStamp: string | null\n /** When the draft was last written. */\n updatedAt: number\n}\n\nexport function besignerDraftKey(ids: BesignerDraftIds): string {\n const version = ids.versionId ?? 'current'\n return (\n `${BESIGNER_DRAFT_KEY_PREFIX}${ids.kind}:` +\n `${ids.scope}:${ids.docId}:${version}`\n )\n}\n\nfunction storageOrNull(): Storage | null {\n try {\n return typeof window === 'undefined' ? null : window.localStorage\n } catch {\n return null\n }\n}\n\n/**\n * Writes the draft, replacing any previous one for this document.\n *\n * Returns false when storage refused it — the caller carries on editing\n * either way. Preview snapshots are spent first when the origin is full\n * (they regenerate on the next Preview click); other documents' drafts only\n * after that, oldest first.\n */\nexport function writeBesignerDraft(\n ids: BesignerDraftIds,\n draft: Omit<BesignerDraft, 'updatedAt'>,\n now: number = Date.now(),\n): boolean {\n const value: BesignerDraft = { ...draft, updatedAt: now }\n return writeLocalStorageWithBudget({\n key: besignerDraftKey(ids),\n value: JSON.stringify(value),\n evictPrefixes: ['aglyn:preview:', BESIGNER_DRAFT_KEY_PREFIX],\n }).ok\n}\n\n/**\n * Reads this document's draft, or null when there is none, it is unreadable,\n * or it has aged out. An expired draft is removed on the way past, so the\n * store self-prunes on the path everyone takes.\n */\nexport function readBesignerDraft(\n ids: BesignerDraftIds,\n now: number = Date.now(),\n): BesignerDraft | null {\n const storage = storageOrNull()\n if (!storage) return null\n const key = besignerDraftKey(ids)\n const raw = storage.getItem(key)\n if (!raw) return null\n let draft: BesignerDraft | null\n try {\n const parsed = JSON.parse(raw) as BesignerDraft\n draft = parsed?.nodes ? parsed : null\n } catch {\n draft = null\n }\n if (!draft) {\n clearBesignerDraft(ids)\n return null\n }\n if (now - (draft.updatedAt ?? 0) > DRAFT_MAX_AGE_MS) {\n clearBesignerDraft(ids)\n return null\n }\n return draft\n}\n\nexport function clearBesignerDraft(ids: BesignerDraftIds): void {\n try {\n storageOrNull()?.removeItem(besignerDraftKey(ids))\n } catch {\n // Nothing to do and nothing worth interrupting an edit for.\n }\n}\n\n/** Drops every expired draft, whichever document it belongs to. */\nexport function pruneBesignerDrafts(now: number = Date.now()): string[] {\n return pruneLocalStorageByAge({\n prefix: BESIGNER_DRAFT_KEY_PREFIX,\n maxAgeMs: DRAFT_MAX_AGE_MS,\n now,\n })\n}\n"],"names":["pruneLocalStorageByAge","writeLocalStorageWithBudget","BESIGNER_DRAFT_KEY_PREFIX","DRAFT_MAX_AGE_MS","besignerDraftKey","ids","version","versionId","kind","scope","docId","storageOrNull","window","localStorage","writeBesignerDraft","draft","now","Date","value","updatedAt","key","JSON","stringify","evictPrefixes","ok","readBesignerDraft","storage","raw","getItem","parsed","parse","nodes","clearBesignerDraft","removeItem","pruneBesignerDrafts","prefix","maxAgeMs"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAEEA,sBAAsB,EACtBC,2BAA2B,QACtB,eAAc;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GAED,gEAAgE,GAChE,OAAO,MAAMC,4BAA4B,eAAc;AAEvD;;;CAGC,GACD,OAAO,MAAMC,mBAAmB,IAAI,KAAK,KAAK,KAAK,KAAI;AA4CvD,OAAO,SAASC,iBAAiBC,GAAqB;QACpCA;IAAhB,MAAMC,WAAUD,iBAAAA,IAAIE,SAAS,YAAbF,iBAAiB;IACjC,OACE,GAAGH,4BAA4BG,IAAIG,IAAI,CAAC,CAAC,CAAC,GAC1C,GAAGH,IAAII,KAAK,CAAC,CAAC,EAAEJ,IAAIK,KAAK,CAAC,CAAC,EAAEJ,SAAS;AAE1C;AAEA,SAASK;IACP,IAAI;QACF,OAAO,OAAOC,WAAW,cAAc,OAAOA,OAAOC,YAAY;IACnE,EAAE,eAAM;QACN,OAAO;IACT;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASC,mBACdT,GAAqB,EACrBU,KAAuC,EACvCC,MAAcC,KAAKD,GAAG,EAAE;IAExB,MAAME,QAAuB,aAAKH;QAAOI,WAAWH;;IACpD,OAAOf,4BAA4B;QACjCmB,KAAKhB,iBAAiBC;QACtBa,OAAOG,KAAKC,SAAS,CAACJ;QACtBK,eAAe;YAAC;YAAkBrB;SAA0B;IAC9D,GAAGsB,EAAE;AACP;AAEA;;;;CAIC,GACD,OAAO,SAASC,kBACdpB,GAAqB,EACrBW,MAAcC,KAAKD,GAAG,EAAE;QAkBbD;IAhBX,MAAMW,UAAUf;IAChB,IAAI,CAACe,SAAS,OAAO;IACrB,MAAMN,MAAMhB,iBAAiBC;IAC7B,MAAMsB,MAAMD,QAAQE,OAAO,CAACR;IAC5B,IAAI,CAACO,KAAK,OAAO;IACjB,IAAIZ;IACJ,IAAI;QACF,MAAMc,SAASR,KAAKS,KAAK,CAACH;QAC1BZ,QAAQc,CAAAA,0BAAAA,OAAQE,KAAK,IAAGF,SAAS;IACnC,EAAE,eAAM;QACNd,QAAQ;IACV;IACA,IAAI,CAACA,OAAO;QACViB,mBAAmB3B;QACnB,OAAO;IACT;IACA,IAAIW,QAAOD,mBAAAA,MAAMI,SAAS,YAAfJ,mBAAmB,KAAKZ,kBAAkB;QACnD6B,mBAAmB3B;QACnB,OAAO;IACT;IACA,OAAOU;AACT;AAEA,OAAO,SAASiB,mBAAmB3B,GAAqB;IACtD,IAAI;YACFM;SAAAA,iBAAAA,oCAAAA,eAAiBsB,UAAU,CAAC7B,iBAAiBC;IAC/C,EAAE,eAAM;IACN,4DAA4D;IAC9D;AACF;AAEA,iEAAiE,GACjE,OAAO,SAAS6B,oBAAoBlB,MAAcC,KAAKD,GAAG,EAAE;IAC1D,OAAOhB,uBAAuB;QAC5BmC,QAAQjC;QACRkC,UAAUjC;QACVa;IACF;AACF"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type Firestore } from 'firebase/firestore';
18
+ import { type ProcessableNodes } from '@aglyn/aglyn';
19
+ import type { BesignerDraftIds } from './besigner-draft-store';
20
+ /**
21
+ * THE WORKING DRAFT — server-side, shared, one per version (AGL-1152).
22
+ *
23
+ * ## Why this exists alongside the local store
24
+ *
25
+ * `besigner-draft-store` is a crash net: it holds keystrokes that were never
26
+ * saved, in this browser, and dies the moment a save succeeds. That is still
27
+ * exactly what it should be, and nothing here changes it.
28
+ *
29
+ * This is the other thing asked for, and it is genuinely different: the
30
+ * draft was originally only to save lost work, but now it is becoming a
31
+ * working document and we want to save the working document as we make changes
32
+ * and then publish after we are all done. So a draft here is written
33
+ * DELIBERATELY, survives the browser, and lives until it is published.
34
+ *
35
+ * ## Why it is not a free version history
36
+ *
37
+ * The same line AGL-1256 drew still holds, and this stays on the safe side of
38
+ * it for a structural reason rather than a promise: the document id is the
39
+ * constant {@link DRAFT_DOC_ID}. There is no second name to write, so there is
40
+ * no list to browse, nothing to name and nothing to choose between — you
41
+ * cannot have more than one. Versions remain the paid feature: many of them,
42
+ * restore points, scheduled release, variants, review cycles.
43
+ *
44
+ * ## Why a subcollection and not a field on the version
45
+ *
46
+ * The tenant reads version documents to render. A draft held as a field on one
47
+ * would be shipped to every render of that page and billed on every read of
48
+ * that document, to serve a value the tenant must never show. As its own
49
+ * document it is read only by an editor that opens it, and it gets its own 1MB
50
+ * budget rather than halving the target's.
51
+ *
52
+ * ## Compressed at rest, like the document it shadows
53
+ *
54
+ * A draft holds the WHOLE working tree, so it is the same size as the version
55
+ * it sits beside — and that version is msgpack. Stored as a plain Firestore
56
+ * map instead, the same tree costs about 1.4x as many bytes, which spends the
57
+ * budget above on encoding rather than on content: the largest page on the
58
+ * platform is 574,865 bytes as msgpack and 839,226 as a map, so its draft ran
59
+ * at 80% of the ceiling while the version sat at 55%.
60
+ *
61
+ * That gap also blinded the guard meant to catch it. `measureNodeMap` sizes a
62
+ * tree with the msgpack encoder — correctly, for the documents that use it —
63
+ * so the editor's near-limit warning read the version's 55% for a draft write
64
+ * that was actually at 80%, and the first thing an author would have learned
65
+ * about the ceiling is a save that stopped working.
66
+ *
67
+ * ## Co-editing
68
+ *
69
+ * There is ONE draft per target, not one per person, which is what makes it
70
+ * work with the live mirror rather than against it: the mirror carries
71
+ * in-flight keystrokes between people in the room, and a draft save promotes
72
+ * that shared state to something durable that everyone in the room — and
73
+ * anyone who joins later, from any browser — loads next. That is why saving a
74
+ * draft clears the mirror exactly as saving the document does: Firestore has
75
+ * become authoritative again, and replaying the mirror over it would re-apply
76
+ * edits the draft already contains.
77
+ */
78
+ /** The only id a draft may have. One per version, by construction. */
79
+ export declare const DRAFT_DOC_ID = "current";
80
+ export interface BesignerServerDraft {
81
+ nodes: ProcessableNodes;
82
+ /**
83
+ * The stored document's version stamp when this draft was taken. What lets
84
+ * the editor say "someone published since you started" honestly rather than
85
+ * silently overwriting them (AGL-674).
86
+ */
87
+ baseStamp: string | null;
88
+ /** Who last wrote it — a shared draft needs to say whose work it holds. */
89
+ updatedByUid: string | null;
90
+ updatedByEmail: string | null;
91
+ }
92
+ /**
93
+ * A draft as the store hands it back: what was written, plus WHEN.
94
+ *
95
+ * The time is the server's stamp, not the reader's clock. It is what the
96
+ * editor tells an author about the draft's age, and a draft saved yesterday
97
+ * that is described as "less than a minute ago" reads as work somebody is
98
+ * doing right now — the one thing a stranded draft is not (AGL-2868).
99
+ */
100
+ export interface StoredServerDraft extends BesignerServerDraft {
101
+ /** Epoch milliseconds of the last write, or null when the document carries no stamp. */
102
+ updatedAt: number | null;
103
+ }
104
+ /**
105
+ * The draft's document, or null when this target cannot hold one — no host
106
+ * scope, no version, or a kind with no versions. Null is a supported answer
107
+ * and every caller treats it as "no draft here", never as an error.
108
+ */
109
+ export declare function serverDraftRef(firestore: Firestore, ids: BesignerDraftIds): import("@firebase/firestore").DocumentReference<import("@firebase/firestore").DocumentData, import("@firebase/firestore").DocumentData>;
110
+ /**
111
+ * Writes the working draft. Resolves false rather than throwing when the
112
+ * target cannot hold one, so a caller does not have to re-derive that.
113
+ */
114
+ /**
115
+ * What a draft save did.
116
+ *
117
+ * `unchanged` is a SUCCESS, not a failure: the draft already holds this tree.
118
+ * Distinguished from `written` because the two deserve different words on
119
+ * screen — "Draft saved" said four times over an untouched document is how a
120
+ * reader stops believing the message (AGL-1483).
121
+ */
122
+ export type ServerDraftWrite = 'written' | 'unchanged' | 'failed';
123
+ export declare function writeServerDraft(firestore: Firestore, ids: BesignerDraftIds, draft: BesignerServerDraft): Promise<ServerDraftWrite>;
124
+ export declare function readServerDraft(firestore: Firestore, ids: BesignerDraftIds): Promise<StoredServerDraft | null>;
125
+ /**
126
+ * Clears the working draft. Called when it has been PUBLISHED — the work is in
127
+ * the document now, so a draft that outlived it would offer to restore the
128
+ * state the author just moved past.
129
+ */
130
+ export declare function clearServerDraft(firestore: Firestore, ids: BesignerDraftIds): Promise<void>;
@@ -0,0 +1,211 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ /**
4
+ * @license
5
+ * Copyright 2026 Aglyn LLC
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */ import { Bytes, deleteDoc, doc, getDoc, serverTimestamp, setDoc } from "firebase/firestore";
19
+ import { decodeStoredNodes, encodeStoredNodes } from "@aglyn/aglyn";
20
+ /**
21
+ * THE WORKING DRAFT — server-side, shared, one per version (AGL-1152).
22
+ *
23
+ * ## Why this exists alongside the local store
24
+ *
25
+ * `besigner-draft-store` is a crash net: it holds keystrokes that were never
26
+ * saved, in this browser, and dies the moment a save succeeds. That is still
27
+ * exactly what it should be, and nothing here changes it.
28
+ *
29
+ * This is the other thing asked for, and it is genuinely different: the
30
+ * draft was originally only to save lost work, but now it is becoming a
31
+ * working document and we want to save the working document as we make changes
32
+ * and then publish after we are all done. So a draft here is written
33
+ * DELIBERATELY, survives the browser, and lives until it is published.
34
+ *
35
+ * ## Why it is not a free version history
36
+ *
37
+ * The same line AGL-1256 drew still holds, and this stays on the safe side of
38
+ * it for a structural reason rather than a promise: the document id is the
39
+ * constant {@link DRAFT_DOC_ID}. There is no second name to write, so there is
40
+ * no list to browse, nothing to name and nothing to choose between — you
41
+ * cannot have more than one. Versions remain the paid feature: many of them,
42
+ * restore points, scheduled release, variants, review cycles.
43
+ *
44
+ * ## Why a subcollection and not a field on the version
45
+ *
46
+ * The tenant reads version documents to render. A draft held as a field on one
47
+ * would be shipped to every render of that page and billed on every read of
48
+ * that document, to serve a value the tenant must never show. As its own
49
+ * document it is read only by an editor that opens it, and it gets its own 1MB
50
+ * budget rather than halving the target's.
51
+ *
52
+ * ## Compressed at rest, like the document it shadows
53
+ *
54
+ * A draft holds the WHOLE working tree, so it is the same size as the version
55
+ * it sits beside — and that version is msgpack. Stored as a plain Firestore
56
+ * map instead, the same tree costs about 1.4x as many bytes, which spends the
57
+ * budget above on encoding rather than on content: the largest page on the
58
+ * platform is 574,865 bytes as msgpack and 839,226 as a map, so its draft ran
59
+ * at 80% of the ceiling while the version sat at 55%.
60
+ *
61
+ * That gap also blinded the guard meant to catch it. `measureNodeMap` sizes a
62
+ * tree with the msgpack encoder — correctly, for the documents that use it —
63
+ * so the editor's near-limit warning read the version's 55% for a draft write
64
+ * that was actually at 80%, and the first thing an author would have learned
65
+ * about the ceiling is a save that stopped working.
66
+ *
67
+ * ## Co-editing
68
+ *
69
+ * There is ONE draft per target, not one per person, which is what makes it
70
+ * work with the live mirror rather than against it: the mirror carries
71
+ * in-flight keystrokes between people in the room, and a draft save promotes
72
+ * that shared state to something durable that everyone in the room — and
73
+ * anyone who joins later, from any browser — loads next. That is why saving a
74
+ * draft clears the mirror exactly as saving the document does: Firestore has
75
+ * become authoritative again, and replaying the mirror over it would re-apply
76
+ * edits the draft already contains.
77
+ */ /** The only id a draft may have. One per version, by construction. */ export const DRAFT_DOC_ID = 'current';
78
+ /**
79
+ * Epoch milliseconds from a stored stamp — a Firestore `Timestamp`, or its
80
+ * `{ seconds, nanoseconds }` shape once it has crossed a serialization — or
81
+ * null for anything else. Null is an honest "not known", which the banner
82
+ * renders by not naming an age at all.
83
+ */ function stampMillis(value) {
84
+ if (!value || typeof value !== 'object') return null;
85
+ const stamp = value;
86
+ if (typeof stamp.toMillis === 'function') {
87
+ try {
88
+ const millis = stamp.toMillis();
89
+ return Number.isFinite(millis) ? millis : null;
90
+ } catch (unused) {
91
+ return null;
92
+ }
93
+ }
94
+ if (typeof stamp.seconds === 'number' && Number.isFinite(stamp.seconds)) {
95
+ var _stamp_nanoseconds;
96
+ return stamp.seconds * 1000 + Math.floor(((_stamp_nanoseconds = stamp.nanoseconds) != null ? _stamp_nanoseconds : 0) / 1e6);
97
+ }
98
+ return null;
99
+ }
100
+ /**
101
+ * `screen` → `screens`. The kinds that have no versioned subcollection get no
102
+ * draft: a template IS its document, so there is nothing for a draft to sit
103
+ * beside, and returning null here is what keeps callers from inventing a path.
104
+ */ const COLLECTION_OF = {
105
+ screen: 'screens',
106
+ layout: 'layouts',
107
+ component: 'components',
108
+ form: 'forms'
109
+ };
110
+ /**
111
+ * The draft's document, or null when this target cannot hold one — no host
112
+ * scope, no version, or a kind with no versions. Null is a supported answer
113
+ * and every caller treats it as "no draft here", never as an error.
114
+ */ export function serverDraftRef(firestore, ids) {
115
+ const collection = COLLECTION_OF[ids.kind];
116
+ if (!collection || !ids.scope || ids.scope === 'platform') return null;
117
+ if (!ids.docId || !ids.versionId) return null;
118
+ return doc(firestore, 'hosts', ids.scope, collection, ids.docId, 'versions', ids.versionId, 'draft', DRAFT_DOC_ID);
119
+ }
120
+ /**
121
+ * The tree last written to each draft, by path.
122
+ *
123
+ * Module scope, so all three editors get the check without repeating it, and
124
+ * so it survives a re-render rather than a mount.
125
+ *
126
+ * A LOCAL baseline, deliberately, where `handleSave` insists on comparing
127
+ * against the stored document. The two are guarding opposite mistakes.
128
+ * `handleSave` must never skip a write that is needed, so a baseline that
129
+ * lies would lose work and it re-reads to be sure. Here a stale baseline
130
+ * only ever causes an extra identical write, which costs one document and
131
+ * changes nothing — while reading the draft back on every click would cost a
132
+ * Firestore read per click for a check nothing depends on.
133
+ */ const lastWritten = new Map();
134
+ export async function writeServerDraft(firestore, ids, draft) {
135
+ var _draft_baseStamp, _draft_updatedByUid;
136
+ const ref = serverDraftRef(firestore, ids);
137
+ if (!ref) return 'failed';
138
+ // Keyed on the whole payload, not just the nodes: a draft carries the base
139
+ // stamp it was taken against, and one taken against a newer document is a
140
+ // different draft even when the tree is identical.
141
+ const fingerprint = JSON.stringify([
142
+ draft.nodes,
143
+ (_draft_baseStamp = draft.baseStamp) != null ? _draft_baseStamp : null,
144
+ (_draft_updatedByUid = draft.updatedByUid) != null ? _draft_updatedByUid : null
145
+ ]);
146
+ if (lastWritten.get(ref.path) === fingerprint) return 'unchanged';
147
+ // Compressed at rest, matching the version this shadows. `nodes` is taken
148
+ // out of the spread rather than overwritten after it, so the plain tree can
149
+ // never reach the write through a future edit that reorders these keys.
150
+ const { nodes } = draft, rest = _object_without_properties_loose(draft, [
151
+ "nodes"
152
+ ]);
153
+ const packed = encodeStoredNodes(nodes);
154
+ // Not `merge`: a draft is the whole working tree, and merging a smaller
155
+ // tree into a larger one would leave nodes from a previous save behind —
156
+ // the shape of AGL-1445, where a partial write resurrects deleted content.
157
+ await setDoc(ref, _extends({}, rest, packed ? {
158
+ nodes: Bytes.fromUint8Array(packed)
159
+ } : {}, {
160
+ updatedAt: serverTimestamp()
161
+ }));
162
+ lastWritten.set(ref.path, fingerprint);
163
+ return 'written';
164
+ }
165
+ export async function readServerDraft(firestore, ids) {
166
+ var _data_baseStamp, _data_updatedByUid, _data_updatedByEmail;
167
+ const ref = serverDraftRef(firestore, ids);
168
+ if (!ref) return null;
169
+ const snapshot = await getDoc(ref);
170
+ if (!snapshot.exists()) return null;
171
+ // `estimate`: a draft this browser wrote a moment ago can still have its
172
+ // `serverTimestamp` pending, and the local estimate of it is a truer age
173
+ // than none.
174
+ const data = snapshot.data({
175
+ serverTimestamps: 'estimate'
176
+ });
177
+ // BOTH stored forms, permanently. Drafts written before compression are
178
+ // plain maps and nothing migrates them, so a reader that understood only
179
+ // bytes would find no tree and report the draft absent — offering an author
180
+ // nothing where their unpublished work actually is. `decodeStoredNodes`
181
+ // returns a plain map unchanged, so one call covers both.
182
+ const nodes = decodeStoredNodes(data == null ? void 0 : data.nodes);
183
+ // A draft with no tree is not a draft. Guarding here rather than at the call
184
+ // site because a half-written document should read as absent, not as an
185
+ // empty canvas someone is about to publish over their page.
186
+ if (!nodes) return null;
187
+ return {
188
+ nodes,
189
+ baseStamp: (_data_baseStamp = data.baseStamp) != null ? _data_baseStamp : null,
190
+ updatedByUid: (_data_updatedByUid = data.updatedByUid) != null ? _data_updatedByUid : null,
191
+ updatedByEmail: (_data_updatedByEmail = data.updatedByEmail) != null ? _data_updatedByEmail : null,
192
+ updatedAt: stampMillis(data.updatedAt)
193
+ };
194
+ }
195
+ /**
196
+ * Clears the working draft. Called when it has been PUBLISHED — the work is in
197
+ * the document now, so a draft that outlived it would offer to restore the
198
+ * state the author just moved past.
199
+ */ export async function clearServerDraft(firestore, ids) {
200
+ const ref = serverDraftRef(firestore, ids);
201
+ if (!ref) return;
202
+ // Forget the fingerprint with the draft. Otherwise the next save of the
203
+ // same tree — a publish, then an undo back to it — would report itself
204
+ // unchanged against a draft that no longer exists.
205
+ lastWritten.delete(ref.path);
206
+ // Best effort: a publish that succeeded must not report failure because the
207
+ // tidy-up afterwards did. A stale draft is offered, not applied.
208
+ await deleteDoc(ref).catch(()=>undefined);
209
+ }
210
+
211
+ //# sourceMappingURL=besigner-server-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/besigner/feature/designer/src/lib/drafts/besigner-server-draft.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Bytes,\n type Firestore,\n deleteDoc,\n doc,\n getDoc,\n serverTimestamp,\n setDoc,\n} from 'firebase/firestore'\n\nimport {\n type ProcessableNodes,\n decodeStoredNodes,\n encodeStoredNodes,\n} from '@aglyn/aglyn'\nimport type { BesignerDraftIds } from './besigner-draft-store'\n\n/**\n * THE WORKING DRAFT — server-side, shared, one per version (AGL-1152).\n *\n * ## Why this exists alongside the local store\n *\n * `besigner-draft-store` is a crash net: it holds keystrokes that were never\n * saved, in this browser, and dies the moment a save succeeds. That is still\n * exactly what it should be, and nothing here changes it.\n *\n * This is the other thing asked for, and it is genuinely different: the\n * draft was originally only to save lost work, but now it is becoming a\n * working document and we want to save the working document as we make changes\n * and then publish after we are all done. So a draft here is written\n * DELIBERATELY, survives the browser, and lives until it is published.\n *\n * ## Why it is not a free version history\n *\n * The same line AGL-1256 drew still holds, and this stays on the safe side of\n * it for a structural reason rather than a promise: the document id is the\n * constant {@link DRAFT_DOC_ID}. There is no second name to write, so there is\n * no list to browse, nothing to name and nothing to choose between — you\n * cannot have more than one. Versions remain the paid feature: many of them,\n * restore points, scheduled release, variants, review cycles.\n *\n * ## Why a subcollection and not a field on the version\n *\n * The tenant reads version documents to render. A draft held as a field on one\n * would be shipped to every render of that page and billed on every read of\n * that document, to serve a value the tenant must never show. As its own\n * document it is read only by an editor that opens it, and it gets its own 1MB\n * budget rather than halving the target's.\n *\n * ## Compressed at rest, like the document it shadows\n *\n * A draft holds the WHOLE working tree, so it is the same size as the version\n * it sits beside — and that version is msgpack. Stored as a plain Firestore\n * map instead, the same tree costs about 1.4x as many bytes, which spends the\n * budget above on encoding rather than on content: the largest page on the\n * platform is 574,865 bytes as msgpack and 839,226 as a map, so its draft ran\n * at 80% of the ceiling while the version sat at 55%.\n *\n * That gap also blinded the guard meant to catch it. `measureNodeMap` sizes a\n * tree with the msgpack encoder — correctly, for the documents that use it —\n * so the editor's near-limit warning read the version's 55% for a draft write\n * that was actually at 80%, and the first thing an author would have learned\n * about the ceiling is a save that stopped working.\n *\n * ## Co-editing\n *\n * There is ONE draft per target, not one per person, which is what makes it\n * work with the live mirror rather than against it: the mirror carries\n * in-flight keystrokes between people in the room, and a draft save promotes\n * that shared state to something durable that everyone in the room — and\n * anyone who joins later, from any browser — loads next. That is why saving a\n * draft clears the mirror exactly as saving the document does: Firestore has\n * become authoritative again, and replaying the mirror over it would re-apply\n * edits the draft already contains.\n */\n\n/** The only id a draft may have. One per version, by construction. */\nexport const DRAFT_DOC_ID = 'current'\n\nexport interface BesignerServerDraft {\n nodes: ProcessableNodes\n /**\n * The stored document's version stamp when this draft was taken. What lets\n * the editor say \"someone published since you started\" honestly rather than\n * silently overwriting them (AGL-674).\n */\n baseStamp: string | null\n /** Who last wrote it — a shared draft needs to say whose work it holds. */\n updatedByUid: string | null\n updatedByEmail: string | null\n}\n\n/**\n * A draft as the store hands it back: what was written, plus WHEN.\n *\n * The time is the server's stamp, not the reader's clock. It is what the\n * editor tells an author about the draft's age, and a draft saved yesterday\n * that is described as \"less than a minute ago\" reads as work somebody is\n * doing right now — the one thing a stranded draft is not (AGL-2868).\n */\nexport interface StoredServerDraft extends BesignerServerDraft {\n /** Epoch milliseconds of the last write, or null when the document carries no stamp. */\n updatedAt: number | null\n}\n\n/**\n * Epoch milliseconds from a stored stamp — a Firestore `Timestamp`, or its\n * `{ seconds, nanoseconds }` shape once it has crossed a serialization — or\n * null for anything else. Null is an honest \"not known\", which the banner\n * renders by not naming an age at all.\n */\nfunction stampMillis(value: unknown): number | null {\n if (!value || typeof value !== 'object') return null\n const stamp = value as {\n toMillis?: () => number\n seconds?: number\n nanoseconds?: number\n }\n if (typeof stamp.toMillis === 'function') {\n try {\n const millis = stamp.toMillis()\n return Number.isFinite(millis) ? millis : null\n } catch {\n return null\n }\n }\n if (typeof stamp.seconds === 'number' && Number.isFinite(stamp.seconds)) {\n return stamp.seconds * 1000 + Math.floor((stamp.nanoseconds ?? 0) / 1e6)\n }\n return null\n}\n\n/**\n * `screen` → `screens`. The kinds that have no versioned subcollection get no\n * draft: a template IS its document, so there is nothing for a draft to sit\n * beside, and returning null here is what keeps callers from inventing a path.\n */\nconst COLLECTION_OF: Partial<Record<BesignerDraftIds['kind'], string>> = {\n screen: 'screens',\n layout: 'layouts',\n component: 'components',\n form: 'forms',\n}\n\n/**\n * The draft's document, or null when this target cannot hold one — no host\n * scope, no version, or a kind with no versions. Null is a supported answer\n * and every caller treats it as \"no draft here\", never as an error.\n */\nexport function serverDraftRef(firestore: Firestore, ids: BesignerDraftIds) {\n const collection = COLLECTION_OF[ids.kind]\n if (!collection || !ids.scope || ids.scope === 'platform') return null\n if (!ids.docId || !ids.versionId) return null\n return doc(\n firestore,\n 'hosts',\n ids.scope,\n collection,\n ids.docId,\n 'versions',\n ids.versionId,\n 'draft',\n DRAFT_DOC_ID,\n )\n}\n\n/**\n * Writes the working draft. Resolves false rather than throwing when the\n * target cannot hold one, so a caller does not have to re-derive that.\n */\n/**\n * What a draft save did.\n *\n * `unchanged` is a SUCCESS, not a failure: the draft already holds this tree.\n * Distinguished from `written` because the two deserve different words on\n * screen — \"Draft saved\" said four times over an untouched document is how a\n * reader stops believing the message (AGL-1483).\n */\nexport type ServerDraftWrite = 'written' | 'unchanged' | 'failed'\n\n/**\n * The tree last written to each draft, by path.\n *\n * Module scope, so all three editors get the check without repeating it, and\n * so it survives a re-render rather than a mount.\n *\n * A LOCAL baseline, deliberately, where `handleSave` insists on comparing\n * against the stored document. The two are guarding opposite mistakes.\n * `handleSave` must never skip a write that is needed, so a baseline that\n * lies would lose work and it re-reads to be sure. Here a stale baseline\n * only ever causes an extra identical write, which costs one document and\n * changes nothing — while reading the draft back on every click would cost a\n * Firestore read per click for a check nothing depends on.\n */\nconst lastWritten = new Map<string, string>()\n\nexport async function writeServerDraft(\n firestore: Firestore,\n ids: BesignerDraftIds,\n draft: BesignerServerDraft,\n): Promise<ServerDraftWrite> {\n const ref = serverDraftRef(firestore, ids)\n if (!ref) return 'failed'\n // Keyed on the whole payload, not just the nodes: a draft carries the base\n // stamp it was taken against, and one taken against a newer document is a\n // different draft even when the tree is identical.\n const fingerprint = JSON.stringify([\n draft.nodes,\n draft.baseStamp ?? null,\n draft.updatedByUid ?? null,\n ])\n if (lastWritten.get(ref.path) === fingerprint) return 'unchanged'\n // Compressed at rest, matching the version this shadows. `nodes` is taken\n // out of the spread rather than overwritten after it, so the plain tree can\n // never reach the write through a future edit that reorders these keys.\n const { nodes, ...rest } = draft\n const packed = encodeStoredNodes(nodes)\n // Not `merge`: a draft is the whole working tree, and merging a smaller\n // tree into a larger one would leave nodes from a previous save behind —\n // the shape of AGL-1445, where a partial write resurrects deleted content.\n await setDoc(ref, {\n ...rest,\n // `Bytes` is what the client SDK accepts for a bytes field;\n // `encodeStoredNodes` returns a bare array so it can stay Firestore-free.\n ...(packed ? { nodes: Bytes.fromUint8Array(packed) } : {}),\n updatedAt: serverTimestamp(),\n })\n lastWritten.set(ref.path, fingerprint)\n return 'written'\n}\n\nexport async function readServerDraft(\n firestore: Firestore,\n ids: BesignerDraftIds,\n): Promise<StoredServerDraft | null> {\n const ref = serverDraftRef(firestore, ids)\n if (!ref) return null\n const snapshot = await getDoc(ref)\n if (!snapshot.exists()) return null\n // `estimate`: a draft this browser wrote a moment ago can still have its\n // `serverTimestamp` pending, and the local estimate of it is a truer age\n // than none.\n const data = snapshot.data({ serverTimestamps: 'estimate' }) as Partial<\n BesignerServerDraft & { updatedAt: unknown }\n >\n // BOTH stored forms, permanently. Drafts written before compression are\n // plain maps and nothing migrates them, so a reader that understood only\n // bytes would find no tree and report the draft absent — offering an author\n // nothing where their unpublished work actually is. `decodeStoredNodes`\n // returns a plain map unchanged, so one call covers both.\n const nodes = decodeStoredNodes<ProcessableNodes>(data?.nodes)\n // A draft with no tree is not a draft. Guarding here rather than at the call\n // site because a half-written document should read as absent, not as an\n // empty canvas someone is about to publish over their page.\n if (!nodes) return null\n return {\n nodes,\n baseStamp: data.baseStamp ?? null,\n updatedByUid: data.updatedByUid ?? null,\n updatedByEmail: data.updatedByEmail ?? null,\n updatedAt: stampMillis(data.updatedAt),\n }\n}\n\n/**\n * Clears the working draft. Called when it has been PUBLISHED — the work is in\n * the document now, so a draft that outlived it would offer to restore the\n * state the author just moved past.\n */\nexport async function clearServerDraft(\n firestore: Firestore,\n ids: BesignerDraftIds,\n): Promise<void> {\n const ref = serverDraftRef(firestore, ids)\n if (!ref) return\n // Forget the fingerprint with the draft. Otherwise the next save of the\n // same tree — a publish, then an undo back to it — would report itself\n // unchanged against a draft that no longer exists.\n lastWritten.delete(ref.path)\n // Best effort: a publish that succeeded must not report failure because the\n // tidy-up afterwards did. A stale draft is offered, not applied.\n await deleteDoc(ref).catch(() => undefined)\n}\n"],"names":["Bytes","deleteDoc","doc","getDoc","serverTimestamp","setDoc","decodeStoredNodes","encodeStoredNodes","DRAFT_DOC_ID","stampMillis","value","stamp","toMillis","millis","Number","isFinite","seconds","Math","floor","nanoseconds","COLLECTION_OF","screen","layout","component","form","serverDraftRef","firestore","ids","collection","kind","scope","docId","versionId","lastWritten","Map","writeServerDraft","draft","ref","fingerprint","JSON","stringify","nodes","baseStamp","updatedByUid","get","path","rest","packed","fromUint8Array","updatedAt","set","readServerDraft","data","snapshot","exists","serverTimestamps","updatedByEmail","clearServerDraft","delete","catch","undefined"],"mappings":";;AAAA;;;;;;;;;;;;;;;CAeC,GAED,SACEA,KAAK,EAELC,SAAS,EACTC,GAAG,EACHC,MAAM,EACNC,eAAe,EACfC,MAAM,QACD,qBAAoB;AAE3B,SAEEC,iBAAiB,EACjBC,iBAAiB,QACZ,eAAc;AAGrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDC,GAED,oEAAoE,GACpE,OAAO,MAAMC,eAAe,UAAS;AA4BrC;;;;;CAKC,GACD,SAASC,YAAYC,KAAc;IACjC,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU,OAAO;IAChD,MAAMC,QAAQD;IAKd,IAAI,OAAOC,MAAMC,QAAQ,KAAK,YAAY;QACxC,IAAI;YACF,MAAMC,SAASF,MAAMC,QAAQ;YAC7B,OAAOE,OAAOC,QAAQ,CAACF,UAAUA,SAAS;QAC5C,EAAE,eAAM;YACN,OAAO;QACT;IACF;IACA,IAAI,OAAOF,MAAMK,OAAO,KAAK,YAAYF,OAAOC,QAAQ,CAACJ,MAAMK,OAAO,GAAG;YAC7BL;QAA1C,OAAOA,MAAMK,OAAO,GAAG,OAAOC,KAAKC,KAAK,CAAC,EAACP,qBAAAA,MAAMQ,WAAW,YAAjBR,qBAAqB,KAAK;IACtE;IACA,OAAO;AACT;AAEA;;;;CAIC,GACD,MAAMS,gBAAmE;IACvEC,QAAQ;IACRC,QAAQ;IACRC,WAAW;IACXC,MAAM;AACR;AAEA;;;;CAIC,GACD,OAAO,SAASC,eAAeC,SAAoB,EAAEC,GAAqB;IACxE,MAAMC,aAAaR,aAAa,CAACO,IAAIE,IAAI,CAAC;IAC1C,IAAI,CAACD,cAAc,CAACD,IAAIG,KAAK,IAAIH,IAAIG,KAAK,KAAK,YAAY,OAAO;IAClE,IAAI,CAACH,IAAII,KAAK,IAAI,CAACJ,IAAIK,SAAS,EAAE,OAAO;IACzC,OAAO9B,IACLwB,WACA,SACAC,IAAIG,KAAK,EACTF,YACAD,IAAII,KAAK,EACT,YACAJ,IAAIK,SAAS,EACb,SACAxB;AAEJ;AAgBA;;;;;;;;;;;;;CAaC,GACD,MAAMyB,cAAc,IAAIC;AAExB,OAAO,eAAeC,iBACpBT,SAAoB,EACpBC,GAAqB,EACrBS,KAA0B;QASxBA,kBACAA;IARF,MAAMC,MAAMZ,eAAeC,WAAWC;IACtC,IAAI,CAACU,KAAK,OAAO;IACjB,2EAA2E;IAC3E,0EAA0E;IAC1E,mDAAmD;IACnD,MAAMC,cAAcC,KAAKC,SAAS,CAAC;QACjCJ,MAAMK,KAAK;SACXL,mBAAAA,MAAMM,SAAS,YAAfN,mBAAmB;SACnBA,sBAAAA,MAAMO,YAAY,YAAlBP,sBAAsB;KACvB;IACD,IAAIH,YAAYW,GAAG,CAACP,IAAIQ,IAAI,MAAMP,aAAa,OAAO;IACtD,0EAA0E;IAC1E,4EAA4E;IAC5E,wEAAwE;IACxE,MAAM,EAAEG,KAAK,EAAW,GAAGL,OAATU,wCAASV;;;IAC3B,MAAMW,SAASxC,kBAAkBkC;IACjC,wEAAwE;IACxE,yEAAyE;IACzE,2EAA2E;IAC3E,MAAMpC,OAAOgC,KAAK,aACbS,MAGCC,SAAS;QAAEN,OAAOzC,MAAMgD,cAAc,CAACD;IAAQ,IAAI,CAAC;QACxDE,WAAW7C;;IAEb6B,YAAYiB,GAAG,CAACb,IAAIQ,IAAI,EAAEP;IAC1B,OAAO;AACT;AAEA,OAAO,eAAea,gBACpBzB,SAAoB,EACpBC,GAAqB;QAwBRyB,iBACGA,oBACEA;IAxBlB,MAAMf,MAAMZ,eAAeC,WAAWC;IACtC,IAAI,CAACU,KAAK,OAAO;IACjB,MAAMgB,WAAW,MAAMlD,OAAOkC;IAC9B,IAAI,CAACgB,SAASC,MAAM,IAAI,OAAO;IAC/B,yEAAyE;IACzE,yEAAyE;IACzE,aAAa;IACb,MAAMF,OAAOC,SAASD,IAAI,CAAC;QAAEG,kBAAkB;IAAW;IAG1D,wEAAwE;IACxE,yEAAyE;IACzE,4EAA4E;IAC5E,wEAAwE;IACxE,0DAA0D;IAC1D,MAAMd,QAAQnC,kBAAoC8C,wBAAAA,KAAMX,KAAK;IAC7D,6EAA6E;IAC7E,wEAAwE;IACxE,4DAA4D;IAC5D,IAAI,CAACA,OAAO,OAAO;IACnB,OAAO;QACLA;QACAC,SAAS,GAAEU,kBAAAA,KAAKV,SAAS,YAAdU,kBAAkB;QAC7BT,YAAY,GAAES,qBAAAA,KAAKT,YAAY,YAAjBS,qBAAqB;QACnCI,cAAc,GAAEJ,uBAAAA,KAAKI,cAAc,YAAnBJ,uBAAuB;QACvCH,WAAWxC,YAAY2C,KAAKH,SAAS;IACvC;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeQ,iBACpB/B,SAAoB,EACpBC,GAAqB;IAErB,MAAMU,MAAMZ,eAAeC,WAAWC;IACtC,IAAI,CAACU,KAAK;IACV,wEAAwE;IACxE,uEAAuE;IACvE,mDAAmD;IACnDJ,YAAYyB,MAAM,CAACrB,IAAIQ,IAAI;IAC3B,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM5C,UAAUoC,KAAKsB,KAAK,CAAC,IAAMC;AACnC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type FieldMuteAction } from '@aglyn/shared-ui-jsx-forms';
18
+ import { type FormControlProps, type ToggleButtonGroupProps } from '@mui/material';
19
+ export interface InlineFormControlProps extends Omit<FormControlProps, 'onChange'> {
20
+ onChange?: ToggleButtonGroupProps['onChange'];
21
+ value?: ToggleButtonGroupProps['value'];
22
+ label?: JSX.Children;
23
+ helperText?: JSX.Children;
24
+ /**
25
+ * Switch this declaration off without losing it (AGL-2486). These rows are
26
+ * not grid-wrapped fields, so they carry the eye themselves — beside the
27
+ * label, where the row has room, rather than in a corner it does not have.
28
+ */
29
+ mute?: FieldMuteAction;
30
+ }
31
+ export declare const InlineFormControl: import("react").ForwardRefExoticComponent<Omit<InlineFormControlProps, "ref"> & import("react").RefAttributes<any>>;
32
+ export default InlineFormControl;
@@ -0,0 +1,85 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ /**
5
+ * @license
6
+ * Copyright 2023 Aglyn LLC
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ import { FIELD_MUTED_STYLES, FieldMuteButton } from "@aglyn/shared-ui-jsx-forms";
20
+ import { Box, FormControl, FormHelperText, FormLabel } from "@mui/material";
21
+ import { forwardRef } from "react";
22
+ export const InlineFormControl = /*#__PURE__*/ forwardRef((props, forwardRef)=>{
23
+ const { helperText, label, mute, onChange, children } = props, rest = _object_without_properties_loose(props, [
24
+ "helperText",
25
+ "label",
26
+ "mute",
27
+ "onChange",
28
+ "children"
29
+ ]);
30
+ return /*#__PURE__*/ _jsxs(FormControl, _extends({
31
+ ref: forwardRef,
32
+ margin: "normal",
33
+ fullWidth: true
34
+ }, rest, {
35
+ sx: [
36
+ (mute == null ? void 0 : mute.muted) ? FIELD_MUTED_STYLES : null,
37
+ ...Array.isArray(rest.sx) ? rest.sx : [
38
+ rest.sx
39
+ ]
40
+ ],
41
+ children: [
42
+ /*#__PURE__*/ _jsxs(Box, {
43
+ sx: {
44
+ display: 'inline-flex',
45
+ alignItems: 'center',
46
+ flexDirection: 'row',
47
+ gap: 1,
48
+ flexWrap: 'wrap'
49
+ },
50
+ children: [
51
+ /*#__PURE__*/ _jsx(FormLabel, {
52
+ component: "label",
53
+ sx: {
54
+ flexBasis: `30%`,
55
+ whiteSpace: 'nowrap',
56
+ overflow: 'hidden',
57
+ flexShrink: 0
58
+ },
59
+ children: label
60
+ }),
61
+ /*#__PURE__*/ _jsx(FieldMuteButton, {
62
+ mute: mute,
63
+ sx: {
64
+ ml: -0.5
65
+ }
66
+ }),
67
+ /*#__PURE__*/ _jsx(Box, {
68
+ sx: {
69
+ // overflow: 'scroll',
70
+ flexGrow: 1
71
+ },
72
+ children: children
73
+ })
74
+ ]
75
+ }),
76
+ /*#__PURE__*/ _jsx(FormHelperText, {
77
+ children: helperText
78
+ })
79
+ ]
80
+ }));
81
+ });
82
+ InlineFormControl.displayName = 'InlineFormControl';
83
+ export default InlineFormControl;
84
+
85
+ //# sourceMappingURL=inline-form-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../../../libs/besigner/feature/designer/src/lib/form-fields/components/shared/inline-form-control.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2023 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n type FieldMuteAction,\n FIELD_MUTED_STYLES,\n FieldMuteButton,\n} from '@aglyn/shared-ui-jsx-forms'\nimport {\n Box,\n FormControl,\n type FormControlProps,\n FormHelperText,\n FormLabel,\n type ToggleButtonGroupProps,\n} from '@mui/material'\nimport { forwardRef } from 'react'\n\nexport interface InlineFormControlProps extends Omit<\n FormControlProps,\n 'onChange'\n> {\n onChange?: ToggleButtonGroupProps['onChange']\n value?: ToggleButtonGroupProps['value']\n label?: JSX.Children\n helperText?: JSX.Children\n /**\n * Switch this declaration off without losing it (AGL-2486). These rows are\n * not grid-wrapped fields, so they carry the eye themselves — beside the\n * label, where the row has room, rather than in a corner it does not have.\n */\n mute?: FieldMuteAction\n}\n\nexport const InlineFormControl = forwardRef<any, InlineFormControlProps>(\n (props, forwardRef) => {\n const { helperText, label, mute, onChange, children, ...rest } = props\n\n return (\n <FormControl\n ref={forwardRef}\n margin=\"normal\"\n fullWidth\n {...rest}\n sx={[\n mute?.muted ? FIELD_MUTED_STYLES : null,\n ...(Array.isArray(rest.sx) ? rest.sx : [rest.sx]),\n ]}\n >\n <Box\n sx={{\n display: 'inline-flex',\n alignItems: 'center',\n flexDirection: 'row',\n gap: 1,\n flexWrap: 'wrap',\n }}\n >\n <FormLabel\n component=\"label\"\n sx={{\n flexBasis: `30%`,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n flexShrink: 0,\n }}\n >\n {label}\n </FormLabel>\n <FieldMuteButton mute={mute} sx={{ ml: -0.5 }} />\n <Box\n sx={{\n // overflow: 'scroll',\n flexGrow: 1,\n }}\n >\n {children}\n </Box>\n </Box>\n\n <FormHelperText>{helperText}</FormHelperText>\n </FormControl>\n )\n },\n)\nInlineFormControl.displayName = 'InlineFormControl'\n\nexport default InlineFormControl\n"],"names":["FIELD_MUTED_STYLES","FieldMuteButton","Box","FormControl","FormHelperText","FormLabel","forwardRef","InlineFormControl","props","helperText","label","mute","onChange","children","rest","ref","margin","fullWidth","sx","muted","Array","isArray","display","alignItems","flexDirection","gap","flexWrap","component","flexBasis","whiteSpace","overflow","flexShrink","ml","flexGrow","displayName"],"mappings":";;;AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAEEA,kBAAkB,EAClBC,eAAe,QACV,6BAA4B;AACnC,SACEC,GAAG,EACHC,WAAW,EAEXC,cAAc,EACdC,SAAS,QAEJ,gBAAe;AACtB,SAASC,UAAU,QAAQ,QAAO;AAkBlC,OAAO,MAAMC,kCAAoBD,WAC/B,CAACE,OAAOF;IACN,MAAM,EAAEG,UAAU,EAAEC,KAAK,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,QAAQ,EAAW,GAAGL,OAATM,wCAASN;;;;;;;IAEjE,qBACE,MAACL;QACCY,KAAKT;QACLU,QAAO;QACPC,SAAS;OACLH;QACJI,IAAI;YACFP,CAAAA,wBAAAA,KAAMQ,KAAK,IAAGnB,qBAAqB;eAC/BoB,MAAMC,OAAO,CAACP,KAAKI,EAAE,IAAIJ,KAAKI,EAAE,GAAG;gBAACJ,KAAKI,EAAE;aAAC;SACjD;;0BAED,MAAChB;gBACCgB,IAAI;oBACFI,SAAS;oBACTC,YAAY;oBACZC,eAAe;oBACfC,KAAK;oBACLC,UAAU;gBACZ;;kCAEA,KAACrB;wBACCsB,WAAU;wBACVT,IAAI;4BACFU,WAAW,CAAC,GAAG,CAAC;4BAChBC,YAAY;4BACZC,UAAU;4BACVC,YAAY;wBACd;kCAECrB;;kCAEH,KAACT;wBAAgBU,MAAMA;wBAAMO,IAAI;4BAAEc,IAAI,CAAC;wBAAI;;kCAC5C,KAAC9B;wBACCgB,IAAI;4BACF,sBAAsB;4BACtBe,UAAU;wBACZ;kCAECpB;;;;0BAIL,KAACT;0BAAgBK;;;;AAGvB,GACD;AACDF,kBAAkB2B,WAAW,GAAG;AAEhC,eAAe3B,kBAAiB"}