jsfe 1.6.0 → 1.7.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 (103) hide show
  1. package/README.md +32 -4
  2. package/dist/forms/action-projection.d.ts +4 -0
  3. package/dist/forms/action-projection.d.ts.map +1 -0
  4. package/dist/forms/action-projection.js +21 -0
  5. package/dist/forms/action-recovery.d.ts +12 -0
  6. package/dist/forms/action-recovery.d.ts.map +1 -0
  7. package/dist/forms/action-recovery.js +125 -0
  8. package/dist/forms/action-tools.d.ts +29 -0
  9. package/dist/forms/action-tools.d.ts.map +1 -0
  10. package/dist/forms/action-tools.js +6 -0
  11. package/dist/forms/address-flows.d.ts +2 -0
  12. package/dist/forms/address-flows.d.ts.map +1 -0
  13. package/dist/forms/address-flows.js +39 -0
  14. package/dist/forms/choice-flow.d.ts +419 -0
  15. package/dist/forms/choice-flow.d.ts.map +1 -0
  16. package/dist/forms/choice-flow.js +707 -0
  17. package/dist/forms/contracts.d.ts +237 -0
  18. package/dist/forms/contracts.d.ts.map +1 -0
  19. package/dist/forms/contracts.js +278 -0
  20. package/dist/forms/flows.d.ts +611 -0
  21. package/dist/forms/flows.d.ts.map +1 -0
  22. package/dist/forms/flows.js +675 -0
  23. package/dist/forms/identity-flows.d.ts +17 -0
  24. package/dist/forms/identity-flows.d.ts.map +1 -0
  25. package/dist/forms/identity-flows.js +302 -0
  26. package/dist/forms/index.d.ts +7 -0
  27. package/dist/forms/index.d.ts.map +1 -0
  28. package/dist/forms/index.js +10 -0
  29. package/dist/forms/prompt-compiler.d.ts +3 -0
  30. package/dist/forms/prompt-compiler.d.ts.map +1 -0
  31. package/dist/forms/prompt-compiler.js +30 -0
  32. package/dist/forms/session-actions.d.ts +14 -0
  33. package/dist/forms/session-actions.d.ts.map +1 -0
  34. package/dist/forms/session-actions.js +40 -0
  35. package/dist/helpers/address.d.ts +27 -0
  36. package/dist/helpers/address.d.ts.map +1 -0
  37. package/dist/helpers/address.js +29 -0
  38. package/dist/helpers/answer.d.ts +5 -0
  39. package/dist/helpers/answer.d.ts.map +1 -1
  40. package/dist/helpers/answer.js +5 -3
  41. package/dist/helpers/choice-offer.d.ts +3 -0
  42. package/dist/helpers/choice-offer.d.ts.map +1 -0
  43. package/dist/helpers/choice-offer.js +6 -0
  44. package/dist/helpers/form-actions.d.ts +13 -0
  45. package/dist/helpers/form-actions.d.ts.map +1 -0
  46. package/dist/helpers/form-actions.js +144 -0
  47. package/dist/helpers/form-sources.d.ts +7 -0
  48. package/dist/helpers/form-sources.d.ts.map +1 -0
  49. package/dist/helpers/form-sources.js +47 -0
  50. package/dist/helpers/form-state.d.ts +94 -0
  51. package/dist/helpers/form-state.d.ts.map +1 -0
  52. package/dist/helpers/form-state.js +870 -0
  53. package/dist/helpers/index.d.ts +114 -1
  54. package/dist/helpers/index.d.ts.map +1 -1
  55. package/dist/helpers/index.js +9 -4
  56. package/dist/helpers/match-inputs.d.ts +14 -0
  57. package/dist/helpers/match-inputs.d.ts.map +1 -1
  58. package/dist/helpers/match-inputs.js +154 -41
  59. package/dist/helpers/money.d.ts +12 -0
  60. package/dist/helpers/money.d.ts.map +1 -0
  61. package/dist/helpers/money.js +54 -0
  62. package/dist/helpers/spoken-money.d.ts +20 -0
  63. package/dist/helpers/spoken-money.d.ts.map +1 -0
  64. package/dist/helpers/spoken-money.js +143 -0
  65. package/dist/host/action-journal.d.ts +98 -0
  66. package/dist/host/action-journal.d.ts.map +1 -0
  67. package/dist/host/action-journal.js +218 -0
  68. package/dist/host/action-session.d.ts +12 -0
  69. package/dist/host/action-session.d.ts.map +1 -0
  70. package/dist/host/action-session.js +29 -0
  71. package/dist/host/capabilities.d.ts +14 -0
  72. package/dist/host/capabilities.d.ts.map +1 -0
  73. package/dist/host/capabilities.js +60 -0
  74. package/dist/host/checkpoint-codec-error.d.ts +6 -0
  75. package/dist/host/checkpoint-codec-error.d.ts.map +1 -0
  76. package/dist/host/checkpoint-codec-error.js +4 -0
  77. package/dist/host/index.d.ts +6 -0
  78. package/dist/host/index.d.ts.map +1 -1
  79. package/dist/host/index.js +6 -0
  80. package/dist/host/intent-stages.d.ts +1 -0
  81. package/dist/host/intent-stages.d.ts.map +1 -1
  82. package/dist/host/intent-stages.js +3 -3
  83. package/dist/host/node.d.ts +17 -0
  84. package/dist/host/node.d.ts.map +1 -0
  85. package/dist/host/node.js +64 -0
  86. package/dist/host/recovery-identity.d.ts +16 -0
  87. package/dist/host/recovery-identity.d.ts.map +1 -0
  88. package/dist/host/recovery-identity.js +73 -0
  89. package/dist/host/recovery-policy.d.ts +5 -0
  90. package/dist/host/recovery-policy.d.ts.map +1 -0
  91. package/dist/host/recovery-policy.js +54 -0
  92. package/dist/host/runtime-manifest.d.ts +3 -0
  93. package/dist/host/runtime-manifest.d.ts.map +1 -0
  94. package/dist/host/runtime-manifest.js +38 -0
  95. package/dist/index.d.ts +61 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +186 -45
  98. package/dist/runtime-identity.d.ts +3 -0
  99. package/dist/runtime-identity.d.ts.map +1 -0
  100. package/dist/runtime-identity.js +1 -0
  101. package/docs/development-release.md +25 -0
  102. package/docs/forms.md +132 -0
  103. package/package.json +15 -4
