@qoretechnologies/reqraft 0.10.53 → 0.10.54-pr.115.g9bc96ed

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 (283) hide show
  1. package/.claude/CLAUDE.md +25 -0
  2. package/.tasks/INDEX.md +1 -0
  3. package/.tasks/STORY_NETWORK_ISOLATION.md +98 -0
  4. package/README.md +1 -1
  5. package/design/FORM_ENGINE_EXPRESSIONS.md +110 -0
  6. package/design/FORM_ENGINE_FIELD_MIGRATION.md +56 -1
  7. package/design/RENDER_EXPRESSION_TRANSPORT.md +76 -10
  8. package/design/SMART_EDITOR_UX.md +21 -0
  9. package/dist/components/dpqlEditor/DpqlEditor.d.ts.map +1 -1
  10. package/dist/components/dpqlEditor/DpqlEditor.js +3 -3
  11. package/dist/components/dpqlEditor/DpqlEditor.js.map +1 -1
  12. package/dist/components/dpqlEditor/dpqlHelpers.d.ts +6 -0
  13. package/dist/components/dpqlEditor/dpqlHelpers.d.ts.map +1 -1
  14. package/dist/components/dpqlEditor/dpqlHelpers.js +21 -2
  15. package/dist/components/dpqlEditor/dpqlHelpers.js.map +1 -1
  16. package/dist/components/dpqlEditor/dpqlProbe.d.ts +37 -0
  17. package/dist/components/dpqlEditor/dpqlProbe.d.ts.map +1 -0
  18. package/dist/components/dpqlEditor/dpqlProbe.js +203 -0
  19. package/dist/components/dpqlEditor/dpqlProbe.js.map +1 -0
  20. package/dist/components/dpqlEditor/dpqlTags.d.ts +8 -0
  21. package/dist/components/dpqlEditor/dpqlTags.d.ts.map +1 -1
  22. package/dist/components/dpqlEditor/dpqlTags.js +5 -1
  23. package/dist/components/dpqlEditor/dpqlTags.js.map +1 -1
  24. package/dist/components/dpqlEditor/index.d.ts +4 -0
  25. package/dist/components/dpqlEditor/index.d.ts.map +1 -1
  26. package/dist/components/dpqlEditor/index.js +5 -1
  27. package/dist/components/dpqlEditor/index.js.map +1 -1
  28. package/dist/components/dpqlEditor/types.d.ts +42 -2
  29. package/dist/components/dpqlEditor/types.d.ts.map +1 -1
  30. package/dist/components/dpqlEditor/types.js +0 -4
  31. package/dist/components/dpqlEditor/types.js.map +1 -1
  32. package/dist/components/dpqlEditor/useDpqlProbe.d.ts +4 -0
  33. package/dist/components/dpqlEditor/useDpqlProbe.d.ts.map +1 -0
  34. package/dist/components/dpqlEditor/useDpqlProbe.js +29 -0
  35. package/dist/components/dpqlEditor/useDpqlProbe.js.map +1 -0
  36. package/dist/components/dpqlEditor/useDpqlSession.d.ts +5 -2
  37. package/dist/components/dpqlEditor/useDpqlSession.d.ts.map +1 -1
  38. package/dist/components/dpqlEditor/useDpqlSession.js +8 -2
  39. package/dist/components/dpqlEditor/useDpqlSession.js.map +1 -1
  40. package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
  41. package/dist/components/form/engine/CompactRow.js +192 -45
  42. package/dist/components/form/engine/CompactRow.js.map +1 -1
  43. package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
  44. package/dist/components/form/engine/CompactToolbar.js +5 -2
  45. package/dist/components/form/engine/CompactToolbar.js.map +1 -1
  46. package/dist/components/form/engine/FormEngine.d.ts +160 -12
  47. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  48. package/dist/components/form/engine/FormEngine.js +376 -75
  49. package/dist/components/form/engine/FormEngine.js.map +1 -1
  50. package/dist/components/form/engine/FormFieldsSkeleton.d.ts +48 -0
  51. package/dist/components/form/engine/FormFieldsSkeleton.d.ts.map +1 -0
  52. package/dist/components/form/engine/FormFieldsSkeleton.js +38 -0
  53. package/dist/components/form/engine/FormFieldsSkeleton.js.map +1 -0
  54. package/dist/components/form/engine/OptionFieldMessages.d.ts +17 -2
  55. package/dist/components/form/engine/OptionFieldMessages.d.ts.map +1 -1
  56. package/dist/components/form/engine/OptionFieldMessages.js +61 -11
  57. package/dist/components/form/engine/OptionFieldMessages.js.map +1 -1
  58. package/dist/components/form/engine/_structuredData/SchemaDataView.d.ts.map +1 -1
  59. package/dist/components/form/engine/_structuredData/SchemaDataView.js +7 -1
  60. package/dist/components/form/engine/_structuredData/SchemaDataView.js.map +1 -1
  61. package/dist/components/form/engine/compactToolbarContext.d.ts +1 -0
  62. package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
  63. package/dist/components/form/engine/readFirst.d.ts +42 -1
  64. package/dist/components/form/engine/readFirst.d.ts.map +1 -1
  65. package/dist/components/form/engine/readFirst.js +74 -7
  66. package/dist/components/form/engine/readFirst.js.map +1 -1
  67. package/dist/components/form/engine/rendererTypes.d.ts +13 -0
  68. package/dist/components/form/engine/rendererTypes.d.ts.map +1 -1
  69. package/dist/components/form/engine/rendererTypes.js.map +1 -1
  70. package/dist/components/form/engine/rowMenuContext.d.ts +78 -0
  71. package/dist/components/form/engine/rowMenuContext.d.ts.map +1 -0
  72. package/dist/components/form/engine/rowMenuContext.js +103 -0
  73. package/dist/components/form/engine/rowMenuContext.js.map +1 -0
  74. package/dist/components/form/engine/typeChoices.d.ts +37 -0
  75. package/dist/components/form/engine/typeChoices.d.ts.map +1 -0
  76. package/dist/components/form/engine/typeChoices.js +25 -0
  77. package/dist/components/form/engine/typeChoices.js.map +1 -0
  78. package/dist/components/form/expressions/DpqlRendering.d.ts +26 -0
  79. package/dist/components/form/expressions/DpqlRendering.d.ts.map +1 -0
  80. package/dist/components/form/expressions/DpqlRendering.js +53 -0
  81. package/dist/components/form/expressions/DpqlRendering.js.map +1 -0
  82. package/dist/components/form/expressions/ExpressionField.d.ts +7 -1
  83. package/dist/components/form/expressions/ExpressionField.d.ts.map +1 -1
  84. package/dist/components/form/expressions/ExpressionField.js +202 -45
  85. package/dist/components/form/expressions/ExpressionField.js.map +1 -1
  86. package/dist/components/form/expressions/argumentPresence.d.ts +97 -0
  87. package/dist/components/form/expressions/argumentPresence.d.ts.map +1 -0
  88. package/dist/components/form/expressions/argumentPresence.js +203 -0
  89. package/dist/components/form/expressions/argumentPresence.js.map +1 -0
  90. package/dist/components/form/expressions/builder/argumentLabel.d.ts.map +1 -1
  91. package/dist/components/form/expressions/builder/argumentLabel.js +9 -4
  92. package/dist/components/form/expressions/builder/argumentLabel.js.map +1 -1
  93. package/dist/components/form/expressions/builder/index.d.ts +15 -2
  94. package/dist/components/form/expressions/builder/index.d.ts.map +1 -1
  95. package/dist/components/form/expressions/builder/index.js +20 -58
  96. package/dist/components/form/expressions/builder/index.js.map +1 -1
  97. package/dist/components/form/expressions/builder/renderTemplate.d.ts +4 -1
  98. package/dist/components/form/expressions/builder/renderTemplate.d.ts.map +1 -1
  99. package/dist/components/form/expressions/builder/renderTemplate.js +10 -67
  100. package/dist/components/form/expressions/builder/renderTemplate.js.map +1 -1
  101. package/dist/components/form/expressions/dpqlMockLanguage.d.ts +76 -0
  102. package/dist/components/form/expressions/dpqlMockLanguage.d.ts.map +1 -0
  103. package/dist/components/form/expressions/dpqlMockLanguage.js +525 -0
  104. package/dist/components/form/expressions/dpqlMockLanguage.js.map +1 -0
  105. package/dist/components/form/expressions/dpqlMockLsp.d.ts +31 -2
  106. package/dist/components/form/expressions/dpqlMockLsp.d.ts.map +1 -1
  107. package/dist/components/form/expressions/dpqlMockLsp.js +86 -80
  108. package/dist/components/form/expressions/dpqlMockLsp.js.map +1 -1
  109. package/dist/components/form/expressions/mockExpressions.d.ts.map +1 -1
  110. package/dist/components/form/expressions/mockExpressions.js +8 -4
  111. package/dist/components/form/expressions/mockExpressions.js.map +1 -1
  112. package/dist/components/form/expressions/renderExpressionToText.d.ts +1 -1
  113. package/dist/components/form/expressions/renderExpressionToText.d.ts.map +1 -1
  114. package/dist/components/form/expressions/renderExpressionToText.js +95 -19
  115. package/dist/components/form/expressions/renderExpressionToText.js.map +1 -1
  116. package/dist/components/form/expressions/types.d.ts +7 -0
  117. package/dist/components/form/expressions/types.d.ts.map +1 -1
  118. package/dist/components/form/expressions/useRenderExpression.d.ts +7 -16
  119. package/dist/components/form/expressions/useRenderExpression.d.ts.map +1 -1
  120. package/dist/components/form/expressions/useRenderExpression.js +50 -126
  121. package/dist/components/form/expressions/useRenderExpression.js.map +1 -1
  122. package/dist/components/form/fields/Field.d.ts.map +1 -1
  123. package/dist/components/form/fields/Field.js +3 -1
  124. package/dist/components/form/fields/Field.js.map +1 -1
  125. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts +11 -1
  126. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
  127. package/dist/components/form/fields/allowed-values/AllowedValues.js +14 -2
  128. package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
  129. package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
  130. package/dist/components/form/fields/auto/AutoFormField.js +32 -8
  131. package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
  132. package/dist/components/form/fields/date/Date.d.ts +1 -1
  133. package/dist/components/form/fields/date/Date.d.ts.map +1 -1
  134. package/dist/components/form/fields/date/Date.js +16 -2
  135. package/dist/components/form/fields/date/Date.js.map +1 -1
  136. package/dist/components/form/fields/rich-text/RichText.d.ts +21 -1
  137. package/dist/components/form/fields/rich-text/RichText.d.ts.map +1 -1
  138. package/dist/components/form/fields/rich-text/RichText.js +140 -8
  139. package/dist/components/form/fields/rich-text/RichText.js.map +1 -1
  140. package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts +2 -1
  141. package/dist/components/form/fields/template/ReadOnlyTemplateTag.d.ts.map +1 -1
  142. package/dist/components/form/fields/template/ReadOnlyTemplateTag.js +3 -2
  143. package/dist/components/form/fields/template/ReadOnlyTemplateTag.js.map +1 -1
  144. package/dist/components/form/fields/template/TemplateField.d.ts +31 -1
  145. package/dist/components/form/fields/template/TemplateField.d.ts.map +1 -1
  146. package/dist/components/form/fields/template/TemplateField.js +528 -50
  147. package/dist/components/form/fields/template/TemplateField.js.map +1 -1
  148. package/dist/components/form/index.d.ts +1 -0
  149. package/dist/components/form/index.d.ts.map +1 -1
  150. package/dist/components/form/index.js +1 -0
  151. package/dist/components/form/index.js.map +1 -1
  152. package/dist/components/smartEditor/SmartEditor.d.ts.map +1 -1
  153. package/dist/components/smartEditor/SmartEditor.js +29 -8
  154. package/dist/components/smartEditor/SmartEditor.js.map +1 -1
  155. package/dist/components/smartEditor/__fixtures__/mockLspServer.d.ts +8 -0
  156. package/dist/components/smartEditor/__fixtures__/mockLspServer.d.ts.map +1 -1
  157. package/dist/components/smartEditor/__fixtures__/mockLspServer.js +53 -10
  158. package/dist/components/smartEditor/__fixtures__/mockLspServer.js.map +1 -1
  159. package/dist/components/smartEditor/useLspSession.d.ts +5 -1
  160. package/dist/components/smartEditor/useLspSession.d.ts.map +1 -1
  161. package/dist/components/smartEditor/useLspSession.js +16 -2
  162. package/dist/components/smartEditor/useLspSession.js.map +1 -1
  163. package/dist/helpers/dpqlDetection.d.ts +58 -0
  164. package/dist/helpers/dpqlDetection.d.ts.map +1 -0
  165. package/dist/helpers/dpqlDetection.js +164 -0
  166. package/dist/helpers/dpqlDetection.js.map +1 -0
  167. package/dist/helpers/optionUiTypes.d.ts +3 -3
  168. package/dist/helpers/options.d.ts +37 -0
  169. package/dist/helpers/options.d.ts.map +1 -1
  170. package/dist/helpers/options.js +78 -1
  171. package/dist/helpers/options.js.map +1 -1
  172. package/dist/helpers/templateItems.d.ts +47 -0
  173. package/dist/helpers/templateItems.d.ts.map +1 -0
  174. package/dist/helpers/templateItems.js +88 -0
  175. package/dist/helpers/templateItems.js.map +1 -0
  176. package/dist/helpers/templateText.d.ts +37 -0
  177. package/dist/helpers/templateText.d.ts.map +1 -0
  178. package/dist/helpers/templateText.js +64 -0
  179. package/dist/helpers/templateText.js.map +1 -0
  180. package/dist/helpers/templates.d.ts +19 -11
  181. package/dist/helpers/templates.d.ts.map +1 -1
  182. package/dist/helpers/templates.js +46 -29
  183. package/dist/helpers/templates.js.map +1 -1
  184. package/dist/helpers/validations.d.ts.map +1 -1
  185. package/dist/helpers/validations.js +56 -9
  186. package/dist/helpers/validations.js.map +1 -1
  187. package/dist/hooks/useArgSchema.d.ts +2 -1
  188. package/dist/hooks/useArgSchema.d.ts.map +1 -1
  189. package/dist/hooks/useFetch/useFetch.d.ts +3 -1
  190. package/dist/hooks/useFetch/useFetch.d.ts.map +1 -1
  191. package/dist/hooks/useFetch/useFetch.js +47 -9
  192. package/dist/hooks/useFetch/useFetch.js.map +1 -1
  193. package/dist/hooks/useTemplates.d.ts +20 -0
  194. package/dist/hooks/useTemplates.d.ts.map +1 -1
  195. package/dist/hooks/useTemplates.js +34 -2
  196. package/dist/hooks/useTemplates.js.map +1 -1
  197. package/dist/index.d.ts +2 -1
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.js +5 -1
  200. package/dist/index.js.map +1 -1
  201. package/dist/stories/storyNetwork.d.ts +36 -0
  202. package/dist/stories/storyNetwork.d.ts.map +1 -0
  203. package/dist/stories/storyNetwork.js +82 -0
  204. package/dist/stories/storyNetwork.js.map +1 -0
  205. package/dist/utils/fetch.d.ts +151 -1
  206. package/dist/utils/fetch.d.ts.map +1 -1
  207. package/dist/utils/fetch.js +256 -44
  208. package/dist/utils/fetch.js.map +1 -1
  209. package/dist/utils/lspClient.d.ts +6 -0
  210. package/dist/utils/lspClient.d.ts.map +1 -1
  211. package/dist/utils/lspClient.js +62 -11
  212. package/dist/utils/lspClient.js.map +1 -1
  213. package/dist/utils/websocket.d.ts +6 -0
  214. package/dist/utils/websocket.d.ts.map +1 -1
  215. package/dist/utils/websocket.js +15 -7
  216. package/dist/utils/websocket.js.map +1 -1
  217. package/package.json +2 -2
  218. package/src/components/dpqlEditor/DpqlEditor.stories.tsx +3 -119
  219. package/src/components/dpqlEditor/DpqlEditor.tsx +5 -2
  220. package/src/components/dpqlEditor/dpqlHelpers.ts +20 -1
  221. package/src/components/dpqlEditor/dpqlProbe.ts +165 -0
  222. package/src/components/dpqlEditor/dpqlTags.ts +13 -0
  223. package/src/components/dpqlEditor/index.ts +4 -0
  224. package/src/components/dpqlEditor/types.ts +38 -2
  225. package/src/components/dpqlEditor/useDpqlProbe.ts +33 -0
  226. package/src/components/dpqlEditor/useDpqlSession.ts +20 -4
  227. package/src/components/form/engine/CompactRow.tsx +240 -51
  228. package/src/components/form/engine/CompactToolbar.tsx +10 -3
  229. package/src/components/form/engine/FormEngine.stories.tsx +423 -120
  230. package/src/components/form/engine/FormEngine.tsx +504 -87
  231. package/src/components/form/engine/FormFieldsSkeleton.tsx +76 -0
  232. package/src/components/form/engine/OptionFieldMessages.tsx +89 -11
  233. package/src/components/form/engine/_structuredData/SchemaDataView.tsx +11 -0
  234. package/src/components/form/engine/compactToolbarContext.ts +1 -1
  235. package/src/components/form/engine/readFirst.ts +86 -7
  236. package/src/components/form/engine/rendererTypes.ts +12 -0
  237. package/src/components/form/engine/rowMenuContext.ts +159 -0
  238. package/src/components/form/engine/typeChoices.ts +55 -0
  239. package/src/components/form/expressions/DpqlRendering.tsx +85 -0
  240. package/src/components/form/expressions/ExpressionField.stories.tsx +826 -48
  241. package/src/components/form/expressions/ExpressionField.tsx +265 -54
  242. package/src/components/form/expressions/argumentPresence.ts +200 -0
  243. package/src/components/form/expressions/builder/ExpressionBuilder.stories.tsx +20 -4
  244. package/src/components/form/expressions/builder/argumentLabel.tsx +10 -4
  245. package/src/components/form/expressions/builder/index.tsx +39 -77
  246. package/src/components/form/expressions/builder/renderTemplate.tsx +23 -56
  247. package/src/components/form/expressions/dpqlMockLanguage.ts +565 -0
  248. package/src/components/form/expressions/dpqlMockLsp.ts +109 -83
  249. package/src/components/form/expressions/mockExpressions.ts +8 -4
  250. package/src/components/form/expressions/renderExpressionToText.ts +112 -22
  251. package/src/components/form/expressions/types.ts +7 -0
  252. package/src/components/form/expressions/useRenderExpression.ts +43 -127
  253. package/src/components/form/fields/Field.tsx +3 -2
  254. package/src/components/form/fields/allowed-values/AllowedValues.tsx +13 -2
  255. package/src/components/form/fields/auto/AutoFormField.stories.tsx +27 -20
  256. package/src/components/form/fields/auto/AutoFormField.tsx +33 -9
  257. package/src/components/form/fields/date/Date.tsx +17 -1
  258. package/src/components/form/fields/rich-text/RichText.tsx +199 -22
  259. package/src/components/form/fields/template/ReadOnlyTemplateTag.tsx +4 -2
  260. package/src/components/form/fields/template/TemplateField.stories.tsx +31 -9
  261. package/src/components/form/fields/template/TemplateField.tsx +714 -122
  262. package/src/components/form/index.tsx +1 -0
  263. package/src/components/log/Log.stories.tsx +2 -1
  264. package/src/components/smartEditor/SmartEditor.tsx +41 -9
  265. package/src/components/smartEditor/__fixtures__/mockLspServer.ts +52 -3
  266. package/src/components/smartEditor/useLspSession.ts +21 -3
  267. package/src/helpers/dpqlDetection.ts +209 -0
  268. package/src/helpers/options.ts +70 -0
  269. package/src/helpers/templateItems.ts +81 -0
  270. package/src/helpers/templateText.ts +92 -0
  271. package/src/helpers/templates.ts +47 -37
  272. package/src/helpers/validations.ts +59 -9
  273. package/src/hooks/useFetch/useFetch.stories.tsx +6 -5
  274. package/src/hooks/useFetch/useFetch.tsx +53 -7
  275. package/src/hooks/useStorage/useStorage.stories.tsx +2 -1
  276. package/src/hooks/useTemplates.ts +41 -0
  277. package/src/hooks/useWebSocket/useWebsocket.stories.tsx +2 -1
  278. package/src/index.tsx +14 -1
  279. package/src/stores/currentUser/currentUser.stories.tsx +2 -1
  280. package/src/stories/storyNetwork.ts +92 -0
  281. package/src/utils/fetch.ts +311 -21
  282. package/src/utils/lspClient.ts +68 -11
  283. package/src/utils/websocket.ts +20 -9
