rafa-engineering 0.0.1b1__tar.gz

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 (321) hide show
  1. rafa_engineering-0.0.1b1/.gitignore +25 -0
  2. rafa_engineering-0.0.1b1/LICENSE +121 -0
  3. rafa_engineering-0.0.1b1/PKG-INFO +175 -0
  4. rafa_engineering-0.0.1b1/README.md +130 -0
  5. rafa_engineering-0.0.1b1/frontend/dist/assets/ActionButton-Bf4Edlki.js +1 -0
  6. rafa_engineering-0.0.1b1/frontend/dist/assets/ActionButton.vue_vue_type_script_setup_true_lang-D4XFensL.js +1 -0
  7. rafa_engineering-0.0.1b1/frontend/dist/assets/ActionButtonInput-Fh_nzqPc.js +1 -0
  8. rafa_engineering-0.0.1b1/frontend/dist/assets/ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js +1 -0
  9. rafa_engineering-0.0.1b1/frontend/dist/assets/AutocompleteInput-BZX1zQNq.js +1 -0
  10. rafa_engineering-0.0.1b1/frontend/dist/assets/BooleanInput-Bwk7TmkZ.js +1 -0
  11. rafa_engineering-0.0.1b1/frontend/dist/assets/BufferGeometryUtils-DCeCGp_k.js +1 -0
  12. rafa_engineering-0.0.1b1/frontend/dist/assets/ChatPanel-CRGfj0rM.js +5 -0
  13. rafa_engineering-0.0.1b1/frontend/dist/assets/ChatPanel-DV8X386K.css +1 -0
  14. rafa_engineering-0.0.1b1/frontend/dist/assets/ChildrenView-BoHMn59N.js +1 -0
  15. rafa_engineering-0.0.1b1/frontend/dist/assets/ColorInput-BPm4Z_Jb.js +1 -0
  16. rafa_engineering-0.0.1b1/frontend/dist/assets/Column-BeMEmV70.js +1 -0
  17. rafa_engineering-0.0.1b1/frontend/dist/assets/DateInput-BCCGUhNt.css +1 -0
  18. rafa_engineering-0.0.1b1/frontend/dist/assets/DateInput-DoB9qbsx.js +1 -0
  19. rafa_engineering-0.0.1b1/frontend/dist/assets/DynamicArrayInput-DMMS0Z-7.css +1 -0
  20. rafa_engineering-0.0.1b1/frontend/dist/assets/DynamicArrayInput-_ZexTyhi.js +1 -0
  21. rafa_engineering-0.0.1b1/frontend/dist/assets/EntityInput-DtkTtCvs.js +1 -0
  22. rafa_engineering-0.0.1b1/frontend/dist/assets/FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js +1 -0
  23. rafa_engineering-0.0.1b1/frontend/dist/assets/FileUpload-D0temXG6.js +1 -0
  24. rafa_engineering-0.0.1b1/frontend/dist/assets/FlowList-BFQbYe4d.js +1 -0
  25. rafa_engineering-0.0.1b1/frontend/dist/assets/FlowList-BJJKReYx.css +1 -0
  26. rafa_engineering-0.0.1b1/frontend/dist/assets/GeoInput-B8mK3_to.js +1 -0
  27. rafa_engineering-0.0.1b1/frontend/dist/assets/GeometrySelectInput-C-dllULO.js +1 -0
  28. rafa_engineering-0.0.1b1/frontend/dist/assets/InlineMarkdown-273vK7EL.css +1 -0
  29. rafa_engineering-0.0.1b1/frontend/dist/assets/InlineMarkdown-DZ6hRlXd.js +1 -0
  30. rafa_engineering-0.0.1b1/frontend/dist/assets/ItemFields.vue_vue_type_script_setup_true_lang-oM-9Jbkr.js +1 -0
  31. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  32. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  33. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  34. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  35. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  36. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  37. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  38. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  39. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  40. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  41. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  42. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  43. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  44. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  45. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  46. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  47. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  48. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  49. rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  50. rafa_engineering-0.0.1b1/frontend/dist/assets/LineBreak-aRafznt0.js +1 -0
  51. rafa_engineering-0.0.1b1/frontend/dist/assets/MapSelectInput-DSHaB30s.js +1 -0
  52. rafa_engineering-0.0.1b1/frontend/dist/assets/MediaEmbed-BJ439byk.js +1 -0
  53. rafa_engineering-0.0.1b1/frontend/dist/assets/Metric-CZNGA3xN.js +1 -0
  54. rafa_engineering-0.0.1b1/frontend/dist/assets/MetricCard.vue_vue_type_script_setup_true_lang-C9JQb8Wv.js +1 -0
  55. rafa_engineering-0.0.1b1/frontend/dist/assets/MultiFileInput-ZXboXAai.js +1 -0
  56. rafa_engineering-0.0.1b1/frontend/dist/assets/NodeList.vue_vue_type_script_setup_true_lang-QazaRbQq.js +1 -0
  57. rafa_engineering-0.0.1b1/frontend/dist/assets/NumberInput-C2W5shMF.js +1 -0
  58. rafa_engineering-0.0.1b1/frontend/dist/assets/NumberInput-ClGTeHqr.css +1 -0
  59. rafa_engineering-0.0.1b1/frontend/dist/assets/OutputText-BCN_LkxG.js +1 -0
  60. rafa_engineering-0.0.1b1/frontend/dist/assets/Page-CaGMez-_.js +1 -0
  61. rafa_engineering-0.0.1b1/frontend/dist/assets/Region.vue_vue_type_script_setup_true_lang-C5zmYcwf.js +1 -0
  62. rafa_engineering-0.0.1b1/frontend/dist/assets/Row-Svp3fhrJ.js +1 -0
  63. rafa_engineering-0.0.1b1/frontend/dist/assets/Section-Bxqg4axO.js +1 -0
  64. rafa_engineering-0.0.1b1/frontend/dist/assets/SelectInput-3bMoZmLo.js +1 -0
  65. rafa_engineering-0.0.1b1/frontend/dist/assets/Tab-DmT7FFbM.js +1 -0
  66. rafa_engineering-0.0.1b1/frontend/dist/assets/TableInput-B6pu8pc-.css +1 -0
  67. rafa_engineering-0.0.1b1/frontend/dist/assets/TableInput-DRy1zZlo.js +1 -0
  68. rafa_engineering-0.0.1b1/frontend/dist/assets/Tabs-D_ly_8Cg.js +1 -0
  69. rafa_engineering-0.0.1b1/frontend/dist/assets/TextBlock-DCx1b51J.js +1 -0
  70. rafa_engineering-0.0.1b1/frontend/dist/assets/TextInput-ChR21tIl.js +1 -0
  71. rafa_engineering-0.0.1b1/frontend/dist/assets/View-5zkwqki7.js +7 -0
  72. rafa_engineering-0.0.1b1/frontend/dist/assets/View-B5J19S_i.css +1 -0
  73. rafa_engineering-0.0.1b1/frontend/dist/assets/Workspace-BHmWCHUw.js +1 -0
  74. rafa_engineering-0.0.1b1/frontend/dist/assets/Workspace-kQMd1Tiw.css +1 -0
  75. rafa_engineering-0.0.1b1/frontend/dist/assets/_commonjsHelpers-CqkleIqs.js +1 -0
  76. rafa_engineering-0.0.1b1/frontend/dist/assets/buildModel-FvbW_vi8.js +1 -0
  77. rafa_engineering-0.0.1b1/frontend/dist/assets/fileRecords-J4dDztnY.js +1 -0
  78. rafa_engineering-0.0.1b1/frontend/dist/assets/geometryPick-D2JWx8eh.js +1 -0
  79. rafa_engineering-0.0.1b1/frontend/dist/assets/geometryScene-DBVxLCLP.js +4012 -0
  80. rafa_engineering-0.0.1b1/frontend/dist/assets/index-BDd7wfsC.css +1 -0
  81. rafa_engineering-0.0.1b1/frontend/dist/assets/index-BR16ovZa.js +81 -0
  82. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
  83. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
  84. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
  85. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-700-normal-CjBOestx.woff2 +0 -0
  86. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
  87. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
  88. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
  89. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-700-normal-BjwYoWNd.woff2 +0 -0
  90. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
  91. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
  92. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
  93. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-700-normal-C3JjAnD8.woff2 +0 -0
  94. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
  95. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
  96. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
  97. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-700-normal-qfdV9bQt.woff2 +0 -0
  98. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  99. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  100. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
  101. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
  102. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
  103. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
  104. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
  105. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-700-normal-Ca8adRJv.woff2 +0 -0
  106. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
  107. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
  108. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
  109. rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-700-normal-DlLaEgI2.woff2 +0 -0
  110. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  111. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  112. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  113. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  114. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  115. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  116. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  117. rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  118. rafa_engineering-0.0.1b1/frontend/dist/assets/katex-BYjW4tYw.css +1 -0
  119. rafa_engineering-0.0.1b1/frontend/dist/assets/katex-DhXJpUyf.js +261 -0
  120. rafa_engineering-0.0.1b1/frontend/dist/assets/leafletChunk-wTN8pUxY.js +1 -0
  121. rafa_engineering-0.0.1b1/frontend/dist/assets/leafletChunk-ySJ7tiBZ.css +1 -0
  122. rafa_engineering-0.0.1b1/frontend/dist/assets/leafletMap-sOqlnmE2.js +2 -0
  123. rafa_engineering-0.0.1b1/frontend/dist/assets/listbox-CB4ZAfo3.js +1 -0
  124. rafa_engineering-0.0.1b1/frontend/dist/assets/loadGltf-3B6-WLUM.js +1 -0
  125. rafa_engineering-0.0.1b1/frontend/dist/assets/loadIfc-XWq_7Qp9.js +6 -0
  126. rafa_engineering-0.0.1b1/frontend/dist/assets/mapSelect-3T3UH25p.js +3 -0
  127. rafa_engineering-0.0.1b1/frontend/dist/assets/material-symbols-outlined-latin-400-normal-C-3S2fI8.woff2 +0 -0
  128. rafa_engineering-0.0.1b1/frontend/dist/assets/plotly.min-CSPuXaX0.js +3789 -0
  129. rafa_engineering-0.0.1b1/frontend/dist/assets/web-ifc-BDaIXFUT.wasm +0 -0
  130. rafa_engineering-0.0.1b1/frontend/dist/favicon.svg +1 -0
  131. rafa_engineering-0.0.1b1/frontend/dist/index.html +20 -0
  132. rafa_engineering-0.0.1b1/frontend/dist/theme-init.js +33 -0
  133. rafa_engineering-0.0.1b1/frontend/dist/web-view-frame.html +154 -0
  134. rafa_engineering-0.0.1b1/hatch_build.py +89 -0
  135. rafa_engineering-0.0.1b1/pyproject.toml +126 -0
  136. rafa_engineering-0.0.1b1/src/rafa/__init__.py +463 -0
  137. rafa_engineering-0.0.1b1/src/rafa/actions/__init__.py +42 -0
  138. rafa_engineering-0.0.1b1/src/rafa/actions/decorators.py +204 -0
  139. rafa_engineering-0.0.1b1/src/rafa/actions/results.py +533 -0
  140. rafa_engineering-0.0.1b1/src/rafa/agent/__init__.py +40 -0
  141. rafa_engineering-0.0.1b1/src/rafa/agent/install.py +428 -0
  142. rafa_engineering-0.0.1b1/src/rafa/agent/scaffold.py +163 -0
  143. rafa_engineering-0.0.1b1/src/rafa/agent/skill/SKILL.md +156 -0
  144. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/access-and-permissions.md +126 -0
  145. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/actions.md +157 -0
  146. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/common-mistakes.md +274 -0
  147. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/entities-and-hierarchy.md +190 -0
  148. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/fields-and-layout.md +218 -0
  149. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/jobs-and-progress.md +105 -0
  150. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/maps-3d-documents-chats.md +175 -0
  151. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/testing-and-checking.md +187 -0
  152. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/validation-and-conditions.md +176 -0
  153. rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/views-and-results.md +206 -0
  154. rafa_engineering-0.0.1b1/src/rafa/agent/templates/README.md.tmpl +34 -0
  155. rafa_engineering-0.0.1b1/src/rafa/agent/templates/gitignore.tmpl +5 -0
  156. rafa_engineering-0.0.1b1/src/rafa/agent/templates/package/__init__.py.tmpl +1 -0
  157. rafa_engineering-0.0.1b1/src/rafa/agent/templates/package/controller.py.tmpl +59 -0
  158. rafa_engineering-0.0.1b1/src/rafa/agent/templates/package/parametrization.py.tmpl +32 -0
  159. rafa_engineering-0.0.1b1/src/rafa/agent/templates/pyproject.toml.tmpl +20 -0
  160. rafa_engineering-0.0.1b1/src/rafa/agent/templates/tests/test_app.py.tmpl +44 -0
  161. rafa_engineering-0.0.1b1/src/rafa/auth.py +72 -0
  162. rafa_engineering-0.0.1b1/src/rafa/chat/__init__.py +26 -0
  163. rafa_engineering-0.0.1b1/src/rafa/chat/execution.py +221 -0
  164. rafa_engineering-0.0.1b1/src/rafa/chat/model.py +194 -0
  165. rafa_engineering-0.0.1b1/src/rafa/chat/service.py +353 -0
  166. rafa_engineering-0.0.1b1/src/rafa/chat/store.py +196 -0
  167. rafa_engineering-0.0.1b1/src/rafa/cli.py +541 -0
  168. rafa_engineering-0.0.1b1/src/rafa/cli_access.py +402 -0
  169. rafa_engineering-0.0.1b1/src/rafa/cli_agent.py +193 -0
  170. rafa_engineering-0.0.1b1/src/rafa/cli_dev.py +223 -0
  171. rafa_engineering-0.0.1b1/src/rafa/core/__init__.py +6 -0
  172. rafa_engineering-0.0.1b1/src/rafa/core/access.py +2915 -0
  173. rafa_engineering-0.0.1b1/src/rafa/core/app_roles.py +276 -0
  174. rafa_engineering-0.0.1b1/src/rafa/core/application.py +2717 -0
  175. rafa_engineering-0.0.1b1/src/rafa/core/calculations.py +253 -0
  176. rafa_engineering-0.0.1b1/src/rafa/core/controller.py +614 -0
  177. rafa_engineering-0.0.1b1/src/rafa/core/entity.py +419 -0
  178. rafa_engineering-0.0.1b1/src/rafa/core/field_permissions.py +146 -0
  179. rafa_engineering-0.0.1b1/src/rafa/core/jobs/__init__.py +0 -0
  180. rafa_engineering-0.0.1b1/src/rafa/core/jobs/execution.py +238 -0
  181. rafa_engineering-0.0.1b1/src/rafa/core/jobs/messages.py +218 -0
  182. rafa_engineering-0.0.1b1/src/rafa/core/jobs/model.py +242 -0
  183. rafa_engineering-0.0.1b1/src/rafa/core/jobs/progress.py +248 -0
  184. rafa_engineering-0.0.1b1/src/rafa/core/jobs/service.py +988 -0
  185. rafa_engineering-0.0.1b1/src/rafa/core/jobs/store.py +412 -0
  186. rafa_engineering-0.0.1b1/src/rafa/core/jobs/wire.py +73 -0
  187. rafa_engineering-0.0.1b1/src/rafa/core/parametrization.py +712 -0
  188. rafa_engineering-0.0.1b1/src/rafa/core/params.py +481 -0
  189. rafa_engineering-0.0.1b1/src/rafa/core/registry.py +215 -0
  190. rafa_engineering-0.0.1b1/src/rafa/core/services/__init__.py +42 -0
  191. rafa_engineering-0.0.1b1/src/rafa/core/services/_common.py +53 -0
  192. rafa_engineering-0.0.1b1/src/rafa/core/services/calculations.py +436 -0
  193. rafa_engineering-0.0.1b1/src/rafa/core/services/edit_locks.py +78 -0
  194. rafa_engineering-0.0.1b1/src/rafa/core/services/entities.py +754 -0
  195. rafa_engineering-0.0.1b1/src/rafa/core/services/revisions.py +200 -0
  196. rafa_engineering-0.0.1b1/src/rafa/core/services/summaries.py +113 -0
  197. rafa_engineering-0.0.1b1/src/rafa/core/steps.py +141 -0
  198. rafa_engineering-0.0.1b1/src/rafa/core/storage.py +370 -0
  199. rafa_engineering-0.0.1b1/src/rafa/core/summary.py +344 -0
  200. rafa_engineering-0.0.1b1/src/rafa/demo.py +88 -0
  201. rafa_engineering-0.0.1b1/src/rafa/documents/__init__.py +65 -0
  202. rafa_engineering-0.0.1b1/src/rafa/documents/_common.py +123 -0
  203. rafa_engineering-0.0.1b1/src/rafa/documents/_sandbox.py +607 -0
  204. rafa_engineering-0.0.1b1/src/rafa/documents/excel.py +264 -0
  205. rafa_engineering-0.0.1b1/src/rafa/documents/images.py +246 -0
  206. rafa_engineering-0.0.1b1/src/rafa/documents/pdf.py +83 -0
  207. rafa_engineering-0.0.1b1/src/rafa/documents/word.py +235 -0
  208. rafa_engineering-0.0.1b1/src/rafa/exceptions.py +257 -0
  209. rafa_engineering-0.0.1b1/src/rafa/fields/__init__.py +98 -0
  210. rafa_engineering-0.0.1b1/src/rafa/fields/autocomplete.py +128 -0
  211. rafa_engineering-0.0.1b1/src/rafa/fields/base.py +412 -0
  212. rafa_engineering-0.0.1b1/src/rafa/fields/buttons.py +181 -0
  213. rafa_engineering-0.0.1b1/src/rafa/fields/chat.py +160 -0
  214. rafa_engineering-0.0.1b1/src/rafa/fields/color.py +109 -0
  215. rafa_engineering-0.0.1b1/src/rafa/fields/containers.py +809 -0
  216. rafa_engineering-0.0.1b1/src/rafa/fields/date.py +249 -0
  217. rafa_engineering-0.0.1b1/src/rafa/fields/file.py +430 -0
  218. rafa_engineering-0.0.1b1/src/rafa/fields/geo.py +535 -0
  219. rafa_engineering-0.0.1b1/src/rafa/fields/geometry_select.py +275 -0
  220. rafa_engineering-0.0.1b1/src/rafa/fields/hidden.py +61 -0
  221. rafa_engineering-0.0.1b1/src/rafa/fields/layout.py +331 -0
  222. rafa_engineering-0.0.1b1/src/rafa/fields/multiselect.py +159 -0
  223. rafa_engineering-0.0.1b1/src/rafa/fields/numeric.py +524 -0
  224. rafa_engineering-0.0.1b1/src/rafa/fields/options.py +390 -0
  225. rafa_engineering-0.0.1b1/src/rafa/fields/output.py +149 -0
  226. rafa_engineering-0.0.1b1/src/rafa/fields/relationships.py +385 -0
  227. rafa_engineering-0.0.1b1/src/rafa/fields/text.py +221 -0
  228. rafa_engineering-0.0.1b1/src/rafa/geo.py +313 -0
  229. rafa_engineering-0.0.1b1/src/rafa/geometry/__init__.py +107 -0
  230. rafa_engineering-0.0.1b1/src/rafa/geometry/material.py +215 -0
  231. rafa_engineering-0.0.1b1/src/rafa/geometry/models.py +221 -0
  232. rafa_engineering-0.0.1b1/src/rafa/geometry/objects.py +1126 -0
  233. rafa_engineering-0.0.1b1/src/rafa/geometry/transform.py +177 -0
  234. rafa_engineering-0.0.1b1/src/rafa/geometry/vector.py +195 -0
  235. rafa_engineering-0.0.1b1/src/rafa/geometry/wire.py +278 -0
  236. rafa_engineering-0.0.1b1/src/rafa/layout/__init__.py +71 -0
  237. rafa_engineering-0.0.1b1/src/rafa/layout/base.py +46 -0
  238. rafa_engineering-0.0.1b1/src/rafa/layout/chat.py +43 -0
  239. rafa_engineering-0.0.1b1/src/rafa/layout/children.py +27 -0
  240. rafa_engineering-0.0.1b1/src/rafa/layout/containers.py +141 -0
  241. rafa_engineering-0.0.1b1/src/rafa/layout/elements.py +105 -0
  242. rafa_engineering-0.0.1b1/src/rafa/layout/geo.py +33 -0
  243. rafa_engineering-0.0.1b1/src/rafa/layout/inputs.py +173 -0
  244. rafa_engineering-0.0.1b1/src/rafa/map_tiles.py +268 -0
  245. rafa_engineering-0.0.1b1/src/rafa/messages.py +211 -0
  246. rafa_engineering-0.0.1b1/src/rafa/persistence/__init__.py +6 -0
  247. rafa_engineering-0.0.1b1/src/rafa/persistence/access_models.py +224 -0
  248. rafa_engineering-0.0.1b1/src/rafa/persistence/chat_models.py +93 -0
  249. rafa_engineering-0.0.1b1/src/rafa/persistence/deletion.py +198 -0
  250. rafa_engineering-0.0.1b1/src/rafa/persistence/dialects.py +96 -0
  251. rafa_engineering-0.0.1b1/src/rafa/persistence/edit_locks.py +322 -0
  252. rafa_engineering-0.0.1b1/src/rafa/persistence/files.py +486 -0
  253. rafa_engineering-0.0.1b1/src/rafa/persistence/job_models.py +207 -0
  254. rafa_engineering-0.0.1b1/src/rafa/persistence/models.py +361 -0
  255. rafa_engineering-0.0.1b1/src/rafa/persistence/params_json.py +154 -0
  256. rafa_engineering-0.0.1b1/src/rafa/persistence/repository.py +930 -0
  257. rafa_engineering-0.0.1b1/src/rafa/persistence/retention.py +507 -0
  258. rafa_engineering-0.0.1b1/src/rafa/persistence/session.py +302 -0
  259. rafa_engineering-0.0.1b1/src/rafa/persistence/storage_models.py +76 -0
  260. rafa_engineering-0.0.1b1/src/rafa/persistence/transfer.py +238 -0
  261. rafa_engineering-0.0.1b1/src/rafa/persistence/types.py +56 -0
  262. rafa_engineering-0.0.1b1/src/rafa/project.py +158 -0
  263. rafa_engineering-0.0.1b1/src/rafa/project_dependencies.py +233 -0
  264. rafa_engineering-0.0.1b1/src/rafa/server/__init__.py +0 -0
  265. rafa_engineering-0.0.1b1/src/rafa/server/api.py +45 -0
  266. rafa_engineering-0.0.1b1/src/rafa/server/auth.py +393 -0
  267. rafa_engineering-0.0.1b1/src/rafa/server/controllers.py +87 -0
  268. rafa_engineering-0.0.1b1/src/rafa/server/dependencies.py +112 -0
  269. rafa_engineering-0.0.1b1/src/rafa/server/dev.py +80 -0
  270. rafa_engineering-0.0.1b1/src/rafa/server/logs.py +80 -0
  271. rafa_engineering-0.0.1b1/src/rafa/server/main.py +511 -0
  272. rafa_engineering-0.0.1b1/src/rafa/server/middleware.py +229 -0
  273. rafa_engineering-0.0.1b1/src/rafa/server/oidc.py +525 -0
  274. rafa_engineering-0.0.1b1/src/rafa/server/params.py +101 -0
  275. rafa_engineering-0.0.1b1/src/rafa/server/purge.py +87 -0
  276. rafa_engineering-0.0.1b1/src/rafa/server/routes/__init__.py +1 -0
  277. rafa_engineering-0.0.1b1/src/rafa/server/routes/_common.py +80 -0
  278. rafa_engineering-0.0.1b1/src/rafa/server/routes/access.py +328 -0
  279. rafa_engineering-0.0.1b1/src/rafa/server/routes/admin.py +318 -0
  280. rafa_engineering-0.0.1b1/src/rafa/server/routes/calculations.py +268 -0
  281. rafa_engineering-0.0.1b1/src/rafa/server/routes/chats.py +188 -0
  282. rafa_engineering-0.0.1b1/src/rafa/server/routes/edit_locks.py +125 -0
  283. rafa_engineering-0.0.1b1/src/rafa/server/routes/entities.py +289 -0
  284. rafa_engineering-0.0.1b1/src/rafa/server/routes/jobs.py +389 -0
  285. rafa_engineering-0.0.1b1/src/rafa/server/routes/navigation.py +86 -0
  286. rafa_engineering-0.0.1b1/src/rafa/server/routes/revisions.py +86 -0
  287. rafa_engineering-0.0.1b1/src/rafa/server/routes/types.py +84 -0
  288. rafa_engineering-0.0.1b1/src/rafa/server/schemas.py +1151 -0
  289. rafa_engineering-0.0.1b1/src/rafa/server/security.py +454 -0
  290. rafa_engineering-0.0.1b1/src/rafa/server/themes.py +326 -0
  291. rafa_engineering-0.0.1b1/src/rafa/server/worker_process.py +320 -0
  292. rafa_engineering-0.0.1b1/src/rafa/server/workers.py +473 -0
  293. rafa_engineering-0.0.1b1/src/rafa/settings.py +586 -0
  294. rafa_engineering-0.0.1b1/src/rafa/testing/__init__.py +397 -0
  295. rafa_engineering-0.0.1b1/src/rafa/testing/checks.py +803 -0
  296. rafa_engineering-0.0.1b1/src/rafa/testing/pytest_plugin.py +50 -0
  297. rafa_engineering-0.0.1b1/src/rafa/testing/screenshot.py +508 -0
  298. rafa_engineering-0.0.1b1/src/rafa/themes/__init__.py +11 -0
  299. rafa_engineering-0.0.1b1/src/rafa/themes/colors.py +181 -0
  300. rafa_engineering-0.0.1b1/src/rafa/themes/css.py +109 -0
  301. rafa_engineering-0.0.1b1/src/rafa/themes/files.py +143 -0
  302. rafa_engineering-0.0.1b1/src/rafa/themes/model.py +423 -0
  303. rafa_engineering-0.0.1b1/src/rafa/themes/tokens.py +124 -0
  304. rafa_engineering-0.0.1b1/src/rafa/ui/__init__.py +75 -0
  305. rafa_engineering-0.0.1b1/src/rafa/ui/adapters/__init__.py +31 -0
  306. rafa_engineering-0.0.1b1/src/rafa/ui/adapters/cli.py +652 -0
  307. rafa_engineering-0.0.1b1/src/rafa/ui/application.py +667 -0
  308. rafa_engineering-0.0.1b1/src/rafa/ui/context.py +153 -0
  309. rafa_engineering-0.0.1b1/src/rafa/ui/protocols.py +681 -0
  310. rafa_engineering-0.0.1b1/src/rafa/utils/__init__.py +29 -0
  311. rafa_engineering-0.0.1b1/src/rafa/utils/dicts.py +37 -0
  312. rafa_engineering-0.0.1b1/src/rafa/utils/memoization.py +312 -0
  313. rafa_engineering-0.0.1b1/src/rafa/utils/migrations.py +316 -0
  314. rafa_engineering-0.0.1b1/src/rafa/validation/__init__.py +22 -0
  315. rafa_engineering-0.0.1b1/src/rafa/validation/callbacks.py +187 -0
  316. rafa_engineering-0.0.1b1/src/rafa/validation/lookup.py +807 -0
  317. rafa_engineering-0.0.1b1/src/rafa/views/__init__.py +91 -0
  318. rafa_engineering-0.0.1b1/src/rafa/views/decorators.py +290 -0
  319. rafa_engineering-0.0.1b1/src/rafa/views/maps.py +990 -0
  320. rafa_engineering-0.0.1b1/src/rafa/views/results.py +1428 -0
  321. rafa_engineering-0.0.1b1/src/rafa/views/safe_html.py +100 -0