@@ -0,0 +1,707 @@
1
+ /** Shared platform choice transport, moved into JSFE so all hosts use one implementation. */
2
+ export const FLOWS = [
3
+ {
4
+ "id": "ask-choice",
5
+ "name": "AskChoice",
6
+ "version": "1.19.0",
7
+ "description": "Worker: ask one question; sets cargo.choice (the matched key, or 'other' with accept_other) and cargo.choiceText. AGENT / 0 reaches a person, EXIT / * ends, a new request is DISPATCHed. With amount: an answer naming an amount returns 'amount' — one marked as money ($, dollars, cents, decimals), or, when it matched no choice, any answer amountInAnswer reads as one (\"109 con 47\"), except an answer with a single digit and no payment verb (\"5\", \"5 please\"), which is a key press (\"pay 5\" is an amount). An exact choice keyed no / decline / done / cancel (or negative) is picked only by its own words and keys, never by a refusal or a deferral. Optional answer_precheck: a caller flow run with { answer } BEFORE the choices are matched; an answer_key it sets wins (the answer_validator contract, which runs only when no choice matched). A caller-set one-time offer (cargo.switchOffer = { text, text_es, words, flow }) is added to the question and consumed by it: an answer in its words runs its flow (reboot) — e.g. ANOTHER ACCOUNT when the account question was skipped (owner 2026-10-17). Optional reask_long: a long answer that matches nothing is asked again once before it is DISPATCHed. Params: question(_es), choices [{key, words, negative?, neutral?}], retry(_es), accept_other, expect ('number' | 'email' | 'contact'), amount, digits, exit_context(_es). With amount: 'marked' (owner 2026-10-18), only a marked amount is one: '$', a dollar or cents word, a decimal, or 'con' / 'and' with two digits ('102 con 21'); a bare number is not.",
8
+ "parameters": [
9
+ { "name": "form_context", "type": "object", "description": "Optional declared FORM reader context {form,current,names,questions}; valid field readings take precedence over stale verification-code echoes." },
10
+ {
11
+ "name": "question",
12
+ "type": "string",
13
+ "description": "The question (English)",
14
+ "required": true
15
+ },
16
+ {
17
+ "name": "question_es",
18
+ "type": "string",
19
+ "description": "The question (Spanish)",
20
+ "required": false
21
+ },
22
+ {
23
+ "name": "choices",
24
+ "type": "array",
25
+ "description": "[{key, words}] in priority order",
26
+ "required": true
27
+ },
28
+ {
29
+ "name": "retry",
30
+ "type": "string",
31
+ "description": "Re-ask wording (English); default \"Sorry, I didn't catch that.\" + the question",
32
+ "required": false
33
+ },
34
+ {
35
+ "name": "retry_es",
36
+ "type": "string",
37
+ "description": "Re-ask wording (Spanish)",
38
+ "required": false
39
+ },
40
+ {
41
+ "name": "accept_other",
42
+ "type": "boolean",
43
+ "description": "Return any other answer as choice \"other\" instead of re-asking",
44
+ "required": false
45
+ },
46
+ {
47
+ "name": "digits",
48
+ "type": "object",
49
+ "description": "Keypad input bounds {min, max} on voice",
50
+ "required": false
51
+ },
52
+ {
53
+ "name": "exit_context",
54
+ "type": "string",
55
+ "description": "What EXIT abandons, for the support message (English)",
56
+ "required": false
57
+ },
58
+ {
59
+ "name": "exit_context_es",
60
+ "type": "string",
61
+ "description": "What EXIT abandons (Spanish)",
62
+ "required": false
63
+ },
64
+ {
65
+ "name": "expect",
66
+ "type": "string",
67
+ "description": "With accept_other: what the answer should be — 'number', 'email' or 'contact' (either). Three or more words of neither shape are another request and are DISPATCHed"
68
+ },
69
+ {
70
+ "name": "amount",
71
+ "type": "boolean",
72
+ "description": "true on a payment question: the answer is kept as spoken (the question's asSpoken) and an answer that names an amount ($1, 1 dollar, 12.50) returns cargo.choice = 'amount' with the text — never a keypad key, never a DISPATCH"
73
+ },
74
+ {
75
+ "name": "pii",
76
+ "type": "boolean",
77
+ "description": "true when the answer is sensitive (a card's security code): every question here is a SAY-GET `pii` (jsfe >= 1.3.5), so the host keeps the answer out of its logs and records"
78
+ },
79
+ {
80
+ "name": "answer_validator",
81
+ "type": "string",
82
+ "description": "Optional flow name. When an answer picks no choice, it is called (call) with { answer } and MAY set answer_key to a choice key, which is then returned as cargo.choice; if it sets none, the answer is handled as before (amount check, re-ask). Fail-closed. The validator must end by completion: a RETURN in it terminates the conversation turn."
83
+ },
84
+ {
85
+ "name": "answer_precheck",
86
+ "type": "string",
87
+ "description": "Optional flow run with { answer } before the choices are matched; an answer_key it sets is the answer's key (for an answer that must not be read as a choice, such as a question)",
88
+ "required": false
89
+ },
90
+ {
91
+ "name": "reask_long",
92
+ "type": "boolean",
93
+ "description": "true: an answer of three words or more that matches no choice is asked again once (the retry question) instead of being DISPATCHed at once; the second miss is DISPATCHed. For a question whose loss costs the caller real work, e.g. the charge confirmation after a card was typed (owner 2026-10-17).",
94
+ "required": false
95
+ },
96
+ {
97
+ "name": "as_spoken",
98
+ "type": "boolean",
99
+ "description": "Keep exact speech independently of numeric or amount semantics"
100
+ }
101
+ ],
102
+ "variables": {
103
+ "ac_answer": {
104
+ "type": "string",
105
+ "value": ""
106
+ },
107
+ "ac_key": {
108
+ "type": "string",
109
+ "value": ""
110
+ },
111
+ "ac_other": {
112
+ "type": "boolean",
113
+ "value": false
114
+ },
115
+ "ac_q_es": {
116
+ "type": "string",
117
+ "value": ""
118
+ },
119
+ "ac_retry": {
120
+ "type": "string",
121
+ "value": ""
122
+ },
123
+ "ac_retry_es": {
124
+ "type": "string",
125
+ "value": ""
126
+ },
127
+ "ac_exit_ctx": {
128
+ "type": "string",
129
+ "value": ""
130
+ },
131
+ "ac_exit_ctx_es": {
132
+ "type": "string",
133
+ "value": ""
134
+ },
135
+ "ac_missed": {
136
+ "type": "boolean",
137
+ "value": false
138
+ },
139
+ "answer_key": {
140
+ "type": "string",
141
+ "description": "Set by answer_validator: the choice key the answer stands for, or empty",
142
+ "value": ""
143
+ },
144
+ "ac_offer": {
145
+ "type": "object",
146
+ "value": null
147
+ },
148
+ "ac_q": {
149
+ "type": "string",
150
+ "value": ""
151
+ },
152
+ "ac_code": {
153
+ "type": "string",
154
+ "value": ""
155
+ },
156
+ "ac_late": {
157
+ "type": "boolean",
158
+ "value": false
159
+ },
160
+ "ac_marked": {
161
+ "type": "boolean",
162
+ "value": false
163
+ },
164
+ "as_spoken": {
165
+ "type": "boolean",
166
+ "value": false
167
+ },
168
+ "contract": {
169
+ "type": "object",
170
+ "value": {
171
+ "version": 1,
172
+ "role": "collector",
173
+ "summary": "Shared channel input transport and platform choice handling",
174
+ "parametersFrom": "parameters"
175
+ }
176
+ }
177
+ },
178
+ "steps": [
179
+ {
180
+ "id": "ac_reset",
181
+ "type": "SET",
182
+ "variable": "assignment_side_effect",
183
+ "value": "cargo.choice = '', cargo.choiceText = ''"
184
+ },
185
+ {
186
+ "id": "ac_accepts_other",
187
+ "type": "SET",
188
+ "variable": "ac_other",
189
+ "value": "typeof accept_other !== 'undefined' && (accept_other === true || accept_other === 'true')"
190
+ },
191
+ {
192
+ "id": "ac_takes_amount",
193
+ "type": "SET",
194
+ "variable": "ac_amount",
195
+ "value": "typeof amount !== 'undefined' && (amount === true || amount === 'true' || amount === 'marked')"
196
+ },
197
+ {
198
+ "id": "ac_takes_marked_amount",
199
+ "type": "SET",
200
+ "variable": "ac_marked",
201
+ "value": "typeof amount !== 'undefined' && amount === 'marked'"
202
+ },
203
+ {
204
+ "id": "ac_takes_pii",
205
+ "type": "SET",
206
+ "variable": "ac_pii",
207
+ "value": "typeof pii !== 'undefined' && (pii === true || pii === 'true')"
208
+ },
209
+ {
210
+ "id": "ac_question_es",
211
+ "type": "SET",
212
+ "variable": "ac_q_es",
213
+ "value": "typeof question_es !== 'undefined' && question_es ? question_es : question"
214
+ },
215
+ {
216
+ "id": "ac_retry_en",
217
+ "type": "SET",
218
+ "variable": "ac_retry",
219
+ "value": "typeof retry !== 'undefined' && retry ? retry : \"Sorry, I didn't catch that. \" + question"
220
+ },
221
+ {
222
+ "id": "ac_retry_spanish",
223
+ "type": "SET",
224
+ "variable": "ac_retry_es",
225
+ "value": "typeof retry_es !== 'undefined' && retry_es ? retry_es : 'Disculpe, no le entendí. ' + ac_q_es"
226
+ },
227
+ {
228
+ "id": "ac_exit_context",
229
+ "type": "SET",
230
+ "variable": "ac_exit_ctx",
231
+ "value": "typeof exit_context !== 'undefined' && exit_context ? exit_context : 'your request'"
232
+ },
233
+ {
234
+ "id": "ac_exit_context_es",
235
+ "type": "SET",
236
+ "variable": "ac_exit_ctx_es",
237
+ "value": "typeof exit_context_es !== 'undefined' && exit_context_es ? exit_context_es : 'su solicitud'"
238
+ },
239
+ {
240
+ "id": "ac_keypad",
241
+ "type": "SET",
242
+ "variable": "assignment_side_effect",
243
+ "value": "(cargo.digits = typeof digits !== 'undefined' && digits && typeof digits === 'object' ? digits : undefined, true)"
244
+ },
245
+ {
246
+ "id": "ac_late_code_take",
247
+ "type": "SET",
248
+ "variable": "ac_code",
249
+ "value": "(function(d) { cargo.otpLateCode = ''; return d.length === 6 && !(typeof expect !== 'undefined' && expect) && !ac_amount ? d : ''; })(String(cargo.otpLateCode || ''))"
250
+ },
251
+ {
252
+ "id": "ac_take_offer",
253
+ "type": "SET",
254
+ "variable": "ac_offer",
255
+ "value": "takeChoiceOffer(cargo)"
256
+ },
257
+ {
258
+ "id": "ac_question_with_offer",
259
+ "type": "SET",
260
+ "variable": "ac_q",
261
+ "value": "question + (ac_offer && ac_offer.text ? ' ' + ac_offer.text : '')"
262
+ },
263
+ {
264
+ "id": "ac_question_with_offer_es",
265
+ "type": "SET",
266
+ "variable": "ac_q_es",
267
+ "value": "ac_q_es + (ac_offer && (ac_offer.text_es || ac_offer.text) ? ' ' + (ac_offer.text_es || ac_offer.text) : '')"
268
+ },
269
+ {
270
+ "id": "ac_ask",
271
+ "type": "SAY-GET",
272
+ "variable": "ac_answer",
273
+ "asSpoken": "ac_amount === true || as_spoken === true",
274
+ "value": "{{ac_q}}",
275
+ "value_es": "{{ac_q_es}}",
276
+ "pii": "ac_pii === true"
277
+ },
278
+ {
279
+ "id": "ac_late_code_check",
280
+ "type": "SET",
281
+ "variable": "ac_late",
282
+ "value": "(function(t, c) { if (typeof form_context !== 'undefined' && form_context && form_context.form) { var fc=form_context, chain=formInputChain(cargo.forms,fc.form,cargo), read=readFormAnswer(t,chain,Array.isArray(fc.names)&&fc.names.length>1?{form:fc.form,names:fc.names}:{form:fc.form,name:fc.current},'',fc.questions||[]); if(read.hits.length || read.ambiguous.length || read.questions.length) return false; } t = String(t || '').trim(); c = String(c || ''); if (c.length !== 6) { return false; } var rest = t.replace(/^(?:(?:el|mi|the|my)\\s+)?(?:c[oó]digo|code)(?:\\s+(?:es|is|era|was))?\\s*[:,.-]?\\s*/i, ''); if (!/^[\\d\\s.,-]+$/.test(rest)) { return false; } var d = rest.replace(/\\D/g, ''); return d.length >= 2 && d.length <= 6 && c.indexOf(d) >= 0; })(ac_answer, ac_code)"
283
+ },
284
+ {
285
+ "id": "ac_late_code_reask",
286
+ "type": "CASE",
287
+ "branches": {
288
+ "condition: ac_late": {
289
+ "id": "ac_late_code_again",
290
+ "type": "FLOW",
291
+ "value": "late-code-reask",
292
+ "callType": "call",
293
+ "parameters": {
294
+ "question": "{{ac_q}}",
295
+ "question_es": "{{ac_q_es}}",
296
+ "code": "{{ac_code}}"
297
+ }
298
+ },
299
+ "default": {
300
+ "id": "ac_late_code_none",
301
+ "type": "SET",
302
+ "variable": "noop",
303
+ "value": "true"
304
+ }
305
+ }
306
+ },
307
+ {
308
+ "id": "ac_late_code_answer",
309
+ "type": "SET",
310
+ "variable": "ac_answer",
311
+ "value": "ac_late ? String(cargo.lateCodeAnswer || '') : ac_answer"
312
+ },
313
+ {
314
+ "id": "ac_late_code_clear",
315
+ "type": "SET",
316
+ "variable": "assignment_side_effect",
317
+ "value": "(cargo.lateCodeAnswer = '', true)"
318
+ },
319
+ {
320
+ "id": "ac_repeat_1",
321
+ "type": "CASE",
322
+ "branches": {
323
+ "condition: /^[\\s¿¡]*(?:(?:por favor|please|a|que|me lo|me|lo|puede|can you|could you)\\s+)*(?:repetir|repite|rep[ií]t[ae](?:lo|la|me|melo|nos)?|rep[ií]tamelo|otra vez|de nuevo|repeat(?:\\s+(?:that|it))?|say (?:that|it) again|again|one more time)(?:\\s+(?:por favor|please|la pregunta|las opciones|eso|that|it))*[\\s.!?¿,]*$/i.test(String(ac_answer || '')) && pickChoice(ac_answer, choices, ac_other) === ''": {
324
+ "id": "ac_repeat_ask_1",
325
+ "type": "SAY-GET",
326
+ "variable": "ac_answer",
327
+ "asSpoken": "ac_amount === true || as_spoken === true",
328
+ "value": "{{ac_q}}",
329
+ "value_es": "{{ac_q_es}}",
330
+ "pii": "ac_pii === true"
331
+ },
332
+ "default": {
333
+ "id": "ac_no_repeat_1",
334
+ "type": "SET",
335
+ "variable": "noop",
336
+ "value": "true"
337
+ }
338
+ }
339
+ },
340
+ {
341
+ "id": "ac_repeat_2",
342
+ "type": "CASE",
343
+ "branches": {
344
+ "condition: /^[\\s¿¡]*(?:(?:por favor|please|a|que|me lo|me|lo|puede|can you|could you)\\s+)*(?:repetir|repite|rep[ií]t[ae](?:lo|la|me|melo|nos)?|rep[ií]tamelo|otra vez|de nuevo|repeat(?:\\s+(?:that|it))?|say (?:that|it) again|again|one more time)(?:\\s+(?:por favor|please|la pregunta|las opciones|eso|that|it))*[\\s.!?¿,]*$/i.test(String(ac_answer || '')) && pickChoice(ac_answer, choices, ac_other) === ''": {
345
+ "id": "ac_repeat_ask_2",
346
+ "type": "SAY-GET",
347
+ "variable": "ac_answer",
348
+ "asSpoken": "ac_amount === true || as_spoken === true",
349
+ "value": "{{ac_q}}",
350
+ "value_es": "{{ac_q_es}}",
351
+ "pii": "ac_pii === true"
352
+ },
353
+ "default": {
354
+ "id": "ac_no_repeat_2",
355
+ "type": "SET",
356
+ "variable": "noop",
357
+ "value": "true"
358
+ }
359
+ }
360
+ },
361
+ {
362
+ "id": "ac_init_precheck_key",
363
+ "type": "SET",
364
+ "variable": "answer_key",
365
+ "value": "''"
366
+ },
367
+ {
368
+ "id": "ac_precheck",
369
+ "type": "CASE",
370
+ "branches": {
371
+ "condition: typeof answer_precheck !== 'undefined' && answer_precheck && String(ac_answer || '').trim()": {
372
+ "id": "ac_run_precheck",
373
+ "type": "FLOW",
374
+ "value": "{{answer_precheck}}",
375
+ "callType": "call",
376
+ "parameters": {
377
+ "answer": "{{ac_answer}}"
378
+ }
379
+ },
380
+ "default": {
381
+ "id": "ac_no_precheck",
382
+ "type": "SET",
383
+ "variable": "noop_precheck",
384
+ "value": "true"
385
+ }
386
+ }
387
+ },
388
+ {
389
+ "id": "ac_precheck_key",
390
+ "type": "SET",
391
+ "variable": "ac_prechecked",
392
+ "value": "typeof answer_key !== 'undefined' && answer_key ? String(answer_key) : ''"
393
+ },
394
+ {
395
+ "id": "ac_match",
396
+ "type": "SET",
397
+ "variable": "ac_key",
398
+ "value": "ac_prechecked ? ac_prechecked : pickChoice(ac_answer, choices, ac_other)"
399
+ },
400
+ {
401
+ "id": "ac_match_offer",
402
+ "type": "SET",
403
+ "variable": "ac_key",
404
+ "value": "ac_offer && Array.isArray(ac_offer.words) && matchesChoice(ac_answer, ac_offer.words) ? '__switch' : ac_key"
405
+ },
406
+ {
407
+ "id": "ac_exact_no_own_words",
408
+ "type": "SET",
409
+ "variable": "ac_key",
410
+ "value": "(function() { var cs = Array.isArray(choices) ? choices : []; var isExactNo = function(c) { return !!c && c.exact === true && (['no', 'decline', 'done', 'cancel'].indexOf(c.key) > -1 || c.negative === true); }; var c = cs.filter(function(x) { return !!x && x.key === ac_key; })[0]; if (!isExactNo(c)) { return ac_key; } else if (pickChoice(ac_answer, [{ key: 'ac_own', words: c.words, exact: true }], false) === 'ac_own') { return ac_key; } else { return pickChoice(ac_answer, cs.filter(function(x) { return !isExactNo(x); }), ac_other); } })()"
411
+ },
412
+ {
413
+ "id": "ac_init_answer_key",
414
+ "type": "SET",
415
+ "variable": "answer_key",
416
+ "value": "''"
417
+ },
418
+ {
419
+ "id": "ac_validate_answer",
420
+ "type": "CASE",
421
+ "branches": {
422
+ "condition: ac_key === '' && typeof answer_validator !== 'undefined' && answer_validator && String(ac_answer || '').trim()": {
423
+ "id": "ac_run_answer_validator",
424
+ "type": "FLOW",
425
+ "value": "{{answer_validator}}",
426
+ "callType": "call",
427
+ "parameters": {
428
+ "answer": "{{ac_answer}}"
429
+ }
430
+ },
431
+ "default": {
432
+ "id": "ac_no_answer_validator",
433
+ "type": "SET",
434
+ "variable": "noop_answer_validator",
435
+ "value": "true"
436
+ }
437
+ }
438
+ },
439
+ {
440
+ "id": "ac_take_answer_key",
441
+ "type": "SET",
442
+ "variable": "ac_key",
443
+ "value": "ac_key === '' && typeof answer_key !== 'undefined' && answer_key ? String(answer_key) : ac_key"
444
+ },
445
+ {
446
+ "id": "ac_amount_check",
447
+ "type": "SET",
448
+ "variable": "ac_key",
449
+ "value": "ac_amount && (isAmountAnswer(ac_answer) || (ac_marked ? (ac_key === '' && /\\d\\s*(?:con|and)\\s*(?:un\\s+)?\\d{2}\\b(?!\\s*\\d)/i.test(String(ac_answer || ''))) : (ac_key === '' && (!/^\\D*\\d\\D*$/.test(String(ac_answer || '')) || /\\b(?:pay|paying|pagar|pagarle|abonar)\\b/i.test(String(ac_answer || ''))) && !/^[\\s,.;]*\\d(?:[\\s,.;]+\\d)+[\\s,.;]*$/.test(String(ac_answer || '')) && !isNaN(amountInAnswer(ac_answer))))) ? '__amount' : ac_key"
450
+ },
451
+ {
452
+ "id": "ac_switch_to_text_key",
453
+ "type": "SET",
454
+ "variable": "ac_key",
455
+ "value": "ac_key === '' && !ac_other && !ac_amount && cargo.voice && String(ac_answer || '').trim() === '9' && !!callerTextNumber(cargo) ? '__text' : ac_key"
456
+ },
457
+ {
458
+ "id": "ac_keypad_again",
459
+ "type": "SET",
460
+ "variable": "assignment_side_effect",
461
+ "value": "(cargo.digits = typeof digits !== 'undefined' && digits && typeof digits === 'object' ? digits : undefined, true)"
462
+ },
463
+ {
464
+ "id": "ac_missed_once",
465
+ "type": "SET",
466
+ "variable": "ac_missed",
467
+ "value": "ac_key === '' && !ac_other && (String(ac_answer || '').split(/\\s+/).filter(function(w) { return /[a-záéíóúüñ]/i.test(w); }).length < 3 || (typeof reask_long !== 'undefined' && (reask_long === true || reask_long === 'true')))"
468
+ },
469
+ {
470
+ "id": "ac_reask_on_miss",
471
+ "type": "CASE",
472
+ "branches": {
473
+ "condition: ac_missed": {
474
+ "id": "ac_reask",
475
+ "type": "SAY-GET",
476
+ "variable": "ac_answer",
477
+ "asSpoken": "ac_amount === true || as_spoken === true",
478
+ "value": "{{ac_retry}}",
479
+ "value_es": "{{ac_retry_es}}",
480
+ "pii": "ac_pii === true"
481
+ },
482
+ "default": {
483
+ "id": "ac_no_reask",
484
+ "type": "SET",
485
+ "variable": "noop",
486
+ "value": "true"
487
+ }
488
+ }
489
+ },
490
+ {
491
+ "id": "ac_repeat_after_miss_1",
492
+ "type": "CASE",
493
+ "branches": {
494
+ "condition: ac_missed && /^[\\s¿¡]*(?:(?:por favor|please|a|que|me lo|me|lo|puede|can you|could you)\\s+)*(?:repetir|repite|rep[ií]t[ae](?:lo|la|me|melo|nos)?|rep[ií]tamelo|otra vez|de nuevo|repeat(?:\\s+(?:that|it))?|say (?:that|it) again|again|one more time)(?:\\s+(?:por favor|please|la pregunta|las opciones|eso|that|it))*[\\s.!?¿,]*$/i.test(String(ac_answer || '')) && pickChoice(ac_answer, choices, ac_other) === ''": {
495
+ "id": "ac_repeat_after_miss_ask_1",
496
+ "type": "SAY-GET",
497
+ "variable": "ac_answer",
498
+ "asSpoken": "ac_amount === true || as_spoken === true",
499
+ "value": "{{ac_q}}",
500
+ "value_es": "{{ac_q_es}}",
501
+ "pii": "ac_pii === true"
502
+ },
503
+ "default": {
504
+ "id": "ac_no_repeat_after_miss_1",
505
+ "type": "SET",
506
+ "variable": "noop",
507
+ "value": "true"
508
+ }
509
+ }
510
+ },
511
+ {
512
+ "id": "ac_repeat_after_miss_2",
513
+ "type": "CASE",
514
+ "branches": {
515
+ "condition: ac_missed && /^[\\s¿¡]*(?:(?:por favor|please|a|que|me lo|me|lo|puede|can you|could you)\\s+)*(?:repetir|repite|rep[ií]t[ae](?:lo|la|me|melo|nos)?|rep[ií]tamelo|otra vez|de nuevo|repeat(?:\\s+(?:that|it))?|say (?:that|it) again|again|one more time)(?:\\s+(?:por favor|please|la pregunta|las opciones|eso|that|it))*[\\s.!?¿,]*$/i.test(String(ac_answer || '')) && pickChoice(ac_answer, choices, ac_other) === ''": {
516
+ "id": "ac_repeat_after_miss_ask_2",
517
+ "type": "SAY-GET",
518
+ "variable": "ac_answer",
519
+ "asSpoken": "ac_amount === true || as_spoken === true",
520
+ "value": "{{ac_q}}",
521
+ "value_es": "{{ac_q_es}}",
522
+ "pii": "ac_pii === true"
523
+ },
524
+ "default": {
525
+ "id": "ac_no_repeat_after_miss_2",
526
+ "type": "SET",
527
+ "variable": "noop",
528
+ "value": "true"
529
+ }
530
+ }
531
+ },
532
+ {
533
+ "id": "ac_init_precheck_key_again",
534
+ "type": "SET",
535
+ "variable": "answer_key",
536
+ "value": "''"
537
+ },
538
+ {
539
+ "id": "ac_precheck_again",
540
+ "type": "CASE",
541
+ "branches": {
542
+ "condition: typeof answer_precheck !== 'undefined' && answer_precheck && String(ac_answer || '').trim()": {
543
+ "id": "ac_run_precheck_again",
544
+ "type": "FLOW",
545
+ "value": "{{answer_precheck}}",
546
+ "callType": "call",
547
+ "parameters": {
548
+ "answer": "{{ac_answer}}"
549
+ }
550
+ },
551
+ "default": {
552
+ "id": "ac_no_precheck_again",
553
+ "type": "SET",
554
+ "variable": "noop_precheck",
555
+ "value": "true"
556
+ }
557
+ }
558
+ },
559
+ {
560
+ "id": "ac_precheck_key_again",
561
+ "type": "SET",
562
+ "variable": "ac_prechecked",
563
+ "value": "typeof answer_key !== 'undefined' && answer_key ? String(answer_key) : ''"
564
+ },
565
+ {
566
+ "id": "ac_match_again",
567
+ "type": "SET",
568
+ "variable": "ac_key",
569
+ "value": "ac_prechecked ? ac_prechecked : (ac_key === '' && !ac_other ? pickChoice(ac_answer, choices, ac_other) : ac_key)"
570
+ },
571
+ {
572
+ "id": "ac_match_again_offer",
573
+ "type": "SET",
574
+ "variable": "ac_key",
575
+ "value": "ac_offer && Array.isArray(ac_offer.words) && matchesChoice(ac_answer, ac_offer.words) ? '__switch' : ac_key"
576
+ },
577
+ {
578
+ "id": "ac_exact_no_own_words_again",
579
+ "type": "SET",
580
+ "variable": "ac_key",
581
+ "value": "ac_key === '' ? ac_key : (function() { var cs = Array.isArray(choices) ? choices : []; var isExactNo = function(c) { return !!c && c.exact === true && (['no', 'decline', 'done', 'cancel'].indexOf(c.key) > -1 || c.negative === true); }; var c = cs.filter(function(x) { return !!x && x.key === ac_key; })[0]; if (!isExactNo(c)) { return ac_key; } else if (pickChoice(ac_answer, [{ key: 'ac_own', words: c.words, exact: true }], false) === 'ac_own') { return ac_key; } else { return pickChoice(ac_answer, cs.filter(function(x) { return !isExactNo(x); }), ac_other); } })()"
582
+ },
583
+ {
584
+ "id": "ac_init_answer_key_again",
585
+ "type": "SET",
586
+ "variable": "answer_key",
587
+ "value": "''"
588
+ },
589
+ {
590
+ "id": "ac_validate_answer_again",
591
+ "type": "CASE",
592
+ "branches": {
593
+ "condition: ac_key === '' && typeof answer_validator !== 'undefined' && answer_validator && String(ac_answer || '').trim()": {
594
+ "id": "ac_run_answer_validator_again",
595
+ "type": "FLOW",
596
+ "value": "{{answer_validator}}",
597
+ "callType": "call",
598
+ "parameters": {
599
+ "answer": "{{ac_answer}}"
600
+ }
601
+ },
602
+ "default": {
603
+ "id": "ac_no_answer_validator_again",
604
+ "type": "SET",
605
+ "variable": "noop_answer_validator",
606
+ "value": "true"
607
+ }
608
+ }
609
+ },
610
+ {
611
+ "id": "ac_take_answer_key_again",
612
+ "type": "SET",
613
+ "variable": "ac_key",
614
+ "value": "ac_key === '' && typeof answer_key !== 'undefined' && answer_key ? String(answer_key) : ac_key"
615
+ },
616
+ {
617
+ "id": "ac_amount_check_again",
618
+ "type": "SET",
619
+ "variable": "ac_key",
620
+ "value": "ac_amount && (isAmountAnswer(ac_answer) || (ac_marked ? (ac_key === '' && /\\d\\s*(?:con|and)\\s*(?:un\\s+)?\\d{2}\\b(?!\\s*\\d)/i.test(String(ac_answer || ''))) : (ac_key === '' && (!/^\\D*\\d\\D*$/.test(String(ac_answer || '')) || /\\b(?:pay|paying|pagar|pagarle|abonar)\\b/i.test(String(ac_answer || ''))) && !/^[\\s,.;]*\\d(?:[\\s,.;]+\\d)+[\\s,.;]*$/.test(String(ac_answer || '')) && !isNaN(amountInAnswer(ac_answer))))) ? '__amount' : ac_key"
621
+ },
622
+ {
623
+ "id": "ac_other_request_check",
624
+ "type": "SET",
625
+ "variable": "ac_key",
626
+ "value": "ac_key === '' && ac_other && typeof expect !== 'undefined' && expect && isOtherRequest(ac_answer, expect) ? '__elsewhere' : ac_key"
627
+ },
628
+ {
629
+ "id": "ac_switch_to_text_key_again",
630
+ "type": "SET",
631
+ "variable": "ac_key",
632
+ "value": "ac_key === '' && !ac_other && !ac_amount && cargo.voice && String(ac_answer || '').trim() === '9' && !!callerTextNumber(cargo) ? '__text' : ac_key"
633
+ },
634
+ {
635
+ "id": "ac_keypad_done",
636
+ "type": "SET",
637
+ "variable": "assignment_side_effect",
638
+ "value": "(cargo.digits = undefined, (ac_key === '__agent' || ac_key === '__exit' || ac_key === '__elsewhere' || (ac_key === '' && !ac_other)) && Array.isArray(cargo.sensitive) ? cargo.sensitive.forEach(function(p) { var o = cargo, k = String(p).split('.'); for (var i = 0; i < k.length - 1 && o; i++) { o = o[k[i]]; } if (o && typeof o === 'object') { o[k[k.length - 1]] = null; } }) : null, true)"
639
+ },
640
+ {
641
+ "id": "ac_route",
642
+ "type": "CASE",
643
+ "branches": {
644
+ "condition: ac_key === '__switch'": {
645
+ "id": "ac_offer_taken",
646
+ "type": "FLOW",
647
+ "value": "{{ac_offer.flow}}",
648
+ "callType": "reboot"
649
+ },
650
+ "condition: ac_key === '__agent'": {
651
+ "id": "ac_agent",
652
+ "type": "FLOW",
653
+ "value": "live-agent-requested",
654
+ "callType": "reboot"
655
+ },
656
+ "condition: ac_key === '__exit'": {
657
+ "id": "ac_exit",
658
+ "type": "FLOW",
659
+ "value": "contact-support",
660
+ "callType": "reboot",
661
+ "parameters": {
662
+ "support_context": "{{ac_exit_ctx}}",
663
+ "support_context_es": "{{ac_exit_ctx_es}}"
664
+ }
665
+ },
666
+ "condition: ac_key === '__text'": {
667
+ "id": "ac_switch_to_text",
668
+ "type": "FLOW",
669
+ "value": "switch-to-text",
670
+ "callType": "reboot"
671
+ },
672
+ "condition: ac_key === '__amount'": {
673
+ "id": "ac_return_amount",
674
+ "type": "SET",
675
+ "variable": "assignment_side_effect",
676
+ "value": "cargo.choice = 'amount', cargo.choiceText = String(ac_answer || '').replace(/\\\\(['\"\\\\])/g, '$1')"
677
+ },
678
+ "condition: ac_key === '__elsewhere'": {
679
+ "id": "ac_elsewhere",
680
+ "type": "DISPATCH",
681
+ "outcome": "{{ac_exit_ctx === 'payment' ? 'unresolved' : ''}}",
682
+ "reason": "{{ac_exit_ctx === 'payment' ? 'payment_incomplete' : ''}}"
683
+ },
684
+ "condition: ac_key === '' && ac_other": {
685
+ "id": "ac_return_other",
686
+ "type": "SET",
687
+ "variable": "assignment_side_effect",
688
+ "value": "cargo.choice = 'other', cargo.choiceText = String(ac_answer || '').replace(/\\\\(['\"\\\\])/g, '$1')"
689
+ },
690
+ "condition: ac_key === ''": {
691
+ "id": "ac_other_request",
692
+ "type": "DISPATCH",
693
+ "outcome": "{{ac_exit_ctx === 'payment' ? 'unresolved' : ''}}",
694
+ "reason": "{{ac_exit_ctx === 'payment' ? 'payment_incomplete' : ''}}"
695
+ },
696
+ "default": {
697
+ "id": "ac_return_choice",
698
+ "type": "SET",
699
+ "variable": "assignment_side_effect",
700
+ "value": "cargo.choice = ac_key, cargo.choiceText = String(ac_answer || '').replace(/\\\\(['\"\\\\])/g, '$1')"
701
+ }
702
+ }
703
+ }
704
+ ],
705
+ "scope": "isolated"
706
+ }
707
+ ];