@nyaruka/temba-components 0.140.0 → 0.141.1

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 (297) hide show
  1. package/.lintstagedrc.js +10 -0
  2. package/CHANGELOG.md +22 -0
  3. package/dist/locales/es.js +5 -5
  4. package/dist/locales/es.js.map +1 -1
  5. package/dist/locales/fr.js +5 -5
  6. package/dist/locales/fr.js.map +1 -1
  7. package/dist/locales/locale-codes.js +11 -2
  8. package/dist/locales/locale-codes.js.map +1 -1
  9. package/dist/locales/pt.js +5 -5
  10. package/dist/locales/pt.js.map +1 -1
  11. package/dist/temba-components.js +263 -156
  12. package/dist/temba-components.js.map +1 -1
  13. package/out-tsc/src/display/FloatingTab.js +1 -1
  14. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  15. package/out-tsc/src/flow/CanvasNode.js +1 -1
  16. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  17. package/out-tsc/src/flow/Editor.js +239 -43
  18. package/out-tsc/src/flow/Editor.js.map +1 -1
  19. package/out-tsc/src/flow/Plumber.js +61 -14
  20. package/out-tsc/src/flow/Plumber.js.map +1 -1
  21. package/out-tsc/src/flow/actions/add_contact_groups.js +4 -1
  22. package/out-tsc/src/flow/actions/add_contact_groups.js.map +1 -1
  23. package/out-tsc/src/flow/actions/add_input_labels.js +4 -1
  24. package/out-tsc/src/flow/actions/add_input_labels.js.map +1 -1
  25. package/out-tsc/src/flow/actions/remove_contact_groups.js +6 -1
  26. package/out-tsc/src/flow/actions/remove_contact_groups.js.map +1 -1
  27. package/out-tsc/src/flow/actions/send_broadcast.js +6 -2
  28. package/out-tsc/src/flow/actions/send_broadcast.js.map +1 -1
  29. package/out-tsc/src/flow/actions/set_contact_channel.js +13 -0
  30. package/out-tsc/src/flow/actions/set_contact_channel.js.map +1 -1
  31. package/out-tsc/src/flow/actions/set_contact_status.js +7 -5
  32. package/out-tsc/src/flow/actions/set_contact_status.js.map +1 -1
  33. package/out-tsc/src/flow/actions/start_session.js +10 -3
  34. package/out-tsc/src/flow/actions/start_session.js.map +1 -1
  35. package/out-tsc/src/flow/nodes/split_by_contact_field.js +18 -5
  36. package/out-tsc/src/flow/nodes/split_by_contact_field.js.map +1 -1
  37. package/out-tsc/src/flow/nodes/split_by_expression.js +1 -1
  38. package/out-tsc/src/flow/nodes/split_by_expression.js.map +1 -1
  39. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js +0 -1
  40. package/out-tsc/src/flow/nodes/split_by_llm_categorize.js.map +1 -1
  41. package/out-tsc/src/flow/nodes/split_by_random.js +0 -1
  42. package/out-tsc/src/flow/nodes/split_by_random.js.map +1 -1
  43. package/out-tsc/src/flow/nodes/split_by_run_result.js +10 -4
  44. package/out-tsc/src/flow/nodes/split_by_run_result.js.map +1 -1
  45. package/out-tsc/src/flow/nodes/wait_for_digits.js +1 -1
  46. package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
  47. package/out-tsc/src/flow/nodes/wait_for_response.js +1 -1
  48. package/out-tsc/src/flow/nodes/wait_for_response.js.map +1 -1
  49. package/out-tsc/src/form/FieldRenderer.js +7 -0
  50. package/out-tsc/src/form/FieldRenderer.js.map +1 -1
  51. package/out-tsc/src/layout/Dialog.js +0 -1
  52. package/out-tsc/src/layout/Dialog.js.map +1 -1
  53. package/out-tsc/src/layout/Modax.js +20 -2
  54. package/out-tsc/src/layout/Modax.js.map +1 -1
  55. package/out-tsc/src/list/ContentMenu.js +14 -1
  56. package/out-tsc/src/list/ContentMenu.js.map +1 -1
  57. package/out-tsc/src/live/ContactChat.js +10 -1
  58. package/out-tsc/src/live/ContactChat.js.map +1 -1
  59. package/out-tsc/src/live/TembaChart.js.map +1 -1
  60. package/out-tsc/src/locales/es.js +5 -5
  61. package/out-tsc/src/locales/es.js.map +1 -1
  62. package/out-tsc/src/locales/fr.js +5 -5
  63. package/out-tsc/src/locales/fr.js.map +1 -1
  64. package/out-tsc/src/locales/locale-codes.js +11 -2
  65. package/out-tsc/src/locales/locale-codes.js.map +1 -1
  66. package/out-tsc/src/locales/pt.js +5 -5
  67. package/out-tsc/src/locales/pt.js.map +1 -1
  68. package/out-tsc/src/simulator/Simulator.js +11 -0
  69. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  70. package/out-tsc/src/store/AppState.js +13 -0
  71. package/out-tsc/src/store/AppState.js.map +1 -1
  72. package/out-tsc/src/version.js +9 -0
  73. package/out-tsc/src/version.js.map +1 -0
  74. package/out-tsc/test/actions/add_contact_groups.test.js +35 -0
  75. package/out-tsc/test/actions/add_contact_groups.test.js.map +1 -1
  76. package/out-tsc/test/actions/add_input_labels.test.js +53 -0
  77. package/out-tsc/test/actions/add_input_labels.test.js.map +1 -0
  78. package/out-tsc/test/actions/enter_flow.test.js +71 -0
  79. package/out-tsc/test/actions/enter_flow.test.js.map +1 -0
  80. package/out-tsc/test/actions/remove_contact_groups.test.js +24 -0
  81. package/out-tsc/test/actions/remove_contact_groups.test.js.map +1 -1
  82. package/out-tsc/test/actions/send_broadcast.test.js +41 -0
  83. package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
  84. package/out-tsc/test/actions/set_contact_channel.test.js +67 -0
  85. package/out-tsc/test/actions/set_contact_channel.test.js.map +1 -0
  86. package/out-tsc/test/actions/set_contact_field.test.js +52 -0
  87. package/out-tsc/test/actions/set_contact_field.test.js.map +1 -0
  88. package/out-tsc/test/actions/set_contact_language.test.js +39 -0
  89. package/out-tsc/test/actions/set_contact_language.test.js.map +1 -0
  90. package/out-tsc/test/actions/set_contact_name.test.js +28 -0
  91. package/out-tsc/test/actions/set_contact_name.test.js.map +1 -0
  92. package/out-tsc/test/actions/set_contact_status.test.js +44 -0
  93. package/out-tsc/test/actions/set_contact_status.test.js.map +1 -0
  94. package/out-tsc/test/actions/set_run_result.test.js +47 -0
  95. package/out-tsc/test/actions/set_run_result.test.js.map +1 -0
  96. package/out-tsc/test/actions/start_session.test.js +76 -0
  97. package/out-tsc/test/actions/start_session.test.js.map +1 -1
  98. package/out-tsc/test/nodes/split_by_contact_field.test.js +50 -0
  99. package/out-tsc/test/nodes/split_by_contact_field.test.js.map +1 -1
  100. package/out-tsc/test/nodes/split_by_run_result.test.js +82 -0
  101. package/out-tsc/test/nodes/split_by_run_result.test.js.map +1 -1
  102. package/out-tsc/test/nodes/split_by_ticket.test.js +139 -0
  103. package/out-tsc/test/nodes/split_by_ticket.test.js.map +1 -0
  104. package/out-tsc/test/nodes/split_by_webhook.test.js +111 -0
  105. package/out-tsc/test/nodes/split_by_webhook.test.js.map +1 -0
  106. package/out-tsc/test/temba-contact-chat.test.js +12 -0
  107. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  108. package/out-tsc/test/temba-flow-editor.test.js +206 -0
  109. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  110. package/out-tsc/test/temba-flow-plumber.test.js +19 -0
  111. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  112. package/out-tsc/test/temba-select.test.js +4 -1
  113. package/out-tsc/test/temba-select.test.js.map +1 -1
  114. package/out-tsc/test/utils.test.js +4 -2
  115. package/out-tsc/test/utils.test.js.map +1 -1
  116. package/package.json +3 -9
  117. package/rollup.components.mjs +7 -1
  118. package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
  119. package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
  120. package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
  121. package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
  122. package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
  123. package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
  124. package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
  125. package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
  126. package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
  127. package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
  128. package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
  129. package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
  130. package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
  131. package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
  132. package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
  133. package/screenshots/truth/actions/add_input_labels/editor/multiple-labels.png +0 -0
  134. package/screenshots/truth/actions/add_input_labels/editor/single-label.png +0 -0
  135. package/screenshots/truth/actions/add_input_labels/render/multiple-labels.png +0 -0
  136. package/screenshots/truth/actions/add_input_labels/render/single-label.png +0 -0
  137. package/screenshots/truth/actions/enter_flow/editor/basic-flow.png +0 -0
  138. package/screenshots/truth/actions/enter_flow/editor/long-flow-name.png +0 -0
  139. package/screenshots/truth/actions/enter_flow/render/basic-flow.png +0 -0
  140. package/screenshots/truth/actions/enter_flow/render/long-flow-name.png +0 -0
  141. package/screenshots/truth/actions/play_audio/render/expression-url.png +0 -0
  142. package/screenshots/truth/actions/play_audio/render/static-url.png +0 -0
  143. package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
  144. package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
  145. package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
  146. package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
  147. package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
  148. package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
  149. package/screenshots/truth/actions/say_msg/render/multiline-text.png +0 -0
  150. package/screenshots/truth/actions/say_msg/render/simple-text.png +0 -0
  151. package/screenshots/truth/actions/say_msg/render/text-with-audio-url.png +0 -0
  152. package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
  153. package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
  154. package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
  155. package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
  156. package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
  157. package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
  158. package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
  159. package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
  160. package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
  161. package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
  162. package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
  163. package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
  164. package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
  165. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  166. package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
  167. package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
  168. package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
  169. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  170. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  171. package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
  172. package/screenshots/truth/actions/set_contact_channel/editor/sms-channel.png +0 -0
  173. package/screenshots/truth/actions/set_contact_channel/editor/whatsapp-channel.png +0 -0
  174. package/screenshots/truth/actions/set_contact_channel/render/sms-channel.png +0 -0
  175. package/screenshots/truth/actions/set_contact_channel/render/whatsapp-channel.png +0 -0
  176. package/screenshots/truth/actions/set_contact_field/editor/clear-value.png +0 -0
  177. package/screenshots/truth/actions/set_contact_field/editor/set-value.png +0 -0
  178. package/screenshots/truth/actions/set_contact_field/render/clear-value.png +0 -0
  179. package/screenshots/truth/actions/set_contact_field/render/set-value.png +0 -0
  180. package/screenshots/truth/actions/set_contact_language/editor/english.png +0 -0
  181. package/screenshots/truth/actions/set_contact_language/editor/french.png +0 -0
  182. package/screenshots/truth/actions/set_contact_language/render/english.png +0 -0
  183. package/screenshots/truth/actions/set_contact_language/render/french.png +0 -0
  184. package/screenshots/truth/actions/set_contact_name/editor/expression-name.png +0 -0
  185. package/screenshots/truth/actions/set_contact_name/editor/static-name.png +0 -0
  186. package/screenshots/truth/actions/set_contact_name/render/expression-name.png +0 -0
  187. package/screenshots/truth/actions/set_contact_name/render/static-name.png +0 -0
  188. package/screenshots/truth/actions/set_contact_status/editor/active.png +0 -0
  189. package/screenshots/truth/actions/set_contact_status/editor/archived.png +0 -0
  190. package/screenshots/truth/actions/set_contact_status/editor/blocked.png +0 -0
  191. package/screenshots/truth/actions/set_contact_status/render/active.png +0 -0
  192. package/screenshots/truth/actions/set_contact_status/render/archived.png +0 -0
  193. package/screenshots/truth/actions/set_contact_status/render/blocked.png +0 -0
  194. package/screenshots/truth/actions/set_run_result/editor/expression-value.png +0 -0
  195. package/screenshots/truth/actions/set_run_result/editor/with-category.png +0 -0
  196. package/screenshots/truth/actions/set_run_result/render/expression-value.png +0 -0
  197. package/screenshots/truth/actions/set_run_result/render/with-category.png +0 -0
  198. package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
  199. package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
  200. package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
  201. package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
  202. package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
  203. package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
  204. package/screenshots/truth/editor/wait.png +0 -0
  205. package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
  206. package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
  207. package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
  208. package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
  209. package/screenshots/truth/nodes/split_by_llm_categorize/editor/basic-categorization.png +0 -0
  210. package/screenshots/truth/nodes/split_by_llm_categorize/editor/custom-input-and-result-name.png +0 -0
  211. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  212. package/screenshots/truth/nodes/split_by_llm_categorize/editor/many-categories.png +0 -0
  213. package/screenshots/truth/nodes/split_by_llm_categorize/editor/minimal-categories.png +0 -0
  214. package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
  215. package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
  216. package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
  217. package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
  218. package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
  219. package/screenshots/truth/nodes/split_by_random/editor/ab-test-multiple-variants.png +0 -0
  220. package/screenshots/truth/nodes/split_by_random/editor/sampling-split.png +0 -0
  221. package/screenshots/truth/nodes/split_by_random/editor/three-way-split.png +0 -0
  222. package/screenshots/truth/nodes/split_by_random/editor/two-bucket-split.png +0 -0
  223. package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
  224. package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
  225. package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
  226. package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
  227. package/screenshots/truth/nodes/wait_for_audio/render/basic-audio-wait.png +0 -0
  228. package/screenshots/truth/nodes/wait_for_dial/render/basic-dial.png +0 -0
  229. package/screenshots/truth/nodes/wait_for_dial/render/dial-with-limits.png +0 -0
  230. package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
  231. package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.png +0 -0
  232. package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
  233. package/screenshots/truth/nodes/wait_for_digits/render/digits-with-rules.png +0 -0
  234. package/screenshots/truth/nodes/wait_for_menu/render/menu-with-digits.png +0 -0
  235. package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
  236. package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
  237. package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
  238. package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.png +0 -0
  239. package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
  240. package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
  241. package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
  242. package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
  243. package/src/display/FloatingTab.ts +1 -1
  244. package/src/flow/CanvasNode.ts +1 -1
  245. package/src/flow/Editor.ts +299 -88
  246. package/src/flow/Plumber.ts +89 -14
  247. package/src/flow/actions/add_contact_groups.ts +4 -1
  248. package/src/flow/actions/add_input_labels.ts +4 -1
  249. package/src/flow/actions/remove_contact_groups.ts +6 -1
  250. package/src/flow/actions/send_broadcast.ts +6 -2
  251. package/src/flow/actions/set_contact_channel.ts +13 -1
  252. package/src/flow/actions/set_contact_status.ts +7 -5
  253. package/src/flow/actions/start_session.ts +10 -3
  254. package/src/flow/nodes/split_by_contact_field.ts +16 -5
  255. package/src/flow/nodes/split_by_expression.ts +1 -1
  256. package/src/flow/nodes/split_by_llm_categorize.ts +0 -1
  257. package/src/flow/nodes/split_by_random.ts +0 -1
  258. package/src/flow/nodes/split_by_run_result.ts +10 -4
  259. package/src/flow/nodes/wait_for_digits.ts +2 -1
  260. package/src/flow/nodes/wait_for_response.ts +1 -1
  261. package/src/form/FieldRenderer.ts +7 -0
  262. package/src/layout/Dialog.ts +0 -1
  263. package/src/layout/Modax.ts +19 -2
  264. package/src/list/ContentMenu.ts +15 -1
  265. package/src/live/ContactChat.ts +10 -1
  266. package/src/live/TembaChart.ts +1 -1
  267. package/src/locales/es.ts +18 -13
  268. package/src/locales/fr.ts +18 -13
  269. package/src/locales/locale-codes.ts +11 -2
  270. package/src/locales/pt.ts +18 -13
  271. package/src/simulator/Simulator.ts +12 -0
  272. package/src/store/AppState.ts +15 -0
  273. package/src/store/flow-definition.d.ts +1 -0
  274. package/src/version.ts +10 -0
  275. package/test/actions/add_contact_groups.test.ts +38 -0
  276. package/test/actions/add_input_labels.test.ts +67 -0
  277. package/test/actions/enter_flow.test.ts +88 -0
  278. package/test/actions/remove_contact_groups.test.ts +29 -0
  279. package/test/actions/send_broadcast.test.ts +44 -0
  280. package/test/actions/set_contact_channel.test.ts +88 -0
  281. package/test/actions/set_contact_field.test.ts +68 -0
  282. package/test/actions/set_contact_language.test.ts +55 -0
  283. package/test/actions/set_contact_name.test.ts +39 -0
  284. package/test/actions/set_contact_status.test.ts +64 -0
  285. package/test/actions/set_run_result.test.ts +61 -0
  286. package/test/actions/start_session.test.ts +82 -0
  287. package/test/nodes/split_by_contact_field.test.ts +59 -0
  288. package/test/nodes/split_by_run_result.test.ts +100 -0
  289. package/test/nodes/split_by_ticket.test.ts +157 -0
  290. package/test/nodes/split_by_webhook.test.ts +131 -0
  291. package/test/temba-contact-chat.test.ts +17 -0
  292. package/test/temba-flow-editor.test.ts +264 -0
  293. package/test/temba-flow-plumber.test.ts +62 -0
  294. package/test/temba-select.test.ts +6 -1
  295. package/test/utils.test.ts +4 -2
  296. package/web-dev-server.config.mjs +5 -1
  297. package/web-test-runner.config.mjs +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AppState.js","sourceRoot":"","sources":["../../../src/store/AppState.ts"],"names":[],"mappings":"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","sourcesContent":["import { createStore, StoreApi } from 'zustand/vanilla';\nimport { fetchResults, generateUUID } from '../utils';\nimport {\n Action,\n Exit,\n FlowDefinition,\n FlowPosition,\n Node,\n NodeUI,\n Router,\n StickyNote\n} from './flow-definition';\nimport { immer } from 'zustand/middleware/immer';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { property } from 'lit/decorators.js';\nimport { produce } from 'immer';\n\nexport const FLOW_SPEC_VERSION = '14.3';\nconst CANVAS_PADDING = 800;\n\n/**\n * Temporary: Reclassify nodes based on whether they contain terminal actions.\n * - execute_actions nodes with a terminal action become \"terminal\"\n * - terminal nodes that no longer have a terminal action become \"execute_actions\"\n * This can be removed once we stop supporting terminal nodes.\n */\nfunction reclassifyTerminalNodes(definition: FlowDefinition): void {\n if (!definition?.nodes || !definition?._ui?.nodes) return;\n\n for (const node of definition.nodes) {\n const nodeUI = definition._ui.nodes[node.uuid];\n if (!nodeUI) continue;\n\n const hasTerminalAction = node.actions?.some(\n (action) => (action as any).terminal === true\n );\n\n if (nodeUI.type === 'execute_actions' && hasTerminalAction) {\n nodeUI.type = 'terminal' as any;\n } else if (nodeUI.type === ('terminal' as any) && !hasTerminalAction) {\n nodeUI.type = 'execute_actions';\n }\n }\n}\n\n/**\n * Reclassify wait_for_response nodes that are actually voice-specific wait types.\n * The server stores all voice waits as wait_for_response, but we detect the specific\n * type from the router's wait hint:\n * - hint.type === 'digits' && hint.count === 1 → wait_for_menu\n * - hint.type === 'digits' (no count) → wait_for_digits\n * - hint.type === 'audio' → wait_for_audio\n */\nfunction reclassifyVoiceWaitNodes(definition: FlowDefinition): void {\n if (!definition?.nodes || !definition?._ui?.nodes) return;\n\n for (const node of definition.nodes) {\n const nodeUI = definition._ui.nodes[node.uuid];\n if (!nodeUI || nodeUI.type !== 'wait_for_response') continue;\n\n const hint = node.router?.wait?.hint;\n if (!hint) continue;\n\n if (hint.type === 'digits' && hint.count === 1) {\n nodeUI.type = 'wait_for_menu' as any;\n } else if (hint.type === 'digits') {\n nodeUI.type = 'wait_for_digits' as any;\n } else if (hint.type === 'audio') {\n nodeUI.type = 'wait_for_audio' as any;\n }\n }\n}\n\n/**\n * Sorts nodes by their position - first by y (top), then by x (left)\n */\nfunction sortNodesByPosition(\n nodes: Node[],\n nodePositions: Record<string, NodeUI>\n): void {\n nodes.sort((a, b) => {\n const posA = nodePositions[a.uuid]?.position;\n const posB = nodePositions[b.uuid]?.position;\n\n // if either position is missing, maintain current order\n if (!posA || !posB) {\n return 0;\n }\n\n // sort by y (top) first\n if (posA.top !== posB.top) {\n return posA.top - posB.top;\n }\n\n // if y is same, sort by x (left)\n return posA.left - posB.left;\n });\n}\n\nexport interface InfoResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface ObjectRef {\n uuid: string;\n name: string;\n}\n\nexport interface TypedObjectRef extends ObjectRef {\n type: string;\n}\n\nexport interface Language {\n code: string;\n name: string;\n}\n\nexport interface FlowIssue {\n type: string;\n node_uuid: string;\n action_uuid?: string;\n description: string;\n dependency?: {\n key: string;\n name: string;\n type: string;\n };\n}\n\nexport interface FlowInfo {\n results: InfoResult[];\n dependencies: TypedObjectRef[];\n counts: { nodes: number; languages: number };\n locals: string[];\n issues?: FlowIssue[];\n}\n\nfunction buildIssueMaps(issues: FlowIssue[] = []): {\n byNode: Map<string, FlowIssue[]>;\n byAction: Map<string, FlowIssue[]>;\n} {\n const byNode = new Map<string, FlowIssue[]>();\n const byAction = new Map<string, FlowIssue[]>();\n for (const issue of issues) {\n if (issue.action_uuid) {\n const actionList = byAction.get(issue.action_uuid) || [];\n actionList.push(issue);\n byAction.set(issue.action_uuid, actionList);\n } else {\n const nodeList = byNode.get(issue.node_uuid) || [];\n nodeList.push(issue);\n byNode.set(issue.node_uuid, nodeList);\n }\n }\n return { byNode, byAction };\n}\n\nexport interface FlowContents {\n definition: FlowDefinition;\n info: FlowInfo;\n}\n\nexport interface Workspace {\n anon: boolean;\n country: string;\n date_style: string;\n languages: string[];\n name: string;\n primary_language: string;\n timezone: string;\n uuid: string;\n}\n\nexport interface CanvasPositions {\n [uuid: string]: FlowPosition;\n}\n\nexport interface Activity {\n segments: { [exitToDestinationKey: string]: number };\n nodes: { [nodeUuid: string]: number };\n}\n\nexport interface AppState {\n flowDefinition: FlowDefinition;\n flowInfo: FlowInfo;\n issuesByNode: Map<string, FlowIssue[]>;\n issuesByAction: Map<string, FlowIssue[]>;\n\n languageCode: string;\n languageNames: { [code: string]: Language };\n workspace: Workspace;\n isTranslating: boolean;\n viewingRevision: boolean;\n\n dirtyDate: Date | null;\n\n canvasSize: { width: number; height: number };\n activity: Activity | null;\n simulatorActivity: Activity | null;\n activityEndpoint: string | null;\n simulatorActive: boolean;\n\n getCurrentActivity: () => Activity | null;\n fetchRevision: (endpoint: string, id?: string) => void;\n fetchWorkspace: (endpoint: string) => Promise<void>;\n fetchAllLanguages: (endpoint: string) => Promise<void>;\n fetchActivity: (endpoint: string) => Promise<void>;\n setActivityEndpoint: (endpoint: string) => void;\n updateActivity: (activity: Activity) => void;\n updateSimulatorActivity: (activity: Activity) => void;\n setSimulatorActive: (active: boolean) => void;\n\n getFlowResults: () => InfoResult[];\n getResultByKey(id: any): InfoResult;\n\n setFlowContents: (flow: FlowContents) => void;\n setFlowInfo: (info: FlowInfo) => void;\n setRevision: (revision: number) => void;\n setLanguageCode: (languageCode: string) => void;\n setDirtyDate: (date: Date) => void;\n expandCanvas: (width: number, height: number) => void;\n\n updateNode(\n uuid: string,\n node: { actions: Action[]; uuid: string; exits: Exit[]; router?: Router }\n ): unknown;\n updateNodeUIConfig(uuid: string, config: Record<string, any>): unknown;\n updateConnection(\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ): unknown;\n updateCanvasPositions: (positions: CanvasPositions) => void;\n removeNodes: (uuids: string[]) => void;\n removeStickyNotes: (uuids: string[]) => void;\n updateStickyNote(uuid: string, sticky: StickyNote): void;\n createStickyNote(position: FlowPosition): string;\n createNode(nodeType: string, position: FlowPosition): string;\n addNode(node: Node, nodeUI: NodeUI): void;\n updateLocalization(\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ): void;\n setTranslationFilters: (filters: { categories: boolean }) => void;\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => void;\n}\n\nexport const zustand = createStore<AppState>()(\n subscribeWithSelector(\n immer((set, get) => ({\n languageNames: {},\n canvasSize: { width: 0, height: 0 },\n languageCode: '',\n workspace: null,\n flowDefinition: null,\n flowInfo: null,\n issuesByNode: new Map(),\n issuesByAction: new Map(),\n isTranslating: false,\n viewingRevision: false,\n dirtyDate: null,\n activity: null,\n simulatorActivity: null,\n activityEndpoint: null,\n simulatorActive: false,\n\n setDirtyDate: (date: Date) => {\n set((state: AppState) => {\n state.dirtyDate = date;\n });\n },\n\n fetchRevision: async (endpoint: string, id: string = null) => {\n const viewingRevision = !!id && id !== 'latest';\n if (!id) {\n id = 'latest';\n }\n const response = await fetch(\n `${endpoint}/${id}/?version=${FLOW_SPEC_VERSION}`\n );\n\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = (await response.json()) as FlowContents;\n reclassifyTerminalNodes(data.definition);\n reclassifyVoiceWaitNodes(data.definition);\n const issueMaps = buildIssueMaps(data.info?.issues);\n set({\n flowInfo: data.info,\n flowDefinition: data.definition,\n viewingRevision,\n issuesByNode: issueMaps.byNode,\n issuesByAction: issueMaps.byAction\n });\n },\n\n fetchWorkspace: async (endpoint) => {\n const response = await fetch(endpoint);\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = await response.json();\n set({ workspace: data });\n },\n\n fetchAllLanguages: async (endpoint) => {\n const results = await fetchResults(endpoint);\n\n // convert array to map for easier lookup\n const allLanguages = results.reduce(function (\n languages: any,\n result: any\n ) {\n languages[result.value] = result.name;\n return languages;\n },\n {});\n\n set({ languageNames: allLanguages });\n },\n\n setActivityEndpoint: (endpoint: string) => {\n set({ activityEndpoint: endpoint });\n },\n\n fetchActivity: async (endpoint: string) => {\n try {\n const response = await fetch(endpoint);\n if (!response.ok) {\n return;\n }\n const data = await response.json();\n set({ activity: data });\n } catch (error) {\n console.error('Failed to fetch activity:', error);\n }\n },\n\n updateActivity: (activity: Activity) => {\n set({ activity });\n },\n\n updateSimulatorActivity: (activity: Activity) => {\n set({ simulatorActivity: activity });\n },\n\n setSimulatorActive: (active: boolean) => {\n set({ simulatorActive: active });\n },\n\n getCurrentActivity: () => {\n const state = get();\n return state.simulatorActive ? state.simulatorActivity : state.activity;\n },\n\n getFlowResults: () => {\n const state = get();\n return state.flowInfo.results;\n },\n\n getResultByKey: (id: any) => {\n const state = get();\n const results = state.flowInfo.results;\n return results.find((result) => result.key === id);\n },\n\n getLanguage: () => {\n const state = get();\n const languageCode = state.languageCode;\n const languageNames = state.languageNames;\n return { name: languageNames[languageCode], code: languageCode };\n },\n\n // todo: eventually we should be doing the fetching\n setFlowContents: (flow: FlowContents) => {\n set((state: AppState) => {\n const flowLang = flow.definition.language;\n // Clone to ensure mutable for sorting\n state.flowDefinition = {\n ...flow.definition,\n nodes: [...(flow.definition.nodes || [])]\n };\n state.flowInfo = flow.info;\n const issueMaps = buildIssueMaps(flow.info?.issues);\n state.issuesByNode = issueMaps.byNode;\n state.issuesByAction = issueMaps.byAction;\n // Reset to the flow's default language when loading a new flow\n state.languageCode = flowLang;\n state.isTranslating = false;\n\n reclassifyTerminalNodes(state.flowDefinition);\n reclassifyVoiceWaitNodes(state.flowDefinition);\n\n // Sort nodes by position when loading flow\n if (state.flowDefinition?.nodes && state.flowDefinition?._ui?.nodes) {\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n }\n });\n },\n\n setFlowInfo: (info: FlowInfo) => {\n set((state: AppState) => {\n state.flowInfo = info;\n const issueMaps = buildIssueMaps(info?.issues);\n state.issuesByNode = issueMaps.byNode;\n state.issuesByAction = issueMaps.byAction;\n });\n },\n\n setRevision: (revision: number) => {\n set((state: AppState) => {\n state.flowDefinition.revision = revision;\n });\n },\n\n setLanguageCode: (languageCode: string) => {\n set((state: AppState) => {\n state.languageCode = languageCode;\n state.isTranslating = state.flowDefinition.language !== languageCode;\n });\n },\n\n expandCanvas: (width: number, height: number) => {\n set((state: AppState) => {\n const minWidth = Math.max(\n state.canvasSize.width,\n width + CANVAS_PADDING\n );\n const minHeight = Math.max(\n state.canvasSize.height,\n height + CANVAS_PADDING\n );\n\n state.canvasSize.width = minWidth;\n state.canvasSize.height = minHeight;\n });\n },\n\n updateCanvasPositions: (positions: CanvasPositions) => {\n set((state: AppState) => {\n for (const uuid in positions) {\n // todo: add nodes that are created and then moved, for now ignore\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = positions[uuid];\n }\n\n // otherwise, it might be a sticky\n else if (state.flowDefinition._ui.stickies[uuid]) {\n state.flowDefinition._ui.stickies[uuid].position =\n positions[uuid];\n }\n }\n\n // Sort nodes by position since positions may have changed\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n removeNodes: (uuids: string[]) => {\n set((state: AppState) => {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.nodes[uuid];\n }\n\n state.flowDefinition = produce(state.flowDefinition, (draft) => {\n // For each node being removed, check if we should reroute connections\n uuids.forEach((removedUuid) => {\n const removedNode = draft.nodes.find(\n (n) => n.uuid === removedUuid\n );\n\n if (!removedNode || !removedNode.exits.length) return;\n\n // Get all destinations (filter out null/undefined)\n const destinations = removedNode.exits\n .map((exit) => exit.destination_uuid)\n .filter((dest) => dest);\n\n // Only proceed if all exits have destinations and they all point to the same place\n if (\n destinations.length === removedNode.exits.length &&\n destinations.every((dest) => dest === destinations[0])\n ) {\n const targetDestination = destinations[0];\n // Don't reroute if the target is also being removed\n if (uuids.includes(targetDestination)) return;\n\n // Find all nodes with exits pointing to the node being removed\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (exit.destination_uuid === removedUuid) {\n // Reroute to the same destination the removed node was going to\n exit.destination_uuid = targetDestination;\n }\n });\n });\n }\n });\n\n // Remove the nodes\n draft.nodes = draft.nodes.filter(\n (node) => !uuids.includes(node.uuid)\n );\n\n // Clear any remaining connections to removed nodes that weren't rerouted\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (uuids.includes(exit.destination_uuid)) {\n exit.destination_uuid = null;\n }\n });\n });\n\n // Sort nodes by position\n sortNodesByPosition(draft.nodes, draft._ui.nodes);\n });\n\n state.dirtyDate = new Date();\n });\n },\n\n removeStickyNotes: (uuids: string[]) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui?.stickies) {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.stickies[uuid];\n }\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNode: (uuid: string, newNode: Node) => {\n set((state: AppState) => {\n const node = state.flowDefinition?.nodes.find((n) => n.uuid === uuid);\n if (node) {\n node.actions = newNode.actions;\n node.uuid = newNode.uuid;\n node.exits = newNode.exits;\n node.router = newNode.router;\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNodeUIConfig: (uuid: string, config: Record<string, any>) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui.nodes[uuid]) {\n // Handle type separately if provided\n if (config.type !== undefined) {\n state.flowDefinition._ui.nodes[uuid].type = config.type;\n }\n\n // Update config (excluding type)\n if (!state.flowDefinition._ui.nodes[uuid].config) {\n state.flowDefinition._ui.nodes[uuid].config = {};\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type, ...configWithoutType } = config;\n Object.assign(\n state.flowDefinition._ui.nodes[uuid].config,\n configWithoutType\n );\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateConnection: (\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ) => {\n /* console.log('Upating connection:', {\n nodeUuid,\n exitUuid,\n destinationNodeUuid\n });*/\n set((state: AppState) => {\n // Find the exit with this UUID\n const node = state.flowDefinition.nodes.find(\n (node) => node.uuid === nodeUuid\n );\n\n const exit = node?.exits.find((e) => e.uuid === exitUuid);\n if (exit) {\n // Update the destination\n exit.destination_uuid = destinationNodeUuid;\n state.dirtyDate = new Date();\n }\n });\n },\n\n updateStickyNote: (uuid: string, sticky: StickyNote) => {\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n state.flowDefinition._ui.stickies[uuid] = sticky;\n state.dirtyDate = new Date();\n });\n },\n\n createStickyNote: (position: FlowPosition): string => {\n const uuid = generateUUID();\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n\n const newSticky: StickyNote = {\n position,\n title: '',\n body: '',\n color: 'yellow'\n };\n\n state.flowDefinition._ui.stickies[uuid] = newSticky;\n state.dirtyDate = new Date();\n });\n return uuid;\n },\n\n createNode: (nodeType: string, position: FlowPosition): string => {\n const uuid = generateUUID();\n const exitUuid = generateUUID();\n\n set((state: AppState) => {\n // Create a basic node with a single exit\n const newNode: Node = {\n uuid,\n actions: [],\n exits: [\n {\n uuid: exitUuid,\n destination_uuid: null\n }\n ]\n };\n\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(newNode);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[uuid] = {\n position,\n type: nodeType as any,\n config: {}\n };\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n\n return uuid;\n },\n\n addNode: (node: Node, nodeUI: NodeUI) => {\n set((state: AppState) => {\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(node);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[node.uuid] = nodeUI;\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n updateLocalization: (\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ) => {\n set((state: AppState) => {\n // Initialize localization structure if it doesn't exist\n if (!state.flowDefinition.localization) {\n state.flowDefinition.localization = {};\n }\n\n if (!state.flowDefinition.localization[languageCode]) {\n state.flowDefinition.localization[languageCode] = {};\n }\n\n // Update or remove the localization for this action\n if (Object.keys(localizationData).length > 0) {\n state.flowDefinition.localization[languageCode][actionUuid] =\n localizationData;\n } else {\n // If no localized values, remove the entry\n delete state.flowDefinition.localization[languageCode][actionUuid];\n }\n\n // Clean up empty language sections\n if (\n Object.keys(state.flowDefinition.localization[languageCode])\n .length === 0\n ) {\n delete state.flowDefinition.localization[languageCode];\n }\n\n // Clean up empty localization object\n if (Object.keys(state.flowDefinition.localization).length === 0) {\n delete state.flowDefinition.localization;\n }\n\n state.dirtyDate = new Date();\n });\n },\n\n setTranslationFilters: (filters: { categories: boolean }) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n const currentFilters = state.flowDefinition._ui\n .translation_filters || {\n categories: false\n };\n\n state.flowDefinition._ui.translation_filters = {\n ...currentFilters,\n categories: !!filters.categories\n };\n\n state.dirtyDate = new Date();\n });\n },\n\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n if (!state.flowDefinition._ui.auto_translations) {\n state.flowDefinition._ui.auto_translations = {};\n }\n\n if (!state.flowDefinition._ui.auto_translations[languageCode]) {\n state.flowDefinition._ui.auto_translations[languageCode] = {};\n }\n\n const existing =\n state.flowDefinition._ui.auto_translations[languageCode][uuid] ||\n [];\n\n const merged = Array.from(\n new Set([...existing, ...(attributes || [])])\n );\n\n state.flowDefinition._ui.auto_translations[languageCode][uuid] =\n merged;\n state.dirtyDate = new Date();\n });\n }\n }))\n )\n);\n\ntype SelectorAwareStoreApi<S extends object> = StoreApi<S> & {\n subscribe: <U>(\n selector: (state: S) => U,\n listener: (value: U, previous: U) => void\n ) => () => void;\n};\n\n/**\n * Custom Lit property decorator that binds a property to a Zustand store subscription.\n *\n * @param store - The Zustand store to subscribe to.\n * @param selector - A function selecting the slice of state to bind to the property.\n */\nexport function fromStore<S extends object, V = unknown>(\n store: SelectorAwareStoreApi<S>,\n selector: (state: S) => V\n): PropertyDecorator {\n return (proto: any, name: string | symbol) => {\n property()(proto, name as string);\n\n const connectedKey = 'connectedCallback';\n const disconnectedKey = 'disconnectedCallback';\n\n const userConnected = proto[connectedKey];\n const userDisconnected = proto[disconnectedKey];\n\n proto[connectedKey] = function () {\n this._zustandUnsubscribe ??= {};\n this[name] = selector(store.getState());\n\n this._zustandUnsubscribe[name] = store.subscribe(selector, (val: V) => {\n this[name] = val;\n });\n\n if (userConnected) userConnected.call(this);\n };\n\n proto[disconnectedKey] = function () {\n this._zustandUnsubscribe?.[name]?.();\n if (userDisconnected) userDisconnected.call(this);\n };\n };\n}\n"]}
1
+ {"version":3,"file":"AppState.js","sourceRoot":"","sources":["../../../src/store/AppState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAY,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAWtD,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACxC,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,SAAS,uBAAuB,CAAC,UAA0B;;IACzD,IAAI,CAAC,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,KAAK,CAAA,IAAI,CAAC,CAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,GAAG,0CAAE,KAAK,CAAA;QAAE,OAAO;IAE1D,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,MAAM,iBAAiB,GAAG,MAAA,IAAI,CAAC,OAAO,0CAAE,IAAI,CAC1C,CAAC,MAAM,EAAE,EAAE,CAAE,MAAc,CAAC,QAAQ,KAAK,IAAI,CAC9C,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,IAAI,iBAAiB,EAAE,CAAC;YAC3D,MAAM,CAAC,IAAI,GAAG,UAAiB,CAAC;QAClC,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAM,UAAkB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACrE,MAAM,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAClC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,wBAAwB,CAAC,UAA0B;;IAC1D,IAAI,CAAC,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,KAAK,CAAA,IAAI,CAAC,CAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,GAAG,0CAAE,KAAK,CAAA;QAAE,OAAO;IAE1D,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAmB;YAAE,SAAS;QAE7D,MAAM,IAAI,GAAG,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,IAAI,0CAAE,IAAI,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,GAAG,eAAsB,CAAC;QACvC,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,GAAG,iBAAwB,CAAC;QACzC,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,GAAG,gBAAuB,CAAC;QACxC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,KAAa,EACb,aAAqC;IAErC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;;QAClB,MAAM,IAAI,GAAG,MAAA,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,0CAAE,QAAQ,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAA,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,0CAAE,QAAQ,CAAC;QAE7C,wDAAwD;QACxD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC;QACX,CAAC;QAED,wBAAwB;QACxB,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QAC7B,CAAC;QAED,iCAAiC;QACjC,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AA2CD,SAAS,cAAc,CAAC,SAAsB,EAAE;IAI9C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YACzD,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACnD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAkGD,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,EAAY,CAC5C,qBAAqB,CACnB,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACnB,aAAa,EAAE,EAAE;IACjB,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IACnC,YAAY,EAAE,EAAE;IAChB,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,IAAI;IACpB,QAAQ,EAAE,IAAI;IACd,YAAY,EAAE,IAAI,GAAG,EAAE;IACvB,cAAc,EAAE,IAAI,GAAG,EAAE;IACzB,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,KAAK;IACtB,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,iBAAiB,EAAE,IAAI;IACvB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,KAAK;IAEtB,YAAY,EAAE,CAAC,IAAU,EAAE,EAAE;QAC3B,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,aAAa,EAAE,KAAK,EAAE,QAAgB,EAAE,KAAa,IAAI,EAAE,EAAE;;QAC3D,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,QAAQ,CAAC;QAChD,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,EAAE,GAAG,QAAQ,CAAC;QAChB,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,QAAQ,IAAI,EAAE,aAAa,iBAAiB,EAAE,CAClD,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiB,CAAC;QACrD,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,wBAAwB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,cAAc,CAAC,MAAA,IAAI,CAAC,IAAI,0CAAE,MAAM,CAAC,CAAC;QACpD,GAAG,CAAC;YACF,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,cAAc,EAAE,IAAI,CAAC,UAAU;YAC/B,eAAe;YACf,YAAY,EAAE,SAAS,CAAC,MAAM;YAC9B,cAAc,EAAE,SAAS,CAAC,QAAQ;SACnC,CAAC,CAAC;IACL,CAAC;IAED,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACpC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE7C,yCAAyC;QACzC,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,UAClC,SAAc,EACd,MAAW;YAEX,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,EAAE,CAAC,CAAC;QAEJ,GAAG,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,mBAAmB,EAAE,CAAC,QAAgB,EAAE,EAAE;QACxC,GAAG,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,aAAa,EAAE,KAAK,EAAE,QAAgB,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,cAAc,EAAE,CAAC,QAAkB,EAAE,EAAE;QACrC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpB,CAAC;IAED,uBAAuB,EAAE,CAAC,QAAkB,EAAE,EAAE;QAC9C,GAAG,CAAC,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,kBAAkB,EAAE,CAAC,MAAe,EAAE,EAAE;QACtC,GAAG,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,kBAAkB,EAAE,GAAG,EAAE;QACvB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC1E,CAAC;IAED,cAAc,EAAE,GAAG,EAAE;QACnB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,cAAc,EAAE,CAAC,EAAO,EAAE,EAAE;QAC1B,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;QACvC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,WAAW,EAAE,GAAG,EAAE;QAChB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IACnE,CAAC;IAED,aAAa,EAAE,GAAG,EAAE;QAClB,GAAG,CAAC;YACF,cAAc,EAAE,IAAI;YACpB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI,GAAG,EAAE;YACvB,cAAc,EAAE,IAAI,GAAG,EAAE;YACzB,QAAQ,EAAE,IAAI;YACd,iBAAiB,EAAE,IAAI;YACvB,eAAe,EAAE,KAAK;YACtB,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,KAAK;SACvB,CAAC,CAAC;IACL,CAAC;IAED,mDAAmD;IACnD,eAAe,EAAE,CAAC,IAAkB,EAAE,EAAE;QACtC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC1C,sCAAsC;YACtC,KAAK,CAAC,cAAc,GAAG;gBACrB,GAAG,IAAI,CAAC,UAAU;gBAClB,KAAK,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;aAC1C,CAAC;YACF,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;YAC3B,MAAM,SAAS,GAAG,cAAc,CAAC,MAAA,IAAI,CAAC,IAAI,0CAAE,MAAM,CAAC,CAAC;YACpD,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC;YACtC,KAAK,CAAC,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC;YAC1C,+DAA+D;YAC/D,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC;YAC9B,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;YAE5B,uBAAuB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAC9C,wBAAwB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAE/C,2CAA2C;YAC3C,IAAI,CAAA,MAAA,KAAK,CAAC,cAAc,0CAAE,KAAK,MAAI,MAAA,MAAA,KAAK,CAAC,cAAc,0CAAE,GAAG,0CAAE,KAAK,CAAA,EAAE,CAAC;gBACpE,mBAAmB,CACjB,KAAK,CAAC,cAAc,CAAC,KAAK,EAC1B,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAC/B,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,EAAE,CAAC,IAAc,EAAE,EAAE;QAC9B,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;YACtB,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,CAAC,CAAC;YAC/C,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC;YACtC,KAAK,CAAC,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,EAAE,CAAC,QAAgB,EAAE,EAAE;QAChC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,KAAK,CAAC,cAAc,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,eAAe,EAAE,CAAC,YAAoB,EAAE,EAAE;QACxC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;YAClC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,QAAQ,KAAK,YAAY,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,YAAY,EAAE,CAAC,KAAa,EAAE,MAAc,EAAE,EAAE;QAC9C,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,KAAK,CAAC,UAAU,CAAC,KAAK,EACtB,KAAK,GAAG,cAAc,CACvB,CAAC;YACF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CACxB,KAAK,CAAC,UAAU,CAAC,MAAM,EACvB,MAAM,GAAG,cAAc,CACxB,CAAC;YAEF,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC;YAClC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,SAAS,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,qBAAqB,EAAE,CAAC,SAA0B,EAAE,EAAE;QACpD,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,kEAAkE;gBAClE,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;gBAClE,CAAC;gBAED,kCAAkC;qBAC7B,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjD,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ;wBAC9C,SAAS,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YAED,0DAA0D;YAC1D,mBAAmB,CACjB,KAAK,CAAC,cAAc,CAAC,KAAK,EAC1B,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAC/B,CAAC;YAEF,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,WAAW,EAAE,CAAC,KAAe,EAAE,EAAE;QAC/B,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC;YAED,KAAK,CAAC,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC7D,sEAAsE;gBACtE,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;oBAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAC9B,CAAC;oBAEF,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM;wBAAE,OAAO;oBAEtD,mDAAmD;oBACnD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK;yBACnC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC;yBACpC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;oBAE1B,mFAAmF;oBACnF,IACE,YAAY,CAAC,MAAM,KAAK,WAAW,CAAC,KAAK,CAAC,MAAM;wBAChD,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,EACtD,CAAC;wBACD,MAAM,iBAAiB,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;wBAC1C,oDAAoD;wBACpD,IAAI,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC;4BAAE,OAAO;wBAE9C,+DAA+D;wBAC/D,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;4BAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gCAC1B,IAAI,IAAI,CAAC,gBAAgB,KAAK,WAAW,EAAE,CAAC;oCAC1C,gEAAgE;oCAChE,IAAI,CAAC,gBAAgB,GAAG,iBAAiB,CAAC;gCAC5C,CAAC;4BACH,CAAC,CAAC,CAAC;wBACL,CAAC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,mBAAmB;gBACnB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAC9B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;gBAEF,yEAAyE;gBACzE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;oBAC3B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;wBAC1B,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;4BAC1C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;wBAC/B,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBAEH,yBAAyB;gBACzB,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB,EAAE,CAAC,KAAe,EAAE,EAAE;QACrC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;;YACtB,IAAI,MAAA,KAAK,CAAC,cAAc,CAAC,GAAG,0CAAE,QAAQ,EAAE,CAAC;gBACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,OAAO,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;YACD,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,UAAU,EAAE,CAAC,IAAY,EAAE,OAAa,EAAE,EAAE;QAC1C,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;;YACtB,MAAM,IAAI,GAAG,MAAA,KAAK,CAAC,cAAc,0CAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YACtE,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;gBAC/B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC/B,CAAC;YACD,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB,EAAE,CAAC,IAAY,EAAE,MAA2B,EAAE,EAAE;QAChE,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,qCAAqC;gBACrC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC9B,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;gBAC1D,CAAC;gBAED,iCAAiC;gBACjC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;oBACjD,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;gBACnD,CAAC;gBACD,6DAA6D;gBAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,EAAE,GAAG,MAAM,CAAC;gBAC9C,MAAM,CAAC,MAAM,CACX,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAC3C,iBAAiB,CAClB,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,EAAE,CAChB,QAAgB,EAChB,QAAgB,EAChB,mBAA2B,EAC3B,EAAE;QACF;;;;aAIK;QACL,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,+BAA+B;YAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAC1C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CACjC,CAAC;YAEF,MAAM,IAAI,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;YAC1D,IAAI,IAAI,EAAE,CAAC;gBACT,yBAAyB;gBACzB,IAAI,CAAC,gBAAgB,GAAG,mBAAmB,CAAC;gBAC5C,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,EAAE,CAAC,IAAY,EAAE,MAAkB,EAAE,EAAE;QACrD,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACvC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;YACzC,CAAC;YACD,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YACjD,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,EAAE,CAAC,QAAsB,EAAU,EAAE;QACnD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACvC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;YACzC,CAAC;YAED,MAAM,SAAS,GAAe;gBAC5B,QAAQ;gBACR,KAAK,EAAE,EAAE;gBACT,IAAI,EAAE,EAAE;gBACR,KAAK,EAAE,QAAQ;aAChB,CAAC;YAEF,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;YACpD,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,EAAE,CAAC,QAAgB,EAAE,QAAsB,EAAU,EAAE;QAC/D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAEhC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,yCAAyC;YACzC,MAAM,OAAO,GAAS;gBACpB,IAAI;gBACJ,OAAO,EAAE,EAAE;gBACX,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,QAAQ;wBACd,gBAAgB,EAAE,IAAI;qBACvB;iBACF;aACF,CAAC;YAEF,sCAAsC;YACtC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEzC,yBAAyB;YACzB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBACpC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC;YACtC,CAAC;YAED,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;gBACrC,QAAQ;gBACR,IAAI,EAAE,QAAe;gBACrB,MAAM,EAAE,EAAE;aACX,CAAC;YAEF,yBAAyB;YACzB,mBAAmB,CACjB,KAAK,CAAC,cAAc,CAAC,KAAK,EAC1B,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAC/B,CAAC;YAEF,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,IAAU,EAAE,MAAc,EAAE,EAAE;QACtC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,sCAAsC;YACtC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEtC,yBAAyB;YACzB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBACpC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC;YACtC,CAAC;YAED,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YAEnD,yBAAyB;YACzB,mBAAmB,CACjB,KAAK,CAAC,cAAc,CAAC,KAAK,EAC1B,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAC/B,CAAC;YAEF,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB,EAAE,CAClB,YAAoB,EACpB,UAAkB,EAClB,gBAAqC,EACrC,EAAE;QACF,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;YACtB,wDAAwD;YACxD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;gBACvC,KAAK,CAAC,cAAc,CAAC,YAAY,GAAG,EAAE,CAAC;YACzC,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;gBACrD,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;YACvD,CAAC;YAED,oDAAoD;YACpD,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7C,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC;oBACzD,gBAAgB,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,OAAO,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,CAAC;YACrE,CAAC;YAED,mCAAmC;YACnC,IACE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;iBACzD,MAAM,KAAK,CAAC,EACf,CAAC;gBACD,OAAO,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YACzD,CAAC;YAED,qCAAqC;YACrC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChE,OAAO,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC;YAC3C,CAAC;YAED,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,qBAAqB,EAAE,CAAC,OAAgC,EAAE,EAAE;QAC1D,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;;YACtB,IAAI,CAAC,CAAA,MAAA,KAAK,CAAC,cAAc,0CAAE,GAAG,CAAA,EAAE,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG;iBAC5C,mBAAmB,IAAI;gBACxB,UAAU,EAAE,KAAK;aAClB,CAAC;YAEF,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,mBAAmB,GAAG;gBAC7C,GAAG,cAAc;gBACjB,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU;aACjC,CAAC;YAEF,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kBAAkB,EAAE,CAClB,YAAoB,EACpB,IAAY,EACZ,UAAoB,EACpB,EAAE;QACF,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE;;YACtB,IAAI,CAAC,CAAA,MAAA,KAAK,CAAC,cAAc,0CAAE,GAAG,CAAA,EAAE,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;gBAChD,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,GAAG,EAAE,CAAC;YAClD,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC9D,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;YAChE,CAAC;YAED,MAAM,QAAQ,GACZ,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC;gBAC9D,EAAE,CAAC;YAEL,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CACvB,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,CAC9C,CAAC;YAEF,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC;gBAC5D,MAAM,CAAC;YACT,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC,CACJ,CACF,CAAC;AASF;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,KAA+B,EAC/B,QAAyB;IAEzB,OAAO,CAAC,KAAU,EAAE,IAAqB,EAAE,EAAE;QAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAc,CAAC,CAAC;QAElC,MAAM,YAAY,GAAG,mBAAmB,CAAC;QACzC,MAAM,eAAe,GAAG,sBAAsB,CAAC;QAE/C,MAAM,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,gBAAgB,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;QAEhD,KAAK,CAAC,YAAY,CAAC,GAAG;;YACpB,MAAA,IAAI,CAAC,mBAAmB,oCAAxB,IAAI,CAAC,mBAAmB,GAAK,EAAE,EAAC;YAChC,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAExC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAM,EAAE,EAAE;gBACpE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;YACnB,CAAC,CAAC,CAAC;YAEH,IAAI,aAAa;gBAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC;QAEF,KAAK,CAAC,eAAe,CAAC,GAAG;;YACvB,MAAA,MAAA,IAAI,CAAC,mBAAmB,0CAAG,IAAI,CAAC,kDAAI,CAAC;YACrC,IAAI,gBAAgB;gBAAE,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { createStore, StoreApi } from 'zustand/vanilla';\nimport { fetchResults, generateUUID } from '../utils';\nimport {\n Action,\n Exit,\n FlowDefinition,\n FlowPosition,\n Node,\n NodeUI,\n Router,\n StickyNote\n} from './flow-definition';\nimport { immer } from 'zustand/middleware/immer';\nimport { subscribeWithSelector } from 'zustand/middleware';\nimport { property } from 'lit/decorators.js';\nimport { produce } from 'immer';\n\nexport const FLOW_SPEC_VERSION = '14.3';\nconst CANVAS_PADDING = 800;\n\n/**\n * Temporary: Reclassify nodes based on whether they contain terminal actions.\n * - execute_actions nodes with a terminal action become \"terminal\"\n * - terminal nodes that no longer have a terminal action become \"execute_actions\"\n * This can be removed once we stop supporting terminal nodes.\n */\nfunction reclassifyTerminalNodes(definition: FlowDefinition): void {\n if (!definition?.nodes || !definition?._ui?.nodes) return;\n\n for (const node of definition.nodes) {\n const nodeUI = definition._ui.nodes[node.uuid];\n if (!nodeUI) continue;\n\n const hasTerminalAction = node.actions?.some(\n (action) => (action as any).terminal === true\n );\n\n if (nodeUI.type === 'execute_actions' && hasTerminalAction) {\n nodeUI.type = 'terminal' as any;\n } else if (nodeUI.type === ('terminal' as any) && !hasTerminalAction) {\n nodeUI.type = 'execute_actions';\n }\n }\n}\n\n/**\n * Reclassify wait_for_response nodes that are actually voice-specific wait types.\n * The server stores all voice waits as wait_for_response, but we detect the specific\n * type from the router's wait hint:\n * - hint.type === 'digits' && hint.count === 1 → wait_for_menu\n * - hint.type === 'digits' (no count) → wait_for_digits\n * - hint.type === 'audio' → wait_for_audio\n */\nfunction reclassifyVoiceWaitNodes(definition: FlowDefinition): void {\n if (!definition?.nodes || !definition?._ui?.nodes) return;\n\n for (const node of definition.nodes) {\n const nodeUI = definition._ui.nodes[node.uuid];\n if (!nodeUI || nodeUI.type !== 'wait_for_response') continue;\n\n const hint = node.router?.wait?.hint;\n if (!hint) continue;\n\n if (hint.type === 'digits' && hint.count === 1) {\n nodeUI.type = 'wait_for_menu' as any;\n } else if (hint.type === 'digits') {\n nodeUI.type = 'wait_for_digits' as any;\n } else if (hint.type === 'audio') {\n nodeUI.type = 'wait_for_audio' as any;\n }\n }\n}\n\n/**\n * Sorts nodes by their position - first by y (top), then by x (left)\n */\nfunction sortNodesByPosition(\n nodes: Node[],\n nodePositions: Record<string, NodeUI>\n): void {\n nodes.sort((a, b) => {\n const posA = nodePositions[a.uuid]?.position;\n const posB = nodePositions[b.uuid]?.position;\n\n // if either position is missing, maintain current order\n if (!posA || !posB) {\n return 0;\n }\n\n // sort by y (top) first\n if (posA.top !== posB.top) {\n return posA.top - posB.top;\n }\n\n // if y is same, sort by x (left)\n return posA.left - posB.left;\n });\n}\n\nexport interface InfoResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface ObjectRef {\n uuid: string;\n name: string;\n}\n\nexport interface TypedObjectRef extends ObjectRef {\n type: string;\n}\n\nexport interface Language {\n code: string;\n name: string;\n}\n\nexport interface FlowIssue {\n type: string;\n node_uuid: string;\n action_uuid?: string;\n description: string;\n dependency?: {\n key: string;\n name: string;\n type: string;\n };\n}\n\nexport interface FlowInfo {\n results: InfoResult[];\n dependencies: TypedObjectRef[];\n counts: { nodes: number; languages: number };\n locals: string[];\n issues?: FlowIssue[];\n}\n\nfunction buildIssueMaps(issues: FlowIssue[] = []): {\n byNode: Map<string, FlowIssue[]>;\n byAction: Map<string, FlowIssue[]>;\n} {\n const byNode = new Map<string, FlowIssue[]>();\n const byAction = new Map<string, FlowIssue[]>();\n for (const issue of issues) {\n if (issue.action_uuid) {\n const actionList = byAction.get(issue.action_uuid) || [];\n actionList.push(issue);\n byAction.set(issue.action_uuid, actionList);\n } else {\n const nodeList = byNode.get(issue.node_uuid) || [];\n nodeList.push(issue);\n byNode.set(issue.node_uuid, nodeList);\n }\n }\n return { byNode, byAction };\n}\n\nexport interface FlowContents {\n definition: FlowDefinition;\n info: FlowInfo;\n}\n\nexport interface Workspace {\n anon: boolean;\n country: string;\n date_style: string;\n languages: string[];\n name: string;\n primary_language: string;\n timezone: string;\n uuid: string;\n}\n\nexport interface CanvasPositions {\n [uuid: string]: FlowPosition;\n}\n\nexport interface Activity {\n segments: { [exitToDestinationKey: string]: number };\n nodes: { [nodeUuid: string]: number };\n}\n\nexport interface AppState {\n flowDefinition: FlowDefinition;\n flowInfo: FlowInfo;\n issuesByNode: Map<string, FlowIssue[]>;\n issuesByAction: Map<string, FlowIssue[]>;\n\n languageCode: string;\n languageNames: { [code: string]: Language };\n workspace: Workspace;\n isTranslating: boolean;\n viewingRevision: boolean;\n\n dirtyDate: Date | null;\n\n canvasSize: { width: number; height: number };\n activity: Activity | null;\n simulatorActivity: Activity | null;\n activityEndpoint: string | null;\n simulatorActive: boolean;\n\n getCurrentActivity: () => Activity | null;\n fetchRevision: (endpoint: string, id?: string) => void;\n fetchWorkspace: (endpoint: string) => Promise<void>;\n fetchAllLanguages: (endpoint: string) => Promise<void>;\n fetchActivity: (endpoint: string) => Promise<void>;\n setActivityEndpoint: (endpoint: string) => void;\n updateActivity: (activity: Activity) => void;\n updateSimulatorActivity: (activity: Activity) => void;\n setSimulatorActive: (active: boolean) => void;\n\n getFlowResults: () => InfoResult[];\n getResultByKey(id: any): InfoResult;\n\n setFlowContents: (flow: FlowContents) => void;\n setFlowInfo: (info: FlowInfo) => void;\n setRevision: (revision: number) => void;\n setLanguageCode: (languageCode: string) => void;\n setDirtyDate: (date: Date) => void;\n expandCanvas: (width: number, height: number) => void;\n\n updateNode(\n uuid: string,\n node: { actions: Action[]; uuid: string; exits: Exit[]; router?: Router }\n ): unknown;\n updateNodeUIConfig(uuid: string, config: Record<string, any>): unknown;\n updateConnection(\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ): unknown;\n updateCanvasPositions: (positions: CanvasPositions) => void;\n removeNodes: (uuids: string[]) => void;\n removeStickyNotes: (uuids: string[]) => void;\n updateStickyNote(uuid: string, sticky: StickyNote): void;\n createStickyNote(position: FlowPosition): string;\n createNode(nodeType: string, position: FlowPosition): string;\n addNode(node: Node, nodeUI: NodeUI): void;\n updateLocalization(\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ): void;\n clearFlowData: () => void;\n setTranslationFilters: (filters: { categories: boolean }) => void;\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => void;\n}\n\nexport const zustand = createStore<AppState>()(\n subscribeWithSelector(\n immer((set, get) => ({\n languageNames: {},\n canvasSize: { width: 0, height: 0 },\n languageCode: '',\n workspace: null,\n flowDefinition: null,\n flowInfo: null,\n issuesByNode: new Map(),\n issuesByAction: new Map(),\n isTranslating: false,\n viewingRevision: false,\n dirtyDate: null,\n activity: null,\n simulatorActivity: null,\n activityEndpoint: null,\n simulatorActive: false,\n\n setDirtyDate: (date: Date) => {\n set((state: AppState) => {\n state.dirtyDate = date;\n });\n },\n\n fetchRevision: async (endpoint: string, id: string = null) => {\n const viewingRevision = !!id && id !== 'latest';\n if (!id) {\n id = 'latest';\n }\n const response = await fetch(\n `${endpoint}/${id}/?version=${FLOW_SPEC_VERSION}`\n );\n\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = (await response.json()) as FlowContents;\n reclassifyTerminalNodes(data.definition);\n reclassifyVoiceWaitNodes(data.definition);\n const issueMaps = buildIssueMaps(data.info?.issues);\n set({\n flowInfo: data.info,\n flowDefinition: data.definition,\n viewingRevision,\n issuesByNode: issueMaps.byNode,\n issuesByAction: issueMaps.byAction\n });\n },\n\n fetchWorkspace: async (endpoint) => {\n const response = await fetch(endpoint);\n if (!response.ok) {\n throw new Error('Network response was not ok');\n }\n const data = await response.json();\n set({ workspace: data });\n },\n\n fetchAllLanguages: async (endpoint) => {\n const results = await fetchResults(endpoint);\n\n // convert array to map for easier lookup\n const allLanguages = results.reduce(function (\n languages: any,\n result: any\n ) {\n languages[result.value] = result.name;\n return languages;\n },\n {});\n\n set({ languageNames: allLanguages });\n },\n\n setActivityEndpoint: (endpoint: string) => {\n set({ activityEndpoint: endpoint });\n },\n\n fetchActivity: async (endpoint: string) => {\n try {\n const response = await fetch(endpoint);\n if (!response.ok) {\n return;\n }\n const data = await response.json();\n set({ activity: data });\n } catch (error) {\n console.error('Failed to fetch activity:', error);\n }\n },\n\n updateActivity: (activity: Activity) => {\n set({ activity });\n },\n\n updateSimulatorActivity: (activity: Activity) => {\n set({ simulatorActivity: activity });\n },\n\n setSimulatorActive: (active: boolean) => {\n set({ simulatorActive: active });\n },\n\n getCurrentActivity: () => {\n const state = get();\n return state.simulatorActive ? state.simulatorActivity : state.activity;\n },\n\n getFlowResults: () => {\n const state = get();\n return state.flowInfo.results;\n },\n\n getResultByKey: (id: any) => {\n const state = get();\n const results = state.flowInfo.results;\n return results.find((result) => result.key === id);\n },\n\n getLanguage: () => {\n const state = get();\n const languageCode = state.languageCode;\n const languageNames = state.languageNames;\n return { name: languageNames[languageCode], code: languageCode };\n },\n\n clearFlowData: () => {\n set({\n flowDefinition: null,\n flowInfo: null,\n issuesByNode: new Map(),\n issuesByAction: new Map(),\n activity: null,\n simulatorActivity: null,\n simulatorActive: false,\n dirtyDate: null,\n viewingRevision: false\n });\n },\n\n // todo: eventually we should be doing the fetching\n setFlowContents: (flow: FlowContents) => {\n set((state: AppState) => {\n const flowLang = flow.definition.language;\n // Clone to ensure mutable for sorting\n state.flowDefinition = {\n ...flow.definition,\n nodes: [...(flow.definition.nodes || [])]\n };\n state.flowInfo = flow.info;\n const issueMaps = buildIssueMaps(flow.info?.issues);\n state.issuesByNode = issueMaps.byNode;\n state.issuesByAction = issueMaps.byAction;\n // Reset to the flow's default language when loading a new flow\n state.languageCode = flowLang;\n state.isTranslating = false;\n\n reclassifyTerminalNodes(state.flowDefinition);\n reclassifyVoiceWaitNodes(state.flowDefinition);\n\n // Sort nodes by position when loading flow\n if (state.flowDefinition?.nodes && state.flowDefinition?._ui?.nodes) {\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n }\n });\n },\n\n setFlowInfo: (info: FlowInfo) => {\n set((state: AppState) => {\n state.flowInfo = info;\n const issueMaps = buildIssueMaps(info?.issues);\n state.issuesByNode = issueMaps.byNode;\n state.issuesByAction = issueMaps.byAction;\n });\n },\n\n setRevision: (revision: number) => {\n set((state: AppState) => {\n state.flowDefinition.revision = revision;\n });\n },\n\n setLanguageCode: (languageCode: string) => {\n set((state: AppState) => {\n state.languageCode = languageCode;\n state.isTranslating = state.flowDefinition.language !== languageCode;\n });\n },\n\n expandCanvas: (width: number, height: number) => {\n set((state: AppState) => {\n const minWidth = Math.max(\n state.canvasSize.width,\n width + CANVAS_PADDING\n );\n const minHeight = Math.max(\n state.canvasSize.height,\n height + CANVAS_PADDING\n );\n\n state.canvasSize.width = minWidth;\n state.canvasSize.height = minHeight;\n });\n },\n\n updateCanvasPositions: (positions: CanvasPositions) => {\n set((state: AppState) => {\n for (const uuid in positions) {\n // todo: add nodes that are created and then moved, for now ignore\n if (state.flowDefinition._ui.nodes[uuid]) {\n state.flowDefinition._ui.nodes[uuid].position = positions[uuid];\n }\n\n // otherwise, it might be a sticky\n else if (state.flowDefinition._ui.stickies[uuid]) {\n state.flowDefinition._ui.stickies[uuid].position =\n positions[uuid];\n }\n }\n\n // Sort nodes by position since positions may have changed\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n removeNodes: (uuids: string[]) => {\n set((state: AppState) => {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.nodes[uuid];\n }\n\n state.flowDefinition = produce(state.flowDefinition, (draft) => {\n // For each node being removed, check if we should reroute connections\n uuids.forEach((removedUuid) => {\n const removedNode = draft.nodes.find(\n (n) => n.uuid === removedUuid\n );\n\n if (!removedNode || !removedNode.exits.length) return;\n\n // Get all destinations (filter out null/undefined)\n const destinations = removedNode.exits\n .map((exit) => exit.destination_uuid)\n .filter((dest) => dest);\n\n // Only proceed if all exits have destinations and they all point to the same place\n if (\n destinations.length === removedNode.exits.length &&\n destinations.every((dest) => dest === destinations[0])\n ) {\n const targetDestination = destinations[0];\n // Don't reroute if the target is also being removed\n if (uuids.includes(targetDestination)) return;\n\n // Find all nodes with exits pointing to the node being removed\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (exit.destination_uuid === removedUuid) {\n // Reroute to the same destination the removed node was going to\n exit.destination_uuid = targetDestination;\n }\n });\n });\n }\n });\n\n // Remove the nodes\n draft.nodes = draft.nodes.filter(\n (node) => !uuids.includes(node.uuid)\n );\n\n // Clear any remaining connections to removed nodes that weren't rerouted\n draft.nodes.forEach((node) => {\n node.exits.forEach((exit) => {\n if (uuids.includes(exit.destination_uuid)) {\n exit.destination_uuid = null;\n }\n });\n });\n\n // Sort nodes by position\n sortNodesByPosition(draft.nodes, draft._ui.nodes);\n });\n\n state.dirtyDate = new Date();\n });\n },\n\n removeStickyNotes: (uuids: string[]) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui?.stickies) {\n for (const uuid of uuids) {\n delete state.flowDefinition._ui.stickies[uuid];\n }\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNode: (uuid: string, newNode: Node) => {\n set((state: AppState) => {\n const node = state.flowDefinition?.nodes.find((n) => n.uuid === uuid);\n if (node) {\n node.actions = newNode.actions;\n node.uuid = newNode.uuid;\n node.exits = newNode.exits;\n node.router = newNode.router;\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateNodeUIConfig: (uuid: string, config: Record<string, any>) => {\n set((state: AppState) => {\n if (state.flowDefinition._ui.nodes[uuid]) {\n // Handle type separately if provided\n if (config.type !== undefined) {\n state.flowDefinition._ui.nodes[uuid].type = config.type;\n }\n\n // Update config (excluding type)\n if (!state.flowDefinition._ui.nodes[uuid].config) {\n state.flowDefinition._ui.nodes[uuid].config = {};\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { type, ...configWithoutType } = config;\n Object.assign(\n state.flowDefinition._ui.nodes[uuid].config,\n configWithoutType\n );\n }\n state.dirtyDate = new Date();\n });\n },\n\n updateConnection: (\n nodeUuid: string,\n exitUuid: string,\n destinationNodeUuid: string\n ) => {\n /* console.log('Upating connection:', {\n nodeUuid,\n exitUuid,\n destinationNodeUuid\n });*/\n set((state: AppState) => {\n // Find the exit with this UUID\n const node = state.flowDefinition.nodes.find(\n (node) => node.uuid === nodeUuid\n );\n\n const exit = node?.exits.find((e) => e.uuid === exitUuid);\n if (exit) {\n // Update the destination\n exit.destination_uuid = destinationNodeUuid;\n state.dirtyDate = new Date();\n }\n });\n },\n\n updateStickyNote: (uuid: string, sticky: StickyNote) => {\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n state.flowDefinition._ui.stickies[uuid] = sticky;\n state.dirtyDate = new Date();\n });\n },\n\n createStickyNote: (position: FlowPosition): string => {\n const uuid = generateUUID();\n set((state: AppState) => {\n if (!state.flowDefinition._ui.stickies) {\n state.flowDefinition._ui.stickies = {};\n }\n\n const newSticky: StickyNote = {\n position,\n title: '',\n body: '',\n color: 'yellow'\n };\n\n state.flowDefinition._ui.stickies[uuid] = newSticky;\n state.dirtyDate = new Date();\n });\n return uuid;\n },\n\n createNode: (nodeType: string, position: FlowPosition): string => {\n const uuid = generateUUID();\n const exitUuid = generateUUID();\n\n set((state: AppState) => {\n // Create a basic node with a single exit\n const newNode: Node = {\n uuid,\n actions: [],\n exits: [\n {\n uuid: exitUuid,\n destination_uuid: null\n }\n ]\n };\n\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(newNode);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[uuid] = {\n position,\n type: nodeType as any,\n config: {}\n };\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n\n return uuid;\n },\n\n addNode: (node: Node, nodeUI: NodeUI) => {\n set((state: AppState) => {\n // Add the node to the flow definition\n state.flowDefinition.nodes.push(node);\n\n // Set up UI for the node\n if (!state.flowDefinition._ui.nodes) {\n state.flowDefinition._ui.nodes = {};\n }\n\n state.flowDefinition._ui.nodes[node.uuid] = nodeUI;\n\n // Sort nodes by position\n sortNodesByPosition(\n state.flowDefinition.nodes,\n state.flowDefinition._ui.nodes\n );\n\n state.dirtyDate = new Date();\n });\n },\n\n updateLocalization: (\n languageCode: string,\n actionUuid: string,\n localizationData: Record<string, any>\n ) => {\n set((state: AppState) => {\n // Initialize localization structure if it doesn't exist\n if (!state.flowDefinition.localization) {\n state.flowDefinition.localization = {};\n }\n\n if (!state.flowDefinition.localization[languageCode]) {\n state.flowDefinition.localization[languageCode] = {};\n }\n\n // Update or remove the localization for this action\n if (Object.keys(localizationData).length > 0) {\n state.flowDefinition.localization[languageCode][actionUuid] =\n localizationData;\n } else {\n // If no localized values, remove the entry\n delete state.flowDefinition.localization[languageCode][actionUuid];\n }\n\n // Clean up empty language sections\n if (\n Object.keys(state.flowDefinition.localization[languageCode])\n .length === 0\n ) {\n delete state.flowDefinition.localization[languageCode];\n }\n\n // Clean up empty localization object\n if (Object.keys(state.flowDefinition.localization).length === 0) {\n delete state.flowDefinition.localization;\n }\n\n state.dirtyDate = new Date();\n });\n },\n\n setTranslationFilters: (filters: { categories: boolean }) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n const currentFilters = state.flowDefinition._ui\n .translation_filters || {\n categories: false\n };\n\n state.flowDefinition._ui.translation_filters = {\n ...currentFilters,\n categories: !!filters.categories\n };\n\n state.dirtyDate = new Date();\n });\n },\n\n markAutoTranslated: (\n languageCode: string,\n uuid: string,\n attributes: string[]\n ) => {\n set((state: AppState) => {\n if (!state.flowDefinition?._ui) {\n return;\n }\n\n if (!state.flowDefinition._ui.auto_translations) {\n state.flowDefinition._ui.auto_translations = {};\n }\n\n if (!state.flowDefinition._ui.auto_translations[languageCode]) {\n state.flowDefinition._ui.auto_translations[languageCode] = {};\n }\n\n const existing =\n state.flowDefinition._ui.auto_translations[languageCode][uuid] ||\n [];\n\n const merged = Array.from(\n new Set([...existing, ...(attributes || [])])\n );\n\n state.flowDefinition._ui.auto_translations[languageCode][uuid] =\n merged;\n state.dirtyDate = new Date();\n });\n }\n }))\n )\n);\n\ntype SelectorAwareStoreApi<S extends object> = StoreApi<S> & {\n subscribe: <U>(\n selector: (state: S) => U,\n listener: (value: U, previous: U) => void\n ) => () => void;\n};\n\n/**\n * Custom Lit property decorator that binds a property to a Zustand store subscription.\n *\n * @param store - The Zustand store to subscribe to.\n * @param selector - A function selecting the slice of state to bind to the property.\n */\nexport function fromStore<S extends object, V = unknown>(\n store: SelectorAwareStoreApi<S>,\n selector: (state: S) => V\n): PropertyDecorator {\n return (proto: any, name: string | symbol) => {\n property()(proto, name as string);\n\n const connectedKey = 'connectedCallback';\n const disconnectedKey = 'disconnectedCallback';\n\n const userConnected = proto[connectedKey];\n const userDisconnected = proto[disconnectedKey];\n\n proto[connectedKey] = function () {\n this._zustandUnsubscribe ??= {};\n this[name] = selector(store.getState());\n\n this._zustandUnsubscribe[name] = store.subscribe(selector, (val: V) => {\n this[name] = val;\n });\n\n if (userConnected) userConnected.call(this);\n };\n\n proto[disconnectedKey] = function () {\n this._zustandUnsubscribe?.[name]?.();\n if (userDisconnected) userDisconnected.call(this);\n };\n };\n}\n"]}
@@ -0,0 +1,9 @@
1
+ let _version = 'dev';
2
+ try {
3
+ _version = __TEMBA_COMPONENTS_VERSION__;
4
+ }
5
+ catch (_a) {
6
+ // not replaced by build tooling; keep default
7
+ }
8
+ export const TEMBA_COMPONENTS_VERSION = _version;
9
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAEA,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,IAAI,CAAC;IACH,QAAQ,GAAG,4BAA4B,CAAC;AAC1C,CAAC;AAAC,WAAM,CAAC;IACP,8CAA8C;AAChD,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,QAAQ,CAAC","sourcesContent":["declare const __TEMBA_COMPONENTS_VERSION__: string;\n\nlet _version = 'dev';\ntry {\n _version = __TEMBA_COMPONENTS_VERSION__;\n} catch {\n // not replaced by build tooling; keep default\n}\n\nexport const TEMBA_COMPONENTS_VERSION = _version;\n"]}
@@ -62,5 +62,40 @@ describe('add_contact_groups action config', () => {
62
62
  ]
63
63
  }, 'descriptive-group-names');
64
64
  });
65
+ describe('metadata stripping', () => {
66
+ it('should strip superfluous API metadata from groups', () => {
67
+ const formData = {
68
+ uuid: 'test-uuid',
69
+ groups: [
70
+ {
71
+ uuid: 'group-1',
72
+ name: 'VIP Customers',
73
+ query: 'status = vip',
74
+ status: 'ready',
75
+ count: 150,
76
+ system: false
77
+ },
78
+ {
79
+ uuid: 'group-2',
80
+ name: 'Beta Testers',
81
+ query: null,
82
+ status: 'ready',
83
+ count: 45,
84
+ system: false
85
+ }
86
+ ]
87
+ };
88
+ const action = add_contact_groups.fromFormData(formData);
89
+ expect(action.groups).to.have.lengthOf(2);
90
+ expect(action.groups[0]).to.deep.equal({
91
+ uuid: 'group-1',
92
+ name: 'VIP Customers'
93
+ });
94
+ expect(action.groups[1]).to.deep.equal({
95
+ uuid: 'group-2',
96
+ name: 'Beta Testers'
97
+ });
98
+ });
99
+ });
65
100
  });
