@cxpinsight/react-native 0.5.0 → 0.8.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +23 -0
  3. package/lib/CXPinsight.d.ts +33 -3
  4. package/lib/CXPinsight.d.ts.map +1 -1
  5. package/lib/CXPinsight.js +57 -3
  6. package/lib/CXPinsight.js.map +1 -1
  7. package/lib/CXPinsightProvider.d.ts.map +1 -1
  8. package/lib/CXPinsightProvider.js +13 -1
  9. package/lib/CXPinsightProvider.js.map +1 -1
  10. package/lib/consent/ConsentBanner.d.ts +18 -0
  11. package/lib/consent/ConsentBanner.d.ts.map +1 -0
  12. package/lib/consent/ConsentBanner.js +90 -0
  13. package/lib/consent/ConsentBanner.js.map +1 -0
  14. package/lib/core/consent.d.ts +16 -1
  15. package/lib/core/consent.d.ts.map +1 -1
  16. package/lib/core/consent.js +79 -32
  17. package/lib/core/consent.js.map +1 -1
  18. package/lib/index.d.ts +4 -0
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +5 -1
  21. package/lib/index.js.map +1 -1
  22. package/lib/survey/SurveyModal.d.ts.map +1 -1
  23. package/lib/survey/SurveyModal.js +94 -55
  24. package/lib/survey/SurveyModal.js.map +1 -1
  25. package/lib/survey/pagesFromV1.d.ts.map +1 -1
  26. package/lib/survey/pagesFromV1.js +30 -76
  27. package/lib/survey/pagesFromV1.js.map +1 -1
  28. package/lib/survey/questions/FileUploadQuestion.d.ts +32 -0
  29. package/lib/survey/questions/FileUploadQuestion.d.ts.map +1 -0
  30. package/lib/survey/questions/FileUploadQuestion.js +105 -0
  31. package/lib/survey/questions/FileUploadQuestion.js.map +1 -0
  32. package/lib/survey/questions/SignatureQuestion.d.ts +15 -0
  33. package/lib/survey/questions/SignatureQuestion.d.ts.map +1 -0
  34. package/lib/survey/questions/SignatureQuestion.js +138 -0
  35. package/lib/survey/questions/SignatureQuestion.js.map +1 -0
  36. package/lib/survey/validate.d.ts.map +1 -1
  37. package/lib/survey/validate.js +13 -163
  38. package/lib/survey/validate.js.map +1 -1
  39. package/lib/survey/voiceParsers.d.ts +12 -42
  40. package/lib/survey/voiceParsers.d.ts.map +1 -1
  41. package/lib/survey/voiceParsers.js +60 -284
  42. package/lib/survey/voiceParsers.js.map +1 -1
  43. package/lib/types.d.ts +24 -0
  44. package/lib/types.d.ts.map +1 -1
  45. package/lib/types.js.map +1 -1
  46. package/package.json +12 -4
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSignatureAvailable = isSignatureAvailable;
4
+ exports.SignatureQuestion = SignatureQuestion;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const react_native_1 = require("react-native");
8
+ const styleContract_1 = require("../styleContract");
9
+ let Svg = null;
10
+ let Path = null;
11
+ try {
12
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
13
+ const mod = require('react-native-svg');
14
+ Svg = (mod?.default ?? mod?.Svg);
15
+ Path = mod?.Path;
16
+ if (!Svg || !Path) {
17
+ Svg = null;
18
+ Path = null;
19
+ }
20
+ }
21
+ catch {
22
+ Svg = null;
23
+ Path = null;
24
+ }
25
+ /** Can this device draw a signature? False → the caller shows its hint. */
26
+ function isSignatureAvailable() {
27
+ return Svg !== null && Path !== null;
28
+ }
29
+ /** One stroke → an SVG path. Straight segments; a signature has enough points. */
30
+ function toPath(stroke) {
31
+ if (!stroke.length)
32
+ return '';
33
+ const [first, ...rest] = stroke;
34
+ return `M ${first.x.toFixed(1)} ${first.y.toFixed(1)}` +
35
+ rest.map((p) => ` L ${p.x.toFixed(1)} ${p.y.toFixed(1)}`).join('');
36
+ }
37
+ /** base64 without Buffer — React Native has no Node globals. */
38
+ function toBase64(input) {
39
+ const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
40
+ let out = '';
41
+ for (let i = 0; i < input.length; i += 3) {
42
+ const a = input.charCodeAt(i);
43
+ const b = input.charCodeAt(i + 1);
44
+ const c = input.charCodeAt(i + 2);
45
+ const n = (a << 16) | ((isNaN(b) ? 0 : b) << 8) | (isNaN(c) ? 0 : c);
46
+ out += CHARS[(n >> 18) & 63] + CHARS[(n >> 12) & 63]
47
+ + (isNaN(b) ? '=' : CHARS[(n >> 6) & 63])
48
+ + (isNaN(c) ? '=' : CHARS[n & 63]);
49
+ }
50
+ return out;
51
+ }
52
+ function SignatureQuestion({ value, onChange, contract = styleContract_1.DARK_CONTRACT, isRtl = false, clearLabel = 'Clear', hintLabel = 'Sign above', }) {
53
+ const [strokes, setStrokes] = (0, react_1.useState)([]);
54
+ const [size, setSize] = (0, react_1.useState)({ w: 0, h: 160 });
55
+ const current = (0, react_1.useRef)([]);
56
+ const ink = contract.textPrimary || '#111';
57
+ const s = (0, react_1.useMemo)(() => styles(contract), [contract]);
58
+ const emit = (all) => {
59
+ // The same trap the web renderer has: an EMPTY pad must produce no answer.
60
+ // Emitting a valid-but-blank image would mark every signature question
61
+ // answered the moment it rendered, and let a REQUIRED one pass unsigned.
62
+ const drawn = all.filter((st) => st.length > 1);
63
+ if (!drawn.length) {
64
+ onChange('');
65
+ return;
66
+ }
67
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${Math.round(size.w)}" height="${Math.round(size.h)}" ` +
68
+ `viewBox="0 0 ${Math.round(size.w)} ${Math.round(size.h)}">` +
69
+ drawn.map((st) => `<path d="${toPath(st)}" stroke="${ink}" stroke-width="2.5" fill="none" ` +
70
+ 'stroke-linecap="round" stroke-linejoin="round"/>').join('') +
71
+ '</svg>';
72
+ // A data URL, matching what the web renderer sends. The image FORMAT
73
+ // differs (SVG here, PNG there) because rasterising on device would cost a
74
+ // second native dependency; the stored value is an opaque data URL either
75
+ // way, and both render in a browser.
76
+ onChange(`data:image/svg+xml;base64,${toBase64(svg)}`);
77
+ };
78
+ const responder = (0, react_1.useMemo)(() => react_native_1.PanResponder.create({
79
+ onStartShouldSetPanResponder: () => true,
80
+ onMoveShouldSetPanResponder: () => true,
81
+ onPanResponderGrant: (e) => {
82
+ current.current = [{ x: e.nativeEvent.locationX, y: e.nativeEvent.locationY }];
83
+ },
84
+ onPanResponderMove: (e) => {
85
+ current.current = [...current.current, { x: e.nativeEvent.locationX, y: e.nativeEvent.locationY }];
86
+ setStrokes((prev) => {
87
+ const next = [...prev];
88
+ next[next.length - 1] = current.current;
89
+ return next.length ? next : [current.current];
90
+ });
91
+ },
92
+ onPanResponderStart: () => setStrokes((prev) => [...prev, current.current]),
93
+ onPanResponderRelease: () => {
94
+ setStrokes((prev) => {
95
+ const next = [...prev];
96
+ next[next.length - 1] = current.current;
97
+ emit(next);
98
+ return next;
99
+ });
100
+ current.current = [];
101
+ },
102
+ // A gesture the OS takes away mid-stroke must still commit what was drawn,
103
+ // or the respondent lifts their finger and the signature vanishes.
104
+ onPanResponderTerminate: () => {
105
+ setStrokes((prev) => { emit(prev); return prev; });
106
+ current.current = [];
107
+ },
108
+ // eslint-disable-next-line react-hooks/exhaustive-deps
109
+ }), [size.w, size.h, ink]);
110
+ const onLayout = (e) => {
111
+ const { width, height } = e.nativeEvent.layout;
112
+ setSize({ w: width, h: height || 160 });
113
+ };
114
+ const clear = () => {
115
+ current.current = [];
116
+ setStrokes([]);
117
+ onChange('');
118
+ };
119
+ const hasInk = strokes.some((st) => st.length > 1);
120
+ return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { children: [(0, jsx_runtime_1.jsx)(react_native_1.View, { style: [s.pad, hasInk && s.padInked], onLayout: onLayout, ...responder.panHandlers, accessibilityLabel: hintLabel, accessibilityHint: "Draw your signature with your finger", children: Svg && Path && size.w > 0 ? ((0, jsx_runtime_1.jsx)(Svg, { width: size.w, height: size.h, children: strokes.filter((st) => st.length > 1).map((st, i) => ((0, jsx_runtime_1.jsx)(Path, { d: toPath(st), stroke: ink, strokeWidth: 2.5, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }, i))) })) : null }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [s.row, isRtl && s.rowRtl], children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: s.hint, children: hasInk ? '' : hintLabel }), (0, jsx_runtime_1.jsx)(react_native_1.TouchableOpacity, { onPress: clear, accessibilityRole: "button", disabled: !hasInk, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: [s.clear, !hasInk && s.clearOff], children: clearLabel }) })] }), value === '' && hasInk ? null : null] }));
121
+ }
122
+ const styles = (c) => react_native_1.StyleSheet.create({
123
+ pad: {
124
+ height: 160,
125
+ borderWidth: 1,
126
+ borderColor: c.inputBorder || '#ccc',
127
+ borderRadius: Number(c.inputRadius ?? 8),
128
+ backgroundColor: c.input || '#fff',
129
+ overflow: 'hidden',
130
+ },
131
+ padInked: { borderColor: c.accent || '#2b6cb0' },
132
+ row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: 8 },
133
+ rowRtl: { flexDirection: 'row-reverse' },
134
+ hint: { fontSize: 12, color: c.textMuted || '#888' },
135
+ clear: { fontSize: 13, fontWeight: '600', color: c.accent || '#2b6cb0' },
136
+ clearOff: { color: c.textMuted || '#aaa' },
137
+ });
138
+ //# sourceMappingURL=SignatureQuestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureQuestion.js","sourceRoot":"","sources":["../../../src/survey/questions/SignatureQuestion.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/survey/validate.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAWtF"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/survey/validate.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEtF"}
@@ -1,169 +1,19 @@
1
1
  "use strict";