@@ -0,0 +1,58 @@
1
+ /** What to do about text that turned out to be an expression. */
2
+ export type TDpqlDetectionOutcome =
3
+ /** Not an expression, or not one we may act on — leave the field alone. */
4
+ 'none'
5
+ /** A real expression, but the text is also a valid literal here: ask. */
6
+ | 'offer'
7
+ /** A real expression, and the text cannot be a literal here: switch. */
8
+ | 'switch';
9
+ /**
10
+ * Cheap, purely lexical "might this be worth asking the server about?".
11
+ * Never decides anything on its own — see the module comment.
12
+ */
13
+ export declare const mightBeDpqlExpression: (text: unknown) => boolean;
14
+ /**
15
+ * The authority: does this `dpql/parse` result describe a REAL expression
16
+ * rather than a literal or a bare template reference? Accepts either the
17
+ * field-ready envelope (`{is_expression, value: {exp, args}}`) the server
18
+ * returns or a bare `{exp, args}` node.
19
+ */
20
+ export declare const isRealExpressionAst: (expression: unknown) => boolean;
21
+ /**
22
+ * `true` when any diagnostic is an outright error. The server reports
23
+ * severity as the string `'error'` on this route and LSP proper uses `1`;
24
+ * both are accepted rather than assuming one.
25
+ */
26
+ export declare const hasErrorDiagnostic: (diagnostics?: Array<{
27
+ severity?: number | string;
28
+ } | undefined | null>) => boolean;
29
+ /**
30
+ * Could this text stand as a literal value of the field's own type? A type
31
+ * that accepts any text (`string`, and every type the form validator passes
32
+ * by default) always can, which is exactly why such a field never
33
+ * auto-switches. Delegates to the form's own validator so the answer is the
34
+ * same one the field itself would give.
35
+ */
36
+ export declare const canBeLiteralOfType: (text: string, type?: string, field?: Record<string, any>) => boolean;
37
+ export interface IClassifyTypedTextArgs {
38
+ /** The text the author typed into the plain field. */
39
+ text: string;
40
+ /** The field's declared type (`ui_type ?? type`). */
41
+ type?: string;
42
+ /** The field schema, for validators that consult `validation_regex` etc. */
43
+ field?: Record<string, any>;
44
+ /** The `dpql/parse` result for `text`, or `undefined` if it has not run. */
45
+ parsed?: {
46
+ success?: boolean;
47
+ expression?: unknown;
48
+ diagnostics?: Array<{
49
+ severity?: number | string;
50
+ }>;
51
+ };
52
+ }
53
+ /**
54
+ * The whole decision, in one pure function so it can be tested without a
55
+ * server, a socket or a rendered field.
56
+ */
57
+ export declare const classifyTypedText: ({ text, type, field, parsed, }: IClassifyTypedTextArgs) => TDpqlDetectionOutcome;
58
+ //# sourceMappingURL=dpqlDetection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpqlDetection.d.ts","sourceRoot":"","sources":["../../src/helpers/dpqlDetection.ts"],"names":[],"mappings":"AAmCA,iEAAiE;AACjE,MAAM,MAAM,qBAAqB;AAC/B,2EAA2E;AACzE,MAAM;AACR,yEAAyE;GACvE,OAAO;AACT,wEAAwE;GACtE,QAAQ,CAAC;AAuDb;;;GAGG;AACH,eAAO,MAAM,qBAAqB,SAAU,OAAO,KAAG,OAYrD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,eAAgB,OAAO,KAAG,OAazD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,iBACf,MAAM;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,CAAC,KACrE,OAIC,CAAC;AAEL;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,SACvB,MAAM,SACL,MAAM,UACL,OAAO,MAAM,EAAE,GAAG,CAAC,KAC1B,OAYF,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,4EAA4E;IAC5E,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,WAAW,CAAC,EAAE,KAAK,CAAC;YAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC,CAAC;KACrD,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,mCAK3B,sBAAsB,KAAG,qBAU3B,CAAC"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.classifyTypedText = exports.canBeLiteralOfType = exports.hasErrorDiagnostic = exports.isRealExpressionAst = exports.mightBeDpqlExpression = void 0;
4
+ // Copyright 2026 Qore Technologies, s.r.o.
5
+ /**
6
+ * Noticing that text typed into a PLAIN (non-expression) field is really a
7
+ * DPQL expression, and deciding what to do about it.
8
+ *
9
+ * The rule this implements, in one sentence: **switch the field into
10
+ * expression mode only when the text cannot be a valid literal for the
11
+ * field's type but IS a real expression; otherwise offer, never silently
12
+ * reinterpret.** Quietly turning the string `a + b` into a concatenation on a
13
+ * `string` field would destroy a legitimate literal, so a type that accepts
14
+ * any text never auto-switches — it only ever offers.
15
+ *
16
+ * ## Why the server has the last word
17
+ *
18
+ * "Does this parse as DPQL?" is NOT a usable test, which is the trap here.
19
+ * Verified against the live LSP: `dpql/parse` reports `success: true` for
20
+ * `hello`, for `42`, for `2026-09-06` and for `@a` — it wraps each of them in
21
+ * a trivial `{exp: 'value', args: [...]}` node. Everything is a valid DPQL
22
+ * program, because a bare literal is one. So a text that parses tells us
23
+ * nothing; what tells us something is the SHAPE of the AST that comes back:
24
+ *
25
+ * | typed text | `exp` | verdict |
26
+ * |-------------------|------------|------------|
27
+ * | `hello`, `42` | `value` | a literal |
28
+ * | `$local:count` | `template` | a template |
29
+ * | `@a > 5` | `>` | expression |
30
+ * | `"a" + "b"` | `+` | expression |
31
+ * | `toInt("5")` | `toInt` | expression |
32
+ *
33
+ * `isRealExpressionAst` is that test, and it is the only authority. The
34
+ * lexical pass below decides nothing — its sole job is to keep a server
35
+ * round-trip off every keystroke of every field.
36
+ */
37
+ var validations_1 = require("./validations");
38
+ /**
39
+ * The `exp` values that mean "this is not an expression": a bare literal and
40
+ * a bare template reference. A template is already the template field's job
41
+ * (`isValueTemplate`), and a literal is what the plain field is for.
42
+ */
43
+ var NON_EXPRESSION_OPS = new Set(['value', 'template']);
44
+ /**
45
+ * Operators and calls whose presence makes a server probe worth the trip.
46
+ * Deliberately generous — a false positive costs one debounced request that
47
+ * comes back `exp: 'value'`, while a false negative silently loses the whole
48
+ * feature.
49
+ *
50
+ * ## Why the spacing rules differ per operator
51
+ *
52
+ * `-` and `/` are ambiguous: they appear inside values nobody means as
53
+ * arithmetic — dates (`2026-09-06`), negative numbers (`-5`), paths (`a/b`),
54
+ * hyphenated names (`well-known-name`). A space next to one is what separates
55
+ * `@a - 1` from those, so they keep a spacing requirement.
56
+ *
57
+ * `+` is NOT ambiguous in that way, and requiring spaces around it lost the
58
+ * feature for the most natural way to type arithmetic: `2 + 1` was offered as
59
+ * an expression while `2+1` and `2+ 1` were not, which reads as the detection
60
+ * working only sometimes. Reported from the live IDE. `+` now counts wherever
61
+ * it appears; if the text turns out to be an ordinary literal the server says
62
+ * so and the offer never appears.
63
+ *
64
+ * The `-`/`/` rule is also relaxed from "spaces on BOTH sides" to "a space on
65
+ * either side", so `@a -1` and `@a- 1` are probed too while every ambiguous
66
+ * value above still is not.
67
+ */
68
+ var DPQL_OPERATOR_PATTERN = new RegExp([
69
+ '(==|!=|<>|>=|<=)', // two-character comparisons
70
+ '[<>*%]', // unambiguous single-character operators
71
+ '(?<!=)=(?!=)', // a lone `=`, not part of `==`
72
+ '\\+', // `+` — unambiguous, so spacing is irrelevant
73
+ '(\\s[-/]|[-/]\\s)', // `-` and `/` need a space on at least one side
74
+ '\\b(and|or|not|like|in|contains)\\b', // word operators
75
+ ].join('|'), 'i');
76
+ /** A function call — `toInt("5")`, `upper(@name)`. */
77
+ var DPQL_CALL_PATTERN = /\b[a-z_]\w*\s*\(/i;
78
+ /**
79
+ * The longest text worth probing. An expression a person types into a form
80
+ * field is short; anything longer is a document, and probing it on every
81
+ * keystroke would be a waste of a round-trip.
82
+ */
83
+ var MAX_PROBE_LENGTH = 512;
84
+ /**
85
+ * Cheap, purely lexical "might this be worth asking the server about?".
86
+ * Never decides anything on its own — see the module comment.
87
+ */
88
+ var mightBeDpqlExpression = function (text) {
89
+ if (typeof text !== 'string') {
90
+ return false;
91
+ }
92
+ var trimmed = text.trim();
93
+ if (!trimmed || trimmed.length > MAX_PROBE_LENGTH) {
94
+ return false;
95
+ }
96
+ return DPQL_OPERATOR_PATTERN.test(trimmed) || DPQL_CALL_PATTERN.test(trimmed);
97
+ };
98
+ exports.mightBeDpqlExpression = mightBeDpqlExpression;
99
+ /**
100
+ * The authority: does this `dpql/parse` result describe a REAL expression
101
+ * rather than a literal or a bare template reference? Accepts either the
102
+ * field-ready envelope (`{is_expression, value: {exp, args}}`) the server
103
+ * returns or a bare `{exp, args}` node.
104
+ */
105
+ var isRealExpressionAst = function (expression) {
106
+ if (!expression || typeof expression !== 'object') {
107
+ return false;
108
+ }
109
+ var envelope = expression;
110
+ var node = (envelope.exp === undefined && envelope.value && typeof envelope.value === 'object'
111
+ ? envelope.value
112
+ : envelope);
113
+ return typeof node.exp === 'string' && !!node.exp && !NON_EXPRESSION_OPS.has(node.exp);
114
+ };
115
+ exports.isRealExpressionAst = isRealExpressionAst;
116
+ /**
117
+ * `true` when any diagnostic is an outright error. The server reports
118
+ * severity as the string `'error'` on this route and LSP proper uses `1`;
119
+ * both are accepted rather than assuming one.
120
+ */
121
+ var hasErrorDiagnostic = function (diagnostics) {
122
+ return !!(diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.some(function (diagnostic) {
123
+ var severity = diagnostic === null || diagnostic === void 0 ? void 0 : diagnostic.severity;
124
+ return severity === 1 || severity === 'error';
125
+ }));
126
+ };
127
+ exports.hasErrorDiagnostic = hasErrorDiagnostic;
128
+ /**
129
+ * Could this text stand as a literal value of the field's own type? A type
130
+ * that accepts any text (`string`, and every type the form validator passes
131
+ * by default) always can, which is exactly why such a field never
132
+ * auto-switches. Delegates to the form's own validator so the answer is the
133
+ * same one the field itself would give.
134
+ */
135
+ var canBeLiteralOfType = function (text, type, field) {
136
+ if (!type) {
137
+ return true;
138
+ }
139
+ try {
140
+ return (0, validations_1.validateField)(type, text, field);
141
+ }
142
+ catch (_a) {
143
+ // A validator that throws must not be read as "this cannot be a
144
+ // literal" — that would auto-switch the field on the strength of a bug.
145
+ return true;
146
+ }
147
+ };
148
+ exports.canBeLiteralOfType = canBeLiteralOfType;
149
+ /**
150
+ * The whole decision, in one pure function so it can be tested without a
151
+ * server, a socket or a rendered field.
152
+ */
153
+ var classifyTypedText = function (_a) {
154
+ var text = _a.text, type = _a.type, field = _a.field, parsed = _a.parsed;
155
+ if (!(parsed === null || parsed === void 0 ? void 0 : parsed.success) || !parsed.expression) {
156
+ return 'none';
157
+ }
158
+ if (!(0, exports.isRealExpressionAst)(parsed.expression) || (0, exports.hasErrorDiagnostic)(parsed.diagnostics)) {
159
+ return 'none';
160
+ }
161
+ return (0, exports.canBeLiteralOfType)(text, type, field) ? 'offer' : 'switch';
162
+ };
163
+ exports.classifyTypedText = classifyTypedText;
164
+ //# sourceMappingURL=dpqlDetection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpqlDetection.js","sourceRoot":"","sources":["../../src/helpers/dpqlDetection.ts"],"names":[],"mappings":"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"}
@@ -24,7 +24,7 @@ export declare const LEGACY_FIELD_UI_TYPES: readonly ["api-manager", "array", "a
24
24
  export declare const KNOWN_QORUS_UI_TYPES: readonly ["string", "long-string", "data", "binary", "richtext", "bool", "boolean", "date", "int", "integer", "float", "number", "byte-size", "timeout", "url", "code-editor", "rgbcolor", "any", "auto", "email", "uri", "uuid", "hostname", "ipv4", "ipv6", "phone", "hash", "free-hash", "list", "free-list", "option_hash", "file", "file-as-string", "collection-documents", "enum", "select-string", "select-array", "multi-select", "workflow", "service", "job", "connection", "mapper", "class", "value-map", "fsm", "qog", "api-schema", "auth-profile", "ai-collection", "ai-endpoint", "ai-guardrail", "ml-model", "release-config", "alertrule", "alertsilence", "installed-release", "business-process", "schema", "test", "processor", "processor-mappings", "data-provider", "tool-catalog", "schema-definition", "test-cases", "test-value-contract", "dpql", "active-windows", "api-manager", "array", "array-auto", "array-of-pairs", "class-array", "class-connectors", "constant-array", "context-selector", "cron", "data-provider-options", "file-array", "fsm-list", "function-array", "http-content", "method-name", "opcua-method-arguments", "opcua-write-values", "options", "select", "service-events", "service-webhooks", "type-selector"];
25
25
  export type TLegacyFieldUiType = (typeof LEGACY_FIELD_UI_TYPES)[number];
26
26
  export type TKnownQorusUiType = (typeof KNOWN_QORUS_UI_TYPES)[number];
27
- export declare const isOptionUiType: (type: unknown) => type is "string" | "number" | "boolean" | "file" | "data" | "date" | "email" | "url" | "list" | "auto" | "richtext" | "uri" | "dpql" | "fsm" | "class" | "active-windows" | "code-editor" | "processor-mappings" | "schema-definition" | "test-cases" | "test-value-contract" | "tool-catalog" | "mapper" | "workflow" | "service" | "job" | "connection" | "value-map" | "qog" | "ai-collection" | "ai-endpoint" | "ai-guardrail" | "binary" | "long-string" | "enum" | "int" | "integer" | "float" | "free-list" | "hash" | "rgbcolor" | "free-hash" | "any" | "bool" | "data-provider" | "byte-size" | "timeout" | "uuid" | "hostname" | "ipv4" | "ipv6" | "phone" | "option_hash" | "file-as-string" | "collection-documents" | "select-string" | "select-array" | "multi-select" | "api-schema" | "auth-profile" | "ml-model" | "release-config" | "alertrule" | "alertsilence" | "installed-release" | "business-process" | "schema" | "test" | "processor";
28
- export declare const isOptionInterfaceUiType: (type: unknown) => type is "fsm" | "class" | "mapper" | "workflow" | "service" | "job" | "connection" | "value-map" | "qog" | "ai-collection" | "ai-endpoint" | "ai-guardrail" | "api-schema" | "auth-profile" | "ml-model" | "release-config" | "alertrule" | "alertsilence" | "installed-release" | "business-process" | "schema" | "test";
29
- export declare const isKnownQorusUiType: (type: unknown) => type is "string" | "number" | "boolean" | "file" | "data" | "select" | "date" | "email" | "url" | "list" | "auto" | "richtext" | "uri" | "options" | "dpql" | "fsm" | "class" | "active-windows" | "code-editor" | "cron" | "processor-mappings" | "schema-definition" | "test-cases" | "test-value-contract" | "tool-catalog" | "mapper" | "workflow" | "service" | "job" | "connection" | "value-map" | "qog" | "ai-collection" | "ai-endpoint" | "ai-guardrail" | "binary" | "long-string" | "enum" | "int" | "integer" | "float" | "free-list" | "hash" | "rgbcolor" | "free-hash" | "any" | "bool" | "data-provider" | "byte-size" | "timeout" | "uuid" | "hostname" | "ipv4" | "ipv6" | "phone" | "option_hash" | "file-as-string" | "collection-documents" | "select-string" | "select-array" | "multi-select" | "api-schema" | "auth-profile" | "ml-model" | "release-config" | "alertrule" | "alertsilence" | "installed-release" | "business-process" | "schema" | "test" | "processor" | "api-manager" | "array" | "array-auto" | "array-of-pairs" | "class-array" | "class-connectors" | "constant-array" | "context-selector" | "data-provider-options" | "file-array" | "fsm-list" | "function-array" | "http-content" | "method-name" | "opcua-method-arguments" | "opcua-write-values" | "service-events" | "service-webhooks" | "type-selector";
27
+ export declare const isOptionUiType: (type: unknown) => type is "string" | "number" | "boolean" | "file" | "data" | "date" | "email" | "url" | "list" | "auto" | "richtext" | "uri" | "dpql" | "mapper" | "workflow" | "service" | "job" | "connection" | "class" | "fsm" | "value-map" | "qog" | "ai-collection" | "ai-endpoint" | "ai-guardrail" | "binary" | "long-string" | "enum" | "int" | "integer" | "float" | "free-list" | "hash" | "rgbcolor" | "free-hash" | "any" | "bool" | "data-provider" | "processor-mappings" | "tool-catalog" | "code-editor" | "active-windows" | "schema-definition" | "test-cases" | "test-value-contract" | "byte-size" | "timeout" | "uuid" | "hostname" | "ipv4" | "ipv6" | "phone" | "option_hash" | "file-as-string" | "collection-documents" | "select-string" | "select-array" | "multi-select" | "api-schema" | "auth-profile" | "ml-model" | "release-config" | "alertrule" | "alertsilence" | "installed-release" | "business-process" | "schema" | "test" | "processor";
28
+ export declare const isOptionInterfaceUiType: (type: unknown) => type is "mapper" | "workflow" | "service" | "job" | "connection" | "class" | "fsm" | "value-map" | "qog" | "ai-collection" | "ai-endpoint" | "ai-guardrail" | "api-schema" | "auth-profile" | "ml-model" | "release-config" | "alertrule" | "alertsilence" | "installed-release" | "business-process" | "schema" | "test";
29
+ export declare const isKnownQorusUiType: (type: unknown) => type is "string" | "number" | "boolean" | "file" | "data" | "select" | "date" | "email" | "url" | "list" | "auto" | "richtext" | "uri" | "dpql" | "mapper" | "workflow" | "service" | "job" | "connection" | "class" | "fsm" | "value-map" | "qog" | "ai-collection" | "ai-endpoint" | "ai-guardrail" | "binary" | "long-string" | "enum" | "int" | "integer" | "float" | "free-list" | "hash" | "rgbcolor" | "free-hash" | "any" | "bool" | "data-provider" | "processor-mappings" | "tool-catalog" | "code-editor" | "options" | "active-windows" | "cron" | "schema-definition" | "test-cases" | "test-value-contract" | "byte-size" | "timeout" | "uuid" | "hostname" | "ipv4" | "ipv6" | "phone" | "option_hash" | "file-as-string" | "collection-documents" | "select-string" | "select-array" | "multi-select" | "api-schema" | "auth-profile" | "ml-model" | "release-config" | "alertrule" | "alertsilence" | "installed-release" | "business-process" | "schema" | "test" | "processor" | "api-manager" | "array" | "array-auto" | "array-of-pairs" | "class-array" | "class-connectors" | "constant-array" | "context-selector" | "data-provider-options" | "file-array" | "fsm-list" | "function-array" | "http-content" | "method-name" | "opcua-method-arguments" | "opcua-write-values" | "service-events" | "service-webhooks" | "type-selector";
30
30
  //# sourceMappingURL=optionUiTypes.d.ts.map
@@ -20,4 +20,41 @@ export declare const getRequiredOptionMessage: (schema: IQorusFormSchema, groups
20
20
  * `'value' in []` is false anyway, but saying so keeps the intent legible.
21
21
  */
22
22
  export declare const getListElementValue: (element: unknown) => unknown;
23
+ /**
24
+ * The schema with every one-of group that offers no choice turned back into a
25
+ * plain required field.
26
+ *
27
+ * A `required_groups` group says *"at least one of these"*, and the whole
28
+ * affordance built on it — the ONE OF header, the `Covers` / `Covered by “X”`
29
+ * chips, the *"this field or X is required"* message — exists to tell an author
30
+ * that they have a CHOICE and which way they have answered it. When the group
31
+ * has a single member in the schema in hand, there is no choice: that field
32
+ * must be set, which is exactly what `required` already means. Saying it in the
33
+ * one-of grammar instead is worse than saying nothing, because a green tick
34
+ * beside a value reads as confirmation of the VALUE — a Qorus test author read
35
+ * `✓ COVERS` beside their service as "yes, this is the service your test is
36
+ * about", which the form never said and cannot know.
37
+ *
38
+ * This is not a hypothetical: a server may legitimately declare a group over an
39
+ * API-only alternative it then hides from the form (Qorus test steps put
40
+ * `target` in a group with `service`, and hide `target`), so the form is handed
41
+ * one member of a two-member group. The group is still real for the API and
42
+ * must stay in the schema the server serves; it is only this form that has
43
+ * nothing to offer.
44
+ *
45
+ * The rewrite is exact rather than cosmetic: a one-of over one option and a
46
+ * required option are the same constraint, so validation, the completion meter
47
+ * and the required-only filter all keep saying what they said — in the grammar
48
+ * that fits.
49
+ *
50
+ * A field in a degenerate group is required by that group ALONE, so it is
51
+ * marked required even when it also belongs to a group that does offer a
52
+ * choice; that other group keeps its affordance and is satisfied by this field
53
+ * either way. The key is deleted rather than emptied because `[]` is truthy,
54
+ * and every consumer tests `option.required_groups` for existence.
55
+ *
56
+ * Returns the schema unchanged — the same object — when no group degenerates,
57
+ * so it can sit on a memo without giving every render a new schema identity.
58
+ */
59
+ export declare const resolveDegenerateRequiredGroups: <T extends IQorusFormSchema>(schema: T) => T;
23
60
  //# sourceMappingURL=options.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/helpers/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,8BAA8B,CAAC;AAEvF,eAAO,MAAM,4BAA4B,WAC/B,gBAAgB,UAChB,MAAM,EAAE,kBACA,MAAM,KACrB,MAAM,EAQR,CAAC;AAEF,eAAO,MAAM,wBAAwB,WAC3B,gBAAgB,UAChB,MAAM,EAAE,gBACF,MAAM,KACnB,MAUF,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,mBAAmB,YAAa,OAAO,KAAG,OAG5C,CAAC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/helpers/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAyB,MAAM,8BAA8B,CAAC;AAEvF,eAAO,MAAM,4BAA4B,WAC/B,gBAAgB,UAChB,MAAM,EAAE,kBACA,MAAM,KACrB,MAAM,EAQR,CAAC;AAEF,eAAO,MAAM,wBAAwB,WAC3B,gBAAgB,UAChB,MAAM,EAAE,gBACF,MAAM,KACnB,MAUF,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,mBAAmB,YAAa,OAAO,KAAG,OAG5C,CAAC;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,+BAA+B,uCAClC,CAAC,KACR,CA8BF,CAAC"}
@@ -1,6 +1,17 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getListElementValue = exports.getRequiredOptionMessage = exports.getOptionsFromRequiredGroups = void 0;
14
+ exports.resolveDegenerateRequiredGroups = exports.getListElementValue = exports.getRequiredOptionMessage = exports.getOptionsFromRequiredGroups = void 0;
4
15
  var getOptionsFromRequiredGroups = function (schema, groups, currentOption) {
5
16
  return Object.keys(schema)
6
17
  .filter(function (option) {
@@ -46,4 +57,70 @@ var getListElementValue = function (element) {
46
57
  : element;
47
58
  };
48
59
  exports.getListElementValue = getListElementValue;
60
+ /**
61
+ * The schema with every one-of group that offers no choice turned back into a
62
+ * plain required field.
63
+ *
64
+ * A `required_groups` group says *"at least one of these"*, and the whole
65
+ * affordance built on it — the ONE OF header, the `Covers` / `Covered by “X”`
66
+ * chips, the *"this field or X is required"* message — exists to tell an author
67
+ * that they have a CHOICE and which way they have answered it. When the group
68
+ * has a single member in the schema in hand, there is no choice: that field
69
+ * must be set, which is exactly what `required` already means. Saying it in the
70
+ * one-of grammar instead is worse than saying nothing, because a green tick
71
+ * beside a value reads as confirmation of the VALUE — a Qorus test author read
72
+ * `✓ COVERS` beside their service as "yes, this is the service your test is
73
+ * about", which the form never said and cannot know.
74
+ *
75
+ * This is not a hypothetical: a server may legitimately declare a group over an
76
+ * API-only alternative it then hides from the form (Qorus test steps put
77
+ * `target` in a group with `service`, and hide `target`), so the form is handed
78
+ * one member of a two-member group. The group is still real for the API and
79
+ * must stay in the schema the server serves; it is only this form that has
80
+ * nothing to offer.
81
+ *
82
+ * The rewrite is exact rather than cosmetic: a one-of over one option and a
83
+ * required option are the same constraint, so validation, the completion meter
84
+ * and the required-only filter all keep saying what they said — in the grammar
85
+ * that fits.
86
+ *
87
+ * A field in a degenerate group is required by that group ALONE, so it is
88
+ * marked required even when it also belongs to a group that does offer a
89
+ * choice; that other group keeps its affordance and is satisfied by this field
90
+ * either way. The key is deleted rather than emptied because `[]` is truthy,
91
+ * and every consumer tests `option.required_groups` for existence.
92
+ *
93
+ * Returns the schema unchanged — the same object — when no group degenerates,
94
+ * so it can sit on a memo without giving every render a new schema identity.
95
+ */
96
+ var resolveDegenerateRequiredGroups = function (schema) {
97
+ if (!schema)
98
+ return schema;
99
+ var membersPerGroup = {};
100
+ Object.values(schema).forEach(function (option) {
101
+ var _a;
102
+ (_a = option === null || option === void 0 ? void 0 : option.required_groups) === null || _a === void 0 ? void 0 : _a.forEach(function (group) {
103
+ var _a;
104
+ membersPerGroup[group] = ((_a = membersPerGroup[group]) !== null && _a !== void 0 ? _a : 0) + 1;
105
+ });
106
+ });
107
+ var degenerate = function (group) { return membersPerGroup[group] < 2; };
108
+ if (!Object.keys(membersPerGroup).some(degenerate))
109
+ return schema;
110
+ var resolved = {};
111
+ Object.entries(schema).forEach(function (_a) {
112
+ var name = _a[0], option = _a[1];
113
+ var groups = option === null || option === void 0 ? void 0 : option.required_groups;
114
+ if (!(groups === null || groups === void 0 ? void 0 : groups.some(degenerate))) {
115
+ resolved[name] = option;
116
+ return;
117
+ }
118
+ var kept = groups.filter(function (group) { return !degenerate(group); });
119
+ var rest = __assign({}, option);
120
+ delete rest.required_groups;
121
+ resolved[name] = __assign(__assign(__assign({}, rest), { required: true }), (kept.length ? { required_groups: kept } : {}));
122
+ });
123
+ return resolved;
124
+ };
125
+ exports.resolveDegenerateRequiredGroups = resolveDegenerateRequiredGroups;
49
126
  //# sourceMappingURL=options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/helpers/options.ts"],"names":[],"mappings":";;;AAEO,IAAM,4BAA4B,GAAG,UAC1C,MAAwB,EACxB,MAAgB,EAChB,aAAsB;IAEtB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SACvB,MAAM,CAAC,UAAC,MAAM;;QACb,OAAO,MAAC,MAAM,CAAC,MAAM,CAA2B,CAAC,eAAe,0CAAE,IAAI,CAAC,UAAC,KAAK;YAC3E,OAAA,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAtB,CAAsB,CACvB,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,KAAK,aAAa,EAAxB,CAAwB,CAAC,CAAC;AAClD,CAAC,CAAC;AAZW,QAAA,4BAA4B,gCAYvC;AAEK,IAAM,wBAAwB,GAAG,UACtC,MAAwB,EACxB,MAAgB,EAChB,YAAoB;IAEpB,IAAK,MAAM,CAAC,YAAY,CAA2B,CAAC,QAAQ,EAAE,CAAC;QAC7D,OAAO,wBAAwB,CAAC;IAClC,CAAC;IAED,IAAM,eAAe,GAAG,IAAA,oCAA4B,EAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC;SAC/E,GAAG,CAAC,UAAC,MAAM,IAAK,OAAC,MAAM,CAAC,MAAM,CAA2B,CAAC,YAAY,EAAtD,CAAsD,CAAC;SACvE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,wBAAiB,eAAe,iBAAc,CAAC;AACxD,CAAC,CAAC;AAdW,QAAA,wBAAwB,4BAcnC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACI,IAAM,mBAAmB,GAAG,UAAC,OAAgB;IAClD,OAAA,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC;QACtF,OAA8B,CAAC,KAAK;QACvC,CAAC,CAAC,OAAO;AAFT,CAES,CAAC;AAHC,QAAA,mBAAmB,uBAGpB"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/helpers/options.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEO,IAAM,4BAA4B,GAAG,UAC1C,MAAwB,EACxB,MAAgB,EAChB,aAAsB;IAEtB,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SACvB,MAAM,CAAC,UAAC,MAAM;;QACb,OAAO,MAAC,MAAM,CAAC,MAAM,CAA2B,CAAC,eAAe,0CAAE,IAAI,CAAC,UAAC,KAAK;YAC3E,OAAA,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAtB,CAAsB,CACvB,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,UAAC,MAAM,IAAK,OAAA,MAAM,KAAK,aAAa,EAAxB,CAAwB,CAAC,CAAC;AAClD,CAAC,CAAC;AAZW,QAAA,4BAA4B,gCAYvC;AAEK,IAAM,wBAAwB,GAAG,UACtC,MAAwB,EACxB,MAAgB,EAChB,YAAoB;IAEpB,IAAK,MAAM,CAAC,YAAY,CAA2B,CAAC,QAAQ,EAAE,CAAC;QAC7D,OAAO,wBAAwB,CAAC;IAClC,CAAC;IAED,IAAM,eAAe,GAAG,IAAA,oCAA4B,EAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC;SAC/E,GAAG,CAAC,UAAC,MAAM,IAAK,OAAC,MAAM,CAAC,MAAM,CAA2B,CAAC,YAAY,EAAtD,CAAsD,CAAC;SACvE,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,wBAAiB,eAAe,iBAAc,CAAC;AACxD,CAAC,CAAC;AAdW,QAAA,wBAAwB,4BAcnC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACI,IAAM,mBAAmB,GAAG,UAAC,OAAgB;IAClD,OAAA,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC;QACtF,OAA8B,CAAC,KAAK;QACvC,CAAC,CAAC,OAAO;AAFT,CAES,CAAC;AAHC,QAAA,mBAAmB,uBAGpB;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACI,IAAM,+BAA+B,GAAG,UAC7C,MAAS;IAET,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAE3B,IAAM,eAAe,GAA2B,EAAE,CAAC;IACnD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAC,MAAM;;QACnC,MAAC,MAAgC,aAAhC,MAAM,uBAAN,MAAM,CAA4B,eAAe,0CAAE,OAAO,CAAC,UAAC,KAAK;;YAChE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,MAAA,eAAe,CAAC,KAAK,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAM,UAAU,GAAG,UAAC,KAAa,IAAc,OAAA,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,EAA1B,CAA0B,CAAC;IAC1E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,MAAM,CAAC;IAElE,IAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAC,EAAc;YAAb,IAAI,QAAA,EAAE,MAAM,QAAA;QAC3C,IAAM,MAAM,GAAI,MAAgC,aAAhC,MAAM,uBAAN,MAAM,CAA4B,eAAe,CAAC;QAClE,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,UAAU,CAAC,CAAA,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,UAAC,KAAK,IAAK,OAAA,CAAC,UAAU,CAAC,KAAK,CAAC,EAAlB,CAAkB,CAAC,CAAC;QAC1D,IAAM,IAAI,gBAAS,MAAgC,CAAE,CAAC;QACtD,OAAO,IAAI,CAAC,eAAe,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,+BACZ,IAAI,KACP,QAAQ,EAAE,IAAI,KACX,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACzB,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,OAAO,QAAa,CAAC;AACvB,CAAC,CAAC;AAhCW,QAAA,+BAA+B,mCAgC1C"}
@@ -0,0 +1,47 @@
1
+ import type { TMarkdownRenderer } from '../components/Description/markdownRendererContext';
2
+ /**
3
+ * What a template picker should actually list.
4
+ *
5
+ * Pickers group templates by category, which is what makes a long catalogue
6
+ * scannable. A LONE category buys nothing and costs a click: the author opens
7
+ * the picker, sees one row naming the category, clicks it, and only then sees
8
+ * the values — with a back arrow as the only other thing on offer. So a single
9
+ * category is opened for them.
10
+ *
11
+ * Two or more categories keep the grouping, because there the headers are doing
12
+ * real work. This only ever removes a step that could not have gone any other
13
+ * way.
14
+ *
15
+ * Lives here rather than beside either picker: `TemplateField` renders the
16
+ * "Select Template" dropdown and `RichText` renders the in-editor `$` list, and
17
+ * `TemplateField` already imports `RichText` — so a shared home is the only one
18
+ * that does not close an import cycle.
19
+ */
20
+ export declare const templateItemsToShow: <T>(items: T[] | undefined) => T[] | undefined;
21
+ /**
22
+ * A picker row's description, DRAWN.
23
+ *
24
+ * A description is prose, and a host that writes prose writes markdown: the
25
+ * same author, in the same dialect, as the field descriptions and schema
26
+ * messages this package already draws through the host's renderer. Left as a
27
+ * string, a row explaining that a step needs a **Fixture Output** printed the
28
+ * asterisks at the reader.
29
+ *
30
+ * WHERE THIS MAY BE CALLED, and why it is not simply done at the source: the
31
+ * template list is a memo KEY in several places — `TemplateField` stringifies
32
+ * both the incoming `templates` and the resolved `filteredTemplates`, and the
33
+ * list is handed down to nested fields that stringify it again. `JSON.stringify`
34
+ * throws on a React element's circular `_owner`, so an element anywhere in the
35
+ * list takes the whole form down to a blank panel.
36
+ *
37
+ * So this runs at the LAST hop only — the call that hands items to a Reqore
38
+ * control, after every key has been computed — and its result is never passed
39
+ * on to anything that might stringify it. Reqore itself does not: it draws the
40
+ * description into a `ReqoreTextEffect` and styled-components filters the prop
41
+ * off the DOM.
42
+ *
43
+ * Without a host renderer the items are returned untouched, so a host that has
44
+ * no markdown keeps exactly what it had.
45
+ */
46
+ export declare const renderTemplateItemDescriptions: <T>(items: T[] | undefined, render: TMarkdownRenderer | undefined) => T[] | undefined;
47
+ //# sourceMappingURL=templateItems.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateItems.d.ts","sourceRoot":"","sources":["../../src/helpers/templateItems.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAE3F;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,mBAAmB,aAAe,CAAC,EAAE,GAAG,SAAS,KAAG,CAAC,EAAE,GAAG,SAMtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,8BAA8B,aAClC,CAAC,EAAE,GAAG,SAAS,UACd,iBAAiB,GAAG,SAAS,KACpC,CAAC,EAAE,GAAG,SAwBR,CAAC"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.renderTemplateItemDescriptions = exports.templateItemsToShow = void 0;
15
+ /**
16
+ * What a template picker should actually list.
17
+ *
18
+ * Pickers group templates by category, which is what makes a long catalogue
19
+ * scannable. A LONE category buys nothing and costs a click: the author opens
20
+ * the picker, sees one row naming the category, clicks it, and only then sees
21
+ * the values — with a back arrow as the only other thing on offer. So a single
22
+ * category is opened for them.
23
+ *
24
+ * Two or more categories keep the grouping, because there the headers are doing
25
+ * real work. This only ever removes a step that could not have gone any other
26
+ * way.
27
+ *
28
+ * Lives here rather than beside either picker: `TemplateField` renders the
29
+ * "Select Template" dropdown and `RichText` renders the in-editor `$` list, and
30
+ * `TemplateField` already imports `RichText` — so a shared home is the only one
31
+ * that does not close an import cycle.
32
+ */
33
+ var templateItemsToShow = function (items) {
34
+ if ((items === null || items === void 0 ? void 0 : items.length) !== 1) {
35
+ return items;
36
+ }
37
+ var only = items[0];
38
+ return Array.isArray(only.items) && only.items.length ? only.items : items;
39
+ };
40
+ exports.templateItemsToShow = templateItemsToShow;
41
+ /**
42
+ * A picker row's description, DRAWN.
43
+ *
44
+ * A description is prose, and a host that writes prose writes markdown: the
45
+ * same author, in the same dialect, as the field descriptions and schema
46
+ * messages this package already draws through the host's renderer. Left as a
47
+ * string, a row explaining that a step needs a **Fixture Output** printed the
48
+ * asterisks at the reader.
49
+ *
50
+ * WHERE THIS MAY BE CALLED, and why it is not simply done at the source: the
51
+ * template list is a memo KEY in several places — `TemplateField` stringifies
52
+ * both the incoming `templates` and the resolved `filteredTemplates`, and the
53
+ * list is handed down to nested fields that stringify it again. `JSON.stringify`
54
+ * throws on a React element's circular `_owner`, so an element anywhere in the
55
+ * list takes the whole form down to a blank panel.
56
+ *
57
+ * So this runs at the LAST hop only — the call that hands items to a Reqore
58
+ * control, after every key has been computed — and its result is never passed
59
+ * on to anything that might stringify it. Reqore itself does not: it draws the
60
+ * description into a `ReqoreTextEffect` and styled-components filters the prop
61
+ * off the DOM.
62
+ *
63
+ * Without a host renderer the items are returned untouched, so a host that has
64
+ * no markdown keeps exactly what it had.
65
+ */
66
+ var renderTemplateItemDescriptions = function (items, render) {
67
+ if (!render || !(items === null || items === void 0 ? void 0 : items.length)) {
68
+ return items;
69
+ }
70
+ return items.map(function (item) {
71
+ var entry = item;
72
+ var next = __assign({}, entry);
73
+ if (typeof entry.description === 'string' && entry.description.trim()) {
74
+ /* `compact`, for the reason the context gives: a row is a constrained
75
+ container, and markdown authored as a document opens with a heading
76
+ that would outgrow the label above it. */
77
+ next.description = render({ value: entry.description, compact: true });
78
+ }
79
+ // Only when the item HAS children — writing the key unconditionally would
80
+ // give every leaf an `items` a picker could read as an empty submenu.
81
+ if (Array.isArray(entry.items)) {
82
+ next.items = (0, exports.renderTemplateItemDescriptions)(entry.items, render);
83
+ }
84
+ return next;
85
+ });
86
+ };
87
+ exports.renderTemplateItemDescriptions = renderTemplateItemDescriptions;
88
+ //# sourceMappingURL=templateItems.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateItems.js","sourceRoot":"","sources":["../../src/helpers/templateItems.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA;;;;;;;;;;;;;;;;;GAiBG;AACI,IAAM,mBAAmB,GAAG,UAAK,KAAsB;IAC5D,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,MAAK,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAA0B,CAAC;IAC/C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,IAAI,CAAC,KAAa,CAAC,CAAC,CAAC,KAAK,CAAC;AACtF,CAAC,CAAC;AANW,QAAA,mBAAmB,uBAM9B;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACI,IAAM,8BAA8B,GAAG,UAC5C,KAAsB,EACtB,MAAqC;IAErC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,CAAA,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,UAAC,IAAI;QACpB,IAAM,KAAK,GAAG,IAAkD,CAAC;QACjE,IAAM,IAAI,GAAG,aAAK,KAAK,CAA6B,CAAC;QAErD,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YACtE;;wDAE4C;YAC5C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,0EAA0E;QAC1E,sEAAsE;QACtE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,GAAG,IAAA,sCAA8B,EAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,IAAS,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AA3BW,QAAA,8BAA8B,kCA2BzC"}
@@ -0,0 +1,37 @@
1
+ import { IReqoreFormTemplates } from '@qoretechnologies/reqore/dist/components/Textarea';
2
+ /** A run of text. */
3
+ export interface ITemplateTextLeaf {
4
+ text: string;
5
+ }
6
+ /** A template reference, drawn as a chip. */
7
+ export interface ITemplateTextTag {
8
+ type: 'tag';
9
+ value: string;
10
+ label: string;
11
+ metadata?: unknown;
12
+ children: ITemplateTextLeaf[];
13
+ }
14
+ /** One line of the string. */
15
+ export interface ITemplateTextParagraph {
16
+ type: 'paragraph';
17
+ children: Array<ITemplateTextLeaf | ITemplateTextTag>;
18
+ }
19
+ /**
20
+ * What a reference chip says: the name the catalogue gives the reference, else
21
+ * the reference as the DPQL Text view labels it (`local: name`), so the same
22
+ * reference reads alike in the Visual builder and the Text view.
23
+ */
24
+ export declare const templateChipLabel: (templates: IReqoreFormTemplates | undefined, value: string) => string;
25
+ /**
26
+ * `text` as paragraphs, one per line, with each template reference a chip.
27
+ *
28
+ * A chip is an inline VOID and holds no text of its own, so a cursor can only
29
+ * sit in the text nodes around it; one is kept on each side even when empty.
30
+ * The chip's label is `templateChipLabel`.
31
+ */
32
+ export declare const templateTextToNodes: (text: string, templates?: IReqoreFormTemplates) => ITemplateTextParagraph[];
33
+ /** The string the paragraphs stand for: each chip written as its reference. */
34
+ export declare const templateNodesToText: (nodes?: ReadonlyArray<{
35
+ children?: unknown[];
36
+ }>) => string;
37
+ //# sourceMappingURL=templateText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateText.d.ts","sourceRoot":"","sources":["../../src/helpers/templateText.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AAQzF,qBAAqB;AACrB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,8BAA8B;AAC9B,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,CAAC;CACvD;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,cAAe,oBAAoB,GAAG,SAAS,SAAS,MAAM,KAAG,MAG9F,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,SACxB,MAAM,cACA,oBAAoB,KAC/B,sBAAsB,EAqBrB,CAAC;AAEL,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,WAAY,cAAc;IAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,KAAG,MAWvE,CAAC"}