66
101
  //# sourceMappingURL=add_contact_groups.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add_contact_groups.test.js","sourceRoot":"","sources":["../../../test/actions/add_contact_groups.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAE/E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;IAExE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;SACvC,EACf,cAAc,CACf,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE;gBAC1C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,wBAAwB,EAAE;gBACnD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE;aAC1C;SACY,EACf,iBAAiB,CAClB,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,wDAAwD;iBAC/D;gBACD;oBACE,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,sDAAsD;iBAC7D;aACF;SACY,EACf,kBAAkB,CACnB,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE;gBACvC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE;gBAC3C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE;gBACzC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE;gBAC7C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;aACrC;SACY,EACf,aAAa,CACd,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oCAAoC,EAAE;gBAC/D,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,sCAAsC,EAAE;gBACjE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,iCAAiC,EAAE;aAC7D;SACY,EACf,yBAAyB,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { add_contact_groups } from '../../src/flow/actions/add_contact_groups';\nimport { AddToGroup } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the add_contact_groups action configuration.\n */\ndescribe('add_contact_groups action config', () => {\n const helper = new ActionTest(add_contact_groups, 'add_contact_groups');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(add_contact_groups.name).to.equal('Add to Group');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'add_contact_groups',\n groups: [{ uuid: 'group-1', name: 'VIP Customers' }]\n } as AddToGroup,\n 'single-group'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'VIP Customers' },\n { uuid: 'group-2', name: 'Newsletter Subscribers' },\n { uuid: 'group-3', name: 'Beta Testers' }\n ]\n } as AddToGroup,\n 'multiple-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'add_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Very Long Group Name That Might Wrap to Multiple Lines'\n },\n {\n uuid: 'group-2',\n name: 'Another Extremely Long Group Name for Testing Layout'\n }\n ]\n } as AddToGroup,\n 'long-group-names'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Sales Team' },\n { uuid: 'group-2', name: 'Marketing Team' },\n { uuid: 'group-3', name: 'Support Team' },\n { uuid: 'group-4', name: 'Development Team' },\n { uuid: 'group-5', name: 'QA Team' }\n ]\n } as AddToGroup,\n 'many-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Customers - Premium Plan (Monthly)' },\n { uuid: 'group-2', name: 'Customers - Enterprise Plan (Annual)' },\n { uuid: 'group-3', name: 'Trial Users - 30 Day Free Trial' }\n ]\n } as AddToGroup,\n 'descriptive-group-names'\n );\n });\n});\n"]}
