@webex/contact-center 3.11.0 → 3.12.0-llmrefactor.2

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 (267) hide show
  1. package/.sdd/manifest.json +882 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +46 -0
  5. package/ai-docs/GETTING_STARTED.md +168 -0
  6. package/ai-docs/GLOSSARY.md +43 -0
  7. package/ai-docs/README.md +138 -0
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +444 -0
  10. package/ai-docs/SECURITY.md +52 -0
  11. package/ai-docs/SERVICE_STATE.md +48 -0
  12. package/ai-docs/SPEC_INDEX.md +65 -0
  13. package/ai-docs/adr/0001-spec-source-policy.md +55 -0
  14. package/ai-docs/adr/README.md +8 -0
  15. package/ai-docs/adr/_adr-template.md +31 -0
  16. package/ai-docs/contact-center-spec.md +341 -0
  17. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  18. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  19. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  20. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  21. package/ai-docs/patterns/testing-patterns.md +480 -0
  22. package/ai-docs/patterns/typescript-patterns.md +365 -0
  23. package/ai-docs/templates/README.md +102 -0
  24. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  25. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  26. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  27. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  28. package/ai-docs/templates/new-method/00-master.md +80 -0
  29. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  30. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  31. package/ai-docs/templates/new-method/03-tests.md +201 -0
  32. package/ai-docs/templates/new-method/04-validation.md +141 -0
  33. package/ai-docs/templates/new-service/00-master.md +109 -0
  34. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  35. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  36. package/ai-docs/templates/new-service/03-integration.md +178 -0
  37. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  38. package/ai-docs/templates/new-service/05-validation.md +145 -0
  39. package/dist/cc.js +379 -50
  40. package/dist/cc.js.map +1 -1
  41. package/dist/config.js +6 -0
  42. package/dist/config.js.map +1 -1
  43. package/dist/constants.js +22 -2
  44. package/dist/constants.js.map +1 -1
  45. package/dist/index.js +27 -5
  46. package/dist/index.js.map +1 -1
  47. package/dist/metrics/behavioral-events.js +114 -0
  48. package/dist/metrics/behavioral-events.js.map +1 -1
  49. package/dist/metrics/constants.js +32 -3
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/services/ApiAiAssistant.js +318 -0
  52. package/dist/services/ApiAiAssistant.js.map +1 -0
  53. package/dist/services/UserPreference.js +427 -0
  54. package/dist/services/UserPreference.js.map +1 -0
  55. package/dist/services/agent/types.js.map +1 -1
  56. package/dist/services/config/Util.js +8 -4
  57. package/dist/services/config/Util.js.map +1 -1
  58. package/dist/services/config/constants.js +35 -2
  59. package/dist/services/config/constants.js.map +1 -1
  60. package/dist/services/config/index.js +41 -2
  61. package/dist/services/config/index.js.map +1 -1
  62. package/dist/services/config/types.js +66 -8
  63. package/dist/services/config/types.js.map +1 -1
  64. package/dist/services/constants.js +27 -1
  65. package/dist/services/constants.js.map +1 -1
  66. package/dist/services/core/Err.js.map +1 -1
  67. package/dist/services/core/Utils.js +122 -25
  68. package/dist/services/core/Utils.js.map +1 -1
  69. package/dist/services/core/aqm-reqs.js +92 -17
  70. package/dist/services/core/aqm-reqs.js.map +1 -1
  71. package/dist/services/core/websocket/WebSocketManager.js +22 -6
  72. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  73. package/dist/services/core/websocket/connection-service.js +3 -1
  74. package/dist/services/core/websocket/connection-service.js.map +1 -1
  75. package/dist/services/core/websocket/types.js.map +1 -1
  76. package/dist/services/index.js +6 -0
  77. package/dist/services/index.js.map +1 -1
  78. package/dist/services/task/Task.js +688 -0
  79. package/dist/services/task/Task.js.map +1 -0
  80. package/dist/services/task/TaskFactory.js +45 -0
  81. package/dist/services/task/TaskFactory.js.map +1 -0
  82. package/dist/services/task/TaskManager.js +751 -457
  83. package/dist/services/task/TaskManager.js.map +1 -1
  84. package/dist/services/task/TaskUtils.js +220 -23
  85. package/dist/services/task/TaskUtils.js.map +1 -1
  86. package/dist/services/task/constants.js +23 -2
  87. package/dist/services/task/constants.js.map +1 -1
  88. package/dist/services/task/dialer.js +129 -0
  89. package/dist/services/task/dialer.js.map +1 -1
  90. package/dist/services/task/digital/Digital.js +77 -0
  91. package/dist/services/task/digital/Digital.js.map +1 -0
  92. package/dist/services/task/state-machine/TaskStateMachine.js +873 -0
  93. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  94. package/dist/services/task/state-machine/actions.js +567 -0
  95. package/dist/services/task/state-machine/actions.js.map +1 -0
  96. package/dist/services/task/state-machine/constants.js +161 -0
  97. package/dist/services/task/state-machine/constants.js.map +1 -0
  98. package/dist/services/task/state-machine/guards.js +382 -0
  99. package/dist/services/task/state-machine/guards.js.map +1 -0
  100. package/dist/services/task/state-machine/index.js +53 -0
  101. package/dist/services/task/state-machine/index.js.map +1 -0
  102. package/dist/services/task/state-machine/types.js +54 -0
  103. package/dist/services/task/state-machine/types.js.map +1 -0
  104. package/dist/services/task/state-machine/uiControlsComputer.js +603 -0
  105. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  106. package/dist/services/task/taskDataNormalizer.js +99 -0
  107. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  108. package/dist/services/task/types.js +227 -4
  109. package/dist/services/task/types.js.map +1 -1
  110. package/dist/services/task/voice/Voice.js +1044 -0
  111. package/dist/services/task/voice/Voice.js.map +1 -0
  112. package/dist/services/task/voice/WebRTC.js +149 -0
  113. package/dist/services/task/voice/WebRTC.js.map +1 -0
  114. package/dist/types/cc.d.ts +894 -0
  115. package/dist/types/config.d.ts +72 -0
  116. package/dist/types/constants.d.ts +66 -0
  117. package/dist/types/index.d.ts +199 -0
  118. package/dist/types/logger-proxy.d.ts +71 -0
  119. package/dist/types/metrics/MetricsManager.d.ts +223 -0
  120. package/dist/types/metrics/behavioral-events.d.ts +29 -0
  121. package/dist/types/metrics/constants.d.ts +181 -0
  122. package/dist/types/services/AddressBook.d.ts +74 -0
  123. package/dist/types/services/ApiAiAssistant.d.ts +49 -0
  124. package/dist/types/services/EntryPoint.d.ts +67 -0
  125. package/dist/types/services/Queue.d.ts +76 -0
  126. package/dist/types/services/UserPreference.d.ts +118 -0
  127. package/dist/types/services/WebCallingService.d.ts +1 -0
  128. package/dist/types/services/agent/index.d.ts +46 -0
  129. package/dist/types/services/agent/types.d.ts +413 -0
  130. package/dist/types/services/config/Util.d.ts +20 -0
  131. package/dist/types/services/config/constants.d.ts +270 -0
  132. package/dist/types/services/config/index.d.ts +177 -0
  133. package/dist/types/services/config/types.d.ts +1368 -0
  134. package/dist/types/services/constants.d.ts +110 -0
  135. package/dist/types/services/core/Err.d.ts +125 -0
  136. package/dist/types/services/core/GlobalTypes.d.ts +58 -0
  137. package/dist/types/services/core/Utils.d.ts +121 -0
  138. package/dist/types/services/core/WebexRequest.d.ts +22 -0
  139. package/dist/types/services/core/aqm-reqs.d.ts +65 -0
  140. package/dist/types/services/core/constants.d.ts +99 -0
  141. package/dist/types/services/core/types.d.ts +47 -0
  142. package/dist/types/services/core/websocket/WebSocketManager.d.ts +36 -0
  143. package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
  144. package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
  145. package/dist/types/services/core/websocket/types.d.ts +37 -0
  146. package/dist/types/services/index.d.ts +54 -0
  147. package/dist/types/services/task/AutoWrapup.d.ts +40 -0
  148. package/dist/types/services/task/Task.d.ts +157 -0
  149. package/dist/types/services/task/TaskFactory.d.ts +12 -0
  150. package/dist/types/services/task/TaskManager.d.ts +1 -0
  151. package/dist/types/services/task/TaskUtils.d.ts +138 -0
  152. package/dist/types/services/task/constants.d.ts +91 -0
  153. package/dist/types/services/task/contact.d.ts +69 -0
  154. package/dist/types/services/task/dialer.d.ts +73 -0
  155. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  156. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1194 -0
  157. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  158. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  159. package/dist/types/services/task/state-machine/guards.d.ts +102 -0
  160. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  161. package/dist/types/services/task/state-machine/types.d.ts +269 -0
  162. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  163. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  164. package/dist/types/services/task/types.d.ts +1856 -0
  165. package/dist/types/services/task/voice/Voice.d.ts +184 -0
  166. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  167. package/dist/types/types.d.ts +778 -0
  168. package/dist/types/utils/PageCache.d.ts +173 -0
  169. package/dist/types/webex-config.d.ts +53 -0
  170. package/dist/types/webex.d.ts +8 -0
  171. package/dist/types.js +130 -1
  172. package/dist/types.js.map +1 -1
  173. package/dist/webex.js +14 -2
  174. package/dist/webex.js.map +1 -1
  175. package/package.json +16 -12
  176. package/src/cc.ts +477 -51
  177. package/src/config.ts +6 -0
  178. package/src/constants.ts +21 -1
  179. package/src/index.ts +24 -5
  180. package/src/metrics/ai-docs/AGENTS.md +350 -0
  181. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  182. package/src/metrics/ai-docs/metrics-spec.md +854 -0
  183. package/src/metrics/behavioral-events.ts +120 -0
  184. package/src/metrics/constants.ts +37 -3
  185. package/src/services/ApiAiAssistant.ts +412 -0
  186. package/src/services/UserPreference.ts +509 -0
  187. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  188. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  189. package/src/services/agent/ai-docs/agent-spec.md +504 -0
  190. package/src/services/agent/types.ts +1 -1
  191. package/src/services/ai-docs/AGENTS.md +386 -0
  192. package/src/services/ai-docs/services-spec.md +492 -0
  193. package/src/services/config/Util.ts +10 -2
  194. package/src/services/config/ai-docs/AGENTS.md +255 -0
  195. package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
  196. package/src/services/config/ai-docs/config-spec.md +669 -0
  197. package/src/services/config/constants.ts +37 -1
  198. package/src/services/config/index.ts +45 -1
  199. package/src/services/config/types.ts +241 -11
  200. package/src/services/constants.ts +29 -0
  201. package/src/services/core/Err.ts +3 -0
  202. package/src/services/core/Utils.ts +143 -30
  203. package/src/services/core/ai-docs/AGENTS.md +381 -0
  204. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  205. package/src/services/core/ai-docs/core-spec.md +783 -0
  206. package/src/services/core/aqm-reqs.ts +100 -22
  207. package/src/services/core/websocket/WebSocketManager.ts +23 -6
  208. package/src/services/core/websocket/connection-service.ts +5 -1
  209. package/src/services/core/websocket/types.ts +1 -1
  210. package/src/services/index.ts +4 -0
  211. package/src/services/task/Task.ts +837 -0
  212. package/src/services/task/TaskFactory.ts +55 -0
  213. package/src/services/task/TaskManager.ts +793 -521
  214. package/src/services/task/TaskUtils.ts +314 -24
  215. package/src/services/task/ai-docs/AGENTS.md +457 -0
  216. package/src/services/task/ai-docs/ARCHITECTURE.md +594 -0
  217. package/src/services/task/ai-docs/task-spec.md +1319 -0
  218. package/src/services/task/constants.ts +23 -0
  219. package/src/services/task/dialer.ts +136 -1
  220. package/src/services/task/digital/Digital.ts +95 -0
  221. package/src/services/task/state-machine/TaskStateMachine.ts +1166 -0
  222. package/src/services/task/state-machine/actions.ts +738 -0
  223. package/src/services/task/state-machine/ai-docs/AGENTS.md +458 -0
  224. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1137 -0
  225. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2177 -0
  226. package/src/services/task/state-machine/constants.ts +172 -0
  227. package/src/services/task/state-machine/guards.ts +445 -0
  228. package/src/services/task/state-machine/index.ts +28 -0
  229. package/src/services/task/state-machine/types.ts +243 -0
  230. package/src/services/task/state-machine/uiControlsComputer.ts +961 -0
  231. package/src/services/task/taskDataNormalizer.ts +137 -0
  232. package/src/services/task/types.ts +734 -71
  233. package/src/services/task/voice/Voice.ts +1270 -0
  234. package/src/services/task/voice/WebRTC.ts +187 -0
  235. package/src/types.ts +205 -2
  236. package/src/utils/AGENTS.md +278 -0
  237. package/src/utils/ai-docs/utils-spec.md +381 -0
  238. package/src/webex.js +2 -0
  239. package/test/unit/spec/cc.ts +503 -43
  240. package/test/unit/spec/logger-proxy.ts +70 -0
  241. package/test/unit/spec/services/ApiAiAssistant.ts +273 -0
  242. package/test/unit/spec/services/UserPreference.ts +401 -0
  243. package/test/unit/spec/services/WebCallingService.ts +7 -1
  244. package/test/unit/spec/services/config/index.ts +85 -29
  245. package/test/unit/spec/services/core/Utils.ts +481 -2
  246. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +137 -41
  247. package/test/unit/spec/services/core/websocket/connection-service.ts +3 -1
  248. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  249. package/test/unit/spec/services/task/Task.ts +477 -0
  250. package/test/unit/spec/services/task/TaskFactory.ts +62 -0
  251. package/test/unit/spec/services/task/TaskManager.ts +1001 -1003
  252. package/test/unit/spec/services/task/TaskUtils.ts +235 -0
  253. package/test/unit/spec/services/task/dialer.ts +372 -96
  254. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  255. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +2651 -0
  256. package/test/unit/spec/services/task/state-machine/guards.ts +637 -0
  257. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  258. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2663 -0
  259. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  260. package/test/unit/spec/services/task/voice/Voice.ts +649 -0
  261. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  262. package/umd/contact-center.min.js +2 -2
  263. package/umd/contact-center.min.js.map +1 -1
  264. package/dist/services/task/index.js +0 -1525
  265. package/dist/services/task/index.js.map +0 -1
  266. package/src/services/task/index.ts +0 -1801
  267. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -0,0 +1,382 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldWrapUpForThisAgent = exports.isSelfConsultingAgent = exports.hasActiveConsultInPostCall = exports.guards = exports.getTaskDataFromEvent = exports.getSelfAgentId = void 0;
