@case-framework/survey-core 0.1.0

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.
@@ -0,0 +1,1586 @@
1
+ import { C as ValueReference, D as structuredCloneMethod, E as shuffleIndices, S as ReferenceUsageType, T as generateId, _ as Expression, a as validateLocale, b as FunctionExpressionNames, c as SurveyItemCore, d as deserializeTemplateValues, f as serializeTemplateValue, g as ContextVariableType, h as ContextVariableExpression, i as SurveyTranslations, l as TemplateDefTypes, m as ConstExpression, o as SurveyItemKey, p as serializeTemplateValues, r as SurveyItemTranslations, s as ReservedSurveyItemTypes, t as Survey, u as deserializeTemplateValue, v as ExpressionType, w as ValueReferenceMethod, x as ResponseVariableExpression, y as FunctionExpression } from "./survey-C3ZHI-5z.mjs";
2
+ import { format } from "date-fns";
3
+ import { enUS } from "date-fns/locale";
4
+
5
+ //#region src/to_mirgrate/data_types/legacy-types.ts
6
+ const isLegacyItemGroupComponent = (item) => {
7
+ const items = item.items;
8
+ return items !== void 0 && items.length > 0;
9
+ };
10
+ const isLegacySurveyGroupItem = (item) => {
11
+ const items = item.items;
12
+ return items !== void 0 && items.length > 0;
13
+ };
14
+
15
+ //#endregion
16
+ //#region src/survey/responses/item-response.ts
17
+ /**
18
+ * SurveyItemResponse to store the response of a survey item.
19
+ */
20
+ var SurveyItemResponse = class SurveyItemResponse {
21
+ itemId;
22
+ meta;
23
+ response;
24
+ itemType;
25
+ constructor(itemDef, response) {
26
+ this.itemId = itemDef.itemId;
27
+ this.response = response;
28
+ this.itemType = itemDef.itemType;
29
+ }
30
+ serialize() {
31
+ return {
32
+ itemId: this.itemId,
33
+ itemType: this.itemType,
34
+ meta: this.meta,
35
+ response: this.response?.serialize()
36
+ };
37
+ }
38
+ static deserialize(json) {
39
+ const newResponse = new SurveyItemResponse({
40
+ itemId: json.itemId,
41
+ itemType: json.itemType
42
+ }, json.response ? ResponseItem.deserialize(json.response) : void 0);
43
+ newResponse.meta = json.meta;
44
+ return newResponse;
45
+ }
46
+ };
47
+ var ResponseItem = class ResponseItem {
48
+ _slots;
49
+ constructor(initialValues) {
50
+ this._slots = new Map(initialValues ?? []);
51
+ }
52
+ get(slotId) {
53
+ return this._slots.get(slotId);
54
+ }
55
+ setSlotValue(slotId, slotResponse) {
56
+ if (slotResponse) this._slots.set(slotId, slotResponse);
57
+ else this._slots.delete(slotId);
58
+ }
59
+ serialize() {
60
+ return { slotValues: Array.from(this._slots.entries()) };
61
+ }
62
+ clone() {
63
+ return new ResponseItem(Array.from(this._slots.entries()));
64
+ }
65
+ static deserialize(json) {
66
+ return new ResponseItem(json.slotValues);
67
+ }
68
+ };
69
+
70
+ //#endregion
71
+ //#region src/survey/responses/response-meta.ts
72
+ const SurveyEventTypes = {
73
+ openSurvey: "openSurvey",
74
+ pageChanged: "pageChanged",
75
+ responeChanged: "responeChanged",
76
+ languageChanged: "languageChanged"
77
+ };
78
+
79
+ //#endregion
80
+ //#region src/survey/responses/survey-response.ts
81
+ /**
82
+ * SurveyResponse to store the responses of a survey.
83
+ */
84
+ var SurveyResponse = class SurveyResponse {
85
+ key;
86
+ participantId;
87
+ submittedAt;
88
+ versionId;
89
+ responses;
90
+ events;
91
+ context;
92
+ constructor(key, versionId) {
93
+ this.key = key;
94
+ this.participantId = "";
95
+ this.submittedAt = 0;
96
+ this.versionId = versionId;
97
+ this.responses = /* @__PURE__ */ new Map();
98
+ this.events = [];
99
+ }
100
+ serialize() {
101
+ return {
102
+ key: this.key,
103
+ participantId: this.participantId,
104
+ submittedAt: this.submittedAt,
105
+ versionId: this.versionId,
106
+ responses: Array.from(this.responses.values()).map((r) => r.serialize()),
107
+ events: this.events,
108
+ context: this.context
109
+ };
110
+ }
111
+ static deserialize(json) {
112
+ const response = new SurveyResponse(json.key, json.versionId);
113
+ response.participantId = json.participantId;
114
+ response.submittedAt = json.submittedAt;
115
+ response.responses = new Map(json.responses.map((r) => [r.itemId, SurveyItemResponse.deserialize(r)]));
116
+ response.context = json.context;
117
+ return response;
118
+ }
119
+ };
120
+
121
+ //#endregion
122
+ //#region src/survey/responses/value-types.ts
123
+ const ValueType = {
124
+ string: "string",
125
+ duration: "duration",
126
+ reference: "reference",
127
+ number: "number",
128
+ boolean: "boolean",
129
+ date: "date",
130
+ stringArray: "string[]",
131
+ durationArray: "duration[]",
132
+ referenceArray: "reference[]",
133
+ numberArray: "number[]",
134
+ dateArray: "date[]"
135
+ };
136
+ const DurationUnits = {
137
+ seconds: "seconds",
138
+ minutes: "minutes",
139
+ hours: "hours",
140
+ days: "days",
141
+ weeks: "weeks",
142
+ months: "months",
143
+ years: "years"
144
+ };
145
+ const NumberPrecision = {
146
+ int: "int",
147
+ float: "float"
148
+ };
149
+
150
+ //#endregion
151
+ //#region src/survey/responses/utils.ts
152
+ const initValueForType = (returnType) => {
153
+ switch (returnType) {
154
+ case ValueType.string: return {
155
+ type: ValueType.string,
156
+ value: ""
157
+ };
158
+ case ValueType.number: return {
159
+ type: ValueType.number,
160
+ value: 0
161
+ };
162
+ case ValueType.boolean: return {
163
+ type: ValueType.boolean,
164
+ value: false
165
+ };
166
+ case ValueType.date: return {
167
+ type: ValueType.date,
168
+ value: Math.floor(Date.now() / 1e3)
169
+ };
170
+ case ValueType.stringArray: return {
171
+ type: ValueType.stringArray,
172
+ value: []
173
+ };
174
+ case ValueType.numberArray: return {
175
+ type: ValueType.numberArray,
176
+ value: []
177
+ };
178
+ case ValueType.dateArray: return {
179
+ type: ValueType.dateArray,
180
+ value: []
181
+ };
182
+ case ValueType.duration: return {
183
+ type: ValueType.duration,
184
+ value: 0,
185
+ unit: DurationUnits.seconds
186
+ };
187
+ case ValueType.reference: return {
188
+ type: ValueType.reference,
189
+ value: ""
190
+ };
191
+ case ValueType.durationArray: return {
192
+ type: ValueType.durationArray,
193
+ value: [],
194
+ unit: DurationUnits.seconds
195
+ };
196
+ case ValueType.referenceArray: return {
197
+ type: ValueType.referenceArray,
198
+ value: []
199
+ };
200
+ default: throw new Error("Invalid return type: " + returnType);
201
+ }
202
+ };
203
+
204
+ //#endregion
205
+ //#region src/expressions/expression-evaluator.ts
206
+ var ExpressionEvaluator = class {
207
+ context;
208
+ constructor(context) {
209
+ this.context = context;
210
+ }
211
+ eval(expression) {
212
+ if (expression === void 0) return;
213
+ switch (expression.type) {
214
+ case ExpressionType.Const: return this.evaluateConst(expression);
215
+ case ExpressionType.Function: return this.evaluateFunction(expression);
216
+ case ExpressionType.ResponseVariable: return this.evaluateResponseVariable(expression);
217
+ case ExpressionType.ContextVariable: return this.evaluateContextVariable(expression);
218
+ default: throw new Error(`Unsupported expression type: ${expression.type}`);
219
+ }
220
+ }
221
+ setContext(context) {
222
+ this.context = context;
223
+ }
224
+ evaluateConst(expression) {
225
+ return expression.value;
226
+ }
227
+ evaluateResponseVariable(expression) {
228
+ const varRef = expression.responseVariableRef;
229
+ switch (varRef.name) {
230
+ case ValueReferenceMethod.get: return this.context?.responses[varRef.itemId]?.response?.get(varRef.slotId);
231
+ case ValueReferenceMethod.isDefined: return {
232
+ type: ValueType.boolean,
233
+ value: this.context?.responses[varRef.itemId]?.response?.get(varRef.slotId) !== void 0
234
+ };
235
+ default: throw new Error(`Unsupported value reference method: ${varRef.name}`);
236
+ }
237
+ }
238
+ evaluateFunction(expression) {
239
+ switch (expression.functionName) {
240
+ case FunctionExpressionNames.and: return this.evaluateAnd(expression);
241
+ case FunctionExpressionNames.or: return this.evaluateOr(expression);
242
+ case FunctionExpressionNames.not: return this.evaluateNot(expression);
243
+ case FunctionExpressionNames.str_eq: return this.evaluateStrEq(expression);
244
+ case FunctionExpressionNames.eq: return this.evaluateEq(expression);
245
+ case FunctionExpressionNames.gt: return this.evaluateGt(expression);
246
+ case FunctionExpressionNames.gte: return this.evaluateGte(expression);
247
+ case FunctionExpressionNames.lt: return this.evaluateLt(expression);
248
+ case FunctionExpressionNames.lte: return this.evaluateLte(expression);
249
+ case FunctionExpressionNames.in_range: return this.evaluateInRange(expression);
250
+ case FunctionExpressionNames.sum: return this.evaluateSum(expression);
251
+ case FunctionExpressionNames.min: return this.evaluateMin(expression);
252
+ case FunctionExpressionNames.max: return this.evaluateMax(expression);
253
+ case FunctionExpressionNames.list_contains: return this.evaluateListContains(expression);
254
+ default: throw new Error(`Unsupported function: ${expression.functionName}`);
255
+ }
256
+ }
257
+ evaluateContextVariable(expression) {
258
+ if (!this.context?.surveyContext) return;
259
+ const surveyContext = this.context.surveyContext;
260
+ switch (expression.contextType) {
261
+ case ContextVariableType.Locale: return {
262
+ type: ValueType.string,
263
+ value: surveyContext.locale
264
+ };
265
+ case ContextVariableType.ParticipantFlag: {
266
+ if (!expression.key) return;
267
+ const flagKey = this.eval(expression.key);
268
+ if (flagKey?.type !== ValueType.string || flagKey.value === void 0) return;
269
+ const flagValue = surveyContext.participantFlags?.[flagKey.value];
270
+ switch (expression.asType) {
271
+ case ValueType.boolean: return {
272
+ type: ValueType.boolean,
273
+ value: flagValue !== void 0
274
+ };
275
+ case ValueType.string:
276
+ if (flagValue === void 0) return;
277
+ return {
278
+ type: ValueType.string,
279
+ value: flagValue
280
+ };
281
+ case ValueType.number: {
282
+ if (flagValue === void 0) return;
283
+ const numValue = parseFloat(flagValue);
284
+ return isNaN(numValue) ? void 0 : {
285
+ type: ValueType.number,
286
+ value: numValue
287
+ };
288
+ }
289
+ case ValueType.date: {
290
+ if (flagValue === void 0) return;
291
+ const timestamp = parseFloat(flagValue);
292
+ return isNaN(timestamp) ? void 0 : {
293
+ type: ValueType.date,
294
+ value: timestamp
295
+ };
296
+ }
297
+ default:
298
+ if (flagValue === void 0) return;
299
+ return {
300
+ type: ValueType.string,
301
+ value: flagValue
302
+ };
303
+ }
304
+ }
305
+ case ContextVariableType.CustomValue: {
306
+ if (!expression.key) return;
307
+ const customKey = this.eval(expression.key);
308
+ if (customKey?.type !== ValueType.string || customKey.value === void 0) return;
309
+ const customValue = surveyContext.customValues?.[customKey.value];
310
+ if (customValue === void 0) return;
311
+ if (expression.asType !== void 0) {
312
+ if (customValue?.type !== expression.asType) throw new Error(`Custom value type does not match expected type, got ${customValue?.type} and expected ${expression.asType}`);
313
+ }
314
+ return customValue;
315
+ }
316
+ case ContextVariableType.CustomExpression: {
317
+ if (!expression.key) return;
318
+ const expressionKey = this.eval(expression.key);
319
+ if (expressionKey?.type !== ValueType.string || expressionKey.value === void 0) return;
320
+ const customExpression = surveyContext.customExpressions?.[expressionKey.value];
321
+ if (typeof customExpression !== ExpressionType.Function || customExpression === void 0) return;
322
+ try {
323
+ const args = expression.arguments;
324
+ const result = customExpression(args);
325
+ if (expression.asType !== void 0) {
326
+ if (result?.type !== expression.asType) throw new Error(`Custom expression result type does not match expected type, got ${result?.type} and expected ${expression.asType}`);
327
+ }
328
+ return result;
329
+ } catch (error) {
330
+ throw new Error(`Error evaluating custom expression: ${error}`);
331
+ }
332
+ }
333
+ }
334
+ }
335
+ evaluateAnd(expression) {
336
+ return {
337
+ type: ValueType.boolean,
338
+ value: expression.arguments.every((arg) => this.eval(arg)?.value === true)
339
+ };
340
+ }
341
+ evaluateOr(expression) {
342
+ return {
343
+ type: ValueType.boolean,
344
+ value: expression.arguments.some((arg) => this.eval(arg)?.value === true)
345
+ };
346
+ }
347
+ evaluateNot(expression) {
348
+ if (expression.arguments.length !== 1 || expression.arguments[0] === void 0) throw new Error(`Not function expects 1 argument, got ${expression.arguments.length}`);
349
+ const resolvedValue = this.eval(expression.arguments[0]);
350
+ if (resolvedValue?.type !== ValueType.boolean) throw new Error(`Not function expects a boolean argument, got ${resolvedValue?.type}`);
351
+ if (resolvedValue === void 0) return {
352
+ type: ValueType.boolean,
353
+ value: false
354
+ };
355
+ return {
356
+ type: ValueType.boolean,
357
+ value: !resolvedValue.value
358
+ };
359
+ }
360
+ evaluateListContains(expression) {
361
+ if (expression.arguments.length !== 2) throw new Error(`List contains function expects 2 arguments, got ${expression.arguments.length}`);
362
+ const resolvedList = this.eval(expression.arguments[0]);
363
+ const resolvedItem = this.eval(expression.arguments[1]);
364
+ if (resolvedList === void 0 || resolvedItem === void 0) return {
365
+ type: ValueType.boolean,
366
+ value: false
367
+ };
368
+ const allowedListTypes = [ValueType.stringArray, ValueType.referenceArray];
369
+ const allowedItemTypes = [ValueType.string, ValueType.reference];
370
+ const resolvedListType = resolvedList.type;
371
+ const resolvedItemType = resolvedItem.type;
372
+ if (!allowedListTypes.includes(resolvedListType) || !allowedItemTypes.includes(resolvedItemType)) throw new Error(`List contains function expects a string array list and a string item, got ${resolvedList?.type} and ${resolvedItem?.type}`);
373
+ const list = resolvedList.value;
374
+ const item = resolvedItem.value;
375
+ return {
376
+ type: ValueType.boolean,
377
+ value: list.includes(item)
378
+ };
379
+ }
380
+ evaluateStrEq(expression) {
381
+ if (expression.arguments.length !== 2) throw new Error(`String equals function expects 2 arguments, got ${expression.arguments.length}`);
382
+ const resolvedA = this.eval(expression.arguments[0]);
383
+ const resolvedB = this.eval(expression.arguments[1]);
384
+ if (resolvedA === void 0 || resolvedB === void 0) return {
385
+ type: ValueType.boolean,
386
+ value: false
387
+ };
388
+ if (resolvedA?.type !== ValueType.string || resolvedB?.type !== ValueType.string) throw new Error(`String equals function expects strings for all arguments, got ${resolvedA?.type} and ${resolvedB?.type}`);
389
+ return {
390
+ type: ValueType.boolean,
391
+ value: resolvedA.value === resolvedB.value
392
+ };
393
+ }
394
+ evaluateEq(expression) {
395
+ if (expression.arguments.length !== 2) throw new Error(`Equals function expects 2 arguments, got ${expression.arguments.length}`);
396
+ const resolvedA = this.eval(expression.arguments[0]);
397
+ const resolvedB = this.eval(expression.arguments[1]);
398
+ if (resolvedA === void 0 || resolvedB === void 0) return {
399
+ type: ValueType.boolean,
400
+ value: false
401
+ };
402
+ if (resolvedA?.type !== resolvedB?.type) throw new Error(`Equals function expects the same type for all arguments, got ${resolvedA?.type} and ${resolvedB?.type}`);
403
+ return {
404
+ type: ValueType.boolean,
405
+ value: resolvedA.value === resolvedB.value
406
+ };
407
+ }
408
+ evaluateGt(expression) {
409
+ if (expression.arguments.length !== 2) throw new Error(`Greater than function expects 2 arguments, got ${expression.arguments.length}`);
410
+ const resolvedA = this.eval(expression.arguments[0]);
411
+ const resolvedB = this.eval(expression.arguments[1]);
412
+ if (resolvedA === void 0 || resolvedB === void 0) return {
413
+ type: ValueType.boolean,
414
+ value: false
415
+ };
416
+ if (resolvedA?.type !== resolvedB?.type) throw new Error(`Greater than function expects the same type for all arguments, got ${resolvedA?.type} and ${resolvedB?.type}`);
417
+ return {
418
+ type: ValueType.boolean,
419
+ value: resolvedA.value > resolvedB.value
420
+ };
421
+ }
422
+ evaluateGte(expression) {
423
+ if (expression.arguments.length !== 2) throw new Error(`Greater than or equal to function expects 2 arguments, got ${expression.arguments.length}`);
424
+ const resolvedA = this.eval(expression.arguments[0]);
425
+ const resolvedB = this.eval(expression.arguments[1]);
426
+ if (resolvedA === void 0 || resolvedB === void 0) return {
427
+ type: ValueType.boolean,
428
+ value: false
429
+ };
430
+ if (resolvedA?.type !== resolvedB?.type) throw new Error(`Greater than or equal to function expects the same type for all arguments, got ${resolvedA?.type} and ${resolvedB?.type}`);
431
+ return {
432
+ type: ValueType.boolean,
433
+ value: resolvedA.value >= resolvedB.value
434
+ };
435
+ }
436
+ evaluateLt(expression) {
437
+ if (expression.arguments.length !== 2) throw new Error(`Less than function expects 2 arguments, got ${expression.arguments.length}`);
438
+ const resolvedA = this.eval(expression.arguments[0]);
439
+ const resolvedB = this.eval(expression.arguments[1]);
440
+ if (resolvedA === void 0 || resolvedB === void 0) return {
441
+ type: ValueType.boolean,
442
+ value: false
443
+ };
444
+ if (resolvedA?.type !== resolvedB?.type) throw new Error(`Less than function expects the same type for all arguments, got ${resolvedA?.type} and ${resolvedB?.type}`);
445
+ return {
446
+ type: ValueType.boolean,
447
+ value: resolvedA.value < resolvedB.value
448
+ };
449
+ }
450
+ evaluateLte(expression) {
451
+ if (expression.arguments.length !== 2) throw new Error(`Less than or equal to function expects 2 arguments, got ${expression.arguments.length}`);
452
+ const resolvedA = this.eval(expression.arguments[0]);
453
+ const resolvedB = this.eval(expression.arguments[1]);
454
+ if (resolvedA === void 0 || resolvedB === void 0) return {
455
+ type: ValueType.boolean,
456
+ value: false
457
+ };
458
+ if (resolvedA?.type !== resolvedB?.type) throw new Error(`Less than or equal to function expects the same type for all arguments, got ${resolvedA?.type} and ${resolvedB?.type}`);
459
+ return {
460
+ type: ValueType.boolean,
461
+ value: resolvedA.value <= resolvedB.value
462
+ };
463
+ }
464
+ evaluateInRange(expression) {
465
+ if (expression.arguments.length !== 4) throw new Error(`In range function expects 4 arguments, got ${expression.arguments.length}`);
466
+ const resolvedValue = this.eval(expression.arguments[0]);
467
+ const resolvedMin = this.eval(expression.arguments[1]);
468
+ const resolvedMax = this.eval(expression.arguments[2]);
469
+ const resolvedInclusive = this.eval(expression.arguments[3])?.value === true;
470
+ if (resolvedValue === void 0 || resolvedMin === void 0 || resolvedMax === void 0) return {
471
+ type: ValueType.boolean,
472
+ value: false
473
+ };
474
+ if (resolvedValue?.type !== ValueType.number || resolvedMin?.type !== ValueType.number || resolvedMax?.type !== ValueType.number) throw new Error(`In range function expects numbers for all arguments, got ${resolvedValue?.type} and ${resolvedMin?.type} and ${resolvedMax?.type}`);
475
+ if (resolvedInclusive) return {
476
+ type: ValueType.boolean,
477
+ value: resolvedValue.value >= resolvedMin.value && resolvedValue.value <= resolvedMax.value
478
+ };
479
+ return {
480
+ type: ValueType.boolean,
481
+ value: resolvedValue.value > resolvedMin.value && resolvedValue.value < resolvedMax.value
482
+ };
483
+ }
484
+ evaluateSum(expression) {
485
+ if (expression.arguments.length < 1) throw new Error(`Sum function expects at least 1 argument, got ${expression.arguments.length}`);
486
+ return expression.arguments.reduce((sum, arg) => {
487
+ if (arg === void 0) return sum;
488
+ const resolvedValue = this.eval(arg);
489
+ if (resolvedValue === void 0) return sum;
490
+ if (resolvedValue?.type === ValueType.number) return {
491
+ type: ValueType.number,
492
+ value: sum.value + resolvedValue.value
493
+ };
494
+ throw new Error(`Sum function expects all arguments to be numbers, got ${resolvedValue?.type}`);
495
+ }, {
496
+ type: ValueType.number,
497
+ value: 0
498
+ });
499
+ }
500
+ evaluateMin(expression) {
501
+ if (expression.arguments.length < 1) throw new Error(`Min function expects at least 1 argument, got ${expression.arguments.length}`);
502
+ return expression.arguments.reduce((min, arg) => {
503
+ if (arg === void 0) return min;
504
+ const resolvedValue = this.eval(arg);
505
+ if (resolvedValue === void 0) return min;
506
+ if (resolvedValue?.type === ValueType.number) return {
507
+ type: ValueType.number,
508
+ value: Math.min(min.value, resolvedValue.value)
509
+ };
510
+ throw new Error(`Min function expects all arguments to be numbers, got ${typeof resolvedValue}`);
511
+ }, {
512
+ type: ValueType.number,
513
+ value: Infinity
514
+ });
515
+ }
516
+ evaluateMax(expression) {
517
+ if (expression.arguments.length < 1) throw new Error(`Max function expects at least 1 argument, got ${expression.arguments.length}`);
518
+ return expression.arguments.reduce((max, arg) => {
519
+ if (arg === void 0) return max;
520
+ const resolvedValue = this.eval(arg);
521
+ if (resolvedValue === void 0) return max;
522
+ if (resolvedValue?.type === ValueType.number) return {
523
+ type: ValueType.number,
524
+ value: Math.max(max.value, resolvedValue.value)
525
+ };
526
+ throw new Error(`Max function expects all arguments to be numbers, got ${typeof resolvedValue}`);
527
+ }, {
528
+ type: ValueType.number,
529
+ value: -Infinity
530
+ });
531
+ }
532
+ };
533
+
534
+ //#endregion
535
+ //#region src/expressions/editors/expression-editor.ts
536
+ var ExpressionEditor = class {
537
+ returnType;
538
+ _editorConfig;
539
+ get editorConfig() {
540
+ return this._editorConfig;
541
+ }
542
+ withEditorConfig(editorConfig) {
543
+ this._editorConfig = editorConfig;
544
+ return this;
545
+ }
546
+ };
547
+ var ConstStringArrayEditor = class extends ExpressionEditor {
548
+ returnType = ValueType.stringArray;
549
+ _values;
550
+ constructor(values, editorConfig) {
551
+ super();
552
+ this._values = values;
553
+ this._editorConfig = editorConfig;
554
+ }
555
+ get values() {
556
+ return this._values;
557
+ }
558
+ set values(values) {
559
+ this._values = values;
560
+ }
561
+ getExpression() {
562
+ return new ConstExpression({
563
+ type: ValueType.stringArray,
564
+ value: this._values
565
+ }, this._editorConfig);
566
+ }
567
+ };
568
+ var ConstStringEditor = class extends ExpressionEditor {
569
+ returnType = ValueType.string;
570
+ _value;
571
+ constructor(value, editorConfig) {
572
+ super();
573
+ this._value = value;
574
+ this._editorConfig = editorConfig;
575
+ }
576
+ get value() {
577
+ return this._value;
578
+ }
579
+ set value(value) {
580
+ this._value = value;
581
+ }
582
+ getExpression() {
583
+ return new ConstExpression({
584
+ type: ValueType.string,
585
+ value: this._value
586
+ }, this._editorConfig);
587
+ }
588
+ };
589
+ var ConstNumberEditor = class extends ExpressionEditor {
590
+ returnType = ValueType.number;
591
+ _value;
592
+ constructor(value, editorConfig) {
593
+ super();
594
+ this._value = value;
595
+ this._editorConfig = editorConfig;
596
+ }
597
+ get value() {
598
+ return this._value;
599
+ }
600
+ set value(value) {
601
+ this._value = value;
602
+ }
603
+ getExpression() {
604
+ return new ConstExpression({
605
+ type: ValueType.number,
606
+ value: this._value
607
+ }, this._editorConfig);
608
+ }
609
+ };
610
+ var ConstBooleanEditor = class extends ExpressionEditor {
611
+ returnType = ValueType.boolean;
612
+ _value;
613
+ constructor(value, editorConfig) {
614
+ super();
615
+ this._value = value;
616
+ this._editorConfig = editorConfig;
617
+ }
618
+ get value() {
619
+ return this._value;
620
+ }
621
+ set value(value) {
622
+ this._value = value;
623
+ }
624
+ getExpression() {
625
+ return new ConstExpression({
626
+ type: ValueType.boolean,
627
+ value: this._value
628
+ }, this._editorConfig);
629
+ }
630
+ };
631
+ var ConstDateEditor = class extends ExpressionEditor {
632
+ returnType = ValueType.date;
633
+ _value;
634
+ constructor(value, editorConfig) {
635
+ super();
636
+ this._value = value;
637
+ this._editorConfig = editorConfig;
638
+ }
639
+ get value() {
640
+ return this._value;
641
+ }
642
+ set value(value) {
643
+ this._value = value;
644
+ }
645
+ getExpression() {
646
+ const value = Math.floor(this._value.getTime() / 1e3);
647
+ return new ConstExpression({
648
+ type: ValueType.date,
649
+ value
650
+ }, this._editorConfig);
651
+ }
652
+ };
653
+ var ConstNumberArrayEditor = class extends ExpressionEditor {
654
+ returnType = ValueType.numberArray;
655
+ _values;
656
+ constructor(values, editorConfig) {
657
+ super();
658
+ this._values = values;
659
+ this._editorConfig = editorConfig;
660
+ }
661
+ get values() {
662
+ return this._values;
663
+ }
664
+ set values(values) {
665
+ this._values = values;
666
+ }
667
+ getExpression() {
668
+ return new ConstExpression({
669
+ type: ValueType.numberArray,
670
+ value: this._values
671
+ }, this._editorConfig);
672
+ }
673
+ };
674
+ var ConstDateArrayEditor = class extends ExpressionEditor {
675
+ returnType = ValueType.dateArray;
676
+ _values;
677
+ constructor(values, editorConfig) {
678
+ super();
679
+ this._values = values;
680
+ this._editorConfig = editorConfig;
681
+ }
682
+ get values() {
683
+ return this._values;
684
+ }
685
+ set values(values) {
686
+ this._values = values;
687
+ }
688
+ getExpression() {
689
+ const value = this._values.map((date) => Math.floor(date.getTime() / 1e3));
690
+ return new ConstExpression({
691
+ type: ValueType.dateArray,
692
+ value
693
+ }, this._editorConfig);
694
+ }
695
+ };
696
+ var ResponseVariableEditor = class extends ExpressionEditor {
697
+ _variableName;
698
+ _variableRef;
699
+ constructor(variableName, variableType, editorConfig) {
700
+ super();
701
+ this._variableName = variableName;
702
+ this._variableRef = new ValueReference(variableName);
703
+ this._editorConfig = editorConfig;
704
+ this.returnType = variableType;
705
+ }
706
+ get variableName() {
707
+ return this._variableName;
708
+ }
709
+ get variableRef() {
710
+ return this._variableRef;
711
+ }
712
+ getExpression() {
713
+ return new ResponseVariableExpression(this._variableName, this._editorConfig);
714
+ }
715
+ };
716
+ var ContextVariableEditor = class extends ExpressionEditor {
717
+ _contextType;
718
+ _key;
719
+ _args;
720
+ _asType;
721
+ constructor(contextType, key, args, asType, editorConfig) {
722
+ super();
723
+ this._contextType = contextType;
724
+ this._key = key;
725
+ this._args = args;
726
+ this._asType = asType;
727
+ this._editorConfig = editorConfig;
728
+ }
729
+ getExpression() {
730
+ return new ContextVariableExpression(this._contextType, this._key?.getExpression(), this._args?.map((arg) => arg.getExpression()), this._asType, this._editorConfig);
731
+ }
732
+ };
733
+ var CtxLocaleEditor = class extends ContextVariableEditor {
734
+ returnType = ValueType.string;
735
+ constructor(editorConfig) {
736
+ super(ContextVariableType.Locale, void 0, void 0, ValueType.string, editorConfig);
737
+ }
738
+ };
739
+ var CtxPFlagIsDefinedEditor = class extends ContextVariableEditor {
740
+ returnType = ValueType.boolean;
741
+ constructor(key, editorConfig) {
742
+ super(ContextVariableType.ParticipantFlag, key, void 0, ValueType.boolean, editorConfig);
743
+ }
744
+ };
745
+ var CtxPFlagStringEditor = class extends ContextVariableEditor {
746
+ returnType = ValueType.string;
747
+ constructor(key, editorConfig) {
748
+ super(ContextVariableType.ParticipantFlag, key, void 0, ValueType.string, editorConfig);
749
+ }
750
+ };
751
+ var CtxPFlagNumEditor = class extends ContextVariableEditor {
752
+ returnType = ValueType.number;
753
+ constructor(key, editorConfig) {
754
+ super(ContextVariableType.ParticipantFlag, key, void 0, ValueType.number, editorConfig);
755
+ }
756
+ };
757
+ var CtxPFlagDateEditor = class extends ContextVariableEditor {
758
+ returnType = ValueType.date;
759
+ constructor(key, editorConfig) {
760
+ super(ContextVariableType.ParticipantFlag, key, void 0, ValueType.date, editorConfig);
761
+ }
762
+ };
763
+ var CtxCustomValueEditor = class extends ContextVariableEditor {
764
+ constructor(key, asType, editorConfig) {
765
+ super(ContextVariableType.CustomValue, key, void 0, asType, editorConfig);
766
+ this.returnType = asType;
767
+ }
768
+ };
769
+ var CtxCustomExpressionEditor = class extends ContextVariableEditor {
770
+ constructor(key, args, asType, editorConfig) {
771
+ super(ContextVariableType.CustomExpression, key, args, asType, editorConfig);
772
+ this.returnType = asType;
773
+ }
774
+ };
775
+ var GroupExpressionEditor = class extends ExpressionEditor {
776
+ _args;
777
+ constructor(args, editorConfig) {
778
+ super();
779
+ this._args = args;
780
+ this._editorConfig = editorConfig;
781
+ }
782
+ get args() {
783
+ return this._args;
784
+ }
785
+ addArg(arg, position) {
786
+ if (position === void 0) this._args.push(arg);
787
+ else this._args.splice(position, 0, arg);
788
+ }
789
+ removeArg(position) {
790
+ this._args.splice(position, 1);
791
+ }
792
+ replaceArg(position, arg) {
793
+ this._args[position] = arg;
794
+ }
795
+ swapArgs(activeIndex, overIndex) {
796
+ const newOrder = [...this._args];
797
+ newOrder.splice(activeIndex, 1);
798
+ newOrder.splice(overIndex, 0, this._args[activeIndex]);
799
+ this._args = newOrder;
800
+ }
801
+ };
802
+ var AndExpressionEditor = class extends GroupExpressionEditor {
803
+ returnType = ValueType.boolean;
804
+ constructor(args, editorConfig) {
805
+ if (args.some((arg) => arg.returnType !== ValueType.boolean)) throw new Error("And expression editor must have boolean arguments");
806
+ super(args, editorConfig);
807
+ }
808
+ getExpression() {
809
+ return new FunctionExpression(FunctionExpressionNames.and, this.args.map((arg) => arg.getExpression()), this._editorConfig);
810
+ }
811
+ };
812
+ var OrExpressionEditor = class extends GroupExpressionEditor {
813
+ returnType = ValueType.boolean;
814
+ constructor(args, editorConfig) {
815
+ if (args.some((arg) => arg.returnType !== ValueType.boolean)) throw new Error("Or expression editor must have boolean arguments");
816
+ super(args, editorConfig);
817
+ }
818
+ getExpression() {
819
+ return new FunctionExpression(FunctionExpressionNames.or, this.args.map((arg) => arg.getExpression()), this._editorConfig);
820
+ }
821
+ };
822
+ var StrListContainsExpressionEditor = class extends ExpressionEditor {
823
+ returnType = ValueType.boolean;
824
+ _list;
825
+ _item;
826
+ constructor(list, item, editorConfig) {
827
+ super();
828
+ if (list.returnType !== ValueType.stringArray) throw new Error("List contains expression editor must have a string array list");
829
+ if (item.returnType !== ValueType.string) throw new Error("List contains expression editor must have a string item");
830
+ this._list = list;
831
+ this._item = item;
832
+ this._editorConfig = editorConfig;
833
+ }
834
+ get list() {
835
+ return this._list;
836
+ }
837
+ get item() {
838
+ return this._item;
839
+ }
840
+ set list(list) {
841
+ this._list = list;
842
+ }
843
+ set item(item) {
844
+ this._item = item;
845
+ }
846
+ getExpression() {
847
+ return new FunctionExpression(FunctionExpressionNames.list_contains, [this._list?.getExpression(), this._item?.getExpression()], this._editorConfig);
848
+ }
849
+ };
850
+ var StrEqExpressionEditor = class extends ExpressionEditor {
851
+ returnType = ValueType.boolean;
852
+ _a;
853
+ _b;
854
+ constructor(a, b, editorConfig) {
855
+ super();
856
+ this._a = a;
857
+ this._b = b;
858
+ this._editorConfig = editorConfig;
859
+ }
860
+ get a() {
861
+ return this._a;
862
+ }
863
+ get b() {
864
+ return this._b;
865
+ }
866
+ set a(a) {
867
+ this._a = a;
868
+ }
869
+ set b(b) {
870
+ this._b = b;
871
+ }
872
+ getExpression() {
873
+ return new FunctionExpression(FunctionExpressionNames.str_eq, [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
874
+ }
875
+ };
876
+ var EqExpressionEditor = class extends ExpressionEditor {
877
+ returnType = ValueType.boolean;
878
+ _a;
879
+ _b;
880
+ constructor(a, b, editorConfig) {
881
+ super();
882
+ this._a = a;
883
+ this._b = b;
884
+ this._editorConfig = editorConfig;
885
+ }
886
+ get a() {
887
+ return this._a;
888
+ }
889
+ get b() {
890
+ return this._b;
891
+ }
892
+ set a(a) {
893
+ this._a = a;
894
+ }
895
+ set b(b) {
896
+ this._b = b;
897
+ }
898
+ getExpression() {
899
+ return new FunctionExpression(FunctionExpressionNames.eq, [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
900
+ }
901
+ };
902
+ var GtExpressionEditor = class extends ExpressionEditor {
903
+ returnType = ValueType.boolean;
904
+ _a;
905
+ _b;
906
+ constructor(a, b, editorConfig) {
907
+ super();
908
+ this._a = a;
909
+ this._b = b;
910
+ this._editorConfig = editorConfig;
911
+ }
912
+ get a() {
913
+ return this._a;
914
+ }
915
+ get b() {
916
+ return this._b;
917
+ }
918
+ set a(a) {
919
+ this._a = a;
920
+ }
921
+ set b(b) {
922
+ this._b = b;
923
+ }
924
+ getExpression() {
925
+ return new FunctionExpression(FunctionExpressionNames.gt, [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
926
+ }
927
+ };
928
+ var GteExpressionEditor = class extends ExpressionEditor {
929
+ returnType = ValueType.boolean;
930
+ _a;
931
+ _b;
932
+ constructor(a, b, editorConfig) {
933
+ super();
934
+ this._a = a;
935
+ this._b = b;
936
+ this._editorConfig = editorConfig;
937
+ }
938
+ get a() {
939
+ return this._a;
940
+ }
941
+ get b() {
942
+ return this._b;
943
+ }
944
+ set a(a) {
945
+ this._a = a;
946
+ }
947
+ set b(b) {
948
+ this._b = b;
949
+ }
950
+ getExpression() {
951
+ return new FunctionExpression(FunctionExpressionNames.gte, [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
952
+ }
953
+ };
954
+ var LtExpressionEditor = class extends ExpressionEditor {
955
+ returnType = ValueType.boolean;
956
+ _a;
957
+ _b;
958
+ constructor(a, b, editorConfig) {
959
+ super();
960
+ this._a = a;
961
+ this._b = b;
962
+ this._editorConfig = editorConfig;
963
+ }
964
+ get a() {
965
+ return this._a;
966
+ }
967
+ get b() {
968
+ return this._b;
969
+ }
970
+ set a(a) {
971
+ this._a = a;
972
+ }
973
+ set b(b) {
974
+ this._b = b;
975
+ }
976
+ getExpression() {
977
+ return new FunctionExpression(FunctionExpressionNames.lt, [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
978
+ }
979
+ };
980
+ var LteExpressionEditor = class extends ExpressionEditor {
981
+ returnType = ValueType.boolean;
982
+ _a;
983
+ _b;
984
+ constructor(a, b, editorConfig) {
985
+ super();
986
+ this._a = a;
987
+ this._b = b;
988
+ this._editorConfig = editorConfig;
989
+ }
990
+ get a() {
991
+ return this._a;
992
+ }
993
+ get b() {
994
+ return this._b;
995
+ }
996
+ set b(b) {
997
+ this._b = b;
998
+ }
999
+ set a(a) {
1000
+ this._a = a;
1001
+ }
1002
+ getExpression() {
1003
+ return new FunctionExpression(FunctionExpressionNames.lte, [this._a?.getExpression(), this._b?.getExpression()], this._editorConfig);
1004
+ }
1005
+ };
1006
+ var InRangeExpressionEditor = class extends ExpressionEditor {
1007
+ returnType = ValueType.boolean;
1008
+ value;
1009
+ min;
1010
+ max;
1011
+ inclusive;
1012
+ constructor(value, min, max, inclusive, editorConfig) {
1013
+ super();
1014
+ this.value = value;
1015
+ this.min = min;
1016
+ this.max = max;
1017
+ this.inclusive = inclusive;
1018
+ this._editorConfig = editorConfig;
1019
+ }
1020
+ getExpression() {
1021
+ return new FunctionExpression(FunctionExpressionNames.in_range, [
1022
+ this.value?.getExpression(),
1023
+ this.min?.getExpression(),
1024
+ this.max?.getExpression(),
1025
+ this.inclusive?.getExpression()
1026
+ ], this._editorConfig);
1027
+ }
1028
+ };
1029
+ var SumExpressionEditor = class extends GroupExpressionEditor {
1030
+ returnType = ValueType.number;
1031
+ constructor(args, editorConfig) {
1032
+ super(args, editorConfig);
1033
+ }
1034
+ getExpression() {
1035
+ return new FunctionExpression(FunctionExpressionNames.sum, this.args.map((arg) => arg.getExpression()), this._editorConfig);
1036
+ }
1037
+ };
1038
+ var MinExpressionEditor = class extends GroupExpressionEditor {
1039
+ returnType = ValueType.number;
1040
+ constructor(args, editorConfig) {
1041
+ super(args, editorConfig);
1042
+ }
1043
+ getExpression() {
1044
+ return new FunctionExpression(FunctionExpressionNames.min, this.args.map((arg) => arg.getExpression()), this._editorConfig);
1045
+ }
1046
+ };
1047
+ var MaxExpressionEditor = class extends GroupExpressionEditor {
1048
+ returnType = ValueType.number;
1049
+ constructor(args, editorConfig) {
1050
+ super(args, editorConfig);
1051
+ }
1052
+ getExpression() {
1053
+ return new FunctionExpression(FunctionExpressionNames.max, this.args.map((arg) => arg.getExpression()), this._editorConfig);
1054
+ }
1055
+ };
1056
+
1057
+ //#endregion
1058
+ //#region src/expressions/editors/expression-editor-generators.ts
1059
+ const const_string_array = (...values) => {
1060
+ return new ConstStringArrayEditor(values);
1061
+ };
1062
+ const const_string = (value) => {
1063
+ return new ConstStringEditor(value);
1064
+ };
1065
+ const const_number_array = (...values) => {
1066
+ return new ConstNumberArrayEditor(values);
1067
+ };
1068
+ const const_number = (value) => {
1069
+ return new ConstNumberEditor(value);
1070
+ };
1071
+ const const_boolean = (value) => {
1072
+ return new ConstBooleanEditor(value);
1073
+ };
1074
+ const const_date = (value) => {
1075
+ return new ConstDateEditor(value);
1076
+ };
1077
+ const const_date_array = (...values) => {
1078
+ return new ConstDateArrayEditor(values);
1079
+ };
1080
+ const response_string = (valueRef) => {
1081
+ return new ResponseVariableEditor(valueRef, ValueType.string);
1082
+ };
1083
+ const response_string_array = (valueRef) => {
1084
+ return new ResponseVariableEditor(valueRef, ValueType.stringArray);
1085
+ };
1086
+ const response_number = (valueRef) => {
1087
+ return new ResponseVariableEditor(valueRef, ValueType.number);
1088
+ };
1089
+ const response_boolean = (valueRef) => {
1090
+ return new ResponseVariableEditor(valueRef, ValueType.boolean);
1091
+ };
1092
+ const response_date = (valueRef) => {
1093
+ return new ResponseVariableEditor(valueRef, ValueType.date);
1094
+ };
1095
+ const response_number_array = (valueRef) => {
1096
+ return new ResponseVariableEditor(valueRef, ValueType.numberArray);
1097
+ };
1098
+ const response_date_array = (valueRef) => {
1099
+ return new ResponseVariableEditor(valueRef, ValueType.dateArray);
1100
+ };
1101
+ const ctx_locale = () => {
1102
+ return new CtxLocaleEditor();
1103
+ };
1104
+ const ctx_pflag_is_defined = (key) => {
1105
+ return new CtxPFlagIsDefinedEditor(key);
1106
+ };
1107
+ const ctx_pflag_string = (key) => {
1108
+ return new CtxPFlagStringEditor(key);
1109
+ };
1110
+ const ctx_pflag_num = (key) => {
1111
+ return new CtxPFlagNumEditor(key);
1112
+ };
1113
+ const ctx_pflag_date = (key) => {
1114
+ return new CtxPFlagDateEditor(key);
1115
+ };
1116
+ const ctx_custom_value = (key, dType) => {
1117
+ return new CtxCustomValueEditor(key, dType);
1118
+ };
1119
+ const ctx_custom_expression = (key, args, returnType) => {
1120
+ return new CtxCustomExpressionEditor(key, args, returnType);
1121
+ };
1122
+ const and = (...args) => {
1123
+ return new AndExpressionEditor(args);
1124
+ };
1125
+ const or = (...args) => {
1126
+ return new OrExpressionEditor(args);
1127
+ };
1128
+ const str_list_contains = (list, item) => {
1129
+ return new StrListContainsExpressionEditor(list, item);
1130
+ };
1131
+ const str_eq = (a, b) => {
1132
+ return new StrEqExpressionEditor(a, b);
1133
+ };
1134
+ const eq = (a, b) => {
1135
+ return new EqExpressionEditor(a, b);
1136
+ };
1137
+ const gt = (a, b) => {
1138
+ return new GtExpressionEditor(a, b);
1139
+ };
1140
+ const gte = (a, b) => {
1141
+ return new GteExpressionEditor(a, b);
1142
+ };
1143
+ const lt = (a, b) => {
1144
+ return new LtExpressionEditor(a, b);
1145
+ };
1146
+ const lte = (a, b) => {
1147
+ return new LteExpressionEditor(a, b);
1148
+ };
1149
+ const in_range = (value, min, max, inclusive) => {
1150
+ return new InRangeExpressionEditor(value, min, max, inclusive);
1151
+ };
1152
+ const sum = (...args) => {
1153
+ return new SumExpressionEditor(args);
1154
+ };
1155
+ const min = (...args) => {
1156
+ return new MinExpressionEditor(args);
1157
+ };
1158
+ const max = (...args) => {
1159
+ return new MaxExpressionEditor(args);
1160
+ };
1161
+
1162
+ //#endregion
1163
+ //#region src/survey/utils/content.ts
1164
+ let ContentType = /* @__PURE__ */ function(ContentType) {
1165
+ ContentType["CQM"] = "CQM";
1166
+ ContentType["md"] = "md";
1167
+ return ContentType;
1168
+ }({});
1169
+ let AttributionType = /* @__PURE__ */ function(AttributionType) {
1170
+ AttributionType["style"] = "style";
1171
+ AttributionType["template"] = "template";
1172
+ return AttributionType;
1173
+ }({});
1174
+
1175
+ //#endregion
1176
+ //#region src/engine/engine.ts
1177
+ var SurveyEngineCore = class {
1178
+ surveyDef;
1179
+ renderedSurveyTree;
1180
+ context;
1181
+ locale;
1182
+ responses;
1183
+ prefills;
1184
+ _events;
1185
+ _openedAt;
1186
+ dateLocales;
1187
+ cache;
1188
+ constructor(survey, context, prefills, dateLocales) {
1189
+ this._openedAt = this._getTimestamp();
1190
+ this.surveyDef = survey;
1191
+ this.context = context ? context : { locale: "en" };
1192
+ this.locale = this.context.locale;
1193
+ this.prefills = prefills ? prefills.reduce((acc, p) => {
1194
+ acc[p.itemId] = SurveyItemResponse.deserialize(p);
1195
+ return acc;
1196
+ }, {}) : void 0;
1197
+ this.dateLocales = dateLocales || [{
1198
+ code: "en",
1199
+ locale: enUS
1200
+ }];
1201
+ this.responses = this.initResponseObject(this.surveyDef.surveyItems);
1202
+ this.initCache();
1203
+ this.evalExpressions();
1204
+ if (!survey.rootItem) throw new Error("constructor: root item not found");
1205
+ this.renderedSurveyTree = this.renderGroup(survey.rootItem);
1206
+ this._events = [{
1207
+ type: SurveyEventTypes.openSurvey,
1208
+ timestamp: this._getTimestamp(),
1209
+ value: this.context.locale
1210
+ }];
1211
+ }
1212
+ setContext(context) {
1213
+ this.context = context;
1214
+ }
1215
+ getDateLocales() {
1216
+ return this.dateLocales.slice();
1217
+ }
1218
+ getCurrentDateLocale() {
1219
+ const found = this.dateLocales.find((dl) => dl.code === this.locale);
1220
+ if (!found) {
1221
+ console.warn(`Locale '${this.locale}' is not available. Using default locale.`);
1222
+ if (this.dateLocales.length > 0) return this.dateLocales[0].locale;
1223
+ return enUS;
1224
+ }
1225
+ return found?.locale;
1226
+ }
1227
+ updateContext(context) {
1228
+ this.context = context;
1229
+ this.locale = context.locale;
1230
+ this._registerSurveyEvent({
1231
+ type: SurveyEventTypes.languageChanged,
1232
+ timestamp: this._getTimestamp(),
1233
+ value: context.locale
1234
+ });
1235
+ this.evalExpressions();
1236
+ this.reRenderSurveyTree();
1237
+ }
1238
+ setResponse(targetKey, response) {
1239
+ const target = this.getResponseItem(targetKey);
1240
+ if (!target) throw new Error("setResponse: target not found for key: " + targetKey);
1241
+ target.response = response;
1242
+ this._registerSurveyEvent({
1243
+ type: SurveyEventTypes.responeChanged,
1244
+ timestamp: this._getTimestamp(),
1245
+ itemId: targetKey
1246
+ });
1247
+ this.evalExpressions();
1248
+ this.reRenderSurveyTree();
1249
+ }
1250
+ get openedAt() {
1251
+ return this._openedAt;
1252
+ }
1253
+ get survey() {
1254
+ return this.surveyDef;
1255
+ }
1256
+ getSurveyPages(size) {
1257
+ const renderedSurvey = flattenTree(this.renderedSurveyTree);
1258
+ const pages = new Array();
1259
+ if (!size) size = "large";
1260
+ let currentPage = [];
1261
+ renderedSurvey.forEach((item) => {
1262
+ if (item.type === ReservedSurveyItemTypes.PageBreak) {
1263
+ if (currentPage.length > 0) {
1264
+ pages.push([...currentPage]);
1265
+ currentPage = [];
1266
+ }
1267
+ return;
1268
+ }
1269
+ currentPage.push(item);
1270
+ if (!this.surveyDef.maxItemsPerPage) return;
1271
+ let max = 0;
1272
+ switch (size) {
1273
+ case "large":
1274
+ max = this.surveyDef.maxItemsPerPage.large;
1275
+ break;
1276
+ case "small":
1277
+ max = this.surveyDef.maxItemsPerPage.small;
1278
+ break;
1279
+ }
1280
+ if (currentPage.length >= max) {
1281
+ pages.push([...currentPage]);
1282
+ currentPage = [];
1283
+ }
1284
+ });
1285
+ if (currentPage.length > 0) pages.push([...currentPage]);
1286
+ return pages;
1287
+ }
1288
+ getRenderedSurveyItem(itemId) {
1289
+ return flattenTree(this.renderedSurveyTree).find((item) => item.id === itemId);
1290
+ }
1291
+ onPageChanged(pageIndex) {
1292
+ this._registerSurveyEvent({
1293
+ type: SurveyEventTypes.pageChanged,
1294
+ timestamp: this._getTimestamp(),
1295
+ value: pageIndex
1296
+ });
1297
+ }
1298
+ getEvents() {
1299
+ return this._events.slice();
1300
+ }
1301
+ getResponses() {
1302
+ const renderedSurvey = flattenTree(this.renderedSurveyTree).filter((item) => item.type !== ReservedSurveyItemTypes.PageBreak);
1303
+ const responses = [];
1304
+ renderedSurvey.forEach((item, index) => {
1305
+ const response = this.getResponseItem(item.id);
1306
+ if (!response) return;
1307
+ response.meta = { position: index };
1308
+ responses.push(response);
1309
+ });
1310
+ return responses;
1311
+ }
1312
+ getDisplayConditionValue(itemKey, componentKey) {
1313
+ if (componentKey) return this.cache.displayConditions[itemKey]?.components?.[componentKey]?.result;
1314
+ return this.cache.displayConditions[itemKey]?.root?.result;
1315
+ }
1316
+ getDisabledConditionValue(itemKey, componentKey) {
1317
+ return this.cache.disabledConditions[itemKey]?.components?.[componentKey]?.result;
1318
+ }
1319
+ getTemplateValue(templateValueKey) {
1320
+ return this.cache.templateValues[templateValueKey]?.value;
1321
+ }
1322
+ getValidationValues(itemKey) {
1323
+ const validations = this.cache.validations[itemKey];
1324
+ if (!validations) return;
1325
+ return Object.keys(validations).reduce((acc, validationKey) => {
1326
+ acc[validationKey] = validations[validationKey].result;
1327
+ return acc;
1328
+ }, {});
1329
+ }
1330
+ initCache() {
1331
+ this.cache = {
1332
+ validations: {},
1333
+ displayConditions: {},
1334
+ templateValues: {},
1335
+ disabledConditions: {}
1336
+ };
1337
+ this.surveyDef.getTemplateValueKeys().forEach((templateKey) => {
1338
+ this.cache.templateValues[templateKey] = {
1339
+ value: void 0,
1340
+ templateDef: this.surveyDef.getTemplateValue(templateKey)
1341
+ };
1342
+ });
1343
+ this.surveyDef.surveyItems.forEach((item, itemId) => {
1344
+ if (item.validations && Object.keys(item.validations).length > 0) {
1345
+ this.cache.validations[itemId] = {};
1346
+ Object.keys(item.validations).forEach((validationKey) => {
1347
+ const valExp = item.validations[validationKey];
1348
+ if (!valExp) {
1349
+ console.warn("initCache: validation expression not found: " + itemId + " " + validationKey);
1350
+ return;
1351
+ }
1352
+ this.cache.validations[itemId][validationKey] = {
1353
+ expression: valExp,
1354
+ result: false
1355
+ };
1356
+ });
1357
+ }
1358
+ if (item.displayConditions !== void 0 && (item.displayConditions.root || item.displayConditions.components)) {
1359
+ this.cache.displayConditions[itemId] = {};
1360
+ if (item.displayConditions.root) this.cache.displayConditions[itemId].root = {
1361
+ expression: item.displayConditions.root,
1362
+ result: false
1363
+ };
1364
+ if (item.displayConditions.components) {
1365
+ this.cache.displayConditions[itemId].components = {};
1366
+ Object.keys(item.displayConditions.components).forEach((componentKey) => {
1367
+ const compExp = item.displayConditions?.components?.[componentKey];
1368
+ if (!compExp) {
1369
+ console.warn("initCache: display condition component expression not found: " + itemId + " " + componentKey);
1370
+ return;
1371
+ }
1372
+ this.cache.displayConditions[itemId].components[componentKey] = {
1373
+ expression: compExp,
1374
+ result: false
1375
+ };
1376
+ });
1377
+ }
1378
+ }
1379
+ if (item.disabledConditions !== void 0 && item.disabledConditions.components !== void 0) {
1380
+ this.cache.disabledConditions[itemId] = { components: {} };
1381
+ Object.keys(item.disabledConditions.components).forEach((componentKey) => {
1382
+ const compExp = item.disabledConditions?.components?.[componentKey];
1383
+ if (!compExp) {
1384
+ console.warn("initCache: disabled condition component expression not found: " + itemId + " " + componentKey);
1385
+ return;
1386
+ }
1387
+ this.cache.disabledConditions[itemId].components[componentKey] = {
1388
+ expression: compExp,
1389
+ result: false
1390
+ };
1391
+ });
1392
+ }
1393
+ });
1394
+ }
1395
+ initResponseObject(items) {
1396
+ const respGroup = {};
1397
+ items.forEach((item, itemId) => {
1398
+ if (!item.isInteractive) return;
1399
+ else {
1400
+ const prefill = this.prefills?.[itemId];
1401
+ const applyPrefill = prefill && prefill.itemType === item.type;
1402
+ respGroup[itemId] = new SurveyItemResponse({
1403
+ itemId,
1404
+ itemType: item.type
1405
+ }, applyPrefill ? prefill.response : void 0);
1406
+ }
1407
+ });
1408
+ return respGroup;
1409
+ }
1410
+ shouldRender(itemId, componentId) {
1411
+ const displayConditionResult = this.getDisplayConditionValue(itemId, componentId);
1412
+ if (displayConditionResult !== void 0) return displayConditionResult;
1413
+ return true;
1414
+ }
1415
+ sequentialRender(groupDef) {
1416
+ const newItems = [];
1417
+ for (const itemId of groupDef.items || []) {
1418
+ if (!this.shouldRender(itemId)) continue;
1419
+ const itemDef = this.surveyDef.surveyItems.get(itemId);
1420
+ if (!itemDef) {
1421
+ console.warn("sequentialRender: item not found: " + itemId);
1422
+ continue;
1423
+ }
1424
+ if (itemDef.type === ReservedSurveyItemTypes.Group) {
1425
+ newItems.push(this.renderGroup(itemDef));
1426
+ continue;
1427
+ }
1428
+ newItems.push({
1429
+ id: itemId,
1430
+ type: itemDef.type
1431
+ });
1432
+ }
1433
+ return {
1434
+ id: groupDef.id,
1435
+ type: ReservedSurveyItemTypes.Group,
1436
+ items: newItems
1437
+ };
1438
+ }
1439
+ randomizedItemRender(groupDef, parent) {
1440
+ const newItems = parent.items?.filter((rItem) => this.shouldRender(rItem.id)) || [];
1441
+ const itemIds = groupDef.items || [];
1442
+ const shuffledIndices = shuffleIndices(itemIds.length);
1443
+ for (const index of shuffledIndices) {
1444
+ const itemId = itemIds[index];
1445
+ if (parent.items?.find((rItem) => rItem.id === itemId)) continue;
1446
+ if (!this.shouldRender(itemId)) continue;
1447
+ const itemDef = this.surveyDef.surveyItems.get(itemId);
1448
+ if (!itemDef) {
1449
+ console.warn("randomizedItemRender: item not found: " + itemId);
1450
+ continue;
1451
+ }
1452
+ if (itemDef.type === ReservedSurveyItemTypes.Group) {
1453
+ newItems.push(this.renderGroup(itemDef, parent));
1454
+ continue;
1455
+ }
1456
+ newItems.push({
1457
+ id: itemId,
1458
+ type: itemDef.type
1459
+ });
1460
+ }
1461
+ return {
1462
+ id: groupDef.id,
1463
+ type: ReservedSurveyItemTypes.Group,
1464
+ items: newItems
1465
+ };
1466
+ }
1467
+ renderGroup(groupDef, parent) {
1468
+ if (!parent) parent = {
1469
+ id: groupDef.id,
1470
+ type: ReservedSurveyItemTypes.Group,
1471
+ items: []
1472
+ };
1473
+ if (groupDef.config.shuffleItems) return this.randomizedItemRender(groupDef, parent);
1474
+ return this.sequentialRender(groupDef);
1475
+ }
1476
+ reRenderSurveyTree() {
1477
+ if (!this.surveyDef.rootItem) throw new Error("reRenderSurveyTree: root item not found");
1478
+ this.renderedSurveyTree = this.renderGroup(this.surveyDef.rootItem);
1479
+ }
1480
+ _registerSurveyEvent(event) {
1481
+ this._events.push(event);
1482
+ }
1483
+ _getTimestamp() {
1484
+ return Math.floor(Date.now() / 1e3);
1485
+ }
1486
+ getResponseItem(itemId) {
1487
+ return this.responses[itemId];
1488
+ }
1489
+ evalExpressions() {
1490
+ const evalEngine = new ExpressionEvaluator({
1491
+ responses: this.responses,
1492
+ surveyContext: this.context
1493
+ });
1494
+ this.evalTemplateValues(evalEngine);
1495
+ this.evalDisplayConditions(evalEngine);
1496
+ this.evalDisableConditions(evalEngine);
1497
+ this.evalValidations(evalEngine);
1498
+ }
1499
+ evalTemplateValues(evalEngine) {
1500
+ Object.keys(this.cache.templateValues).forEach((templateValueKey) => {
1501
+ const templateValue = this.cache.templateValues[templateValueKey];
1502
+ if (!templateValue.templateDef?.expression) {
1503
+ console.warn("evalTemplateValues: template value expression not found: " + templateValueKey);
1504
+ return;
1505
+ }
1506
+ let evaluatedValue = evalEngine.eval(templateValue.templateDef.expression);
1507
+ if (evaluatedValue === void 0) {
1508
+ console.warn("evalTemplateValues: template value expression returned undefined: " + templateValueKey);
1509
+ return;
1510
+ }
1511
+ switch (templateValue.templateDef.type) {
1512
+ case TemplateDefTypes.Date2String:
1513
+ if (evaluatedValue.type !== ValueType.date) {
1514
+ console.warn("evalTemplateValues: template value expression returned non-date value: " + templateValueKey);
1515
+ return;
1516
+ }
1517
+ evaluatedValue = {
1518
+ type: ValueType.string,
1519
+ value: format(/* @__PURE__ */ new Date(evaluatedValue.value * 1e3), templateValue.templateDef.dateFormat)
1520
+ };
1521
+ break;
1522
+ default: break;
1523
+ }
1524
+ this.cache.templateValues[templateValueKey].value = evaluatedValue;
1525
+ });
1526
+ }
1527
+ evalDisplayConditions(evalEngine) {
1528
+ Object.keys(this.cache.displayConditions).forEach((itemKey) => {
1529
+ const displayCondition = this.cache.displayConditions[itemKey];
1530
+ if (displayCondition.root) {
1531
+ const resolvedValue = evalEngine.eval(displayCondition.root.expression);
1532
+ if (resolvedValue === void 0 || resolvedValue.type !== ValueType.boolean) {
1533
+ console.warn("evalDisplayConditions: display condition expression returned undefined: " + itemKey);
1534
+ return;
1535
+ }
1536
+ this.cache.displayConditions[itemKey].root.result = resolvedValue.value;
1537
+ }
1538
+ if (displayCondition.components) Object.keys(displayCondition.components).forEach((componentKey) => {
1539
+ const resolvedValue = evalEngine.eval(displayCondition.components[componentKey].expression);
1540
+ if (resolvedValue === void 0 || resolvedValue.type !== ValueType.boolean) {
1541
+ console.warn("evalDisplayConditions: display condition component expression returned undefined: " + itemKey + "." + componentKey);
1542
+ return;
1543
+ }
1544
+ this.cache.displayConditions[itemKey].components[componentKey].result = resolvedValue.value;
1545
+ });
1546
+ });
1547
+ }
1548
+ evalDisableConditions(evalEngine) {
1549
+ Object.keys(this.cache.disabledConditions).forEach((itemKey) => {
1550
+ const disableCondition = this.cache.disabledConditions[itemKey];
1551
+ if (disableCondition.components) Object.keys(disableCondition.components).forEach((componentKey) => {
1552
+ const resolvedValue = evalEngine.eval(disableCondition.components[componentKey].expression);
1553
+ if (resolvedValue === void 0 || resolvedValue.type !== ValueType.boolean) {
1554
+ console.warn("evalDisableConditions: disable condition component expression returned undefined: " + itemKey + "." + componentKey);
1555
+ return;
1556
+ }
1557
+ this.cache.disabledConditions[itemKey].components[componentKey].result = resolvedValue.value;
1558
+ });
1559
+ });
1560
+ }
1561
+ evalValidations(evalEngine) {
1562
+ Object.keys(this.cache.validations).forEach((itemId) => {
1563
+ const validation = this.cache.validations[itemId];
1564
+ Object.keys(validation).forEach((validationKey) => {
1565
+ const resolvedValue = evalEngine.eval(validation[validationKey].expression);
1566
+ if (resolvedValue === void 0 || resolvedValue.type !== ValueType.boolean) {
1567
+ console.warn("evalValidations: validation expression returned undefined: " + itemId + "." + validationKey);
1568
+ return;
1569
+ }
1570
+ this.cache.validations[itemId][validationKey].result = resolvedValue.value;
1571
+ });
1572
+ });
1573
+ }
1574
+ };
1575
+ const flattenTree = (itemTree) => {
1576
+ const flatTree = new Array();
1577
+ itemTree.items?.forEach((item) => {
1578
+ if (item.type === ReservedSurveyItemTypes.Group) flatTree.push(...flattenTree(item));
1579
+ else flatTree.push({ ...item });
1580
+ });
1581
+ return flatTree;
1582
+ };
1583
+
1584
+ //#endregion
1585
+ export { AndExpressionEditor, AttributionType, ConstBooleanEditor, ConstDateArrayEditor, ConstDateEditor, ConstExpression, ConstNumberArrayEditor, ConstNumberEditor, ConstStringArrayEditor, ConstStringEditor, ContentType, ContextVariableExpression, ContextVariableType, CtxCustomExpressionEditor, CtxCustomValueEditor, CtxLocaleEditor, CtxPFlagDateEditor, CtxPFlagIsDefinedEditor, CtxPFlagNumEditor, CtxPFlagStringEditor, DurationUnits, EqExpressionEditor, Expression, ExpressionEditor, ExpressionEvaluator, ExpressionType, FunctionExpression, FunctionExpressionNames, GtExpressionEditor, GteExpressionEditor, InRangeExpressionEditor, LtExpressionEditor, LteExpressionEditor, MaxExpressionEditor, MinExpressionEditor, NumberPrecision, OrExpressionEditor, ReferenceUsageType, ReservedSurveyItemTypes, ResponseItem, ResponseVariableEditor, ResponseVariableExpression, StrEqExpressionEditor, StrListContainsExpressionEditor, SumExpressionEditor, Survey, SurveyEngineCore, SurveyEventTypes, SurveyItemCore, SurveyItemKey, SurveyItemResponse, SurveyItemTranslations, SurveyResponse, SurveyTranslations, TemplateDefTypes, ValueReference, ValueReferenceMethod, ValueType, and, const_boolean, const_date, const_date_array, const_number, const_number_array, const_string, const_string_array, ctx_custom_expression, ctx_custom_value, ctx_locale, ctx_pflag_date, ctx_pflag_is_defined, ctx_pflag_num, ctx_pflag_string, deserializeTemplateValue, deserializeTemplateValues, eq, flattenTree, generateId, gt, gte, in_range, initValueForType, isLegacyItemGroupComponent, isLegacySurveyGroupItem, lt, lte, max, min, or, response_boolean, response_date, response_date_array, response_number, response_number_array, response_string, response_string_array, serializeTemplateValue, serializeTemplateValues, shuffleIndices, str_eq, str_list_contains, structuredCloneMethod, sum, validateLocale };
1586
+ //# sourceMappingURL=index.mjs.map