@@ -0,0 +1,25 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+ .python-version
9
+ *.db
10
+ misc.xml
11
+ .idea
12
+
13
+ # Virtual environments
14
+ .venv
15
+ venv
16
+
17
+ .claude
18
+ .gemini-clipboard
19
+
20
+ # MkDocs build output
21
+ site/
22
+
23
+ node_modules
24
+ .coverage
25
+ coverage.json
@@ -0,0 +1,121 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: Enrique García
6
+
7
+ Licensed Work: Rafa (the Python package rafa-engineering and its web app),
8
+ version 0.1.0 and later. The Licensed Work is
9
+ (c) 2026 Enrique García.
10
+
11
+ Additional Use Grant: You may make production use of the Licensed Work if at
12
+ least one of the following applies to you:
13
+
14
+ (a) you are a natural person;
15
+
16
+ (b) you are an organization that qualifies as a small
17
+ enterprise as defined in Commission Recommendation
18
+ 2003/361/EC: fewer than 50 staff and an annual
19
+ turnover or annual balance sheet total not exceeding
20
+ EUR 10 million, counted together with your partner
21
+ and linked enterprises as that Recommendation
22
+ prescribes;
23
+
24
+ (c) you are an accredited educational institution or a
25
+ non-profit research organization, and you use the
26
+ Licensed Work for teaching, study or research.
27
+
28
+ This grant does not cover production use (i) on behalf
29
+ of, for, or as a service to an organization that does
30
+ not itself qualify under (b) or (c), or (ii) in which
31
+ people acting on behalf of such an organization use the
32
+ Licensed Work or an application built with it. Such use
33
+ requires a commercial license from the Licensor.
34
+
35
+ Change Date: Four years from the date the Licensed Work is published.
36
+ Each version has its own Change Date.
37
+
38
+ Change License: Apache License, Version 2.0
39
+
40
+ For a commercial license, or any other licensing question, contact
41
+ Enrique García at enriquegarcia@live.nl.
42
+
43
+ Notice
44
+
45
+ The Business Source License (this document, or the "License") is not an Open
46
+ Source license. However, the Licensed Work will eventually be made available
47
+ under an Open Source License, as stated in this License.
48
+
49
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
50
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
51
+
52
+ -----------------------------------------------------------------------------
53
+
54
+ Business Source License 1.1
55
+
56
+ Terms
57
+
58
+ The Licensor hereby grants you the right to copy, modify, create derivative
59
+ works, redistribute, and make non-production use of the Licensed Work. The
60
+ Licensor may make an Additional Use Grant, above, permitting limited
61
+ production use.
62
+
63
+ Effective on the Change Date, or the fourth anniversary of the first publicly
64
+ available distribution of a specific version of the Licensed Work under this
65
+ License, whichever comes first, the Licensor hereby grants you rights under
66
+ the terms of the Change License, and the rights granted in the paragraph
67
+ above terminate.
68
+
69
+ If your use of the Licensed Work does not comply with the requirements
70
+ currently in effect as described in this License, you must purchase a
71
+ commercial license from the Licensor, its affiliated entities, or authorized
72
+ resellers, or you must refrain from using the Licensed Work.
73
+
74
+ All copies of the original and modified Licensed Work, and derivative works
75
+ of the Licensed Work, are subject to this License. This License applies
76
+ separately for each version of the Licensed Work and the Change Date may vary
77
+ for each version of the Licensed Work released by Licensor.
78
+
79
+ You must conspicuously display this License on each original or modified copy
80
+ of the Licensed Work. If you receive the Licensed Work in original or
81
+ modified form from a third party, the terms and conditions set forth in this
82
+ License apply to your use of that work.
83
+
84
+ Any use of the Licensed Work in violation of this License will automatically
85
+ terminate your rights under this License for the current and all other
86
+ versions of the Licensed Work.
87
+
88
+ This License does not grant you any right in any trademark or logo of
89
+ Licensor or its affiliates (provided that you may use a trademark or logo of
90
+ Licensor as expressly required by this License).
91
+
92
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
93
+ AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
94
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
95
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
96
+ TITLE.
97
+
98
+ MariaDB hereby grants you permission to use this License’s text to license
99
+ your works, and to refer to it using the trademark “Business Source License”,
100
+ as long as you comply with the Covenants of Licensor below.
101
+
102
+ Covenants of Licensor
103
+
104
+ In consideration of the right to use this License’s text and the “Business
105
+ Source License” name and trademark, Licensor covenants to MariaDB, and to all
106
+ other recipients of the licensed work to be provided by Licensor:
107
+
108
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
109
+ or a license that is compatible with GPL Version 2.0 or a later version,
110
+ where “compatible” means that software provided under the Change License can
111
+ be included in a program with software provided under GPL Version 2.0 or a
112
+ later version. Licensor may specify additional Change Licenses without
113
+ limitation.
114
+
115
+ 2. To either: (a) specify an additional grant of rights to use that does not
116
+ impose any additional restriction on the right granted in this License, as
117
+ the Additional Use Grant; or (b) insert the text “None”.
118
+
119
+ 3. To specify a Change Date.
120
+
121
+ 4. Not to modify this License in any other way.
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.5
2
+ Name: rafa-engineering
3
+ Version: 0.0.1b1
4
+ Summary: A self-hosted application framework for engineering web applications
5
+ Project-URL: Homepage, https://github.com/egarciamendez/rafa
6
+ Project-URL: Documentation, https://github.com/egarciamendez/rafa/tree/main/docs
7
+ Project-URL: Changelog, https://github.com/egarciamendez/rafa/blob/main/docs/changelog.md
8
+ Author: Enrique García
9
+ License: BUSL-1.1
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: Other/Proprietary License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Requires-Python: >=3.12
18
+ Requires-Dist: fastapi>=0.100.0
19
+ Requires-Dist: packaging>=23.0
20
+ Requires-Dist: pydantic-settings>=2.7
21
+ Requires-Dist: pydantic>=2.0
22
+ Requires-Dist: python-multipart>=0.0.6
23
+ Requires-Dist: sqlmodel>=0.0.22
24
+ Requires-Dist: uvicorn>=0.20.0
25
+ Requires-Dist: watchfiles>=0.21
26
+ Provides-Extra: documents
27
+ Requires-Dist: docxtpl>=0.19; extra == 'documents'
28
+ Requires-Dist: openpyxl>=3.1; extra == 'documents'
29
+ Requires-Dist: pypdf>=5.0; extra == 'documents'
30
+ Provides-Extra: maps
31
+ Requires-Dist: mapyta>=1.1; extra == 'maps'
32
+ Provides-Extra: oidc
33
+ Requires-Dist: httpx>=0.27; extra == 'oidc'
34
+ Requires-Dist: pyjwt[crypto]>=2.8; extra == 'oidc'
35
+ Provides-Extra: plotly-export
36
+ Requires-Dist: kaleido>=1.0; extra == 'plotly-export'
37
+ Requires-Dist: plotly>=6.1; extra == 'plotly-export'
38
+ Provides-Extra: plots
39
+ Requires-Dist: matplotlib>=3.8; extra == 'plots'
40
+ Provides-Extra: postgres
41
+ Requires-Dist: psycopg[binary]>=3.2; extra == 'postgres'
42
+ Provides-Extra: screenshot
43
+ Requires-Dist: playwright>=1.49; extra == 'screenshot'
44
+ Description-Content-Type: text/markdown
45
+
46
+ # Rafa
47
+
48
+ **Build engineering web apps in plain Python.** Declare the inputs, write the calculation, get a
49
+ browser workspace with forms, live views, revisions and a database. A library you run on your
50
+ own infrastructure.
51
+
52
+ <picture>
53
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-light.png">
54
+ <img alt="The workspace: loads of a foundation pad on the left, its soil pressure chart on the canvas, metrics in the results panel on the right" src="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-dark.png">
55
+ </picture>
56
+
57
+ - **Python SDK** (`rafa`): parametrizations, controllers, views, actions, entities,
58
+ revisions, migrations. Stored in SQLite or PostgreSQL through SQLModel.
59
+ - **Server**: a FastAPI app that serves the HTTP API and the web UI from one process.
60
+ - **Web app**: a Vue 3 workspace rendered from layout JSON the server generates from your
61
+ Python classes: entity browser, autosave with undo and revision history, RUN for slow
62
+ calculations, keyboard shortcuts and a command palette, dark and light theme.
63
+
64
+ ## Quickstart
65
+
66
+ Requires Python 3.12+. The package contains the web app, so no Node.js is needed. Rafa is in
67
+ beta:
68
+
69
+ ```bash
70
+ pip install rafa-engineering # or: uv add rafa-engineering
71
+ rafa serve --demo # http://127.0.0.1:7232
72
+ rafa new bridge-checks && cd bridge-checks # a new app of your own
73
+ rafa dev # it, restarted and checked on every change
74
+ ```
75
+
76
+ The [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) walks from the install to your own app in the browser,
77
+ and shows how to run the [example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) from a checkout.
78
+
79
+ ## Features
80
+
81
+ - **Declarative inputs**: 25 field types (numbers, options, dates, tables, dynamic arrays,
82
+ files, entity references) in tabs and sections, with `Lookup` constraints and conditional
83
+ visibility.
84
+ - **Views**: `@view` returns HTML, data, a table, an image, a PDF, a Plotly chart or 3D
85
+ geometry; `@metric` shows a number in the results panel. Fast views refresh on every change,
86
+ slow views run on **RUN**.
87
+ - **Actions**: `@action` methods become buttons that return a message, a file download, new
88
+ input values or candidate designs to choose from.
89
+ - **Entities**: typed, hierarchical records with navigation, cascade rules, soft delete and
90
+ recovery.
91
+ - **Revisions**: every save is a revision; list, read and restore.
92
+ - **Schema migrations**: evolve a parametrization without losing stored data.
93
+ - **Server**: one `rafa serve` command, sign-in (API key, proxy, OpenID Connect or your
94
+ own hook), SQLite or PostgreSQL, backups, retention, calculation limits, a Docker image.
95
+ - **Design system**: one token file drives the web app's dark and light theme.
96
+
97
+ Overview: [docs/features.md](https://github.com/egarciamendez/rafa/blob/main/docs/features.md).
98
+
99
+ ## Documentation
100
+
101
+ | You want to | Read |
102
+ |---|---|
103
+ | Try it in 5 minutes | [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) |
104
+ | Learn the SDK step by step | [Tutorial](https://github.com/egarciamendez/rafa/blob/main/docs/tutorial/index.md) |
105
+ | Look up a term | [Concepts](https://github.com/egarciamendez/rafa/blob/main/docs/concepts.md) |
106
+ | Learn from working apps | [Example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) |
107
+ | Solve a specific task | [How-to guides](https://github.com/egarciamendez/rafa/blob/main/docs/how-to/index.md) |
108
+ | Use the web app | [User guide](https://github.com/egarciamendez/rafa/blob/main/docs/user-guide/index.md) |
109
+ | Run or deploy the server | [Run the server](https://github.com/egarciamendez/rafa/blob/main/docs/server/index.md), [Deploy](https://github.com/egarciamendez/rafa/blob/main/docs/server/deploy.md), [Settings](https://github.com/egarciamendez/rafa/blob/main/docs/server/settings.md) |
110
+ | Call the HTTP API | [HTTP API](https://github.com/egarciamendez/rafa/blob/main/docs/reference/http-api.md) |
111
+ | Look up a class | [Reference](https://github.com/egarciamendez/rafa/blob/main/docs/reference/index.md) |
112
+ | Know why it works this way | [Decisions](https://github.com/egarciamendez/rafa/blob/main/docs/decisions.md), [Architecture](https://github.com/egarciamendez/rafa/blob/main/docs/about/architecture.md) |
113
+
114
+ Build the documentation site locally:
115
+
116
+ ```bash
117
+ uv sync --group docs
118
+ uv run properdocs serve -f properdocs.yml # http://127.0.0.1:8000
119
+ ```
120
+
121
+ ## Project layout
122
+
123
+ ```
124
+ src/rafa/ Python SDK (package `rafa`)
125
+ core/ Application, Controller, Parametrization, Entity, Params, services
126
+ fields/ input fields and layout (Tab, Section, ...)
127
+ views/ actions/ @view, @metric, @action and their result types
128
+ layout/ layout tree sent to the web app as JSON
129
+ persistence/ SQLModel models and repositories
130
+ server/ FastAPI app, settings, middleware
131
+ frontend/ Vue 3 + Vite + Tailwind web app
132
+ design_system/ design tokens (colors_and_type.css) and UI kit
133
+ examples/ example apps: engineering_app (Beam, Project, Showcase), foundation_app,
134
+ beam_formulas_app
135
+ docs/ documentation site (properdocs)
136
+ tests/ pytest suite
137
+ ```
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ uv sync --all-groups # Python dependencies (dev + docs)
143
+ uv run pytest # tests
144
+ uv run ruff check . && uv run ruff format --check .
145
+ uv run ty check . # type check
146
+
147
+ # Frontend development: the API with reload (answering the dev server's origin), and Vite
148
+ RAFA_CORS_ORIGINS=http://localhost:5173 \
149
+ uv run uvicorn rafa.server.main:app --reload --port 8000 --no-proxy-headers
150
+ cd frontend
151
+ npm ci
152
+ npm run dev # http://localhost:5173, uses the API on :8000
153
+ npm run build # type check + production build to dist/
154
+ npm test # Storybook story tests (needs Playwright Chromium)
155
+ ```
156
+
157
+ CI runs all of the above plus a strict docs build, and builds the wheel, installs it outside
158
+ the checkout and serves an app from it. See [Contributing](https://github.com/egarciamendez/rafa/blob/main/docs/contributing.md).
159
+
160
+ ## License
161
+
162
+ Rafa is licensed under the [Business Source License 1.1](https://github.com/egarciamendez/rafa/blob/main/LICENSE). Production use is free for:
163
+
164
+ - individuals;
165
+ - small enterprises: fewer than 50 staff and at most EUR 10 million turnover or balance sheet
166
+ total (the EU definition, Recommendation 2003/361/EC, group companies included);
167
+ - teaching, study and research at educational institutions and non-profit research
168
+ organizations.
169
+
170
+ Development, testing and evaluation are free for everyone. Production use on behalf of, for, or
171
+ by people of a larger organization needs a commercial license: contact Enrique García at
172
+ enriquegarcia@live.nl. Four years after its release, each version becomes available under the
173
+ Apache License 2.0.
174
+
175
+ © 2026 Enrique García
@@ -0,0 +1,130 @@
1
+ # Rafa
2
+
3
+ **Build engineering web apps in plain Python.** Declare the inputs, write the calculation, get a
4
+ browser workspace with forms, live views, revisions and a database. A library you run on your
5
+ own infrastructure.
6
+
7
+ <picture>
8
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-light.png">
9
+ <img alt="The workspace: loads of a foundation pad on the left, its soil pressure chart on the canvas, metrics in the results panel on the right" src="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-dark.png">
10
+ </picture>
11
+
12
+ - **Python SDK** (`rafa`): parametrizations, controllers, views, actions, entities,
13
+ revisions, migrations. Stored in SQLite or PostgreSQL through SQLModel.
14
+ - **Server**: a FastAPI app that serves the HTTP API and the web UI from one process.
15
+ - **Web app**: a Vue 3 workspace rendered from layout JSON the server generates from your
16
+ Python classes: entity browser, autosave with undo and revision history, RUN for slow
17
+ calculations, keyboard shortcuts and a command palette, dark and light theme.
18
+
19
+ ## Quickstart
20
+
21
+ Requires Python 3.12+. The package contains the web app, so no Node.js is needed. Rafa is in
22
+ beta:
23
+
24
+ ```bash
25
+ pip install rafa-engineering # or: uv add rafa-engineering
26
+ rafa serve --demo # http://127.0.0.1:7232
27
+ rafa new bridge-checks && cd bridge-checks # a new app of your own
28
+ rafa dev # it, restarted and checked on every change
29
+ ```
30
+
31
+ The [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) walks from the install to your own app in the browser,
32
+ and shows how to run the [example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) from a checkout.
33
+
34
+ ## Features
35
+
36
+ - **Declarative inputs**: 25 field types (numbers, options, dates, tables, dynamic arrays,
37
+ files, entity references) in tabs and sections, with `Lookup` constraints and conditional
38
+ visibility.
39
+ - **Views**: `@view` returns HTML, data, a table, an image, a PDF, a Plotly chart or 3D
40
+ geometry; `@metric` shows a number in the results panel. Fast views refresh on every change,
41
+ slow views run on **RUN**.
42
+ - **Actions**: `@action` methods become buttons that return a message, a file download, new
43
+ input values or candidate designs to choose from.
44
+ - **Entities**: typed, hierarchical records with navigation, cascade rules, soft delete and
45
+ recovery.
46
+ - **Revisions**: every save is a revision; list, read and restore.
47
+ - **Schema migrations**: evolve a parametrization without losing stored data.
48
+ - **Server**: one `rafa serve` command, sign-in (API key, proxy, OpenID Connect or your
49
+ own hook), SQLite or PostgreSQL, backups, retention, calculation limits, a Docker image.
50
+ - **Design system**: one token file drives the web app's dark and light theme.
51
+
52
+ Overview: [docs/features.md](https://github.com/egarciamendez/rafa/blob/main/docs/features.md).
53
+
54
+ ## Documentation
55
+
56
+ | You want to | Read |
57
+ |---|---|
58
+ | Try it in 5 minutes | [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) |
59
+ | Learn the SDK step by step | [Tutorial](https://github.com/egarciamendez/rafa/blob/main/docs/tutorial/index.md) |
60
+ | Look up a term | [Concepts](https://github.com/egarciamendez/rafa/blob/main/docs/concepts.md) |
61
+ | Learn from working apps | [Example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) |
62
+ | Solve a specific task | [How-to guides](https://github.com/egarciamendez/rafa/blob/main/docs/how-to/index.md) |
63
+ | Use the web app | [User guide](https://github.com/egarciamendez/rafa/blob/main/docs/user-guide/index.md) |
64
+ | Run or deploy the server | [Run the server](https://github.com/egarciamendez/rafa/blob/main/docs/server/index.md), [Deploy](https://github.com/egarciamendez/rafa/blob/main/docs/server/deploy.md), [Settings](https://github.com/egarciamendez/rafa/blob/main/docs/server/settings.md) |
65
+ | Call the HTTP API | [HTTP API](https://github.com/egarciamendez/rafa/blob/main/docs/reference/http-api.md) |
66
+ | Look up a class | [Reference](https://github.com/egarciamendez/rafa/blob/main/docs/reference/index.md) |
67
+ | Know why it works this way | [Decisions](https://github.com/egarciamendez/rafa/blob/main/docs/decisions.md), [Architecture](https://github.com/egarciamendez/rafa/blob/main/docs/about/architecture.md) |
68
+
69
+ Build the documentation site locally:
70
+
71
+ ```bash
72
+ uv sync --group docs
73
+ uv run properdocs serve -f properdocs.yml # http://127.0.0.1:8000
74
+ ```
75
+
76
+ ## Project layout
77
+
78
+ ```
79
+ src/rafa/ Python SDK (package `rafa`)
80
+ core/ Application, Controller, Parametrization, Entity, Params, services
81
+ fields/ input fields and layout (Tab, Section, ...)
82
+ views/ actions/ @view, @metric, @action and their result types
83
+ layout/ layout tree sent to the web app as JSON
84
+ persistence/ SQLModel models and repositories
85
+ server/ FastAPI app, settings, middleware
86
+ frontend/ Vue 3 + Vite + Tailwind web app
87
+ design_system/ design tokens (colors_and_type.css) and UI kit
88
+ examples/ example apps: engineering_app (Beam, Project, Showcase), foundation_app,
89
+ beam_formulas_app
90
+ docs/ documentation site (properdocs)
91
+ tests/ pytest suite
92
+ ```
93
+
94
+ ## Development
95
+
96
+ ```bash
97
+ uv sync --all-groups # Python dependencies (dev + docs)
98
+ uv run pytest # tests
99
+ uv run ruff check . && uv run ruff format --check .
100
+ uv run ty check . # type check
101
+
102
+ # Frontend development: the API with reload (answering the dev server's origin), and Vite
103
+ RAFA_CORS_ORIGINS=http://localhost:5173 \
104
+ uv run uvicorn rafa.server.main:app --reload --port 8000 --no-proxy-headers
105
+ cd frontend
106
+ npm ci
107
+ npm run dev # http://localhost:5173, uses the API on :8000
108
+ npm run build # type check + production build to dist/
109
+ npm test # Storybook story tests (needs Playwright Chromium)
110
+ ```
111
+
112
+ CI runs all of the above plus a strict docs build, and builds the wheel, installs it outside
113
+ the checkout and serves an app from it. See [Contributing](https://github.com/egarciamendez/rafa/blob/main/docs/contributing.md).
114
+
115
+ ## License
116
+
117
+ Rafa is licensed under the [Business Source License 1.1](https://github.com/egarciamendez/rafa/blob/main/LICENSE). Production use is free for:
118
+
119
+ - individuals;
120
+ - small enterprises: fewer than 50 staff and at most EUR 10 million turnover or balance sheet
121
+ total (the EU definition, Recommendation 2003/361/EC, group companies included);
122
+ - teaching, study and research at educational institutions and non-profit research
123
+ organizations.
124
+
125
+ Development, testing and evaluation are free for everyone. Production use on behalf of, for, or
126
+ by people of a larger organization needs a commercial license: contact Enrique García at
127
+ enriquegarcia@live.nl. Four years after its release, each version becomes available under the
128
+ Apache License 2.0.
129
+
130
+ © 2026 Enrique García
@@ -0,0 +1 @@
1
+ import{_ as o}from"./ActionButton.vue_vue_type_script_setup_true_lang-D4XFensL.js";import"./ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js";import"./index-BR16ovZa.js";export{o as default};
@@ -0,0 +1 @@
1
+ import{_ as p}from"./ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js";import{d as x,l as t,T as A,A as z,a7 as B,m as h,S as K,o as v,p as d,w as j,h as w,t as C,x as J,f as o,i as S}from"./index-BR16ovZa.js";const V=x({__name:"ActionButton",props:{label:{},action_slug:{},variant:{},icon:{},confirmation_message:{},description:{},disabled:{type:Boolean},block:{type:Boolean},size:{}},setup(a){const e=a,r=t(A,null),b=t(z,null),l=o(()=>b?.(e.action_slug)??null),g=t(B,"canvas"),c=o(()=>g==="inspector"),s=S(!1),n=o(()=>e.label||e.action_slug),f=t(h,null),m=t(K,null),i=o(()=>f?.(e.action_slug)??null),y=()=>{i.value&&m?.(i.value.id)},u=o(()=>e.variant==="text"?"ghost":c.value&&e.variant!=="danger"?"secondary":e.variant??"primary"),k=async()=>{if(!r){console.warn("ActionButton: no trigger-action provided");return}s.value=!0;try{await r(e.action_slug,e.confirmation_message,n.value,u.value)}finally{s.value=!1}};return(_,$)=>i.value?(v(),d(p,{key:0,job:i.value,text:n.value,variant:u.value,size:a.size,icon:a.icon,block:a.block||c.value,onStop:y},null,8,["job","text","variant","size","icon","block"])):(v(),d(J,{key:1,variant:u.value,size:a.size??"md",icon:a.icon,loading:s.value,disabled:a.disabled||!!l.value,block:a.block||c.value,title:l.value?`${n.value}: ${l.value}`:a.description||n.value,onClick:k},{default:j(()=>[w(C(n.value),1)]),_:1},8,["variant","size","icon","loading","disabled","block","title"]))}});export{V as _};
@@ -0,0 +1 @@
1
+ import{d as x,l as o,T as A,A as $,m as B,S as w,o as t,c as i,t as c,e as m,p as v,w as j,h as C,x as J,f as s,i as K}from"./index-BR16ovZa.js";import{_ as S}from"./ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js";const T={class:"flex flex-col gap-2 w-full"},V={key:0,class:"label"},I=["id"],N=["id"],z=x({__name:"ActionButtonInput",props:{name:{},label:{},value:{},method:{},variant:{},icon:{},button_label:{},confirmation_message:{},description:{},disabled:{type:Boolean},error:{}},setup(e){const a=e,u=o(A,null),f=o($,null),r=s(()=>f?.(a.method)??null),y=o(B,null),g=o(w,null),l=s(()=>y?.(a.method)??null),h=()=>{l.value&&g?.(l.value.id)},d=K(!1),n=s(()=>a.button_label||a.label),b=s(()=>a.variant==="danger"?"danger":"secondary"),k=async()=>{if(!u){console.warn("ActionButtonInput: no trigger-action provided");return}d.value=!0;try{await u(a.method,a.confirmation_message,n.value,a.variant??"primary")}finally{d.value=!1}};return(D,E)=>(t(),i("div",T,[e.button_label&&e.label&&e.label!==e.button_label?(t(),i("span",V,c(e.label),1)):m("",!0),l.value?(t(),v(S,{key:1,job:l.value,text:n.value,variant:b.value,icon:e.icon,block:"",onStop:h},null,8,["job","text","variant","icon"])):(t(),v(J,{key:2,id:e.name,variant:b.value,icon:e.icon,loading:d.value,disabled:e.disabled||!!r.value,title:r.value?`${n.value}: ${r.value}`:n.value,"aria-describedby":e.error||e.description?`${e.name}-help`:void 0,block:"",onClick:k},{default:j(()=>[C(c(n.value),1)]),_:1},8,["id","variant","icon","loading","disabled","title","aria-describedby"])),e.error?(t(),i("p",{key:3,id:`${e.name}-help`,role:"alert",class:"field-error -mt-1"},c(e.error),9,I)):e.description?(t(),i("p",{key:4,id:`${e.name}-help`,class:"field-help -mt-1"},c(e.description),9,N)):m("",!0)]))}});export{z as default};
@@ -0,0 +1 @@
1
+ import{d as g,o as t,c as i,n as u,b as d,a as p,w as j,h as k,t as m,e as l,x as b,p as y,Q as z,f as r,bF as $,q as h}from"./index-BR16ovZa.js";const w={class:"flex items-stretch gap-2 min-w-0"},B={key:0,class:"ml-1 font-mono normal-case tracking-normal"},N=g({__name:"ActionJobButton",props:{job:{},text:{},variant:{},size:{},icon:{},block:{type:Boolean}},emits:["stop"],setup(e,{emit:f}){const a=e,v=f,s=r(()=>$(a.job.progress)),n=r(()=>a.job.stop_reason?"Stopping…":a.job.status==="queued"?"Queued":h(a.job.progress)),x=r(()=>{const o=a.job;return`${a.text} is running${o.message?`: ${o.message}`:""}`});return(o,c)=>(t(),i("div",{class:u(["flex flex-col gap-1 min-w-0",{"w-full":e.block}]),"data-action-job":""},[d("div",w,[p(b,{class:"flex-1",variant:e.variant,size:e.size??"md",icon:e.icon,loading:"",title:x.value,"aria-label":`${e.text}: ${n.value??"running"}`},{default:j(()=>[k(m(e.text),1),n.value?(t(),i("span",B,m(n.value),1)):l("",!0)]),_:1},8,["variant","size","icon","title","aria-label"]),e.job.can_stop?(t(),y(b,{key:0,variant:"secondary",size:e.size==="sm"?"sm":"md",icon:"stop",disabled:!!e.job.stop_reason,"aria-label":`Stop ${e.text}`,title:"Stop",onClick:c[0]||(c[0]=C=>v("stop"))},null,8,["size","disabled","aria-label"])):l("",!0)]),d("div",{class:u(["rafa-bar !h-0.5",{"rafa-bar-indeterminate":s.value===null}]),"aria-hidden":"true"},[s.value!==null?(t(),i("div",{key:0,class:"rafa-bar-fill",style:z({width:`${s.value}%`})},null,4)):l("",!0)],2)],2))}});export{N as _};
@@ -0,0 +1 @@
1
+ import{d as j,N as U,o as r,p as $,w as q,b as m,u as o,c as d,a as D,L as M,e as v,O as z,aE as G,bC as H,F as J,g as Q,t as N,i as y,f as x}from"./index-BR16ovZa.js";import{_ as R}from"./FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js";import{_ as W,n as X,u as Y}from"./listbox-CB4ZAfo3.js";import"./InlineMarkdown-DZ6hRlXd.js";const Z=["data-open","data-invalid","data-disabled","data-readonly"],_={key:0,class:"rafa-unit rafa-prefix"},ee=["id","aria-expanded","aria-controls","aria-activedescendant","aria-invalid","aria-describedby","disabled","readonly","placeholder"],ae={key:2,class:"rafa-unit"},te=["id","aria-selected","data-active","onMouseenter","onClick"],le={class:"flex-1 truncate"},ne={key:0,"aria-hidden":"true",class:"material-symbols-outlined text-[16px] text-accent"},oe={key:0,class:"rafa-popover-note"},de=j({__name:"AutocompleteInput",props:{name:{},label:{},value:{},options:{},min_chars:{},prefix:{},suffix:{},description:{},disabled:{type:Boolean},read_only:{type:Boolean},required:{type:Boolean},error:{}},emits:["update:value"],setup(t,{emit:T}){const s=t,C=T,n=y(""),i=y(!1),f=x(()=>s.min_chars??1),h=e=>{const a=(s.options??[]).find(c=>c.value===e);return a?a.label:e!=null?String(e):""};U(()=>s.value,e=>{n.value=h(e),i.value=!1},{immediate:!0});const b=x(()=>{const e=s.options??[];if(!i.value)return e;if(n.value.length<f.value)return[];const a=n.value.toLowerCase();return e.filter(c=>c.label.toLowerCase().includes(a)||String(c.value).toLowerCase().includes(a))}),k=X("autocomplete"),w=y(null),I=y(null),g=x(()=>s.disabled||s.read_only),l=Y({items:b,labelOf:e=>e.label,onSelect:e=>{n.value=e.label,i.value=!1,C("update:value",e.value)},initialIndex:()=>b.value.findIndex(e=>e.value===s.value),idPrefix:k}),V=x(()=>i.value&&n.value.length<f.value),L=()=>{i.value=!0,n.value.length>=f.value?l.openList(0):l.closeList()},E=e=>{const a=e;!i.value&&a.inputType==="insertText"&&a.data&&(n.value=a.data),L()},F=e=>{if(g.value||i.value)return;const a=e.clipboardData?.getData("text/plain");a&&(e.preventDefault(),n.value=a.replace(/\s+/g," ").trim(),L())},A=e=>{if(!g.value){if(e.key==="Escape"&&!l.open.value&&i.value){n.value=h(s.value),i.value=!1;return}l.onKeydown(e,{textInput:!0})}},K=()=>{l.closeList(),i.value&&(n.value=h(s.value),i.value=!1)},O=()=>{n.value="",i.value=!1,l.closeList(),C("update:value",null),I.value?.focus()},B=x(()=>f.value>1?`Type ${f.value}+ characters…`:"Search…");return(e,a)=>(r(),$(R,{name:t.name,label:t.label,description:t.description,error:t.error,required:t.required},{default:q(({describedBy:c,invalid:S})=>[m("div",{ref_key:"control",ref:w,class:"rafa-control","data-open":o(l).open.value||void 0,"data-invalid":S||void 0,"data-disabled":t.disabled||void 0,"data-readonly":t.read_only&&!t.disabled||void 0},[t.prefix?(r(),d("span",_,[D(M,{text:t.prefix},null,8,["text"])])):v("",!0),a[4]||(a[4]=m("span",{"aria-hidden":"true",class:"material-symbols-outlined text-[16px] text-fg-subtle self-center ml-2.5"},"search",-1)),z(m("input",{id:t.name,ref_key:"input",ref:I,"onUpdate:modelValue":a[0]||(a[0]=u=>n.value=u),type:"text",role:"combobox","aria-autocomplete":"list","aria-expanded":o(l).open.value,"aria-controls":o(k),"aria-activedescendant":o(l).open.value&&o(l).activeIndex.value>=0?o(l).optionId(o(l).activeIndex.value):void 0,"aria-invalid":S||void 0,"aria-describedby":c,disabled:t.disabled,readonly:t.read_only,placeholder:B.value,autocomplete:"off",spellcheck:"false",class:"rafa-control-input pl-2",onInput:E,onPaste:F,onKeydown:A,onBlur:K},null,40,ee),[[G,n.value]]),n.value&&!g.value?(r(),d("button",{key:1,type:"button",tabindex:"-1","aria-label":"Clear",class:"flex items-center justify-center w-7 shrink-0 text-fg-subtle hover:text-fg transition-colors duration-150",onMousedown:a[1]||(a[1]=H(()=>{},["prevent"])),onClick:O},[...a[3]||(a[3]=[m("span",{"aria-hidden":"true",class:"material-symbols-outlined text-[16px]"},"close",-1)])],32)):v("",!0),t.suffix?(r(),d("span",ae,[D(M,{text:t.suffix},null,8,["text"])])):v("",!0)],8,Z),o(l).open.value?(r(),$(W,{key:0,id:o(k),role:"listbox",anchor:w.value,"aria-label":t.label??t.name,onClose:a[2]||(a[2]=u=>o(l).closeList())},{default:q(()=>[(r(!0),d(J,null,Q(b.value,(u,p)=>(r(),d("div",{id:o(l).optionId(p),key:String(u.value),role:"option",class:"rafa-option","aria-selected":u.value===t.value,"data-active":o(l).activeIndex.value===p||void 0,onMouseenter:P=>o(l).setActive(p),onClick:P=>o(l).select(p)},[m("span",le,N(u.label),1),u.value===t.value?(r(),d("span",ne,"check")):v("",!0)],40,te))),128)),b.value.length?v("",!0):(r(),d("div",oe,N(V.value?B.value:"No results"),1))]),_:1},8,["id","anchor","aria-label"])):v("",!0)]),_:1},8,["name","label","description","error","required"]))}});export{de as default};
@@ -0,0 +1 @@
1
+ import{d as v,l as y,b9 as x,i as g,N as k,o as r,c as n,b as o,u as d,n as i,e as u,a as f,L as w,t as p,f as B}from"./index-BR16ovZa.js";import{I as C}from"./InlineMarkdown-DZ6hRlXd.js";const $={class:"flex flex-col gap-1 w-full"},N=["id","role","checked","disabled","aria-readonly","aria-invalid","aria-describedby"],I={key:0,class:"material-symbols-outlined text-[14px]"},V=["id"],j=["id"],F=v({__name:"BooleanInput",props:{name:{},label:{},value:{type:[Boolean,null]},description:{},variant:{},disabled:{type:Boolean},read_only:{type:Boolean},error:{}},emits:["update:value"],setup(e,{emit:b}){const s=y(x,!1),t=e,h=b,l=g(!!t.value);k(()=>t.value,a=>{l.value=!!a});const c=B(()=>{let a="bg-sunken border-line-strong";return l.value?a="bg-accent-fill border-accent-fill text-on-fill":t.error?a="bg-sunken border-danger":t.disabled||(a+=" group-hover:border-fg-disabled"),t.disabled?a+" opacity-40":a}),m=a=>{if(t.read_only){a.target.checked=l.value;return}l.value=a.target.checked,h("update:value",l.value)};return(a,z)=>(r(),n("div",$,[o("label",{class:i(["group inline-flex items-center gap-2 min-h-5 w-fit",e.disabled?"cursor-not-allowed":"cursor-pointer"])},[o("input",{id:e.name,type:"checkbox",role:e.variant==="switch"?"switch":void 0,class:"peer sr-only",checked:l.value,disabled:e.disabled,"aria-readonly":e.read_only||void 0,"aria-invalid":e.error?!0:void 0,"aria-describedby":e.error?`${e.name}-error`:e.description&&!d(s)?`${e.name}-help`:void 0,onChange:m},null,40,N),e.variant==="switch"?(r(),n("span",{key:0,"aria-hidden":"true",class:i(["relative w-8 h-4 shrink-0 rounded-full border transition-colors duration-150 peer-focus-visible:shadow-focus-ring",c.value])},[o("span",{class:i(["absolute top-px left-px w-3 h-3 rounded-full transition-transform duration-150",l.value?"translate-x-4 bg-on-fill":"bg-fg-subtle"])},null,2)],2)):(r(),n("span",{key:1,"aria-hidden":"true",class:i(["flex items-center justify-center w-4 h-4 shrink-0 rounded-sm border transition-colors duration-150 peer-focus-visible:shadow-focus-ring",[c.value,{"border-dashed":e.read_only}]])},[l.value?(r(),n("span",I,"check")):u("",!0)],2)),o("span",{class:i(["text-xs select-none",[e.disabled?"text-fg-disabled":"text-fg-muted",{"sr-only":d(s)}]])},[f(w,{text:e.label},null,8,["text"])],2)],2),e.error?(r(),n("p",{key:0,id:`${e.name}-error`,role:"alert",class:i(["field-error pl-6",{"sr-only":d(s)}])},p(e.error),11,V)):e.description&&!d(s)?(r(),n("p",{key:1,id:`${e.name}-help`,class:"field-help pl-6"},[f(C,{text:e.description},null,8,["text"])],8,j)):u("",!0)]))}});export{F as default};
@@ -0,0 +1 @@
1
+ import{B as y,J as T,an as E,am as p,al as G}from"./geometryScene-DBVxLCLP.js";function x(i,a=!1){const r=i[0].index!==null,m=new Set(Object.keys(i[0].attributes)),s=new Set(Object.keys(i[0].morphAttributes)),f={},t={},d=i[0].morphTargetsRelative,u=new y;let g=0;for(let e=0;e<i.length;++e){const n=i[e];let l=0;if(r!==(n.index!==null))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const o in n.attributes){if(!m.has(o))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+'. All geometries must have compatible attributes; make sure "'+o+'" attribute exists among all geometries, or in none of them.'),null;f[o]===void 0&&(f[o]=[]),f[o].push(n.attributes[o]),l++}if(l!==m.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". Make sure all geometries have the same number of attributes."),null;if(d!==n.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const o in n.morphAttributes){if(!s.has(o))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". .morphAttributes must be consistent throughout all geometries."),null;t[o]===void 0&&(t[o]=[]),t[o].push(n.morphAttributes[o])}if(a){let o;if(r)o=n.index.count;else if(n.attributes.position!==void 0)o=n.attributes.position.count;else return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". The geometry must have either an index or a position attribute"),null;u.addGroup(g,o,e),g+=o}}if(r){let e=0;const n=[];for(let l=0;l<i.length;++l){const o=i[l].index;for(let c=0;c<o.count;++c)n.push(o.getX(c)+e);e+=i[l].attributes.position.count}u.setIndex(n)}for(const e in f){const n=b(f[e]);if(!n)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+e+" attribute."),null;u.setAttribute(e,n)}for(const e in t){const n=t[e][0].length;if(n===0)break;u.morphAttributes=u.morphAttributes||{},u.morphAttributes[e]=[];for(let l=0;l<n;++l){const o=[];for(let h=0;h<t[e].length;++h)o.push(t[e][h][l]);const c=b(o);if(!c)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+e+" morphAttribute."),null;u.morphAttributes[e].push(c)}}return u}function b(i){let a,r,m,s=-1,f=0;for(let g=0;g<i.length;++g){const e=i[g];if(a===void 0&&(a=e.array.constructor),a!==e.array.constructor)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes."),null;if(r===void 0&&(r=e.itemSize),r!==e.itemSize)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes."),null;if(m===void 0&&(m=e.normalized),m!==e.normalized)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes."),null;if(s===-1&&(s=e.gpuType),s!==e.gpuType)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes."),null;f+=e.count*r}const t=new a(f),d=new T(t,r,m);let u=0;for(let g=0;g<i.length;++g){const e=i[g];if(e.isInterleavedBufferAttribute){const n=u/r;for(let l=0,o=e.count;l<o;l++)for(let c=0;c<r;c++){const h=e.getComponent(l,c);d.setComponent(l+n,c,h)}}else t.set(e.array,u);u+=e.count*r}return s!==void 0&&(d.gpuType=s),d}function B(i,a){if(a===E)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),i;if(a===p||a===G){let r=i.getIndex();if(r===null){const t=[],d=i.getAttribute("position");if(d!==void 0){for(let u=0;u<d.count;u++)t.push(u);i.setIndex(t),r=i.getIndex()}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),i}const m=r.count-2,s=[];if(a===p)for(let t=1;t<=m;t++)s.push(r.getX(0)),s.push(r.getX(t)),s.push(r.getX(t+1));else for(let t=0;t<m;t++)t%2===0?(s.push(r.getX(t)),s.push(r.getX(t+1)),s.push(r.getX(t+2))):(s.push(r.getX(t+2)),s.push(r.getX(t+1)),s.push(r.getX(t)));s.length/3!==m&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const f=i.clone();return f.setIndex(s),f.clearGroups(),f}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",a),i}export{x as m,B as t};
@@ -0,0 +1,5 @@
1
+ import{ba as Me,d as Q,N as H,o as i,c as d,i as T,bb as De,bc as Be,b0 as Ne,_ as Re,bd as ve,W as ge,n as U,b as y,t as h,e as g,p as C,x as K,w as O,h as $,f as c,be as He,bf as Z,af as pe,ae as I,bg as ee,bh as q,ab as Ue,bi as he,bj as ye,bk as Ke,bl as be,bm as we,bn as Oe,bo as qe,bp as ze,l as V,a8 as Fe,R as Pe,I as Ve,E as Ye,s as ie,a1 as Je,u as ue,a as We,F as E,g as Xe,O as Ge,aE as Qe,bq as Ze,br as Ie}from"./index-BR16ovZa.js";const et={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},j=e=>e.replace(/[&<>"']/g,t=>et[t]),tt=/^(https?:\/\/|mailto:)/i;function ce(e){const t=(e??"").trim();return tt.test(t)?t:null}const de=(e,t)=>`<a href="${j(e)}" target="_blank" rel="noopener noreferrer nofollow">${t}</a>`,nt=new Me({gfm:!0,breaks:!0,async:!1,renderer:{html({text:e}){return j(e)},link(e){const t=this.parser.parseInline(e.tokens),n=ce(e.href);return n?de(n,t):t},image({href:e,text:t}){const n=ce(e),a=j(t||e||"");return n?de(n,a||j(n)):a}}}),at=/(```[\s\S]*?(?:```|$)|`[^`\n]*`)|\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\]|\\\(([\s\S]+?)\\\)|\$(?=[^\s`])([^$\n`]*?[^\s`])\$(?!\d)/g;function st(e){const t=[],n=e.replace(at,(o,l,r,s,u,v)=>{if(l!==void 0)return o;const p=r!==void 0||s!==void 0;t.push({source:(r??s??u??v??"").trim(),display:p});const b=`CHATMATH${t.length-1}X`;return p?`
2
+
3
+ ${b}
4
+
5
+ `:b});let a;try{a=nt.parse(n)}catch{a=`<p>${j(n)}</p>`}return{html:a,math:t}}const ot=/CHATMATH(\d+)X/g,lt=["innerHTML"],rt=Q({__name:"ChatMarkdown",props:{content:{}},setup(e){const t=e,n=T("");let a=0;function o(r,s){if(!r)return s.display?`<pre>${j(s.source)}</pre>`:`<code>${j(s.source)}</code>`;try{const u=r.renderToString(s.source,{displayMode:s.display,throwOnError:!1,maxSize:10,maxExpand:200});return s.display?`<div class="katex-display-wrapper">${u}</div>`:u}catch{return`<code>${j(s.source)}</code>`}}async function l(){const r=++a,s=st(t.content);let u=null;if(s.math.length){try{u=await De()}catch{u=null}if(r!==a)return}n.value=Be(Ne(s.html),ot,s.math.map(v=>o(u,v)))}return H(()=>t.content,l,{immediate:!0}),(r,s)=>(i(),d("div",{class:"rafa-prose rafa-prose-compact rafa-chat-text rafa-text-box",innerHTML:n.value},null,8,lt))}}),ke=Re(rt,[["__scopeId","data-v-18e5088f"]]),S=e=>typeof e=="string"&&e?e:null,fe=(e,t)=>typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):t,it=["user","assistant"],ut=["done","pending","stopped","failed"];function ct(e){if(!e||typeof e!="object")return null;const t=S(e.label),n=e.params;return!t||!n||typeof n!="object"||Array.isArray(n)||!Object.keys(n).length?null:{label:t,params:n}}function G(e){return!e||typeof e!="object"||!it.includes(e.role)?null:{id:S(e.id),role:e.role,content:typeof e.content=="string"?e.content:"",at:S(e.at),status:ut.includes(e.status)?e.status:"done",note:S(e.note),suggestion:ct(e.suggestion),author:S(e.author)}}function dt(e){if(!e||typeof e!="object"||!S(e.entity_id)||!S(e.chat))return null;const t=Array.isArray(e.messages)?e.messages.map(G).filter(n=>n!==null):[];return{entity_id:e.entity_id,chat:e.chat,label:S(e.label)??e.chat,messages:t,answering:e.answering===!0,job_id:S(e.job_id),can_send:e.can_send===!0,trimmed:e.trimmed===!0,max_messages:fe(e.max_messages,100),max_message_length:fe(e.max_message_length,4e3)}}function xe(e,t=0){const n=G(e?.question),a=G(e?.answer),o=ve(e?.job,t);return n&&a&&o?{question:n,answer:a,job:o}:null}function me(e){if(!e||e.type!=="ChatReply")return null;const t=e.data?.text;return typeof t=="string"?t:null}function ft(e){const t=[],n=(a,o)=>{for(const[l,r]of Object.entries(a)){const s=o?`${o}.${l}`:l;r&&typeof r=="object"&&!Array.isArray(r)&&Object.keys(r).length?n(r,s):t.push([s,r])}};return n(e.params,""),t}function mt(e){return`Older messages were removed: this chat keeps the last ${e.toLocaleString("en-US")}.`}function vt(e,t){return e<t*.9?null:`${e.toLocaleString("en-US")} / ${t.toLocaleString("en-US")}`}function gt(e){return e.key==="Enter"&&!e.shiftKey&&!e.isComposing&&!e.altKey&&!e.ctrlKey&&!e.metaKey}function pt(e){switch(e.status){case"stopped":return e.note??"Stopped.";case"failed":return e.note??"No answer.";default:return e.note}}function ht(e,t){return e.role==="assistant"?"Assistant":t&&e.author?e.author:"You"}function yt(e,t=new Date){if(!e)return null;const n=new Date(e);if(Number.isNaN(n.getTime()))return null;const a=n.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:!1});return n.toDateString()===t.toDateString()?a:`${n.toLocaleDateString("en-US",{month:"short",day:"numeric"})}, ${a}`}function bt(e){return e.blocked?"This chat is read-only now.":e.canSend?e.editLockedBy:e.permission==="edit"?"You can read this conversation. Editors can send messages.":e.permission==="manage"?"You can read this conversation. Project admins can send messages.":`You can read this conversation. Sending needs the ${e.permission} permission.`}const wt=["aria-busy","data-role","data-status"],kt={class:"flex items-center gap-2 min-w-0"},xt=["datetime"],$t=["aria-label","title"],St={class:"material-symbols-outlined text-[16px]","aria-hidden":"true"},_t={key:1,class:"m-0 text-xs leading-normal text-fg whitespace-pre-wrap [overflow-wrap:anywhere]"},Tt={key:2,class:"m-0 label !text-link",role:"status"},jt={key:4,class:"flex flex-wrap items-center gap-2 pt-1"},Ct=Q({__name:"ChatMessage",props:{message:{},streaming:{default:null},showAuthors:{type:Boolean,default:!1},canRetry:{type:Boolean,default:!1},applyDenial:{default:null}},emits:["retry","apply"],setup(e,{emit:t}){const n=e,a=t,o=c(()=>n.message.status==="pending"),l=c(()=>o.value?n.streaming??"":n.message.content),r=c(()=>ht(n.message,n.showAuthors)),s=c(()=>yt(n.message.at)),u=c(()=>pt(n.message)),v=c(()=>n.message.role==="assistant"),p=T(null);let b=null;async function W(){try{await navigator.clipboard.writeText(l.value),p.value="ok"}catch{p.value="failed"}b&&clearTimeout(b),b=setTimeout(()=>p.value=null,2e3)}ge(()=>{b&&clearTimeout(b)});const A=c(()=>p.value==="ok"?"Copied":p.value==="failed"?"Cannot copy to the clipboard":"Copy message");return(B,_)=>(i(),d("article",{class:U(["flex flex-col gap-1 min-w-0 rounded px-3 py-2",v.value?"bg-transparent":"bg-elevated border border-line-subtle"]),"aria-busy":o.value||void 0,"data-role":e.message.role,"data-status":e.message.status},[y("header",kt,[y("span",{class:U(["label min-w-0 truncate",{"!text-link":v.value}])},h(r.value),3),s.value&&e.message.at?(i(),d("time",{key:0,class:"font-mono text-[11px] text-fg-subtle shrink-0",datetime:e.message.at},h(s.value),9,xt)):g("",!0),l.value?(i(),d("button",{key:1,type:"button",class:"ml-auto shrink-0 w-6 h-6 flex items-center justify-center rounded text-fg-subtle hover:text-fg hover:bg-elevated","aria-label":`${A.value}: ${r.value}${s.value?`, ${s.value}`:""}`,title:A.value,onClick:W},[y("span",St,h(p.value==="ok"?"check":"content_copy"),1)],8,$t)):g("",!0)]),v.value&&l.value?(i(),C(ke,{key:0,content:l.value},null,8,["content"])):l.value?(i(),d("p",_t,h(l.value),1)):g("",!0),o.value?(i(),d("p",Tt,"Writing…")):u.value?(i(),d("p",{key:3,class:U(["m-0 text-[11px] leading-4",e.message.status==="failed"?"text-danger":"text-fg-muted"])},h(u.value),3)):g("",!0),e.message.suggestion&&e.message.status==="done"||e.canRetry&&!o.value?(i(),d("div",jt,[e.message.suggestion&&e.message.status==="done"?(i(),C(K,{key:0,class:"!normal-case !tracking-normal",variant:"secondary",size:"sm",icon:"edit_note",disabled:!!e.applyDenial,title:e.applyDenial??`Set the inputs: ${e.message.suggestion.label}`,onClick:_[0]||(_[0]=x=>a("apply"))},{default:O(()=>[$(h(e.message.suggestion.label),1)]),_:1},8,["disabled","title"])):g("",!0),e.canRetry&&!o.value?(i(),C(K,{key:1,variant:"ghost",size:"sm",icon:"refresh",onClick:_[1]||(_[1]=x=>a("retry"))},{default:O(()=>[..._[2]||(_[2]=[$("Ask again",-1)])]),_:1})):g("",!0)])):g("",!0)],10,wt))}}),Y=Ke(new Map),$e=(e,t)=>`${e}|${t}`,J=(e,t)=>`/entities/${encodeURIComponent(e)}/chats/${encodeURIComponent(t)}`,te=()=>typeof performance>"u"?Date.now():performance.now();function At(e,t){return Y.get($e(e,t))??null}function D(e,t){const n=$e(e,t);return Y.has(n)||Y.set(n,{conversation:null,loading:!1,error:null,sending:!1}),Y.get(n)}async function M(e,t){const n=D(e,t);n.loading=!n.conversation;try{const a=dt((await q.get(J(e,t))).data);if(!a)throw new Error("Not a conversation");return n.conversation=a,n.error=null,a.job_id&&!I.has(a.job_id)&&Lt(e,t,a.job_id),a}catch(a){return n.error=ye(a),null}finally{n.loading=!1}}async function Lt(e,t,n){try{const a=ve((await q.get(`/jobs/${n}`)).data,te());a&&be(a,{notify:!1})}catch{}await we(n),await M(e,t)}function Et(e){const t=e?.job_id;if(!t)return null;const n=I.get(t);return n?me(n.partial)??me(n.result)??"":null}function Mt(e){const t=e?.job_id;return!!t&&pe(I.get(t)??{status:"queued"})}function ne(e,t,n,a){const o=ye(n),l=Oe(n),r=l===409?qe(n):null;return r&&ze(e,r),l===409&&M(e,t),Z(l===400?"warning":"error",`${a}: ${o}`),l!==400&&he.notify(l===409||l===429?"warning":"error",a,o),{ok:!1,error:o}}async function Se(e,t,n,a){const o=xe(n,te()),l=D(e,t);if(!o){await M(e,t);return}const r=l.conversation;if(r){const s=r.messages.filter(u=>u.id!==o.answer.id&&u.id!==o.question.id);!a&&s[s.length-1]?.role==="assistant"&&s.pop(),l.conversation={...r,messages:a?[...s,o.question,o.answer]:[...s,o.answer],answering:pe(o.job),job_id:o.job.id}}be(o.job,{notify:!1}),await we(o.job.id),await M(e,t)}async function Dt(e,t,n){const a=n.trim();if(!a)return{ok:!1,error:"Type a message first."};const o=D(e,t);if(!await ee(e))return{ok:!1,error:"Someone else is editing this entity."};o.sending=!0;try{const l=await q.post(`${J(e,t)}/messages`,{content:a});return Se(e,t,l.data,xe(l.data)?.question??null),{ok:!0}}catch(l){return ne(e,t,l,"Message not sent")}finally{o.sending=!1}}async function Bt(e,t){if(!await ee(e))return{ok:!1,error:"Someone else is editing this entity."};const n=D(e,t);n.sending=!0;try{const a=await q.post(`${J(e,t)}/retry`);return Se(e,t,a.data,null),{ok:!0}}catch(a){return ne(e,t,a,"Not asked again")}finally{n.sending=!1}}async function Nt(e,t){const n=D(e,t).conversation?.job_id;n&&await Ue(n)}async function Rt(e,t){const n=D(e,t).conversation?.label??"chat";if(!await he.confirm({title:"Clear the conversation?",body:`Every message of ${n} is removed, for everyone who can open this entity. This cannot be undone.`,confirmLabel:"Clear",danger:!0})||!await ee(e))return!1;try{return await q.delete(`${J(e,t)}/messages`),Z("info",`Cleared ${n}`),await M(e,t),!0}catch(o){return ne(e,t,o,"Not cleared"),!1}}function Ht(e){const t=ft(e);He(t,{undoKey:`chat-suggestion-${te()}`}),Z("info",`Applied: ${e.label}`)}const Ut=["aria-labelledby"],Kt={class:"flex items-center gap-2 min-w-0"},Ot=["id"],qt={key:0,class:"field-help -mt-1 m-0"},zt=["aria-labelledby"],Ft={key:0,class:"m-0 field-help text-center"},Pt={key:1,class:"px-3 py-2 min-w-0","data-first-message":""},Vt={key:2,class:"m-0 label text-center py-2",role:"status"},Yt={key:3,class:"m-0 field-error text-center py-2",role:"alert"},Jt={key:4,class:"m-0 field-help text-center py-2"},Wt=["data-invalid"],Xt=["id","placeholder","aria-label","aria-describedby","aria-invalid"],Gt={class:"flex items-center gap-2 min-w-0"},Qt=["id","role"],Zt={key:2,class:"m-0 field-help"},tn=Q({__name:"ChatPanel",props:{name:{},label:{},description:{default:null},first_message:{default:null},placeholder:{default:null},permission:{default:"edit"},max_message_length:{default:4e3},disabled:{type:Boolean},read_only:{type:Boolean}},setup(e){const t=e,n=V(Fe,T(null)),a=V(Pe,null),o=V(Ve,null),l=V(Ye,null),r=c(()=>n.value?At(n.value,t.name):null),s=c(()=>r.value?.conversation??null),u=c(()=>s.value?.messages??[]),v=c(()=>!!s.value?.answering),p=c(()=>Mt(s.value)),b=c(()=>Et(s.value)),W=c(()=>Ze(Ie.value)),A=c(()=>bt({canSend:s.value?.can_send??!1,permission:t.permission,editLockedBy:l?.value?.kind==="other"?l.value.text:null,blocked:t.disabled||t.read_only})),B=c(()=>!!s.value&&!A.value),_=c(()=>a?.value??(l?.value?.kind==="other"?l.value.text:null)??o?.value?.text??null),x=T(""),w=T(null),ae=c(()=>vt(x.value.trim().length,t.max_message_length)),N=c(()=>x.value.trim().length>t.max_message_length),z=T(null),R=T(null),_e=c(()=>`${t.name}-chat-input`),X=c(()=>`${t.name}-chat-label`),se=c(()=>`${t.name}-chat-help`);async function oe(){if(!n.value||!B.value||v.value||r.value?.sending)return;if(N.value){w.value=`The message has ${x.value.trim().length.toLocaleString("en-US")} characters; at most ${t.max_message_length.toLocaleString("en-US")} are allowed. Shorten it.`;return}const f=await Dt(n.value,t.name,x.value);f.ok?(x.value="",w.value=null,F.value=!0):w.value=f.error}function Te(f){gt(f)&&(f.preventDefault(),oe())}async function je(){n.value&&(await Nt(n.value,t.name),z.value?.focus())}async function Ce(){if(!n.value)return;const f=await Bt(n.value,t.name);w.value=f.ok?null:f.error,F.value=!0}async function Ae(){n.value&&await Rt(n.value,t.name)&&(w.value=null,await ie(),z.value?.focus())}const Le=c(()=>{const f=u.value[u.value.length-1];return f&&f.role==="assistant"?f.id:null}),F=T(!0);function Ee(){const f=R.value;f&&(F.value=f.scrollHeight-f.scrollTop-f.clientHeight<24)}H([()=>u.value.length,b],async()=>{F.value&&(await ie(),R.value&&(R.value.scrollTop=R.value.scrollHeight))});let L=null;async function P(){n.value&&await M(n.value,t.name)}function le(){L&&clearTimeout(L),L=null,v.value&&!s.value?.job_id&&(L=setTimeout(async()=>{await P(),le()},3e3))}H([v,()=>s.value?.job_id],le),H(n,P);const re=()=>{P()};return Je(()=>{P(),window.addEventListener("focus",re)}),ge(()=>{window.removeEventListener("focus",re),L&&clearTimeout(L)}),H(p,(f,m)=>{m&&!f&&document.activeElement===document.body&&z.value?.focus()}),(f,m)=>(i(),d("section",{class:"flex flex-col gap-2 w-full min-w-0","aria-labelledby":X.value,"data-chat":""},[y("div",Kt,[y("span",{id:X.value,class:"label min-w-0 truncate"},h(e.label),9,Ot),B.value&&u.value.length?(i(),C(K,{key:0,class:"ml-auto -my-1",variant:"ghost",size:"sm",icon:"delete_sweep",disabled:v.value,title:v.value?"Stop the answer first":void 0,"aria-label":`Clear ${e.label}`,onClick:Ae},{default:O(()=>[...m[2]||(m[2]=[$("Clear",-1)])]),_:1},8,["disabled","title","aria-label"])):g("",!0)]),e.description?(i(),d("p",qt,h(e.description),1)):g("",!0),y("div",{ref_key:"log",ref:R,role:"log","aria-live":"polite","aria-labelledby":X.value,tabindex:"0",class:"flex flex-col gap-2 max-h-[420px] min-h-24 overflow-y-auto rounded-md border border-line bg-sunken p-2 focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",onScroll:Ee},[s.value?.trimmed?(i(),d("p",Ft,h(ue(mt)(s.value.max_messages)),1)):g("",!0),e.first_message?(i(),d("div",Pt,[m[3]||(m[3]=y("span",{class:"label !text-link"},"Assistant",-1)),We(ke,{content:e.first_message},null,8,["content"])])):g("",!0),(i(!0),d(E,null,Xe(u.value,k=>(i(),C(Ct,{key:k.id??k.at??"",message:k,streaming:k.status==="pending"&&k.id===u.value[u.value.length-1]?.id?b.value:null,"show-authors":W.value,"can-retry":B.value&&!v.value&&k.id===Le.value,"apply-denial":_.value,onRetry:Ce,onApply:It=>k.suggestion&&ue(Ht)(k.suggestion)},null,8,["message","streaming","show-authors","can-retry","apply-denial","onApply"]))),128)),r.value?.loading?(i(),d("p",Vt,"Loading…")):r.value?.error&&!s.value?(i(),d("p",Yt,h(r.value.error),1)):s.value&&!u.value.length&&!e.first_message?(i(),d("p",Jt,"No messages yet.")):g("",!0)],40,zt),B.value?(i(),d(E,{key:1},[y("div",{class:"rafa-control rafa-control-multiline","data-invalid":N.value||!!w.value||void 0},[Ge(y("textarea",{id:_e.value,ref_key:"box",ref:z,"onUpdate:modelValue":m[0]||(m[0]=k=>x.value=k),rows:"2",placeholder:e.placeholder??"Ask a question","aria-label":`Message to ${e.label}`,"aria-describedby":se.value,"aria-invalid":N.value||void 0,class:"rafa-control-input py-2 leading-normal resize-y min-h-14 max-h-60",onKeydown:Te,onInput:m[1]||(m[1]=k=>w.value=null)},null,40,Xt),[[Qe,x.value]])],8,Wt),y("div",Gt,[y("p",{id:se.value,class:U(["m-0 min-w-0 flex-1",w.value?"field-error":"field-help"]),role:w.value?"alert":void 0},[w.value?(i(),d(E,{key:0},[$(h(w.value),1)],64)):v.value&&!p.value?(i(),d(E,{key:1},[$("Someone else's question is being answered.")],64)):(i(),d(E,{key:2},[m[5]||(m[5]=$("Enter to send, Shift+Enter for a new line",-1)),ae.value?(i(),d(E,{key:0},[m[4]||(m[4]=$(" · ",-1)),y("span",{class:U(["font-mono",{"text-danger":N.value}])},h(ae.value),3)],64)):g("",!0)],64))],10,Qt),p.value?(i(),C(K,{key:0,variant:"secondary",size:"sm",icon:"stop","aria-label":`Stop the answer of ${e.label}`,onClick:je},{default:O(()=>[...m[6]||(m[6]=[$("Stop",-1)])]),_:1},8,["aria-label"])):(i(),C(K,{key:1,variant:"primary",size:"sm",icon:"send",loading:r.value?.sending,disabled:!x.value.trim()||v.value||N.value,"aria-label":`Send the message to ${e.label}`,onClick:oe},{default:O(()=>[...m[7]||(m[7]=[$("Send",-1)])]),_:1},8,["loading","disabled","aria-label"]))])],64)):s.value&&A.value?(i(),d("p",Zt,h(A.value),1)):g("",!0)],8,Ut))}});export{tn as default};
@@ -0,0 +1 @@
1
+ .rafa-chat-text[data-v-18e5088f] .katex{font-size:1.05em}
@@ -0,0 +1 @@
1
+ import{d as C,a1 as O,W as $,N as x,bs as I,o as B,c as D,a as N,u as o,bt as k,bu as L,U as V,bv as j,bw as A,f as s,a4 as R,a5 as c,bx as S,by as U,V as _,bz as z,i as p,bA as M,bB as T}from"./index-BR16ovZa.js";const h=C({__name:"ChildrenView",props:{label:{default:"Children"},display:{default:"cards"},child_types:{default:()=>[]}},setup(b){const n=b,l=s(()=>R.value),i=s(()=>l.value?c.value.filter(e=>e.parent_id===l.value.id):[]),y=s(()=>Object.values(S.value).map(e=>({name:e.name,label:e.label,summary:e.summary??[]}))),m=s(()=>U(l.value,"edit")?n.child_types.map(e=>({name:e,label:_(e)})):[]),f=s(()=>Object.fromEntries(i.value.map(e=>[e.id,z(e.id)]))),r=p(null),u=p(typeof IntersectionObserver>"u");let d=null;O(()=>{u.value||!r.value||(d=new IntersectionObserver(e=>{e.some(a=>a.isIntersecting)&&(u.value=!0)}),d.observe(r.value))}),$(()=>d?.disconnect()),x([i,u],([e,a])=>{a&&I(e)},{immediate:!0});const v=p(null),w=e=>{const a=c.value.find(t=>t.id===e.id);return!!a&&M(a)},E=e=>{l.value&&T(e,l.value.id)};return(e,a)=>(B(),D("div",{ref_key:"root",ref:r,class:"h-full overflow-auto","data-children-view":""},[N(A,{entities:i.value,types:y.value,display:n.display==="table"?"table":"cards",values:f.value,"create-types":m.value,"can-duplicate":w,"rename-save":(t,g)=>o(j)(t,g),"renaming-id":v.value,label:l.value?`${n.label} of ${l.value.name}`:n.label,"empty-text":m.value.length?`No ${n.label.toLowerCase()} yet. Add one to begin.`:`No ${n.label.toLowerCase()} yet.`,onOpen:a[0]||(a[0]=t=>o(V)(t)),onCreate:E,onDuplicate:a[1]||(a[1]=t=>o(L)(t)),onDelete:a[2]||(a[2]=t=>o(k)(t)),onStartRename:a[3]||(a[3]=t=>v.value=t),onRenameDone:a[4]||(a[4]=t=>v.value=null)},null,8,["entities","types","display","values","create-types","rename-save","renaming-id","label","empty-text"])],512))}});export{h as default};
@@ -0,0 +1 @@
1
+ import{_ as k}from"./FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js";import{d as B,i as f,N as I,o as q,p as A,w as E,b as u,n as L,Q as z,f as b}from"./index-BR16ovZa.js";import"./InlineMarkdown-DZ6hRlXd.js";const F=["data-invalid","data-disabled","data-readonly"],H=["title"],N=["id","value","disabled"],T=["id","value","disabled","readonly","aria-invalid","aria-describedby"],p="#000000",R=B({__name:"ColorInput",props:{name:{},label:{},value:{},description:{},disabled:{type:Boolean},read_only:{type:Boolean},required:{type:Boolean},error:{}},emits:["update:value"],setup(e,{emit:y}){const c=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;function r(l){const a=l.trim().toLowerCase();if(/^#[0-9a-f]{3}$/.test(a)){const[,n,d,h]=a;return`#${n}${n}${d}${d}${h}${h}`}return a}const t=e,m=y,s=f(t.value?r(t.value):p),o=f(t.value?r(t.value):""),i=f(!1);I(()=>t.value,l=>{s.value=l?r(l):p,o.value=l?r(l):"",i.value=!1});const w=b(()=>c.test(o.value)?r(o.value):s.value),x=b(()=>t.error||(i.value?"Enter a valid hex colour (#ff0000 or #f00).":null)),v=b(()=>t.disabled||t.read_only),$=l=>{const a=l.target.value.toLowerCase();s.value=a,o.value=a,i.value=!1,m("update:value",a)},g=l=>{const a=l.target.value;if(o.value=a,c.test(a)){const n=r(a);s.value=n,i.value=!1,m("update:value",n)}},C=()=>{i.value=o.value.length>0&&!c.test(o.value)};return(l,a)=>(q(),A(k,{name:e.name,label:e.label,description:e.description,error:x.value,required:e.required,"for-id":`${e.name}-text`},{default:E(({describedBy:n,invalid:d})=>[u("div",{class:"rafa-control","data-invalid":d||void 0,"data-disabled":e.disabled||void 0,"data-readonly":e.read_only&&!e.disabled||void 0},[u("label",{class:L(["relative self-center ml-1.5 w-5 h-5 shrink-0 rounded-sm border border-line-strong overflow-hidden",v.value?"cursor-not-allowed opacity-60":"cursor-pointer"]),title:v.value?void 0:"Choose colour"},[u("span",{class:"absolute inset-0",style:z({background:w.value})},null,4),u("input",{id:`${e.name}-picker`,type:"color",value:s.value,disabled:v.value,"aria-label":"Choose colour",class:"absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed",onInput:$},null,40,N)],10,H),u("input",{id:`${e.name}-text`,type:"text",value:o.value,disabled:e.disabled,readonly:e.read_only,placeholder:"#rrggbb",maxlength:"7",spellcheck:"false",autocomplete:"off","aria-invalid":d||void 0,"aria-describedby":n,class:"rafa-control-input font-mono pl-2",onInput:g,onChange:C},null,40,T)],8,F)]),_:1},8,["name","label","description","error","required","for-id"]))}});export{R as default};
@@ -0,0 +1 @@
1
+ import{d as o,o as a,c as n,r as c,Q as r,f as p}from"./index-BR16ovZa.js";const i=o({__name:"Column",props:{width:{},gap:{},children:{}},setup(l){const t=l,s=p(()=>{const e={gap:`${(t.gap??4)*4}px`};return t.width?e.flex=`0 0 calc(${t.width/12*100}% - 16px)`:e.flex="1",e});return(e,d)=>(a(),n("div",{class:"flex flex-col min-w-0",style:r(s.value)},[c(e.$slots,"default")],4))}});export{i as default};
@@ -0,0 +1 @@
1
+ input[type=date][data-v-732b2199]::-webkit-calendar-picker-indicator{opacity:.55;cursor:pointer}input[type=date][data-v-732b2199]::-webkit-calendar-picker-indicator:hover{opacity:.9}
@@ -0,0 +1 @@
1
+ import{_ as c}from"./FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js";import{d as m,i as v,N as b,o as y,p as f,w as x,b as t,_ as h}from"./index-BR16ovZa.js";import"./InlineMarkdown-DZ6hRlXd.js";const B=["data-invalid","data-disabled","data-readonly"],p=["id","value","min","max","disabled","readonly","aria-invalid","aria-describedby"],g=m({__name:"DateInput",props:{name:{},label:{},value:{},description:{},min:{},max:{},disabled:{type:Boolean},read_only:{type:Boolean},required:{type:Boolean},error:{}},emits:["update:value"],setup(a,{emit:o}){const i=a,r=o,e=v(i.value??"");b(()=>i.value,d=>{e.value=d??""});const s=d=>{e.value=d.target.value,r("update:value",e.value||null)};return(d,l)=>(y(),f(c,{name:a.name,label:a.label,description:a.description,error:a.error,required:a.required},{default:x(({describedBy:u,invalid:n})=>[t("div",{class:"rafa-control","data-invalid":n||void 0,"data-disabled":a.disabled||void 0,"data-readonly":a.read_only&&!a.disabled||void 0},[l[0]||(l[0]=t("span",{"aria-hidden":"true",class:"material-symbols-outlined text-[16px] text-fg-subtle self-center ml-2.5"}," calendar_today ",-1)),t("input",{id:a.name,type:"date",value:e.value,min:a.min??void 0,max:a.max??void 0,disabled:a.disabled,readonly:a.read_only,"aria-invalid":n||void 0,"aria-describedby":u,class:"rafa-control-input font-mono pl-2",onChange:s},null,40,p)],8,B)]),_:1},8,["name","label","description","error","required"]))}}),I=h(g,[["__scopeId","data-v-732b2199"]]);export{I as default};
@@ -0,0 +1 @@
1
+ select.rafa-control-input option[data-v-dfb2c9e9]{background:var(--color-bg-elevated);color:var(--color-text-primary)}