7
+ var _TaskUtils = require("../TaskUtils");
8
+ var _constants = require("./constants");
9
+ /**
10
+ * Task State Machine Guards
11
+ *
12
+ * Guard functions that determine if a state transition is allowed.
13
+ * These functions validate the current context before allowing transitions.
14
+ *
15
+ * All guards are consolidated here for:
16
+ * - Single source of truth
17
+ * - Easy testing
18
+ * - Reusability across state machine transitions
19
+ *
20
+ * Guards are organized by category:
21
+ * 1. Helper Functions - Extract data from events/context
22
+ * 2. Hydrate Guards - For state restoration on page refresh
23
+ * 3. Conference Guards - Conference state checks
24
+ * 4. Customer Guards - Customer presence checks
25
+ * 5. Consult Guards - Consult flow checks
26
+ * 6. Wrapup Guards - End-of-call flow checks
27
+ * 7. Server State Guards - Check backend-reported state
28
+ * 8. Recording Guards - Recording state checks
29
+ */
30
+
31
+ const getTaskDataFromEvent = event => event && typeof event === 'object' && 'taskData' in event ? event.taskData : undefined;
32
+ exports.getTaskDataFromEvent = getTaskDataFromEvent;
33
+ const getSelfAgentId = (context, taskData) => context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;
34
+ exports.getSelfAgentId = getSelfAgentId;
35
+ const isSelfConsultingAgent = (context, taskData) => {
36
+ const selfAgentId = getSelfAgentId(context, taskData);
37
+ if (!selfAgentId) return false;
38
+ return taskData?.consultingAgentId === selfAgentId;
39
+ };
40
+
41
+ /**
42
+ * Detects an active consult during post_call state (customer left but agents still consulting).
43
+ * Shared by hydration guard (isInteractionConsulting) and action (deriveTaskDataUpdates).
44
+ */
45
+ exports.isSelfConsultingAgent = isSelfConsultingAgent;
46
+ const hasActiveConsultInPostCall = (taskData, selfAgentId) => {
47
+ if (taskData?.interaction?.state !== _constants.INTERACTION_STATE.POST_CALL || !selfAgentId) return false;
48
+ const selfParticipant = taskData.interaction?.participants?.[selfAgentId];
49
+ const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(media => media?.mType === _constants.MEDIA_TYPE_CONSULT);
50
+ return selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING && hasConsultMedia;
51
+ };
52
+
53
+ /**
54
+ * Determines if this agent should enter WRAPPING_UP state.
55
+ * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted
56
+ */
57
+ exports.hasActiveConsultInPostCall = hasActiveConsultInPostCall;
58
+ const shouldWrapUpForThisAgent = (context, taskData) => {
59
+ const selfAgentId = getSelfAgentId(context, taskData);
60
+ if (!selfAgentId) return false;
61
+ const pending = taskData?.agentsPendingWrapUp;
62
+ if (Array.isArray(pending) && pending.length > 0) {
63
+ return pending.includes(selfAgentId);
64
+ }
65
+ const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;
66
+ const wrapUpRequired = taskData?.wrapUpRequired === true;
67
+ if (wrapUpRequired || participantWrapUp) {
68
+ return true;
69
+ }
70
+ const owner = taskData?.interaction?.owner;
71
+ if (owner && owner === selfAgentId) {
72
+ return true;
73
+ }
74
+ if (taskData?.isConsulted === false) {
75
+ return true;
76
+ }
77
+ return false;
78
+ };
79
+ exports.shouldWrapUpForThisAgent = shouldWrapUpForThisAgent;
80
+ const guards = exports.guards = {
81
+ // Hydrate Guards
82
+ isInteractionTerminated: ({
83
+ context,
84
+ event
85
+ }) => {
86
+ const taskData = getTaskDataFromEvent(event);
87
+ if (taskData?.interaction?.isTerminated === true) return true;
88
+ const selfAgentId = getSelfAgentId(context, taskData);
89
+ if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {
90
+ return true;
91
+ }
92
+ return false;
93
+ },
94
+ isInteractionConsulting: ({
95
+ event,
96
+ context
97
+ }) => {
98
+ const taskData = getTaskDataFromEvent(event);
99
+ if (taskData?.interaction?.state === _constants.INTERACTION_STATE.CONSULTING) return true;
100
+
101
+ // Hydrate can report interaction as conference/hold while this agent is actively consulting.
102
+ // Detect consult by participant consultState + consult media, independent of top-level state.
103
+ const selfAgentId = getSelfAgentId(context, taskData);
104
+ const selfParticipant = selfAgentId ? taskData?.interaction?.participants?.[selfAgentId] : null;
105
+ const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(media => media?.mType === _constants.MEDIA_TYPE_CONSULT);
106
+ const selfActiveConsult = selfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING;
107
+ const selfPendingConsultInitiated = selfParticipant?.consultState === 'consultInitiated' && taskData?.isConsulted === false;
108
+ if ((selfActiveConsult || selfPendingConsultInitiated) && hasConsultMedia) {
109
+ return true;
110
+ }
111
+
112
+ // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult
113
+ const cpd = taskData?.interaction?.callProcessingDetails;
114
+ if (cpd?.relationshipType === 'consult' && taskData?.interaction?.state === _constants.INTERACTION_STATE.CONNECTED) {
115
+ return true;
116
+ }
117
+
118
+ // Customer left during consult: interaction state is "post_call" but consult
119
+ // between agents is still active. Detect via agent's consultState + consult media.
120
+ if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {
121
+ return true;
122
+ }
123
+
124
+ // Customer left during consult: interaction state is "post_call" but consult
125
+ // between agents is still active. Detect via agent's consultState + consult media.
126
+ if (taskData?.interaction?.state === _constants.INTERACTION_STATE.POST_CALL) {
127
+ const postCallSelfAgentId = getSelfAgentId(context, taskData);
128
+ const postCallSelfParticipant = postCallSelfAgentId ? taskData?.interaction?.participants?.[postCallSelfAgentId] : null;
129
+ const hasPostCallConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(media => media?.mType === _constants.MEDIA_TYPE_CONSULT);
130
+ if (postCallSelfParticipant?.consultState === _constants.CONSULT_STATE.CONSULTING && hasPostCallConsultMedia) {
131
+ return true;
132
+ }
133
+ }
134
+ return false;
135
+ },
136
+ isEpDnPendingConferenceMergeHydrate: ({
137
+ event,
138
+ context
139
+ }) => {
140
+ const taskData = getTaskDataFromEvent(event);
141
+ return (0, _TaskUtils.isEpDnConsultPendingConferenceMerge)(taskData, getSelfAgentId(context, taskData));
142
+ },
143
+ isInteractionHeld: ({
144
+ event
145
+ }) => {
146
+ const taskData = getTaskDataFromEvent(event);
147
+ if (taskData?.interaction?.state === 'hold') return true;
148
+ const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;
149
+ if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {
150
+ return true;
151
+ }
152
+ return false;
153
+ },
154
+ isInteractionConnected: ({
155
+ event
156
+ }) => {
157
+ const taskData = getTaskDataFromEvent(event);
158
+ return taskData?.interaction?.state === _constants.INTERACTION_STATE.CONNECTED;
159
+ },
160
+ isConferencingByParticipants: ({
161
+ event
162
+ }) => {
163
+ const taskData = getTaskDataFromEvent(event);
164
+ if (!taskData) return false;
165
+ const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;
166
+ const media = taskData.interaction?.media?.[mainCallId];
167
+ const participants = taskData.interaction?.participants;
168
+ if (!media?.participants || !participants) return false;
169
+ let agentCount = 0;
170
+ for (const pId of media.participants) {
171
+ const p = participants[pId];
172
+ if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {
173
+ agentCount += 1;
174
+ }
175
+ }
176
+ return agentCount >= 2;
177
+ },
178
+ // Conference Guards
179
+ conferenceInProgressFromEvent: ({
180
+ event
181
+ }) => {
182
+ const taskData = getTaskDataFromEvent(event);
183
+ if (!taskData?.interaction) return false;
184
+ return (0, _TaskUtils.getIsConferenceInProgress)(taskData);
185
+ },
186
+ /**
187
+ * Conference hold signal for conference-downgraded consult-end transitions.
188
+ * Backend can report this as boolean or string.
189
+ */
190
+ isConferenceHoldParticipantFromEvent: ({
191
+ context,
192
+ event
193
+ }) => {
194
+ const taskData = getTaskDataFromEvent(event) ?? context.taskData;
195
+ const callProcessingDetails = taskData?.interaction?.callProcessingDetails;
196
+ const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant;
197
+ return conferenceHoldParticipant === true || conferenceHoldParticipant === 'true';
198
+ },
199
+ /**
200
+ * Conference downgrade check specifically for transitioning back to CONNECTED.
201
+ *
202
+ * Returns true only when:
203
+ * - conference has downgraded (fewer than 2 active agent participants in main call)
204
+ * - customer is still in the call
205
+ * - current agent is still in the main call
206
+ */
207
+ shouldDowngradeConferenceToConnected: ({
208
+ context,
209
+ event
210
+ }) => {
211
+ const eventTaskData = getTaskDataFromEvent(event);
212
+ const taskData = eventTaskData ?? context.taskData;
213
+ if (!taskData?.interaction) return false;
214
+ const selfAgentId = getSelfAgentId(context, taskData);
215
+ if (!selfAgentId) return false;
216
+ const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;
217
+ if (!mainCallId) return false;
218
+
219
+ // Don't downgrade while backend still reports conference.
220
+ if (taskData.interaction.state === _constants.INTERACTION_STATE.CONFERENCE) return false;
221
+ const agentParticipantsCount = (0, _TaskUtils.getConferenceParticipantsCount)(taskData.interaction, mainCallId);
222
+ if (agentParticipantsCount >= 2) return false;
223
+ const customerInCall = (0, _TaskUtils.getIsCustomerInCall)(taskData.interaction, mainCallId);
224
+ if (!customerInCall) return false;
225
+ const selfInMainCall = Boolean(taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId));
226
+ return selfInMainCall;
227
+ },
228
+ // Consult Guards
229
+ /**
230
+ * Check if this agent initiated the consult (using event data)
231
+ * Handles both consultingAgentId and fallback to context flag
232
+ */
233
+ didInitiateConsult: ({
234
+ context,
235
+ event
236
+ }) => {
237
+ const taskData = getTaskDataFromEvent(event);
238
+ if (taskData?.isConsulted === true) return false;
239
+ return taskData?.consultingAgentId ? isSelfConsultingAgent(context, taskData) : context.consultInitiator === true;
240
+ },
241
+ /**
242
+ * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding
243
+ * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).
244
+ */
245
+ isConsultingAssignment: ({
246
+ event
247
+ }) => {
248
+ const taskData = getTaskDataFromEvent(event);
249
+ if (!taskData) return false;
250
+ const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;
251
+ return taskData.isConsulted === true || relationshipType === 'consult' || taskData.interaction?.state === _constants.INTERACTION_STATE.CONSULTING;
252
+ },
253
+ // Wrapup Guards
254
+ isCampaignPreviewContactEnded: ({
255
+ context,
256
+ event
257
+ }) => {
258
+ if (event?.type !== _constants.TaskEvent.CONTACT_ENDED) {
259
+ return false;
260
+ }
261
+ const taskData = getTaskDataFromEvent(event);
262
+ if (!(0, _TaskUtils.isCampaignPreviewTask)(taskData)) {
263
+ return false;
264
+ }
265
+ const selfAgentId = getSelfAgentId(context, taskData);
266
+ const pending = taskData?.agentsPendingWrapUp;
267
+ const isPendingWrapUp = Array.isArray(pending) && !!selfAgentId && pending.includes(selfAgentId);
268
+ const participantIsWrapUp = !!selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;
269
+ const explicitWrapUp = taskData?.wrapUpRequired === true || participantIsWrapUp || isPendingWrapUp || taskData?.interaction?.state === 'wrapUp';
270
+ return !explicitWrapUp;
271
+ },
272
+ shouldWrapUp: ({
273
+ context,
274
+ event
275
+ }) => {
276
+ const taskData = getTaskDataFromEvent(event);
277
+ if (!taskData) return false;
278
+ if (event?.type === _constants.TaskEvent.CONFERENCE_END) {
279
+ const selfAgentId = getSelfAgentId(context, taskData);
280
+ if (!selfAgentId) return false;
281
+ const pending = taskData?.agentsPendingWrapUp;
282
+ if (Array.isArray(pending) && pending.length > 0) {
283
+ return pending.includes(selfAgentId);
284
+ }
285
+ const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;
286
+ const wrapUpRequired = taskData?.wrapUpRequired === true;
287
+ return wrapUpRequired || participantWrapUp;
288
+ }
289
+ return shouldWrapUpForThisAgent(context, taskData);
290
+ },
291
+ /**
292
+ * Check if wrapUpRequired in payload OR is consult initiator
293
+ */
294
+ shouldWrapUpOrIsInitiator: ({
295
+ context,
296
+ event
297
+ }) => {
298
+ const taskData = getTaskDataFromEvent(event);
299
+ return Boolean(taskData?.wrapUpRequired || context.consultInitiator);
300
+ },
301
+ /**
302
+ * True if PARTICIPANT_LEAVE indicates that *this* agent left the conference.
303
+ *
304
+ * Important: PARTICIPANT_LEAVE is broadcast to all agents in the conference.
305
+ * Only the agent whose id matches the leaving participant should transition to
306
+ * TERMINATED / WRAPPING_UP based on wrapup rules.
307
+ */
308
+ didCurrentAgentLeaveConference: ({
309
+ context,
310
+ event
311
+ }) => {
312
+ const taskData = getTaskDataFromEvent(event);
313
+ const selfAgentId = getSelfAgentId(context, taskData);
314
+ if (!selfAgentId) return false;
315
+ const participantIdFromEvent = event && typeof event === 'object' && 'participantId' in event ? event.participantId : undefined;
316
+ const participantId = participantIdFromEvent ?? taskData?.participantId;
317
+ if (Boolean(participantId) && participantId === selfAgentId) {
318
+ return true;
319
+ }
320
+
321
+ // For EP-DN agents the backend removes the leaving participant entirely
322
+ // from the participants map (rather than setting hasLeft). If this task
323
+ // is in CONFERENCING (implied by the guard being evaluated here) but the
324
+ // agent is absent from the updated participants, they have left.
325
+ const participants = taskData?.interaction?.participants;
326
+ if (participants && !(selfAgentId in participants)) {
327
+ return true;
328
+ }
329
+ return false;
330
+ },
331
+ /**
332
+ * True when this agent initiated the conference transfer (widgets or desktop).
333
+ * Mirrors determineConsultInitiator: consultingAgentId === self only (not consultState).
334
+ */
335
+ isSelfConferenceTransferInitiator: ({
336
+ context,
337
+ event
338
+ }) => {
339
+ if (context.transferConferenceRequested === true) return true;
340
+ const taskData = getTaskDataFromEvent(event);
341
+ const selfAgentId = getSelfAgentId(context, taskData);
342
+ if (!selfAgentId || !taskData) return false;
343
+ return taskData.consultingAgentId === selfAgentId;
344
+ },
345
+ /**
346
+ * True when another agent performed conference transfer and this agent should
347
+ * only refresh task data (stay in the current state). False when this agent
348
+ * initiated the transfer (desktop or widgets) or has left the interaction.
349
+ */
350
+ isPassiveConferenceTransferObserver: ({
351
+ context,
352
+ event
353
+ }) => {
354
+ if (guards.isSelfConferenceTransferInitiator({
355
+ context,
356
+ event
357
+ })) return false;
358
+ const taskData = getTaskDataFromEvent(event);
359
+ const selfAgentId = getSelfAgentId(context, taskData);
360
+ if (selfAgentId && taskData?.interaction?.participants) {
361
+ if (!(selfAgentId in taskData.interaction.participants)) return false;
362
+ if (taskData.interaction.participants[selfAgentId]?.hasLeft === true) return false;
363
+ }
364
+ return true;
365
+ },
366
+ isCampaignReservationAccept: ({
367
+ event
368
+ }) => {
369
+ return event?.type === _constants.TaskEvent.TASK_INCOMING && event.isCampaignReservationAccept === true;
370
+ },
371
+ // Server State Guards
372
+ isPrimaryMediaOnHold: ({
373
+ event
374
+ }) => {
375
+ const taskData = getTaskDataFromEvent(event);
376
+ if (!taskData) return false;
377
+ const mediaId = taskData.mediaResourceId;
378
+ if (!mediaId) return false;
379
+ return taskData.interaction?.media?.[mediaId]?.isHold === true;
380
+ }
381
+ };
382
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_TaskUtils","require","_constants","getTaskDataFromEvent","event","taskData","undefined","exports","getSelfAgentId","context","uiControlConfig","agentId","isSelfConsultingAgent","selfAgentId","consultingAgentId","hasActiveConsultInPostCall","interaction","state","INTERACTION_STATE","POST_CALL","selfParticipant","participants","hasConsultMedia","Object","values","media","some","mType","MEDIA_TYPE_CONSULT","consultState","CONSULT_STATE","CONSULTING","shouldWrapUpForThisAgent","pending","agentsPendingWrapUp","Array","isArray","length","includes","participantWrapUp","isWrapUp","wrapUpRequired","owner","isConsulted","guards","isInteractionTerminated","isTerminated","isInteractionConsulting","selfActiveConsult","selfPendingConsultInitiated","cpd","callProcessingDetails","relationshipType","CONNECTED","postCallSelfAgentId","postCallSelfParticipant","hasPostCallConsultMedia","isEpDnPendingConferenceMergeHydrate","isEpDnConsultPendingConferenceMerge","isInteractionHeld","mainMediaId","mainInteractionId","interactionId","isHold","isInteractionConnected","isConferencingByParticipants","mainCallId","agentCount","pId","p","pType","hasLeft","conferenceInProgressFromEvent","getIsConferenceInProgress","isConferenceHoldParticipantFromEvent","conferenceHoldParticipant","shouldDowngradeConferenceToConnected","eventTaskData","CONFERENCE","agentParticipantsCount","getConferenceParticipantsCount","customerInCall","getIsCustomerInCall","selfInMainCall","Boolean","didInitiateConsult","consultInitiator","isConsultingAssignment","isCampaignPreviewContactEnded","type","TaskEvent","CONTACT_ENDED","isCampaignPreviewTask","isPendingWrapUp","participantIsWrapUp","explicitWrapUp","shouldWrapUp","CONFERENCE_END","shouldWrapUpOrIsInitiator","didCurrentAgentLeaveConference","participantIdFromEvent","participantId","isSelfConferenceTransferInitiator","transferConferenceRequested","isPassiveConferenceTransferObserver","isCampaignReservationAccept","TASK_INCOMING","isPrimaryMediaOnHold","mediaId","mediaResourceId"],"sources":["guards.ts"],"sourcesContent":["/**\n * Task State Machine Guards\n *\n * Guard functions that determine if a state transition is allowed.\n * These functions validate the current context before allowing transitions.\n *\n * All guards are consolidated here for:\n * - Single source of truth\n * - Easy testing\n * - Reusability across state machine transitions\n *\n * Guards are organized by category:\n * 1. Helper Functions - Extract data from events/context\n * 2. Hydrate Guards - For state restoration on page refresh\n * 3. Conference Guards - Conference state checks\n * 4. Customer Guards - Customer presence checks\n * 5. Consult Guards - Consult flow checks\n * 6. Wrapup Guards - End-of-call flow checks\n * 7. Server State Guards - Check backend-reported state\n * 8. Recording Guards - Recording state checks\n */\n\nimport {TaskContext, TaskEventPayload} from './types';\nimport {TaskData} from '../types';\nimport {\n getIsCustomerInCall,\n getConferenceParticipantsCount,\n getIsConferenceInProgress,\n isCampaignPreviewTask,\n isEpDnConsultPendingConferenceMerge,\n} from '../TaskUtils';\nimport {TaskEvent, INTERACTION_STATE, CONSULT_STATE, MEDIA_TYPE_CONSULT} from './constants';\n\nexport const getTaskDataFromEvent = (event?: TaskEventPayload): TaskData | undefined =>\n event && typeof event === 'object' && 'taskData' in event\n ? (event as {taskData?: TaskData}).taskData\n : undefined;\n\nexport const getSelfAgentId = (context: TaskContext, taskData?: TaskData): string | undefined =>\n context.uiControlConfig?.agentId ?? context.taskData?.agentId ?? taskData?.agentId;\n\nexport const isSelfConsultingAgent = (context: TaskContext, taskData?: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n return taskData?.consultingAgentId === selfAgentId;\n};\n\n/**\n * Detects an active consult during post_call state (customer left but agents still consulting).\n * Shared by hydration guard (isInteractionConsulting) and action (deriveTaskDataUpdates).\n */\nexport const hasActiveConsultInPostCall = (\n taskData: TaskData | undefined,\n selfAgentId?: string\n): boolean => {\n if (taskData?.interaction?.state !== INTERACTION_STATE.POST_CALL || !selfAgentId) return false;\n\n const selfParticipant = taskData.interaction?.participants?.[selfAgentId];\n const hasConsultMedia = Object.values(taskData.interaction?.media ?? {}).some(\n (media) => (media as {mType?: string})?.mType === MEDIA_TYPE_CONSULT\n );\n\n return selfParticipant?.consultState === CONSULT_STATE.CONSULTING && hasConsultMedia;\n};\n\n/**\n * Determines if this agent should enter WRAPPING_UP state.\n * Priority: agentsPendingWrapUp > wrapUpRequired / participant.isWrapUp > ownership > !isConsulted\n */\nexport const shouldWrapUpForThisAgent = (context: TaskContext, taskData: TaskData): boolean => {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp = taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n if (wrapUpRequired || participantWrapUp) {\n return true;\n }\n\n const owner = taskData?.interaction?.owner;\n if (owner && owner === selfAgentId) {\n return true;\n }\n\n if (taskData?.isConsulted === false) {\n return true;\n }\n\n return false;\n};\n\nexport interface GuardParams {\n context: TaskContext;\n event?: TaskEventPayload;\n}\n\nexport type GuardFunction = (params: GuardParams) => boolean;\n\nexport const guards = {\n // Hydrate Guards\n isInteractionTerminated: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.isTerminated === true) return true;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConsulting: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === INTERACTION_STATE.CONSULTING) return true;\n\n // Hydrate can report interaction as conference/hold while this agent is actively consulting.\n // Detect consult by participant consultState + consult media, independent of top-level state.\n const selfAgentId = getSelfAgentId(context, taskData);\n const selfParticipant = selfAgentId ? taskData?.interaction?.participants?.[selfAgentId] : null;\n const hasConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n const selfActiveConsult = selfParticipant?.consultState === CONSULT_STATE.CONSULTING;\n const selfPendingConsultInitiated =\n selfParticipant?.consultState === 'consultInitiated' && taskData?.isConsulted === false;\n if ((selfActiveConsult || selfPendingConsultInitiated) && hasConsultMedia) {\n return true;\n }\n\n // EP_DN consulted agent: backend reports state as 'connected' but CPD indicates consult\n const cpd = taskData?.interaction?.callProcessingDetails;\n if (\n cpd?.relationshipType === 'consult' &&\n taskData?.interaction?.state === INTERACTION_STATE.CONNECTED\n ) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (hasActiveConsultInPostCall(taskData, getSelfAgentId(context, taskData))) {\n return true;\n }\n\n // Customer left during consult: interaction state is \"post_call\" but consult\n // between agents is still active. Detect via agent's consultState + consult media.\n if (taskData?.interaction?.state === INTERACTION_STATE.POST_CALL) {\n const postCallSelfAgentId = getSelfAgentId(context, taskData);\n const postCallSelfParticipant = postCallSelfAgentId\n ? taskData?.interaction?.participants?.[postCallSelfAgentId]\n : null;\n const hasPostCallConsultMedia = Object.values(taskData?.interaction?.media ?? {}).some(\n (media: any) => media?.mType === MEDIA_TYPE_CONSULT\n );\n if (\n postCallSelfParticipant?.consultState === CONSULT_STATE.CONSULTING &&\n hasPostCallConsultMedia\n ) {\n return true;\n }\n }\n\n return false;\n },\n\n isEpDnPendingConferenceMergeHydrate: ({event, context}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return isEpDnConsultPendingConferenceMerge(taskData, getSelfAgentId(context, taskData));\n },\n\n isInteractionHeld: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n if (taskData?.interaction?.state === 'hold') return true;\n\n const mainMediaId = taskData?.interaction?.mainInteractionId || taskData?.interactionId;\n if (mainMediaId && taskData?.interaction?.media?.[mainMediaId]?.isHold === true) {\n return true;\n }\n\n return false;\n },\n\n isInteractionConnected: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return taskData?.interaction?.state === INTERACTION_STATE.CONNECTED;\n },\n\n isConferencingByParticipants: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mainCallId = taskData.interaction?.mainInteractionId || taskData.interactionId;\n const media = taskData.interaction?.media?.[mainCallId];\n const participants = taskData.interaction?.participants;\n if (!media?.participants || !participants) return false;\n let agentCount = 0;\n for (const pId of media.participants) {\n const p = participants[pId];\n if (p && p.pType !== 'Customer' && p.pType !== 'Supervisor' && !p.hasLeft) {\n agentCount += 1;\n }\n }\n\n return agentCount >= 2;\n },\n\n // Conference Guards\n conferenceInProgressFromEvent: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData?.interaction) return false;\n\n return getIsConferenceInProgress(taskData);\n },\n\n /**\n * Conference hold signal for conference-downgraded consult-end transitions.\n * Backend can report this as boolean or string.\n */\n isConferenceHoldParticipantFromEvent: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event) ?? context.taskData;\n const callProcessingDetails = taskData?.interaction?.callProcessingDetails as\n | {conferenceHoldParticipant?: boolean | string}\n | undefined;\n const conferenceHoldParticipant = callProcessingDetails?.conferenceHoldParticipant;\n\n return conferenceHoldParticipant === true || conferenceHoldParticipant === 'true';\n },\n\n /**\n * Conference downgrade check specifically for transitioning back to CONNECTED.\n *\n * Returns true only when:\n * - conference has downgraded (fewer than 2 active agent participants in main call)\n * - customer is still in the call\n * - current agent is still in the main call\n */\n shouldDowngradeConferenceToConnected: ({context, event}: GuardParams): boolean => {\n const eventTaskData = getTaskDataFromEvent(event);\n const taskData = eventTaskData ?? context.taskData;\n if (!taskData?.interaction) return false;\n\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const mainCallId = taskData.interaction.mainInteractionId || taskData.interactionId;\n if (!mainCallId) return false;\n\n // Don't downgrade while backend still reports conference.\n if (taskData.interaction.state === INTERACTION_STATE.CONFERENCE) return false;\n\n const agentParticipantsCount = getConferenceParticipantsCount(taskData.interaction, mainCallId);\n if (agentParticipantsCount >= 2) return false;\n\n const customerInCall = getIsCustomerInCall(taskData.interaction, mainCallId);\n if (!customerInCall) return false;\n\n const selfInMainCall = Boolean(\n taskData.interaction.media?.[mainCallId]?.participants?.includes(selfAgentId)\n );\n\n return selfInMainCall;\n },\n\n // Consult Guards\n /**\n * Check if this agent initiated the consult (using event data)\n * Handles both consultingAgentId and fallback to context flag\n */\n didInitiateConsult: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (taskData?.isConsulted === true) return false;\n\n return taskData?.consultingAgentId\n ? isSelfConsultingAgent(context, taskData)\n : context.consultInitiator === true;\n },\n\n /**\n * EP-DN / consulted consult legs can arrive as AGENT_CONTACT_ASSIGNED without a preceding\n * AgentConsulting event. When that happens, we should enter CONSULTING (not CONNECTED).\n */\n isConsultingAssignment: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n const relationshipType = taskData.interaction?.callProcessingDetails?.relationshipType;\n\n return (\n taskData.isConsulted === true ||\n relationshipType === 'consult' ||\n taskData.interaction?.state === INTERACTION_STATE.CONSULTING\n );\n },\n\n // Wrapup Guards\n isCampaignPreviewContactEnded: ({context, event}: GuardParams): boolean => {\n if (event?.type !== TaskEvent.CONTACT_ENDED) {\n return false;\n }\n\n const taskData = getTaskDataFromEvent(event);\n if (!isCampaignPreviewTask(taskData)) {\n return false;\n }\n\n const selfAgentId = getSelfAgentId(context, taskData);\n const pending = taskData?.agentsPendingWrapUp;\n const isPendingWrapUp =\n Array.isArray(pending) && !!selfAgentId && pending.includes(selfAgentId);\n const participantIsWrapUp =\n !!selfAgentId && taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const explicitWrapUp =\n taskData?.wrapUpRequired === true ||\n participantIsWrapUp ||\n isPendingWrapUp ||\n taskData?.interaction?.state === 'wrapUp';\n\n return !explicitWrapUp;\n },\n\n shouldWrapUp: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n\n if (event?.type === TaskEvent.CONFERENCE_END) {\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const pending = taskData?.agentsPendingWrapUp;\n if (Array.isArray(pending) && pending.length > 0) {\n return pending.includes(selfAgentId);\n }\n\n const participantWrapUp =\n taskData?.interaction?.participants?.[selfAgentId]?.isWrapUp === true;\n const wrapUpRequired = taskData?.wrapUpRequired === true;\n\n return wrapUpRequired || participantWrapUp;\n }\n\n return shouldWrapUpForThisAgent(context, taskData);\n },\n\n /**\n * Check if wrapUpRequired in payload OR is consult initiator\n */\n shouldWrapUpOrIsInitiator: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n\n return Boolean(taskData?.wrapUpRequired || context.consultInitiator);\n },\n\n /**\n * True if PARTICIPANT_LEAVE indicates that *this* agent left the conference.\n *\n * Important: PARTICIPANT_LEAVE is broadcast to all agents in the conference.\n * Only the agent whose id matches the leaving participant should transition to\n * TERMINATED / WRAPPING_UP based on wrapup rules.\n */\n didCurrentAgentLeaveConference: ({context, event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId) return false;\n\n const participantIdFromEvent =\n event && typeof event === 'object' && 'participantId' in event\n ? (event as {participantId?: string}).participantId\n : undefined;\n const participantId = participantIdFromEvent ?? taskData?.participantId;\n\n if (Boolean(participantId) && participantId === selfAgentId) {\n return true;\n }\n\n // For EP-DN agents the backend removes the leaving participant entirely\n // from the participants map (rather than setting hasLeft). If this task\n // is in CONFERENCING (implied by the guard being evaluated here) but the\n // agent is absent from the updated participants, they have left.\n const participants = taskData?.interaction?.participants;\n if (participants && !(selfAgentId in participants)) {\n return true;\n }\n\n return false;\n },\n\n /**\n * True when this agent initiated the conference transfer (widgets or desktop).\n * Mirrors determineConsultInitiator: consultingAgentId === self only (not consultState).\n */\n isSelfConferenceTransferInitiator: ({context, event}: GuardParams): boolean => {\n if (context.transferConferenceRequested === true) return true;\n\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (!selfAgentId || !taskData) return false;\n\n return taskData.consultingAgentId === selfAgentId;\n },\n\n /**\n * True when another agent performed conference transfer and this agent should\n * only refresh task data (stay in the current state). False when this agent\n * initiated the transfer (desktop or widgets) or has left the interaction.\n */\n isPassiveConferenceTransferObserver: ({context, event}: GuardParams): boolean => {\n if (guards.isSelfConferenceTransferInitiator({context, event})) return false;\n\n const taskData = getTaskDataFromEvent(event);\n const selfAgentId = getSelfAgentId(context, taskData);\n if (selfAgentId && taskData?.interaction?.participants) {\n if (!(selfAgentId in taskData.interaction.participants)) return false;\n if (taskData.interaction.participants[selfAgentId]?.hasLeft === true) return false;\n }\n\n return true;\n },\n\n isCampaignReservationAccept: ({event}: GuardParams): boolean => {\n return event?.type === TaskEvent.TASK_INCOMING && event.isCampaignReservationAccept === true;\n },\n\n // Server State Guards\n isPrimaryMediaOnHold: ({event}: GuardParams): boolean => {\n const taskData = getTaskDataFromEvent(event);\n if (!taskData) return false;\n const mediaId = taskData.mediaResourceId;\n if (!mediaId) return false;\n\n return taskData.interaction?.media?.[mediaId]?.isHold === true;\n },\n};\n\nexport type GuardName = keyof typeof guards;\n"],"mappings":";;;;;;AAwBA,IAAAA,UAAA,GAAAC,OAAA;AAOA,IAAAC,UAAA,GAAAD,OAAA;AA/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaO,MAAME,oBAAoB,GAAIC,KAAwB,IAC3DA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,UAAU,IAAIA,KAAK,GACpDA,KAAK,CAA2BC,QAAQ,GACzCC,SAAS;AAACC,OAAA,CAAAJ,oBAAA,GAAAA,oBAAA;AAET,MAAMK,cAAc,GAAGA,CAACC,OAAoB,EAAEJ,QAAmB,KACtEI,OAAO,CAACC,eAAe,EAAEC,OAAO,IAAIF,OAAO,CAACJ,QAAQ,EAAEM,OAAO,IAAIN,QAAQ,EAAEM,OAAO;AAACJ,OAAA,CAAAC,cAAA,GAAAA,cAAA;AAE9E,MAAMI,qBAAqB,GAAGA,CAACH,OAAoB,EAAEJ,QAAmB,KAAc;EAC3F,MAAMQ,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;EACrD,IAAI,CAACQ,WAAW,EAAE,OAAO,KAAK;EAE9B,OAAOR,QAAQ,EAAES,iBAAiB,KAAKD,WAAW;AACpD,CAAC;;AAED;AACA;AACA;AACA;AAHAN,OAAA,CAAAK,qBAAA,GAAAA,qBAAA;AAIO,MAAMG,0BAA0B,GAAGA,CACxCV,QAA8B,EAC9BQ,WAAoB,KACR;EACZ,IAAIR,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAKC,4BAAiB,CAACC,SAAS,IAAI,CAACN,WAAW,EAAE,OAAO,KAAK;EAE9F,MAAMO,eAAe,GAAGf,QAAQ,CAACW,WAAW,EAAEK,YAAY,GAAGR,WAAW,CAAC;EACzE,MAAMS,eAAe,GAAGC,MAAM,CAACC,MAAM,CAACnB,QAAQ,CAACW,WAAW,EAAES,KAAK,IAAI,CAAC,CAAC,CAAC,CAACC,IAAI,CAC1ED,KAAK,IAAMA,KAAK,EAAuBE,KAAK,KAAKC,6BACpD,CAAC;EAED,OAAOR,eAAe,EAAES,YAAY,KAAKC,wBAAa,CAACC,UAAU,IAAIT,eAAe;AACtF,CAAC;;AAED;AACA;AACA;AACA;AAHAf,OAAA,CAAAQ,0BAAA,GAAAA,0BAAA;AAIO,MAAMiB,wBAAwB,GAAGA,CAACvB,OAAoB,EAAEJ,QAAkB,KAAc;EAC7F,MAAMQ,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;EACrD,IAAI,CAACQ,WAAW,EAAE,OAAO,KAAK;EAE9B,MAAMoB,OAAO,GAAG5B,QAAQ,EAAE6B,mBAAmB;EAC7C,IAAIC,KAAK,CAACC,OAAO,CAACH,OAAO,CAAC,IAAIA,OAAO,CAACI,MAAM,GAAG,CAAC,EAAE;IAChD,OAAOJ,OAAO,CAACK,QAAQ,CAACzB,WAAW,CAAC;EACtC;EAEA,MAAM0B,iBAAiB,GAAGlC,QAAQ,EAAEW,WAAW,EAAEK,YAAY,GAAGR,WAAW,CAAC,EAAE2B,QAAQ,KAAK,IAAI;EAC/F,MAAMC,cAAc,GAAGpC,QAAQ,EAAEoC,cAAc,KAAK,IAAI;EACxD,IAAIA,cAAc,IAAIF,iBAAiB,EAAE;IACvC,OAAO,IAAI;EACb;EAEA,MAAMG,KAAK,GAAGrC,QAAQ,EAAEW,WAAW,EAAE0B,KAAK;EAC1C,IAAIA,KAAK,IAAIA,KAAK,KAAK7B,WAAW,EAAE;IAClC,OAAO,IAAI;EACb;EAEA,IAAIR,QAAQ,EAAEsC,WAAW,KAAK,KAAK,EAAE;IACnC,OAAO,IAAI;EACb;EAEA,OAAO,KAAK;AACd,CAAC;AAACpC,OAAA,CAAAyB,wBAAA,GAAAA,wBAAA;AASK,MAAMY,MAAM,GAAArC,OAAA,CAAAqC,MAAA,GAAG;EACpB;EACAC,uBAAuB,EAAEA,CAAC;IAACpC,OAAO;IAAEL;EAAkB,CAAC,KAAc;IACnE,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAE5C,IAAIC,QAAQ,EAAEW,WAAW,EAAE8B,YAAY,KAAK,IAAI,EAAE,OAAO,IAAI;IAE7D,MAAMjC,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,IAAIQ,WAAW,IAAIR,QAAQ,EAAEW,WAAW,EAAEK,YAAY,GAAGR,WAAW,CAAC,EAAE2B,QAAQ,KAAK,IAAI,EAAE;MACxF,OAAO,IAAI;IACb;IAEA,OAAO,KAAK;EACd,CAAC;EAEDO,uBAAuB,EAAEA,CAAC;IAAC3C,KAAK;IAAEK;EAAoB,CAAC,KAAc;IACnE,MAAMJ,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAE5C,IAAIC,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAKC,4BAAiB,CAACa,UAAU,EAAE,OAAO,IAAI;;IAE9E;IACA;IACA,MAAMlB,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,MAAMe,eAAe,GAAGP,WAAW,GAAGR,QAAQ,EAAEW,WAAW,EAAEK,YAAY,GAAGR,WAAW,CAAC,GAAG,IAAI;IAC/F,MAAMS,eAAe,GAAGC,MAAM,CAACC,MAAM,CAACnB,QAAQ,EAAEW,WAAW,EAAES,KAAK,IAAI,CAAC,CAAC,CAAC,CAACC,IAAI,CAC3ED,KAAU,IAAKA,KAAK,EAAEE,KAAK,KAAKC,6BACnC,CAAC;IACD,MAAMoB,iBAAiB,GAAG5B,eAAe,EAAES,YAAY,KAAKC,wBAAa,CAACC,UAAU;IACpF,MAAMkB,2BAA2B,GAC/B7B,eAAe,EAAES,YAAY,KAAK,kBAAkB,IAAIxB,QAAQ,EAAEsC,WAAW,KAAK,KAAK;IACzF,IAAI,CAACK,iBAAiB,IAAIC,2BAA2B,KAAK3B,eAAe,EAAE;MACzE,OAAO,IAAI;IACb;;IAEA;IACA,MAAM4B,GAAG,GAAG7C,QAAQ,EAAEW,WAAW,EAAEmC,qBAAqB;IACxD,IACED,GAAG,EAAEE,gBAAgB,KAAK,SAAS,IACnC/C,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAKC,4BAAiB,CAACmC,SAAS,EAC5D;MACA,OAAO,IAAI;IACb;;IAEA;IACA;IACA,IAAItC,0BAA0B,CAACV,QAAQ,EAAEG,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC,CAAC,EAAE;MAC3E,OAAO,IAAI;IACb;;IAEA;IACA;IACA,IAAIA,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAKC,4BAAiB,CAACC,SAAS,EAAE;MAChE,MAAMmC,mBAAmB,GAAG9C,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;MAC7D,MAAMkD,uBAAuB,GAAGD,mBAAmB,GAC/CjD,QAAQ,EAAEW,WAAW,EAAEK,YAAY,GAAGiC,mBAAmB,CAAC,GAC1D,IAAI;MACR,MAAME,uBAAuB,GAAGjC,MAAM,CAACC,MAAM,CAACnB,QAAQ,EAAEW,WAAW,EAAES,KAAK,IAAI,CAAC,CAAC,CAAC,CAACC,IAAI,CACnFD,KAAU,IAAKA,KAAK,EAAEE,KAAK,KAAKC,6BACnC,CAAC;MACD,IACE2B,uBAAuB,EAAE1B,YAAY,KAAKC,wBAAa,CAACC,UAAU,IAClEyB,uBAAuB,EACvB;QACA,OAAO,IAAI;MACb;IACF;IAEA,OAAO,KAAK;EACd,CAAC;EAEDC,mCAAmC,EAAEA,CAAC;IAACrD,KAAK;IAAEK;EAAoB,CAAC,KAAc;IAC/E,MAAMJ,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAE5C,OAAO,IAAAsD,8CAAmC,EAACrD,QAAQ,EAAEG,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC,CAAC;EACzF,CAAC;EAEDsD,iBAAiB,EAAEA,CAAC;IAACvD;EAAkB,CAAC,KAAc;IACpD,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAE5C,IAAIC,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAK,MAAM,EAAE,OAAO,IAAI;IAExD,MAAM2C,WAAW,GAAGvD,QAAQ,EAAEW,WAAW,EAAE6C,iBAAiB,IAAIxD,QAAQ,EAAEyD,aAAa;IACvF,IAAIF,WAAW,IAAIvD,QAAQ,EAAEW,WAAW,EAAES,KAAK,GAAGmC,WAAW,CAAC,EAAEG,MAAM,KAAK,IAAI,EAAE;MAC/E,OAAO,IAAI;IACb;IAEA,OAAO,KAAK;EACd,CAAC;EAEDC,sBAAsB,EAAEA,CAAC;IAAC5D;EAAkB,CAAC,KAAc;IACzD,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAE5C,OAAOC,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAKC,4BAAiB,CAACmC,SAAS;EACrE,CAAC;EAEDY,4BAA4B,EAAEA,CAAC;IAAC7D;EAAkB,CAAC,KAAc;IAC/D,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAI,CAACC,QAAQ,EAAE,OAAO,KAAK;IAC3B,MAAM6D,UAAU,GAAG7D,QAAQ,CAACW,WAAW,EAAE6C,iBAAiB,IAAIxD,QAAQ,CAACyD,aAAa;IACpF,MAAMrC,KAAK,GAAGpB,QAAQ,CAACW,WAAW,EAAES,KAAK,GAAGyC,UAAU,CAAC;IACvD,MAAM7C,YAAY,GAAGhB,QAAQ,CAACW,WAAW,EAAEK,YAAY;IACvD,IAAI,CAACI,KAAK,EAAEJ,YAAY,IAAI,CAACA,YAAY,EAAE,OAAO,KAAK;IACvD,IAAI8C,UAAU,GAAG,CAAC;IAClB,KAAK,MAAMC,GAAG,IAAI3C,KAAK,CAACJ,YAAY,EAAE;MACpC,MAAMgD,CAAC,GAAGhD,YAAY,CAAC+C,GAAG,CAAC;MAC3B,IAAIC,CAAC,IAAIA,CAAC,CAACC,KAAK,KAAK,UAAU,IAAID,CAAC,CAACC,KAAK,KAAK,YAAY,IAAI,CAACD,CAAC,CAACE,OAAO,EAAE;QACzEJ,UAAU,IAAI,CAAC;MACjB;IACF;IAEA,OAAOA,UAAU,IAAI,CAAC;EACxB,CAAC;EAED;EACAK,6BAA6B,EAAEA,CAAC;IAACpE;EAAkB,CAAC,KAAc;IAChE,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAI,CAACC,QAAQ,EAAEW,WAAW,EAAE,OAAO,KAAK;IAExC,OAAO,IAAAyD,oCAAyB,EAACpE,QAAQ,CAAC;EAC5C,CAAC;EAED;AACF;AACA;AACA;EACEqE,oCAAoC,EAAEA,CAAC;IAACjE,OAAO;IAAEL;EAAkB,CAAC,KAAc;IAChF,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC,IAAIK,OAAO,CAACJ,QAAQ;IAChE,MAAM8C,qBAAqB,GAAG9C,QAAQ,EAAEW,WAAW,EAAEmC,qBAExC;IACb,MAAMwB,yBAAyB,GAAGxB,qBAAqB,EAAEwB,yBAAyB;IAElF,OAAOA,yBAAyB,KAAK,IAAI,IAAIA,yBAAyB,KAAK,MAAM;EACnF,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,oCAAoC,EAAEA,CAAC;IAACnE,OAAO;IAAEL;EAAkB,CAAC,KAAc;IAChF,MAAMyE,aAAa,GAAG1E,oBAAoB,CAACC,KAAK,CAAC;IACjD,MAAMC,QAAQ,GAAGwE,aAAa,IAAIpE,OAAO,CAACJ,QAAQ;IAClD,IAAI,CAACA,QAAQ,EAAEW,WAAW,EAAE,OAAO,KAAK;IAExC,MAAMH,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,IAAI,CAACQ,WAAW,EAAE,OAAO,KAAK;IAE9B,MAAMqD,UAAU,GAAG7D,QAAQ,CAACW,WAAW,CAAC6C,iBAAiB,IAAIxD,QAAQ,CAACyD,aAAa;IACnF,IAAI,CAACI,UAAU,EAAE,OAAO,KAAK;;IAE7B;IACA,IAAI7D,QAAQ,CAACW,WAAW,CAACC,KAAK,KAAKC,4BAAiB,CAAC4D,UAAU,EAAE,OAAO,KAAK;IAE7E,MAAMC,sBAAsB,GAAG,IAAAC,yCAA8B,EAAC3E,QAAQ,CAACW,WAAW,EAAEkD,UAAU,CAAC;IAC/F,IAAIa,sBAAsB,IAAI,CAAC,EAAE,OAAO,KAAK;IAE7C,MAAME,cAAc,GAAG,IAAAC,8BAAmB,EAAC7E,QAAQ,CAACW,WAAW,EAAEkD,UAAU,CAAC;IAC5E,IAAI,CAACe,cAAc,EAAE,OAAO,KAAK;IAEjC,MAAME,cAAc,GAAGC,OAAO,CAC5B/E,QAAQ,CAACW,WAAW,CAACS,KAAK,GAAGyC,UAAU,CAAC,EAAE7C,YAAY,EAAEiB,QAAQ,CAACzB,WAAW,CAC9E,CAAC;IAED,OAAOsE,cAAc;EACvB,CAAC;EAED;EACA;AACF;AACA;AACA;EACEE,kBAAkB,EAAEA,CAAC;IAAC5E,OAAO;IAAEL;EAAkB,CAAC,KAAc;IAC9D,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAIC,QAAQ,EAAEsC,WAAW,KAAK,IAAI,EAAE,OAAO,KAAK;IAEhD,OAAOtC,QAAQ,EAAES,iBAAiB,GAC9BF,qBAAqB,CAACH,OAAO,EAAEJ,QAAQ,CAAC,GACxCI,OAAO,CAAC6E,gBAAgB,KAAK,IAAI;EACvC,CAAC;EAED;AACF;AACA;AACA;EACEC,sBAAsB,EAAEA,CAAC;IAACnF;EAAkB,CAAC,KAAc;IACzD,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAI,CAACC,QAAQ,EAAE,OAAO,KAAK;IAE3B,MAAM+C,gBAAgB,GAAG/C,QAAQ,CAACW,WAAW,EAAEmC,qBAAqB,EAAEC,gBAAgB;IAEtF,OACE/C,QAAQ,CAACsC,WAAW,KAAK,IAAI,IAC7BS,gBAAgB,KAAK,SAAS,IAC9B/C,QAAQ,CAACW,WAAW,EAAEC,KAAK,KAAKC,4BAAiB,CAACa,UAAU;EAEhE,CAAC;EAED;EACAyD,6BAA6B,EAAEA,CAAC;IAAC/E,OAAO;IAAEL;EAAkB,CAAC,KAAc;IACzE,IAAIA,KAAK,EAAEqF,IAAI,KAAKC,oBAAS,CAACC,aAAa,EAAE;MAC3C,OAAO,KAAK;IACd;IAEA,MAAMtF,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAI,CAAC,IAAAwF,gCAAqB,EAACvF,QAAQ,CAAC,EAAE;MACpC,OAAO,KAAK;IACd;IAEA,MAAMQ,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,MAAM4B,OAAO,GAAG5B,QAAQ,EAAE6B,mBAAmB;IAC7C,MAAM2D,eAAe,GACnB1D,KAAK,CAACC,OAAO,CAACH,OAAO,CAAC,IAAI,CAAC,CAACpB,WAAW,IAAIoB,OAAO,CAACK,QAAQ,CAACzB,WAAW,CAAC;IAC1E,MAAMiF,mBAAmB,GACvB,CAAC,CAACjF,WAAW,IAAIR,QAAQ,EAAEW,WAAW,EAAEK,YAAY,GAAGR,WAAW,CAAC,EAAE2B,QAAQ,KAAK,IAAI;IACxF,MAAMuD,cAAc,GAClB1F,QAAQ,EAAEoC,cAAc,KAAK,IAAI,IACjCqD,mBAAmB,IACnBD,eAAe,IACfxF,QAAQ,EAAEW,WAAW,EAAEC,KAAK,KAAK,QAAQ;IAE3C,OAAO,CAAC8E,cAAc;EACxB,CAAC;EAEDC,YAAY,EAAEA,CAAC;IAACvF,OAAO;IAAEL;EAAkB,CAAC,KAAc;IACxD,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAI,CAACC,QAAQ,EAAE,OAAO,KAAK;IAE3B,IAAID,KAAK,EAAEqF,IAAI,KAAKC,oBAAS,CAACO,cAAc,EAAE;MAC5C,MAAMpF,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;MACrD,IAAI,CAACQ,WAAW,EAAE,OAAO,KAAK;MAE9B,MAAMoB,OAAO,GAAG5B,QAAQ,EAAE6B,mBAAmB;MAC7C,IAAIC,KAAK,CAACC,OAAO,CAACH,OAAO,CAAC,IAAIA,OAAO,CAACI,MAAM,GAAG,CAAC,EAAE;QAChD,OAAOJ,OAAO,CAACK,QAAQ,CAACzB,WAAW,CAAC;MACtC;MAEA,MAAM0B,iBAAiB,GACrBlC,QAAQ,EAAEW,WAAW,EAAEK,YAAY,GAAGR,WAAW,CAAC,EAAE2B,QAAQ,KAAK,IAAI;MACvE,MAAMC,cAAc,GAAGpC,QAAQ,EAAEoC,cAAc,KAAK,IAAI;MAExD,OAAOA,cAAc,IAAIF,iBAAiB;IAC5C;IAEA,OAAOP,wBAAwB,CAACvB,OAAO,EAAEJ,QAAQ,CAAC;EACpD,CAAC;EAED;AACF;AACA;EACE6F,yBAAyB,EAAEA,CAAC;IAACzF,OAAO;IAAEL;EAAkB,CAAC,KAAc;IACrE,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAE5C,OAAOgF,OAAO,CAAC/E,QAAQ,EAAEoC,cAAc,IAAIhC,OAAO,CAAC6E,gBAAgB,CAAC;EACtE,CAAC;EAED;AACF;AACA;AACA;AACA;AACA;AACA;EACEa,8BAA8B,EAAEA,CAAC;IAAC1F,OAAO;IAAEL;EAAkB,CAAC,KAAc;IAC1E,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,MAAMS,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,IAAI,CAACQ,WAAW,EAAE,OAAO,KAAK;IAE9B,MAAMuF,sBAAsB,GAC1BhG,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,eAAe,IAAIA,KAAK,GACzDA,KAAK,CAA8BiG,aAAa,GACjD/F,SAAS;IACf,MAAM+F,aAAa,GAAGD,sBAAsB,IAAI/F,QAAQ,EAAEgG,aAAa;IAEvE,IAAIjB,OAAO,CAACiB,aAAa,CAAC,IAAIA,aAAa,KAAKxF,WAAW,EAAE;MAC3D,OAAO,IAAI;IACb;;IAEA;IACA;IACA;IACA;IACA,MAAMQ,YAAY,GAAGhB,QAAQ,EAAEW,WAAW,EAAEK,YAAY;IACxD,IAAIA,YAAY,IAAI,EAAER,WAAW,IAAIQ,YAAY,CAAC,EAAE;MAClD,OAAO,IAAI;IACb;IAEA,OAAO,KAAK;EACd,CAAC;EAED;AACF;AACA;AACA;EACEiF,iCAAiC,EAAEA,CAAC;IAAC7F,OAAO;IAAEL;EAAkB,CAAC,KAAc;IAC7E,IAAIK,OAAO,CAAC8F,2BAA2B,KAAK,IAAI,EAAE,OAAO,IAAI;IAE7D,MAAMlG,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,MAAMS,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,IAAI,CAACQ,WAAW,IAAI,CAACR,QAAQ,EAAE,OAAO,KAAK;IAE3C,OAAOA,QAAQ,CAACS,iBAAiB,KAAKD,WAAW;EACnD,CAAC;EAED;AACF;AACA;AACA;AACA;EACE2F,mCAAmC,EAAEA,CAAC;IAAC/F,OAAO;IAAEL;EAAkB,CAAC,KAAc;IAC/E,IAAIwC,MAAM,CAAC0D,iCAAiC,CAAC;MAAC7F,OAAO;MAAEL;IAAK,CAAC,CAAC,EAAE,OAAO,KAAK;IAE5E,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,MAAMS,WAAW,GAAGL,cAAc,CAACC,OAAO,EAAEJ,QAAQ,CAAC;IACrD,IAAIQ,WAAW,IAAIR,QAAQ,EAAEW,WAAW,EAAEK,YAAY,EAAE;MACtD,IAAI,EAAER,WAAW,IAAIR,QAAQ,CAACW,WAAW,CAACK,YAAY,CAAC,EAAE,OAAO,KAAK;MACrE,IAAIhB,QAAQ,CAACW,WAAW,CAACK,YAAY,CAACR,WAAW,CAAC,EAAE0D,OAAO,KAAK,IAAI,EAAE,OAAO,KAAK;IACpF;IAEA,OAAO,IAAI;EACb,CAAC;EAEDkC,2BAA2B,EAAEA,CAAC;IAACrG;EAAkB,CAAC,KAAc;IAC9D,OAAOA,KAAK,EAAEqF,IAAI,KAAKC,oBAAS,CAACgB,aAAa,IAAItG,KAAK,CAACqG,2BAA2B,KAAK,IAAI;EAC9F,CAAC;EAED;EACAE,oBAAoB,EAAEA,CAAC;IAACvG;EAAkB,CAAC,KAAc;IACvD,MAAMC,QAAQ,GAAGF,oBAAoB,CAACC,KAAK,CAAC;IAC5C,IAAI,CAACC,QAAQ,EAAE,OAAO,KAAK;IAC3B,MAAMuG,OAAO,GAAGvG,QAAQ,CAACwG,eAAe;IACxC,IAAI,CAACD,OAAO,EAAE,OAAO,KAAK;IAE1B,OAAOvG,QAAQ,CAACW,WAAW,EAAES,KAAK,GAAGmF,OAAO,CAAC,EAAE7C,MAAM,KAAK,IAAI;EAChE;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "TaskEvent", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _constants.TaskEvent;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "TaskState", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _constants.TaskState;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "actions", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _actions.actions;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "createInitialContext", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _actions.createInitialContext;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "createTaskStateMachine", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _TaskStateMachine.createTaskStateMachine;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "guards", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _guards.guards;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "isEventOfType", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _types.isEventOfType;
46
+ }
47
+ });
48
+ var _TaskStateMachine = require("./TaskStateMachine");
49
+ var _constants = require("./constants");
50
+ var _types = require("./types");
51
+ var _guards = require("./guards");
52
+ var _actions = require("./actions");
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_TaskStateMachine","require","_constants","_types","_guards","_actions"],"sources":["index.ts"],"sourcesContent":["/**\n * Task State Machine\n *\n * Export all state machine components for easy importing\n */\n\n// Main state machine\nexport {createTaskStateMachine} from './TaskStateMachine';\nexport type {TaskStateMachine} from './TaskStateMachine';\n\n// Types & enums\nexport {TaskState, TaskEvent} from './constants';\nexport {isEventOfType} from './types';\nexport type {\n TaskContext,\n TaskEventPayload,\n TaskStateMachineConfig,\n UIControlConfig,\n TaskActionsMap,\n TaskActionArgs,\n} from './types';\n\n// Guards\nexport {guards} from './guards';\nexport type {GuardParams, GuardFunction} from './guards';\n\n// Actions\nexport {actions, createInitialContext} from './actions';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,IAAAA,iBAAA,GAAAC,OAAA;AAIA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAWA,IAAAG,OAAA,GAAAH,OAAA;AAIA,IAAAI,QAAA,GAAAJ,OAAA","ignoreList":[]}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isEventOfType = isEventOfType;
7
+ var _constants = require("./constants");
8
+ /**
9
+ * Task State Machine Types
10
+ *
11
+ * Type definitions for the XState-based task state machine.
12
+ * These types define states, events, context, and schemas for task lifecycle management.
13
+ */
14
+
15
+ /**
16
+ * Represents a participant in a conference call
17
+ */
18
+
19
+ /**
20
+ * UI Control configuration for the task
21
+ */
22
+
23
+ /**
24
+ * Task state machine context.
25
+ * Only stores data that cannot be derived from state machine state.
26
+ */
27
+
28
+ /**
29
+ * Base event type - all events have a type property
30
+ */
31
+
32
+ /**
33
+ * Event payload mapping - defines the payload for each event type
34
+ */
35
+
36
+ /**
37
+ * Union of all possible event payloads
38
+ */
39
+
40
+ /**
41
+ * Type guard to check event type
42
+ */
43
+ function isEventOfType(event, type) {
44
+ return Boolean(event && event.type === type);
45
+ }
46
+
47
+ /**
48
+ * Recording control state for UI controls computer
49
+ */
50
+
51
+ /**
52
+ * State machine configuration type
53
+ */
54
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_constants","require","isEventOfType","event","type","Boolean"],"sources":["types.ts"],"sourcesContent":["/**\n * Task State Machine Types\n *\n * Type definitions for the XState-based task state machine.\n * These types define states, events, context, and schemas for task lifecycle management.\n */\n\nimport type {AnyStateNodeConfig, ActionFunctionMap, EventObject, ActionArgs} from 'xstate';\nimport {DestinationType, TaskChannelType, TaskData, TaskUIControls, VoiceVariant} from '../types';\nimport {TaskEvent, TaskState} from './constants';\n\n/**\n * Represents a participant in a conference call\n */\nexport interface ConferenceParticipant {\n /** Unique identifier for the participant */\n id: string;\n /** Type of participant (agent, customer, or external party) */\n type: 'AGENT' | 'CUSTOMER' | 'EXTERNAL';\n /** Display name of the participant */\n name?: string;\n /** Timestamp when participant joined the conference */\n joinedAt: Date;\n /** Whether this participant initiated the conference */\n isInitiator: boolean;\n /** Whether this participant can be removed from the conference */\n canBeRemoved: boolean;\n}\n\n/**\n * UI Control configuration for the task\n */\nexport interface UIControlConfig {\n /** Whether end call button is enabled (config option) */\n isEndTaskEnabled: boolean;\n /** Whether end consult button is enabled (config option) */\n isEndConsultEnabled: boolean;\n /** Channel type determines which controls are available */\n channelType: TaskChannelType;\n /** Optional voice channel variant to toggle WebRTC-specific controls */\n voiceVariant?: VoiceVariant;\n /** Whether recording controls should be shown for this task */\n isRecordingEnabled: boolean;\n /** Current agent ID for ownership checks (transfer conference) */\n agentId?: string;\n}\n\n/**\n * Task state machine context.\n * Only stores data that cannot be derived from state machine state.\n */\nexport interface TaskContext {\n taskData: TaskData | null;\n\n // Consult tracking\n consultInitiator: boolean;\n exitingConference: boolean;\n consultFromConference: boolean;\n transferConferenceRequested: boolean;\n consultDestinationType: DestinationType | null;\n consultDestinationAgentId: string | null;\n consultDestinationAgentJoined: boolean;\n consultCallHeld: boolean;\n /** Set by deriveTaskDataUpdates / clearConsultState when EP-DN consult is merged to conference before Agent 2 joins (CAI-8329). */\n hideBlindTransferForEpDnPendingMerge: boolean;\n\n // Recording\n recordingControlsAvailable: boolean;\n recordingInProgress: boolean;\n\n // UI\n uiControlConfig: UIControlConfig;\n uiControls: TaskUIControls;\n}\n\nexport type RecordingStateUpdate = Partial<\n Pick<TaskContext, 'recordingControlsAvailable' | 'recordingInProgress'>\n>;\n\n/**\n * Base event type - all events have a type property\n */\ntype BaseEvent<T extends TaskEvent> = {type: T};\n\n/**\n * Event payload mapping - defines the payload for each event type\n */\ninterface TaskEventPayloadMap {\n [TaskEvent.TASK_INCOMING]: BaseEvent<TaskEvent.TASK_INCOMING> & {\n taskData: TaskData;\n /** Set when campaign preview reservation accept is receieved */\n isCampaignReservationAccept?: boolean;\n };\n [TaskEvent.TASK_OFFERED]: BaseEvent<TaskEvent.TASK_OFFERED> & {taskData: TaskData};\n [TaskEvent.OFFER_CONSULT]: BaseEvent<TaskEvent.OFFER_CONSULT> & {taskData: TaskData};\n [TaskEvent.HYDRATE]: BaseEvent<TaskEvent.HYDRATE> & {taskData: TaskData; agentId?: string};\n [TaskEvent.CONTACT_UPDATED]: BaseEvent<TaskEvent.CONTACT_UPDATED> & {taskData: TaskData};\n [TaskEvent.CONTACT_OWNER_CHANGED]: BaseEvent<TaskEvent.CONTACT_OWNER_CHANGED> & {\n taskData: TaskData;\n };\n [TaskEvent.ASSIGN]: BaseEvent<TaskEvent.ASSIGN> & {taskData: TaskData};\n [TaskEvent.HOLD_INITIATED]: BaseEvent<TaskEvent.HOLD_INITIATED> & {mediaResourceId: string};\n [TaskEvent.HOLD_SUCCESS]: BaseEvent<TaskEvent.HOLD_SUCCESS> & {\n mediaResourceId: string;\n taskData?: TaskData;\n };\n [TaskEvent.HOLD_FAILED]: BaseEvent<TaskEvent.HOLD_FAILED> & {\n reason?: string;\n mediaResourceId: string;\n };\n [TaskEvent.UNHOLD_INITIATED]: BaseEvent<TaskEvent.UNHOLD_INITIATED> & {mediaResourceId: string};\n [TaskEvent.UNHOLD_SUCCESS]: BaseEvent<TaskEvent.UNHOLD_SUCCESS> & {\n mediaResourceId: string;\n taskData?: TaskData;\n };\n [TaskEvent.UNHOLD_FAILED]: BaseEvent<TaskEvent.UNHOLD_FAILED> & {\n reason?: string;\n mediaResourceId: string;\n };\n [TaskEvent.CONSULT]: BaseEvent<TaskEvent.CONSULT> & {\n destination: string;\n destAgentId?: string;\n destinationType: DestinationType;\n };\n [TaskEvent.CONSULT_SUCCESS]: BaseEvent<TaskEvent.CONSULT_SUCCESS> & {taskData?: TaskData};\n [TaskEvent.CONSULT_CREATED]: BaseEvent<TaskEvent.CONSULT_CREATED> & {taskData: TaskData};\n [TaskEvent.CONSULTING_ACTIVE]: BaseEvent<TaskEvent.CONSULTING_ACTIVE> & {\n consultDestinationAgentJoined: boolean;\n taskData?: TaskData;\n };\n [TaskEvent.CONSULT_END]: BaseEvent<TaskEvent.CONSULT_END> & {taskData?: TaskData};\n [TaskEvent.CONSULT_FAILED]: BaseEvent<TaskEvent.CONSULT_FAILED> & {\n reason?: string;\n taskData?: TaskData;\n };\n [TaskEvent.MERGE_TO_CONFERENCE]: BaseEvent<TaskEvent.MERGE_TO_CONFERENCE>;\n [TaskEvent.CONFERENCE_START]: BaseEvent<TaskEvent.CONFERENCE_START> & {\n participants?: ConferenceParticipant[];\n taskData?: TaskData;\n };\n [TaskEvent.CONFERENCE_FAILED]: BaseEvent<TaskEvent.CONFERENCE_FAILED> & {\n reason?: string;\n taskData?: TaskData;\n };\n [TaskEvent.CONFERENCE_END]: BaseEvent<TaskEvent.CONFERENCE_END> & {taskData: TaskData};\n [TaskEvent.TRANSFER_CONFERENCE]: BaseEvent<TaskEvent.TRANSFER_CONFERENCE> & {agentId?: string};\n [TaskEvent.PARTICIPANT_LEAVE]: BaseEvent<TaskEvent.PARTICIPANT_LEAVE> & {\n participantId?: string;\n taskData: TaskData;\n };\n [TaskEvent.EXIT_CONFERENCE]: BaseEvent<TaskEvent.EXIT_CONFERENCE> & {agentId?: string};\n [TaskEvent.EXIT_CONFERENCE_SUCCESS]: BaseEvent<TaskEvent.EXIT_CONFERENCE_SUCCESS> & {\n taskData: TaskData;\n };\n [TaskEvent.EXIT_CONFERENCE_FAILED]: BaseEvent<TaskEvent.EXIT_CONFERENCE_FAILED> & {\n reason?: string;\n };\n [TaskEvent.TRANSFER_CONFERENCE_SUCCESS]: BaseEvent<TaskEvent.TRANSFER_CONFERENCE_SUCCESS> & {\n taskData: TaskData;\n };\n [TaskEvent.TRANSFER_CONFERENCE_FAILED]: BaseEvent<TaskEvent.TRANSFER_CONFERENCE_FAILED> & {\n reason?: string;\n };\n [TaskEvent.RECORDING_STARTED]: BaseEvent<TaskEvent.RECORDING_STARTED> & {taskData: TaskData};\n [TaskEvent.PAUSE_RECORDING]: BaseEvent<TaskEvent.PAUSE_RECORDING> & {taskData: TaskData};\n [TaskEvent.RESUME_RECORDING]: BaseEvent<TaskEvent.RESUME_RECORDING> & {taskData: TaskData};\n [TaskEvent.TRANSFER_SUCCESS]: BaseEvent<TaskEvent.TRANSFER_SUCCESS> & {taskData?: TaskData};\n [TaskEvent.TRANSFER_FAILED]: BaseEvent<TaskEvent.TRANSFER_FAILED> & {\n reason?: string;\n taskData?: TaskData;\n };\n [TaskEvent.WRAPUP_COMPLETE]: BaseEvent<TaskEvent.WRAPUP_COMPLETE> & {taskData?: TaskData};\n [TaskEvent.TASK_WRAPUP]: BaseEvent<TaskEvent.TASK_WRAPUP> & {taskData?: TaskData};\n [TaskEvent.RONA]: BaseEvent<TaskEvent.RONA> & {taskData?: TaskData; reason?: string};\n [TaskEvent.CONTACT_ENDED]: BaseEvent<TaskEvent.CONTACT_ENDED> & {taskData: TaskData};\n [TaskEvent.ASSIGN_FAILED]: BaseEvent<TaskEvent.ASSIGN_FAILED> & {reason?: string};\n [TaskEvent.INVITE_FAILED]: BaseEvent<TaskEvent.INVITE_FAILED> & {reason?: string};\n [TaskEvent.OUTBOUND_FAILED]: BaseEvent<TaskEvent.OUTBOUND_FAILED> & {\n reason?: string;\n taskData?: TaskData;\n };\n [TaskEvent.CAMPAIGN_PREVIEW_ACCEPT_FAILED]: BaseEvent<TaskEvent.CAMPAIGN_PREVIEW_ACCEPT_FAILED> & {\n taskData?: TaskData;\n };\n [TaskEvent.CAMPAIGN_PREVIEW_SKIP_FAILED]: BaseEvent<TaskEvent.CAMPAIGN_PREVIEW_SKIP_FAILED> & {\n taskData?: TaskData;\n };\n [TaskEvent.CAMPAIGN_PREVIEW_REMOVE_FAILED]: BaseEvent<TaskEvent.CAMPAIGN_PREVIEW_REMOVE_FAILED> & {\n taskData?: TaskData;\n };\n [TaskEvent.SWITCH_TO_MAIN_CALL]: BaseEvent<TaskEvent.SWITCH_TO_MAIN_CALL>;\n [TaskEvent.SWITCH_TO_CONSULT]: BaseEvent<TaskEvent.SWITCH_TO_CONSULT>;\n [TaskEvent.ACCEPT]: BaseEvent<TaskEvent.ACCEPT>;\n [TaskEvent.DECLINE]: BaseEvent<TaskEvent.DECLINE>;\n [TaskEvent.END]: BaseEvent<TaskEvent.END> & {taskData?: TaskData};\n [TaskEvent.CTQ_CANCEL]: BaseEvent<TaskEvent.CTQ_CANCEL> & {taskData: TaskData};\n [TaskEvent.CTQ_CANCEL_FAILED]: BaseEvent<TaskEvent.CTQ_CANCEL_FAILED> & {taskData: TaskData};\n}\n\n/**\n * Union of all possible event payloads\n */\nexport type TaskEventPayload = TaskEventPayloadMap[TaskEvent];\n\n/**\n * Type guard to check event type\n */\nexport function isEventOfType<T extends TaskEvent>(\n event: TaskEventPayload | undefined,\n type: T\n): event is TaskEventPayloadMap[T] {\n return Boolean(event && event.type === type);\n}\n\n/**\n * Recording control state for UI controls computer\n */\nexport interface RecordingControlState {\n available: boolean;\n inProgress: boolean;\n}\n\n/**\n * State machine configuration type\n */\nexport interface TaskStateMachineConfig {\n id: string;\n initial: TaskState;\n context: TaskContext;\n states: Record<string, AnyStateNodeConfig>;\n}\n\nexport type TaskActionsMap = ActionFunctionMap<\n TaskContext,\n TaskEventPayload,\n never,\n {type: string; params: undefined},\n never,\n never,\n EventObject\n>;\n\nexport type TaskActionArgs = ActionArgs<TaskContext, TaskEventPayload, TaskEventPayload>;\n"],"mappings":";;;;;;AASA,IAAAA,UAAA,GAAAC,OAAA;AATA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;;AAgBA;AACA;AACA;;AAgBA;AACA;AACA;AACA;;AA6BA;AACA;AACA;;AAGA;AACA;AACA;;AAiHA;AACA;AACA;;AAGA;AACA;AACA;AACO,SAASC,aAAaA,CAC3BC,KAAmC,EACnCC,IAAO,EAC0B;EACjC,OAAOC,OAAO,CAACF,KAAK,IAAIA,KAAK,CAACC,IAAI,KAAKA,IAAI,CAAC;AAC9C;;AAEA;AACA;AACA;;AAMA;AACA;AACA","ignoreList":[]}