1
+ {"version":3,"file":"add_contact_groups.test.js","sourceRoot":"","sources":["../../../test/actions/add_contact_groups.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { add_contact_groups } from '../../src/flow/actions/add_contact_groups';\nimport { AddToGroup } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the add_contact_groups action configuration.\n */\ndescribe('add_contact_groups action config', () => {\n const helper = new ActionTest(add_contact_groups, 'add_contact_groups');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(add_contact_groups.name).to.equal('Add to Group');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'add_contact_groups',\n groups: [{ uuid: 'group-1', name: 'VIP Customers' }]\n } as AddToGroup,\n 'single-group'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'VIP Customers' },\n { uuid: 'group-2', name: 'Newsletter Subscribers' },\n { uuid: 'group-3', name: 'Beta Testers' }\n ]\n } as AddToGroup,\n 'multiple-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'add_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Very Long Group Name That Might Wrap to Multiple Lines'\n },\n {\n uuid: 'group-2',\n name: 'Another Extremely Long Group Name for Testing Layout'\n }\n ]\n } as AddToGroup,\n 'long-group-names'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Sales Team' },\n { uuid: 'group-2', name: 'Marketing Team' },\n { uuid: 'group-3', name: 'Support Team' },\n { uuid: 'group-4', name: 'Development Team' },\n { uuid: 'group-5', name: 'QA Team' }\n ]\n } as AddToGroup,\n 'many-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'add_contact_groups',\n groups: [\n { uuid: 'group-1', name: 'Customers - Premium Plan (Monthly)' },\n { uuid: 'group-2', name: 'Customers - Enterprise Plan (Annual)' },\n { uuid: 'group-3', name: 'Trial Users - 30 Day Free Trial' }\n ]\n } as AddToGroup,\n 'descriptive-group-names'\n );\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from groups', () => {\n const formData = {\n uuid: 'test-uuid',\n groups: [\n {\n uuid: 'group-1',\n name: 'VIP Customers',\n query: 'status = vip',\n status: 'ready',\n count: 150,\n system: false\n },\n {\n uuid: 'group-2',\n name: 'Beta Testers',\n query: null,\n status: 'ready',\n count: 45,\n system: false\n }\n ]\n };\n\n const action = add_contact_groups.fromFormData(formData) as AddToGroup;\n\n expect(action.groups).to.have.lengthOf(2);\n expect(action.groups[0]).to.deep.equal({\n uuid: 'group-1',\n name: 'VIP Customers'\n });\n expect(action.groups[1]).to.deep.equal({\n uuid: 'group-2',\n name: 'Beta Testers'\n });\n });\n });\n});\n"]}
@@ -0,0 +1,53 @@
1
+ import { expect } from '@open-wc/testing';
2
+ import { add_input_labels } from '../../src/flow/actions/add_input_labels';
3
+ import { ActionTest } from '../ActionHelper';
4
+ /**
5
+ * Test suite for the add_input_labels action configuration.
6
+ */
7
+ describe('add_input_labels action config', () => {
8
+ const helper = new ActionTest(add_input_labels, 'add_input_labels');
9
+ describe('basic properties', () => {
10
+ helper.testBasicProperties();
11
+ it('has correct name', () => {
12
+ expect(add_input_labels.name).to.equal('Add Input Labels');
13
+ });
14
+ });
15
+ describe('action scenarios', () => {
16
+ helper.testAction({
17
+ uuid: 'test-action-1',
18
+ type: 'add_input_labels',
19
+ labels: [{ uuid: 'label-1', name: 'Important' }]
20
+ }, 'single-label');
21
+ helper.testAction({
22
+ uuid: 'test-action-2',
23
+ type: 'add_input_labels',
24
+ labels: [
25
+ { uuid: 'label-1', name: 'Important' },
26
+ { uuid: 'label-2', name: 'Follow Up' },
27
+ { uuid: 'label-3', name: 'Spam' }
28
+ ]
29
+ }, 'multiple-labels');
30
+ });
31
+ describe('metadata stripping', () => {
32
+ it('should strip superfluous API metadata from labels', () => {
33
+ const formData = {
34
+ uuid: 'test-uuid',
35
+ labels: [
36
+ { uuid: 'label-1', name: 'Important', count: 250 },
37
+ { uuid: 'label-2', name: 'Follow Up', count: 42 }
38
+ ]
39
+ };
40
+ const action = add_input_labels.fromFormData(formData);
41
+ expect(action.labels).to.have.lengthOf(2);
42
+ expect(action.labels[0]).to.deep.equal({
43
+ uuid: 'label-1',
44
+ name: 'Important'
45
+ });
46
+ expect(action.labels[1]).to.deep.equal({
47
+ uuid: 'label-2',
48
+ name: 'Follow Up'
49
+ });
50
+ });
51
+ });
52
+ });
53
+ //# sourceMappingURL=add_input_labels.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add_input_labels.test.js","sourceRoot":"","sources":["../../../test/actions/add_input_labels.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAE3E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAEpE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;SAC/B,EACnB,cAAc,CACf,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE;gBACtC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE;gBACtC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;aAClC;SACgB,EACnB,iBAAiB,CAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;YAC3D,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE;oBACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE;oBAClD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;iBAClD;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAmB,CAAC;YAEzE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBACrC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBACrC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { add_input_labels } from '../../src/flow/actions/add_input_labels';\nimport { AddInputLabels } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the add_input_labels action configuration.\n */\ndescribe('add_input_labels action config', () => {\n const helper = new ActionTest(add_input_labels, 'add_input_labels');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(add_input_labels.name).to.equal('Add Input Labels');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'add_input_labels',\n labels: [{ uuid: 'label-1', name: 'Important' }]\n } as AddInputLabels,\n 'single-label'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'add_input_labels',\n labels: [\n { uuid: 'label-1', name: 'Important' },\n { uuid: 'label-2', name: 'Follow Up' },\n { uuid: 'label-3', name: 'Spam' }\n ]\n } as AddInputLabels,\n 'multiple-labels'\n );\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from labels', () => {\n const formData = {\n uuid: 'test-uuid',\n labels: [\n { uuid: 'label-1', name: 'Important', count: 250 },\n { uuid: 'label-2', name: 'Follow Up', count: 42 }\n ]\n };\n\n const action = add_input_labels.fromFormData(formData) as AddInputLabels;\n\n expect(action.labels).to.have.lengthOf(2);\n expect(action.labels[0]).to.deep.equal({\n uuid: 'label-1',\n name: 'Important'\n });\n expect(action.labels[1]).to.deep.equal({\n uuid: 'label-2',\n name: 'Follow Up'\n });\n });\n });\n});\n"]}
@@ -0,0 +1,71 @@
1
+ import { expect } from '@open-wc/testing';
2
+ import { enter_flow } from '../../src/flow/actions/enter_flow';
3
+ import { ActionTest } from '../ActionHelper';
4
+ /**
5
+ * Test suite for the enter_flow action configuration.
6
+ */
7
+ describe('enter_flow action config', () => {
8
+ const helper = new ActionTest(enter_flow, 'enter_flow');
9
+ describe('basic properties', () => {
10
+ helper.testBasicProperties();
11
+ it('has correct name', () => {
12
+ expect(enter_flow.name).to.equal('Enter a Flow');
13
+ });
14
+ });
15
+ describe('action scenarios', () => {
16
+ helper.testAction({
17
+ uuid: 'test-action-1',
18
+ type: 'enter_flow',
19
+ terminal: true,
20
+ flow: { uuid: 'flow-1', name: 'Registration Flow' }
21
+ }, 'basic-flow');
22
+ helper.testAction({
23
+ uuid: 'test-action-2',
24
+ type: 'enter_flow',
25
+ terminal: true,
26
+ flow: {
27
+ uuid: 'flow-2',
28
+ name: 'Very Long Flow Name That Tests Layout Wrapping'
29
+ }
30
+ }, 'long-flow-name');
31
+ });
32
+ describe('metadata stripping', () => {
33
+ it('should strip superfluous API metadata from flow', () => {
34
+ const formData = {
35
+ uuid: 'test-uuid',
36
+ flow: [
37
+ {
38
+ uuid: 'flow-1',
39
+ name: 'Registration Flow',
40
+ type: 'message',
41
+ archived: false,
42
+ labels: [],
43
+ expires: 720,
44
+ runs: { active: 0, waiting: 5, completed: 100 },
45
+ results: [],
46
+ parent_refs: [],
47
+ created_on: '2024-01-01T00:00:00.000Z',
48
+ modified_on: '2024-06-15T12:00:00.000Z'
49
+ }
50
+ ]
51
+ };
52
+ const action = enter_flow.fromFormData(formData);
53
+ expect(action.flow).to.deep.equal({
54
+ uuid: 'flow-1',
55
+ name: 'Registration Flow'
56
+ });
57
+ });
58
+ it('should handle flow selected via value key', () => {
59
+ const formData = {
60
+ uuid: 'test-uuid',
61
+ flow: [{ value: 'flow-1', name: 'Test Flow' }]
62
+ };
63
+ const action = enter_flow.fromFormData(formData);
64
+ expect(action.flow).to.deep.equal({
65
+ uuid: 'flow-1',
66
+ name: 'Test Flow'
67
+ });
68
+ });
69
+ });
70
+ });
71
+ //# sourceMappingURL=enter_flow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enter_flow.test.js","sourceRoot":"","sources":["../../../test/actions/enter_flow.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;GAEG;AACH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAExD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE7B,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE;SACvC,EACd,YAAY,CACb,CAAC;QAEF,MAAM,CAAC,UAAU,CACf;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,gDAAgD;aACvD;SACW,EACd,gBAAgB,CACjB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE;oBACJ;wBACE,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,mBAAmB;wBACzB,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,KAAK;wBACf,MAAM,EAAE,EAAE;wBACV,OAAO,EAAE,GAAG;wBACZ,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;wBAC/C,OAAO,EAAE,EAAE;wBACX,WAAW,EAAE,EAAE;wBACf,UAAU,EAAE,0BAA0B;wBACtC,WAAW,EAAE,0BAA0B;qBACxC;iBACF;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAc,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBAChC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,mBAAmB;aAC1B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;aAC/C,CAAC;YAEF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAc,CAAC;YAE9D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;gBAChC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,WAAW;aAClB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { enter_flow } from '../../src/flow/actions/enter_flow';\nimport { EnterFlow } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the enter_flow action configuration.\n */\ndescribe('enter_flow action config', () => {\n const helper = new ActionTest(enter_flow, 'enter_flow');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(enter_flow.name).to.equal('Enter a Flow');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'enter_flow',\n terminal: true,\n flow: { uuid: 'flow-1', name: 'Registration Flow' }\n } as EnterFlow,\n 'basic-flow'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'enter_flow',\n terminal: true,\n flow: {\n uuid: 'flow-2',\n name: 'Very Long Flow Name That Tests Layout Wrapping'\n }\n } as EnterFlow,\n 'long-flow-name'\n );\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from flow', () => {\n const formData = {\n uuid: 'test-uuid',\n flow: [\n {\n uuid: 'flow-1',\n name: 'Registration Flow',\n type: 'message',\n archived: false,\n labels: [],\n expires: 720,\n runs: { active: 0, waiting: 5, completed: 100 },\n results: [],\n parent_refs: [],\n created_on: '2024-01-01T00:00:00.000Z',\n modified_on: '2024-06-15T12:00:00.000Z'\n }\n ]\n };\n\n const action = enter_flow.fromFormData(formData) as EnterFlow;\n\n expect(action.flow).to.deep.equal({\n uuid: 'flow-1',\n name: 'Registration Flow'\n });\n });\n\n it('should handle flow selected via value key', () => {\n const formData = {\n uuid: 'test-uuid',\n flow: [{ value: 'flow-1', name: 'Test Flow' }]\n };\n\n const action = enter_flow.fromFormData(formData) as EnterFlow;\n\n expect(action.flow).to.deep.equal({\n uuid: 'flow-1',\n name: 'Test Flow'\n });\n });\n });\n});\n"]}
@@ -222,5 +222,29 @@ describe('remove_contact_groups action config', () => {
222
222
  expect(Object.keys(result.errors)).to.have.length(0);
223
223
  });