2
- // Answer validation — spec §8 + type-specific rules. Kept in lockstep
3
- // with apps/frontend/src/components/survey/renderer/lib/validate.ts,
4
- // with two mobile simplifications:
5
- //
6
- // - Mobile question components emit primitive values, not the
7
- // compound {text,attachments} / {choice,otherText} shapes that
8
- // the web renderer uses for allowAttachments + "Other". Whenever
9
- // the value shape simplifies, the mobile helper's per-type path
10
- // shrinks too.
11
- // - inputType regexes stay identical so a text field flagged as
12
- // invalid on web reads as invalid on mobile and vice versa.
13
- //
14
- // Order per spec §8: required → type-specific format → rules[] array.
15
- // Empty non-required answers are valid — a blank optional email
16
- // shouldn't complain about missing '@'.
17
2
  Object.defineProperty(exports, "__esModule", { value: true });
18
3
  exports.validateAnswer = validateAnswer;
19
- const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
20
- const URL_RE = /^https?:\/\/[\w.\-]+(?:\.[\w.\-]+)+(?:[/?#][^\s]*)?$/i;
4
+ // Answer validation now lives in @cxpinsight/survey-spec.
5
+ //
6
+ // This file was the superset in type routing (email / number / csat / ces) and
7
+ // the subset in emptiness: its isEmpty only understood primitives, so a
8
+ // compound value like `{ choice: undefined }` counted as answered. The shared
9
+ // version takes the dispatcher from here and the type-aware isEmpty from the
10
+ // React renderer.
11
+ //
12
+ // One behaviour changes on mobile: the required message is now "This field is
13
+ // required" rather than "This question requires an answer", so the wording is
14
+ // the same wherever a respondent meets it.
15
+ const survey_spec_1 = require("@cxpinsight/survey-spec");
21
16
  function validateAnswer(question, value) {
22
- const empty = isEmpty(value);
23
- if ((question.required || question.isRequired) && empty) {
24
- return 'This question requires an answer';
25
- }
26
- if (empty)
27
- return null; // optional + blank → OK
28
- const typeErr = validateByType(question, value);
29
- if (typeErr)
30
- return typeErr;
31
- return validateRules(question, value);
32
- }
33
- function isEmpty(v) {
34
- if (v === undefined || v === null)
35
- return true;
36
- if (typeof v === 'string')
37
- return v.trim().length === 0;
38
- if (Array.isArray(v))
39
- return v.length === 0;
40
- if (typeof v === 'number')
41
- return Number.isNaN(v);
42
- return false; // 0, false, non-empty obj → not empty
43
- }
44
- function validateByType(question, value) {
45
- switch (question.type) {
46
- case 'text':
47
- case 'comment':
48
- case 'email':
49
- case 'number':
50
- return validateTextish(question, value);
51
- case 'checkbox':
52
- return validateCheckbox(question, value);
53
- case 'rating':
54
- case 'csat':
55
- case 'ces':
56
- case 'nps':
57
- return validateNumericRange(question, value);
58
- default:
59
- return null;
60
- }
61
- }
62
- function validateTextish(question, value) {
63
- const trimmed = String(value ?? '').trim();
64
- const inputType = question.inputType || (question.type === 'email' ? 'email' : question.type === 'number' ? 'number' : undefined);
65
- if (inputType === 'email' && !EMAIL_RE.test(trimmed)) {
66
- return 'Please enter a valid email address (e.g., you@example.com)';
67
- }
68
- if (inputType === 'url' && !URL_RE.test(trimmed)) {
69
- return 'Please enter a full URL, including https://';
70
- }
71
- if (inputType === 'number' && Number.isNaN(Number(trimmed))) {
72
- return 'Please enter a number';
73
- }
74
- if (inputType === 'tel' && !/^[\d\s+\-()]{3,}$/.test(trimmed)) {
75
- return 'Please enter a valid phone number';
76
- }
77
- const maxLength = typeof question.maxLength === 'number' ? question.maxLength : undefined;
78
- if (maxLength !== undefined && trimmed.length > maxLength) {
79
- return `Please keep this under ${maxLength} characters`;
80
- }
81
- // minLength was only honoured through the rules[] array, never as a direct
82
- // question property — so a question with minLength set in the builder was
83
- // enforced on links and silently ignored here. Same survey, different rules,
84
- // depending on how the respondent arrived.
85
- const minLength = typeof question.minLength === 'number'
86
- ? question.minLength
87
- : undefined;
88
- if (minLength !== undefined && trimmed.length < minLength) {
89
- return `Please enter at least ${minLength} characters`;
90
- }
91
- return null;
92
- }
93
- function validateCheckbox(question, value) {
94
- const arr = Array.isArray(value) ? value : [];
95
- const count = arr.length;
96
- const minCount = typeof question.minCount === 'number' ? question.minCount : undefined;
97
- const maxCount = typeof question.maxCount === 'number' ? question.maxCount : undefined;
98
- if (minCount !== undefined && count < minCount)
99
- return `Please select at least ${minCount}`;
100
- if (maxCount !== undefined && count > maxCount)
101
- return `Please select at most ${maxCount}`;
102
- return null;
103
- }
104
- function validateNumericRange(question, value) {
105
- if (typeof value !== 'number')
106
- return null;
107
- const min = typeof question.minValue === 'number' ? question.minValue : undefined;
108
- const max = typeof question.maxValue === 'number' ? question.maxValue : undefined;
109
- if (min !== undefined && value < min)
110
- return `Must be at least ${min}`;
111
- if (max !== undefined && value > max)
112
- return `Must be at most ${max}`;
113
- return null;
114
- }
115
- function validateRules(question, value) {
116
- const rules = Array.isArray(question.rules)
117
- ? question.rules
118
- : [];
119
- if (rules.length === 0)
120
- return null;
121
- const str = typeof value === 'string' ? value : String(value ?? '');
122
- for (const r of rules) {
123
- const err = applyRule(r, str);
124
- if (err)
125
- return r.message || err;
126
- }
127
- return null;
128
- }
129
- function applyRule(rule, str) {
130
- switch (rule.type) {
131
- case 'minLength':
132
- if (typeof rule.value === 'number' && str.length < rule.value)
133
- return `At least ${rule.value} characters`;
134
- return null;
135
- case 'maxLength':
136
- if (typeof rule.value === 'number' && str.length > rule.value)
137
- return `At most ${rule.value} characters`;
138
- return null;
139
- case 'min':
140
- if (typeof rule.value === 'number' && Number(str) < rule.value)
141
- return `Must be at least ${rule.value}`;
142
- return null;
143
- case 'max':
144
- if (typeof rule.value === 'number' && Number(str) > rule.value)
145
- return `Must be at most ${rule.value}`;
146
- return null;
147
- case 'email':
148
- if (!EMAIL_RE.test(str))
149
- return 'Please enter a valid email address';
150
- return null;
151
- case 'url':
152
- if (!URL_RE.test(str))
153
- return 'Please enter a valid URL';
154
- return null;
155
- case 'pattern': {
156
- if (typeof rule.value !== 'string')
157
- return null;
158
- try {
159
- const re = new RegExp(rule.value);
160
- return re.test(str) ? null : 'Format doesn\'t match';
161
- }
162
- catch {
163
- return null;
164
- }
165
- }
166
- default: return null;
167
- }
17
+ return (0, survey_spec_1.validateAnswer)(question, value);
168
18
  }
169
19
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/survey/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/survey/validate.ts"],"names":[],"mappings":";;;AAAA,0DAA0D;AAC1D,EAAE;AACF,+EAA+E;AAC/E,wEAAwE;AACxE,8EAA8E;AAC9E,6EAA6E;AAC7E,kBAAkB;AAClB,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,2CAA2C;AAC3C,yDAA+E;AAG/E,wBAA+B,QAAwB,EAAE,KAAc;IACrE,OAAO,IAAA,4BAAkB,EAAC,QAAoD,EAAE,KAAK,CAAC,CAAC;AACzF,CAAC"}
@@ -1,47 +1,17 @@
1
+ import { type VoiceQuestion } from '@cxpinsight/survey-spec';
2
+ export { auditVoiceQuestions, voiceDisclaimer, skipNoteText, scaffoldFor, buildPromptText, } from '@cxpinsight/survey-spec';
3
+ /**
4
+ * Mobile's four levels. The spec distinguishes 'assist' (readable, answer it
5
+ * on screen) from 'none' (voice cannot produce this at all); this renderer
6
+ * treats both the same way — read it, hand off — so they collapse to
7
+ * 'partial', which is exactly what it returned before.
8
+ */
1
9
  export type VoiceSupport = 'full' | 'matrix' | 'read' | 'partial';
2
- interface VQuestion {
3
- type?: string;
4
- title?: string;
5
- text?: string;
6
- label?: string;
7
- options?: unknown;
8
- choices?: unknown;
9
- yesLabel?: string;
10
- noLabel?: string;
11
- minValue?: number;
12
- maxValue?: number;
13
- minLabel?: string;
14
- maxLabel?: string;
15
- rows?: unknown;
16
- columns?: unknown;
17
- }
18
- export declare function parseAnswer(q: VQuestion, transcript: string): {
19
- value: unknown;
20
- parsed: boolean;
21
- };
22
10
  export declare function voiceSupport(type: string): VoiceSupport;
23
11
  export declare function voiceCanHandle(type: string): boolean;
24
- interface AuditQ {
25
- type?: string;
26
- isRequired?: boolean;
27
- required?: boolean;
28
- }
29
- export declare function auditVoiceQuestions(questions: AuditQ[]): {
30
- blocking: AuditQ[];
31
- skippable: AuditQ[];
32
- };
33
- export declare function voiceDisclaimer(n: number, lang?: string): string;
34
- export declare function skipNoteText(lang?: string): string;
35
- export declare function scaffoldFor(lang: string): {
36
- scale: (min: number, max: number, minL?: string, maxL?: string) => string;
37
- binary: (y: string, n: string) => string;
38
- options: (o: string[]) => string;
39
- multi: (o: string[]) => string;
40
- ranking: (o: string[]) => string;
41
- date: () => string;
42
- matrixStem: (stem: string) => string;
43
- matrixRow: (row: string, cols: string[]) => string;
12
+ /** Match a spoken answer, then wrap it in the shape this renderer stores. */
13
+ export declare function parseAnswer(q: VoiceQuestion, transcript: string): {
14
+ value: unknown;
15
+ parsed: boolean;
44
16
  };
45
- export declare function buildPromptText(q: VQuestion, lang: string): string;
46
- export {};
47
17
  //# sourceMappingURL=voiceParsers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"voiceParsers.d.ts","sourceRoot":"","sources":["../../src/survey/voiceParsers.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAGlE,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3E,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnC;AAiHD,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAajG;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAYvD;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAA6C;AAElG,UAAU,MAAM;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE;AAE5E,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAQpG;AACD,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAGhE;AACD,wBAAgB,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlD;AAkCD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM;WA9B/B,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM;YACjE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM;aAC/B,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM;WACzB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM;aACrB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,MAAM;UAC1B,MAAM,MAAM;gBACN,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM;eACzB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM;EAuB6E;AAIjI,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAYlE"}
1
+ {"version":3,"file":"voiceParsers.d.ts","sourceRoot":"","sources":["../../src/survey/voiceParsers.ts"],"names":[],"mappings":"AAkBA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,GACjF,MAAM,yBAAyB,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAElE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAGvD;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAA6C;AAIlG,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CA6CrG"}