224
224
  });
225
+ describe('metadata stripping', () => {
226
+ it('should strip superfluous API metadata from groups', () => {
227
+ const formData = {
228
+ uuid: 'test-uuid',
229
+ all_groups: false,
230
+ groups: [
231
+ {
232
+ uuid: 'group-1',
233
+ name: 'VIP Customers',
234
+ query: 'status = vip',
235
+ status: 'ready',
236
+ count: 150,
237
+ system: false
238
+ }
239
+ ]
240
+ };
241
+ const action = remove_contact_groups.fromFormData(formData);
242
+ expect(action.groups).to.have.lengthOf(1);
243
+ expect(action.groups[0]).to.deep.equal({
244
+ uuid: 'group-1',
245
+ name: 'VIP Customers'
246
+ });
247
+ });
248
+ });
225
249
  });
226
250
  //# sourceMappingURL=remove_contact_groups.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove_contact_groups.test.js","sourceRoot":"","sources":["../../../test/actions/remove_contact_groups.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { remove_contact_groups } from '../../src/flow/actions/remove_contact_groups';\nimport { RemoveFromGroup } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the remove_contact_groups action configuration.\n */\ndescribe('remove_contact_groups action config', () => {\n const helper = new ActionTest(remove_contact_groups, 'remove_contact_groups');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(remove_contact_groups.name).to.equal('Remove from Group');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'VIP Customers',\n status: 'ready',\n system: false,\n query: '',\n count: 150\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'single-group'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Newsletter Subscribers',\n status: 'ready',\n system: false,\n query: '',\n count: 1250\n },\n {\n uuid: 'group-2',\n name: 'Beta Testers',\n status: 'ready',\n system: false,\n query: '',\n count: 45\n },\n {\n uuid: 'group-3',\n name: 'Inactive Users',\n status: 'ready',\n system: false,\n query: '',\n count: 300\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'multiple-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'remove_contact_groups',\n groups: [],\n all_groups: true\n } as RemoveFromGroup,\n 'remove-from-all-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Customers - Premium Subscription (Annual Billing)',\n status: 'ready',\n system: false,\n query: '',\n count: 89\n },\n {\n uuid: 'group-2',\n name: 'Users - Trial Period Expired (30+ Days)',\n status: 'ready',\n system: false,\n query: '',\n count: 234\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'long-descriptive-group-names'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Sales Team',\n status: 'ready',\n system: false,\n query: '',\n count: 12\n },\n {\n uuid: 'group-2',\n name: 'Marketing Team',\n status: 'ready',\n system: false,\n query: '',\n count: 8\n },\n {\n uuid: 'group-3',\n name: 'Support Team',\n status: 'ready',\n system: false,\n query: '',\n count: 15\n },\n {\n uuid: 'group-4',\n name: 'Development Team',\n status: 'ready',\n system: false,\n query: '',\n count: 25\n },\n {\n uuid: 'group-5',\n name: 'QA Team',\n status: 'ready',\n system: false,\n query: '',\n count: 6\n },\n {\n uuid: 'group-6',\n name: 'Management Team',\n status: 'ready',\n system: false,\n query: '',\n count: 4\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'many-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-6',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Unsubscribed Users',\n status: 'ready',\n system: false,\n query: '',\n count: 567\n },\n {\n uuid: 'group-2',\n name: 'Bounced Email Addresses',\n status: 'ready',\n system: false,\n query: '',\n count: 89\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'cleanup-groups'\n );\n });\n\n describe('validation edge cases', () => {\n it('fails validation when no groups selected and all_groups is false', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: [],\n all_groups: false\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.false;\n expect(result.errors.groups).to.equal(\n 'At least one group must be selected or check \"Remove from All Groups\"'\n );\n });\n\n it('fails validation when groups is undefined and all_groups is false', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: undefined as any,\n all_groups: false\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.false;\n expect(result.errors.groups).to.equal(\n 'At least one group must be selected or check \"Remove from All Groups\"'\n );\n });\n\n it('passes validation when all_groups is true even with empty groups', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: [],\n all_groups: true\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.true;\n expect(Object.keys(result.errors)).to.have.length(0);\n });\n\n it('passes validation when groups are provided and all_groups is false', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Test Group',\n status: 'ready',\n system: false,\n query: '',\n count: 10\n }\n ],\n all_groups: false\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.true;\n expect(Object.keys(result.errors)).to.have.length(0);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"remove_contact_groups.test.js","sourceRoot":"","sources":["../../../test/actions/remove_contact_groups.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { remove_contact_groups } from '../../src/flow/actions/remove_contact_groups';\nimport { RemoveFromGroup } from '../../src/store/flow-definition';\nimport { ActionTest } from '../ActionHelper';\n\n/**\n * Test suite for the remove_contact_groups action configuration.\n */\ndescribe('remove_contact_groups action config', () => {\n const helper = new ActionTest(remove_contact_groups, 'remove_contact_groups');\n\n describe('basic properties', () => {\n helper.testBasicProperties();\n\n it('has correct name', () => {\n expect(remove_contact_groups.name).to.equal('Remove from Group');\n });\n });\n\n describe('action scenarios', () => {\n helper.testAction(\n {\n uuid: 'test-action-1',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'VIP Customers',\n status: 'ready',\n system: false,\n query: '',\n count: 150\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'single-group'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-2',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Newsletter Subscribers',\n status: 'ready',\n system: false,\n query: '',\n count: 1250\n },\n {\n uuid: 'group-2',\n name: 'Beta Testers',\n status: 'ready',\n system: false,\n query: '',\n count: 45\n },\n {\n uuid: 'group-3',\n name: 'Inactive Users',\n status: 'ready',\n system: false,\n query: '',\n count: 300\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'multiple-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-3',\n type: 'remove_contact_groups',\n groups: [],\n all_groups: true\n } as RemoveFromGroup,\n 'remove-from-all-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-4',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Customers - Premium Subscription (Annual Billing)',\n status: 'ready',\n system: false,\n query: '',\n count: 89\n },\n {\n uuid: 'group-2',\n name: 'Users - Trial Period Expired (30+ Days)',\n status: 'ready',\n system: false,\n query: '',\n count: 234\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'long-descriptive-group-names'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-5',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Sales Team',\n status: 'ready',\n system: false,\n query: '',\n count: 12\n },\n {\n uuid: 'group-2',\n name: 'Marketing Team',\n status: 'ready',\n system: false,\n query: '',\n count: 8\n },\n {\n uuid: 'group-3',\n name: 'Support Team',\n status: 'ready',\n system: false,\n query: '',\n count: 15\n },\n {\n uuid: 'group-4',\n name: 'Development Team',\n status: 'ready',\n system: false,\n query: '',\n count: 25\n },\n {\n uuid: 'group-5',\n name: 'QA Team',\n status: 'ready',\n system: false,\n query: '',\n count: 6\n },\n {\n uuid: 'group-6',\n name: 'Management Team',\n status: 'ready',\n system: false,\n query: '',\n count: 4\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'many-groups'\n );\n\n helper.testAction(\n {\n uuid: 'test-action-6',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Unsubscribed Users',\n status: 'ready',\n system: false,\n query: '',\n count: 567\n },\n {\n uuid: 'group-2',\n name: 'Bounced Email Addresses',\n status: 'ready',\n system: false,\n query: '',\n count: 89\n }\n ],\n all_groups: false\n } as RemoveFromGroup,\n 'cleanup-groups'\n );\n });\n\n describe('validation edge cases', () => {\n it('fails validation when no groups selected and all_groups is false', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: [],\n all_groups: false\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.false;\n expect(result.errors.groups).to.equal(\n 'At least one group must be selected or check \"Remove from All Groups\"'\n );\n });\n\n it('fails validation when groups is undefined and all_groups is false', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: undefined as any,\n all_groups: false\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.false;\n expect(result.errors.groups).to.equal(\n 'At least one group must be selected or check \"Remove from All Groups\"'\n );\n });\n\n it('passes validation when all_groups is true even with empty groups', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: [],\n all_groups: true\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.true;\n expect(Object.keys(result.errors)).to.have.length(0);\n });\n\n it('passes validation when groups are provided and all_groups is false', () => {\n const action: RemoveFromGroup = {\n uuid: 'test-action',\n type: 'remove_contact_groups',\n groups: [\n {\n uuid: 'group-1',\n name: 'Test Group',\n status: 'ready',\n system: false,\n query: '',\n count: 10\n }\n ],\n all_groups: false\n };\n\n const result = remove_contact_groups.validate(action);\n expect(result.valid).to.be.true;\n expect(Object.keys(result.errors)).to.have.length(0);\n });\n });\n\n describe('metadata stripping', () => {\n it('should strip superfluous API metadata from groups', () => {\n const formData = {\n uuid: 'test-uuid',\n all_groups: false,\n groups: [\n {\n uuid: 'group-1',\n name: 'VIP Customers',\n query: 'status = vip',\n status: 'ready',\n count: 150,\n system: false\n }\n ]\n };\n\n const action = remove_contact_groups.fromFormData(\n formData\n ) as RemoveFromGroup;\n\n expect(action.groups).to.have.lengthOf(1);\n expect(action.groups[0]).to.deep.equal({\n uuid: 'group-1',\n name: 'VIP Customers'\n });\n });\n });\n});\n"]}
@@ -148,6 +148,47 @@ describe('send_broadcast action config', () => {
148
148
  send_broadcast.sanitize(formData);
149
149
  expect(formData.text).to.equal('Test message');
150
150
  });
151
+ it('should strip superfluous API metadata from contacts and groups', () => {
152
+ const formData = {
153
+ uuid: 'test-uuid',
154
+ recipients: [
155
+ {
156
+ uuid: 'contact-1',
157
+ name: 'Alice',
158
+ status: 'active',
159
+ language: 'eng',
160
+ urns: ['tel:+250788123456'],
161
+ groups: [{ uuid: 'g-1', name: 'G1' }],
162
+ fields: { age: '30' },
163
+ created_on: '2024-01-01T00:00:00.000Z',
164
+ modified_on: '2024-06-15T12:00:00.000Z',
165
+ last_seen_on: '2024-06-14T10:00:00.000Z'
166
+ },
167
+ {
168
+ uuid: 'group-1',
169
+ name: 'Subscribers',
170
+ group: true,
171
+ query: null,
172
+ status: 'ready',
173
+ count: 500,
174
+ system: false
175
+ }
176
+ ],
177
+ text: 'Hello!',
178
+ attachments: []
179
+ };
180
+ const action = send_broadcast.fromFormData(formData);
181
+ expect(action.contacts).to.have.lengthOf(1);
182
+ expect(action.contacts[0]).to.deep.equal({
183
+ uuid: 'contact-1',
184
+ name: 'Alice'
185
+ });
186
+ expect(action.groups).to.have.lengthOf(1);
187
+ expect(action.groups[0]).to.deep.equal({
188
+ uuid: 'group-1',
189
+ name: 'Subscribers'
190
+ });
191
+ });
151
192
  });
152
193
  });
153
194
  //# sourceMappingURL=send_broadcast.test.js.map