@zoho_apptics/apptics-js-sdk 1.0.2 → 2.0.0-beta

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 (226) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +13 -0
  3. package/README.md +747 -11
  4. package/dist/apptics.esm.min.js +3 -0
  5. package/dist/apptics.esm.min.js.map +1 -0
  6. package/dist/apptics.min.js +3 -0
  7. package/dist/apptics.min.js.map +1 -0
  8. package/dist/chunks/batch-BU_mTpm1.min.js +3 -0
  9. package/dist/chunks/batch-BU_mTpm1.min.js.map +1 -0
  10. package/dist/chunks/logs-Bea5zUW_.min.js +3 -0
  11. package/dist/chunks/logs-Bea5zUW_.min.js.map +1 -0
  12. package/dist/cjs/auto-init.d.ts +8 -0
  13. package/dist/cjs/auto-init.js +32 -0
  14. package/dist/cjs/core/attempts.d.ts +28 -0
  15. package/dist/cjs/core/attempts.js +113 -0
  16. package/dist/cjs/core/batch.d.ts +32 -0
  17. package/dist/cjs/core/batch.js +115 -0
  18. package/dist/cjs/core/callsite.d.ts +28 -0
  19. package/dist/cjs/core/callsite.js +93 -0
  20. package/dist/cjs/core/consent.d.ts +23 -0
  21. package/dist/cjs/core/consent.js +130 -0
  22. package/dist/cjs/core/constants.d.ts +212 -0
  23. package/dist/cjs/core/constants.js +299 -0
  24. package/dist/cjs/core/db.d.ts +40 -0
  25. package/dist/cjs/core/db.js +334 -0
  26. package/dist/cjs/core/debug.d.ts +22 -0
  27. package/dist/cjs/core/debug.js +88 -0
  28. package/dist/cjs/core/env.d.ts +28 -0
  29. package/dist/cjs/core/env.js +267 -0
  30. package/dist/cjs/core/framework-id.d.ts +1 -0
  31. package/dist/cjs/core/framework-id.js +9 -0
  32. package/dist/cjs/core/guard.d.ts +2 -0
  33. package/dist/cjs/core/guard.js +72 -0
  34. package/dist/cjs/core/hooks.d.ts +41 -0
  35. package/dist/cjs/core/hooks.js +23 -0
  36. package/dist/cjs/core/logger.d.ts +16 -0
  37. package/dist/cjs/core/logger.js +86 -0
  38. package/dist/cjs/core/state.d.ts +69 -0
  39. package/dist/cjs/core/state.js +78 -0
  40. package/dist/cjs/core/storage.d.ts +46 -0
  41. package/dist/cjs/core/storage.js +229 -0
  42. package/dist/cjs/core/transport.d.ts +83 -0
  43. package/dist/cjs/core/transport.js +441 -0
  44. package/dist/cjs/core/utils.d.ts +26 -0
  45. package/dist/cjs/core/utils.js +175 -0
  46. package/dist/cjs/core/validate.d.ts +18 -0
  47. package/dist/cjs/core/validate.js +233 -0
  48. package/dist/cjs/device/appversion.d.ts +20 -0
  49. package/dist/cjs/device/appversion.js +158 -0
  50. package/dist/cjs/device/index.d.ts +23 -0
  51. package/dist/cjs/device/index.js +372 -0
  52. package/dist/cjs/engagement/api-rules.d.ts +84 -0
  53. package/dist/cjs/engagement/api-rules.js +219 -0
  54. package/dist/cjs/engagement/auto-api.d.ts +7 -0
  55. package/dist/cjs/engagement/auto-api.js +200 -0
  56. package/dist/cjs/engagement/auto-screen.d.ts +16 -0
  57. package/dist/cjs/engagement/auto-screen.js +241 -0
  58. package/dist/cjs/engagement/defined-events.d.ts +23 -0
  59. package/dist/cjs/engagement/defined-events.js +58 -0
  60. package/dist/cjs/engagement/send.d.ts +6 -0
  61. package/dist/cjs/engagement/send.js +99 -0
  62. package/dist/cjs/engagement/session.d.ts +42 -0
  63. package/dist/cjs/engagement/session.js +327 -0
  64. package/dist/cjs/engagement/track.d.ts +56 -0
  65. package/dist/cjs/engagement/track.js +350 -0
  66. package/dist/cjs/errors/send.d.ts +6 -0
  67. package/dist/cjs/errors/send.js +73 -0
  68. package/dist/cjs/errors/track.d.ts +4 -0
  69. package/dist/cjs/errors/track.js +127 -0
  70. package/dist/cjs/feedback/controls.d.ts +31 -0
  71. package/dist/cjs/feedback/controls.js +286 -0
  72. package/dist/cjs/feedback/index.d.ts +8 -0
  73. package/dist/cjs/feedback/index.js +37 -0
  74. package/dist/cjs/feedback/logs.d.ts +40 -0
  75. package/dist/cjs/feedback/logs.js +202 -0
  76. package/dist/cjs/feedback/send.d.ts +25 -0
  77. package/dist/cjs/feedback/send.js +178 -0
  78. package/dist/cjs/feedback/template.d.ts +2 -0
  79. package/dist/cjs/feedback/template.js +162 -0
  80. package/dist/cjs/feedback/ui.d.ts +55 -0
  81. package/dist/cjs/feedback/ui.js +631 -0
  82. package/dist/cjs/heatmap/index.d.ts +16 -0
  83. package/dist/cjs/heatmap/index.js +22 -0
  84. package/dist/cjs/heatmap/send.d.ts +13 -0
  85. package/dist/cjs/heatmap/send.js +82 -0
  86. package/dist/cjs/heatmap/track.d.ts +4 -0
  87. package/dist/cjs/heatmap/track.js +377 -0
  88. package/dist/cjs/index.d.ts +68 -0
  89. package/dist/cjs/index.js +150 -0
  90. package/dist/cjs/lifecycle.d.ts +14 -0
  91. package/dist/cjs/lifecycle.js +538 -0
  92. package/dist/cjs/package.json +3 -0
  93. package/dist/cjs/remoteconfig/custom.d.ts +10 -0
  94. package/dist/cjs/remoteconfig/custom.js +78 -0
  95. package/dist/cjs/remoteconfig/evaluate.d.ts +24 -0
  96. package/dist/cjs/remoteconfig/evaluate.js +171 -0
  97. package/dist/cjs/remoteconfig/fetch.d.ts +24 -0
  98. package/dist/cjs/remoteconfig/fetch.js +214 -0
  99. package/dist/cjs/remoteconfig/index.d.ts +13 -0
  100. package/dist/cjs/remoteconfig/index.js +90 -0
  101. package/dist/cjs/remoteconfig/store.d.ts +18 -0
  102. package/dist/cjs/remoteconfig/store.js +98 -0
  103. package/dist/cjs/remotelog/gate.d.ts +11 -0
  104. package/dist/cjs/remotelog/gate.js +54 -0
  105. package/dist/cjs/remotelog/index.d.ts +25 -0
  106. package/dist/cjs/remotelog/index.js +55 -0
  107. package/dist/cjs/remotelog/logger.d.ts +28 -0
  108. package/dist/cjs/remotelog/logger.js +139 -0
  109. package/dist/cjs/remotelog/send.d.ts +13 -0
  110. package/dist/cjs/remotelog/send.js +153 -0
  111. package/dist/cjs/scheduler.d.ts +8 -0
  112. package/dist/cjs/scheduler.js +78 -0
  113. package/dist/cjs/types.d.ts +312 -0
  114. package/dist/cjs/user/index.d.ts +33 -0
  115. package/dist/cjs/user/index.js +178 -0
  116. package/dist/esm/auto-init.d.ts +8 -0
  117. package/dist/esm/auto-init.js +29 -0
  118. package/dist/esm/core/attempts.d.ts +28 -0
  119. package/dist/esm/core/attempts.js +106 -0
  120. package/dist/esm/core/batch.d.ts +32 -0
  121. package/dist/esm/core/batch.js +108 -0
  122. package/dist/esm/core/callsite.d.ts +28 -0
  123. package/dist/esm/core/callsite.js +89 -0
  124. package/dist/esm/core/consent.d.ts +23 -0
  125. package/dist/esm/core/consent.js +120 -0
  126. package/dist/esm/core/constants.d.ts +212 -0
  127. package/dist/esm/core/constants.js +277 -0
  128. package/dist/esm/core/db.d.ts +40 -0
  129. package/dist/esm/core/db.js +324 -0
  130. package/dist/esm/core/debug.d.ts +22 -0
  131. package/dist/esm/core/debug.js +81 -0
  132. package/dist/esm/core/env.d.ts +28 -0
  133. package/dist/esm/core/env.js +251 -0
  134. package/dist/esm/core/framework-id.d.ts +1 -0
  135. package/dist/esm/core/framework-id.js +7 -0
  136. package/dist/esm/core/guard.d.ts +2 -0
  137. package/dist/esm/core/guard.js +70 -0
  138. package/dist/esm/core/hooks.d.ts +41 -0
  139. package/dist/esm/core/hooks.js +21 -0
  140. package/dist/esm/core/logger.d.ts +16 -0
  141. package/dist/esm/core/logger.js +82 -0
  142. package/dist/esm/core/state.d.ts +69 -0
  143. package/dist/esm/core/state.js +73 -0
  144. package/dist/esm/core/storage.d.ts +46 -0
  145. package/dist/esm/core/storage.js +219 -0
  146. package/dist/esm/core/transport.d.ts +83 -0
  147. package/dist/esm/core/transport.js +425 -0
  148. package/dist/esm/core/utils.d.ts +26 -0
  149. package/dist/esm/core/utils.js +161 -0
  150. package/dist/esm/core/validate.d.ts +18 -0
  151. package/dist/esm/core/validate.js +226 -0
  152. package/dist/esm/device/appversion.d.ts +20 -0
  153. package/dist/esm/device/appversion.js +153 -0
  154. package/dist/esm/device/index.d.ts +23 -0
  155. package/dist/esm/device/index.js +362 -0
  156. package/dist/esm/engagement/api-rules.d.ts +84 -0
  157. package/dist/esm/engagement/api-rules.js +211 -0
  158. package/dist/esm/engagement/auto-api.d.ts +7 -0
  159. package/dist/esm/engagement/auto-api.js +198 -0
  160. package/dist/esm/engagement/auto-screen.d.ts +16 -0
  161. package/dist/esm/engagement/auto-screen.js +238 -0
  162. package/dist/esm/engagement/defined-events.d.ts +23 -0
  163. package/dist/esm/engagement/defined-events.js +55 -0
  164. package/dist/esm/engagement/send.d.ts +6 -0
  165. package/dist/esm/engagement/send.js +96 -0
  166. package/dist/esm/engagement/session.d.ts +42 -0
  167. package/dist/esm/engagement/session.js +315 -0
  168. package/dist/esm/engagement/track.d.ts +56 -0
  169. package/dist/esm/engagement/track.js +340 -0
  170. package/dist/esm/errors/send.d.ts +6 -0
  171. package/dist/esm/errors/send.js +70 -0
  172. package/dist/esm/errors/track.d.ts +4 -0
  173. package/dist/esm/errors/track.js +123 -0
  174. package/dist/esm/feedback/controls.d.ts +31 -0
  175. package/dist/esm/feedback/controls.js +280 -0
  176. package/dist/esm/feedback/index.d.ts +8 -0
  177. package/dist/esm/feedback/index.js +30 -0
  178. package/dist/esm/feedback/logs.d.ts +40 -0
  179. package/dist/esm/feedback/logs.js +188 -0
  180. package/dist/esm/feedback/send.d.ts +25 -0
  181. package/dist/esm/feedback/send.js +175 -0
  182. package/dist/esm/feedback/template.d.ts +2 -0
  183. package/dist/esm/feedback/template.js +159 -0
  184. package/dist/esm/feedback/ui.d.ts +55 -0
  185. package/dist/esm/feedback/ui.js +626 -0
  186. package/dist/esm/heatmap/index.d.ts +16 -0
  187. package/dist/esm/heatmap/index.js +17 -0
  188. package/dist/esm/heatmap/send.d.ts +13 -0
  189. package/dist/esm/heatmap/send.js +79 -0
  190. package/dist/esm/heatmap/track.d.ts +4 -0
  191. package/dist/esm/heatmap/track.js +374 -0
  192. package/dist/esm/index.d.ts +68 -0
  193. package/dist/esm/index.js +122 -0
  194. package/dist/esm/lifecycle.d.ts +14 -0
  195. package/dist/esm/lifecycle.js +534 -0
  196. package/dist/esm/package.json +3 -0
  197. package/dist/esm/remoteconfig/custom.d.ts +10 -0
  198. package/dist/esm/remoteconfig/custom.js +74 -0
  199. package/dist/esm/remoteconfig/evaluate.d.ts +24 -0
  200. package/dist/esm/remoteconfig/evaluate.js +166 -0
  201. package/dist/esm/remoteconfig/fetch.d.ts +24 -0
  202. package/dist/esm/remoteconfig/fetch.js +210 -0
  203. package/dist/esm/remoteconfig/index.d.ts +13 -0
  204. package/dist/esm/remoteconfig/index.js +85 -0
  205. package/dist/esm/remoteconfig/store.d.ts +18 -0
  206. package/dist/esm/remoteconfig/store.js +91 -0
  207. package/dist/esm/remotelog/gate.d.ts +11 -0
  208. package/dist/esm/remotelog/gate.js +48 -0
  209. package/dist/esm/remotelog/index.d.ts +25 -0
  210. package/dist/esm/remotelog/index.js +51 -0
  211. package/dist/esm/remotelog/logger.d.ts +28 -0
  212. package/dist/esm/remotelog/logger.js +136 -0
  213. package/dist/esm/remotelog/send.d.ts +13 -0
  214. package/dist/esm/remotelog/send.js +149 -0
  215. package/dist/esm/scheduler.d.ts +8 -0
  216. package/dist/esm/scheduler.js +74 -0
  217. package/dist/esm/types.d.ts +312 -0
  218. package/dist/esm/user/index.d.ts +33 -0
  219. package/dist/esm/user/index.js +170 -0
  220. package/dist/feedback.esm.min.js +3 -0
  221. package/dist/feedback.esm.min.js.map +1 -0
  222. package/dist/heatmap.esm.min.js +3 -0
  223. package/dist/heatmap.esm.min.js.map +1 -0
  224. package/dist/style.css +1 -0
  225. package/package.json +124 -7
  226. package/src/appticssdk.js +0 -1
@@ -0,0 +1,626 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { AP_TRACKING_STATUS } from '../core/constants.js';
3
+ import { _ZAP } from '../core/state.js';
4
+ import { Console } from '../core/logger.js';
5
+ import { isEmpty, isEmptyObj } from '../core/utils.js';
6
+ import { opt_in_status } from '../core/consent.js';
7
+ import { timerHtml, feedbackUIHtml } from './template.js';
8
+ import { sendFeedbackData } from './send.js';
9
+ import { wireDrag, wireUserPicker, wireLogControls, logChoice, userChoice } from './controls.js';
10
+
11
+ // Quartz is an optional page-level SDK. Without it every call is a no-op (fix #5).
12
+ const QUARTZ_NOOP = {
13
+ startRecording() { },
14
+ previewVideo() { },
15
+ editVideo() { },
16
+ clearFeedback() { },
17
+ endRecording() { },
18
+ setVideoContent() { },
19
+ submitRecording() { return Promise.resolve({}); }
20
+ };
21
+ const QUARTZ_CONSTANTS_NOOP = { ErrorType: {}, FeedbackState: {} };
22
+ function hasQuartz() {
23
+ return typeof Quartz !== 'undefined' && !!Quartz; // no i18n
24
+ }
25
+ function quartz() {
26
+ return typeof Quartz !== 'undefined' && Quartz ? Quartz : QUARTZ_NOOP; // no i18n
27
+ }
28
+ function quartzConstants() {
29
+ return typeof QuartzConstants !== 'undefined' && QuartzConstants ? QuartzConstants : QUARTZ_CONSTANTS_NOOP; // no i18n
30
+ }
31
+ /**
32
+ * Sends feedback and reflects the outcome in the modal (if open). Resolves with the outcome, or
33
+ * null when nothing was attempted (offline, or Apptics is disabled for this client).
34
+ */
35
+ function submitFeedback(dataobj) {
36
+ return sendFeedbackData(dataobj).then(function (result) {
37
+ if (!result) {
38
+ return null;
39
+ }
40
+ feedback.handleStatusmsg(result.ok, result.message);
41
+ if (result.ok) {
42
+ setTimeout(() => {
43
+ feedback.close();
44
+ }, 2000);
45
+ }
46
+ return result;
47
+ });
48
+ }
49
+ function sendFeedback(feedbackType, feedbackMessage, attachments, logsFiles, includeDyninfo, includeLog) {
50
+ const dataobj = {
51
+ type: !isEmpty(feedbackType) ? feedbackType : 1,
52
+ message: feedbackMessage || '', // no i18n
53
+ attachment: attachments || null,
54
+ logsFiles: logsFiles || null,
55
+ // both flags stay as given: unset lets send.ts decide from what is actually stored
56
+ includeDyninfo: includeDyninfo,
57
+ includeLog: includeLog,
58
+ quartzid: '' // no i18n
59
+ };
60
+ // an app awaiting this must be able to tell its user the feedback did not go: resolving on a
61
+ // failure would have it say "thanks, sent" for a report the server never received
62
+ return submitFeedback(dataobj).then(function (result) {
63
+ if (!result) {
64
+ throw new Error('apptics.sendFeedback: not sent, the browser is offline or Apptics is disabled for this client'); // no i18n
65
+ }
66
+ if (!result.ok) {
67
+ throw new Error('apptics.sendFeedback: not sent, ' + result.message); // no i18n
68
+ }
69
+ });
70
+ }
71
+ /**
72
+ * The request both submit buttons send. A recording only adds its quartzid; everything else — the
73
+ * chosen type, the attachments, the log and diagnostics toggles — is read the same way, so one
74
+ * builder keeps the recording path from quietly falling behind the plain one.
75
+ */
76
+ function buildFeedbackRequest(modal, message, quartzid) {
77
+ var seltype = modal.querySelector('.zasdk-selected').getAttribute('data-type'); // no i18n
78
+ var fileInput = modal.querySelector("#zasdkFileInput"); // no i18n
79
+ var files = fileInput.files;
80
+ return {
81
+ type: !isEmpty(seltype) ? feedback.typeObj[seltype] : 1,
82
+ message: message,
83
+ attachment: (files && files.length > 0) ? files : (feedback._opts.attachments || null),
84
+ logsFiles: feedback._opts.logFiles || null,
85
+ includeLog: logChoice.includeLog,
86
+ includeDyninfo: logChoice.includeDyninfo,
87
+ quartzid: quartzid
88
+ };
89
+ }
90
+ /**
91
+ * Opens the form, optionally pre-filled. `isAnonymous` starts the user picker on Anonymous even
92
+ * when a user is registered; the include flags start their toggles on.
93
+ */
94
+ /**
95
+ * A DataTransfer to hold the chosen attachments, or null where one cannot be made.
96
+ *
97
+ * It is the only way to build a FileList, which is what an <input type="file"> will accept back,
98
+ * so the attachment list is kept in one. The constructor is newer than the rest of the modal -
99
+ * Safari only gained it in 14.1 - and a plain `new DataTransfer()` throws on anything older,
100
+ * which took the whole form down with it on open. Feedback without attachments is worth far more
101
+ * than no feedback at all, so the form opens either way and the file input is left alone.
102
+ */
103
+ function newTransfer() {
104
+ try {
105
+ return typeof DataTransfer === 'function' ? new DataTransfer() : null; // no i18n
106
+ }
107
+ catch (err) {
108
+ Console.warn('apptics.feedback: this browser cannot build a file list, attachments are off'); // no i18n
109
+ return null;
110
+ }
111
+ }
112
+ function feedbackOpen(type, message, includeLog, includeDyninfo, attachments, logFiles, isAnonymous) {
113
+ const opts = {
114
+ includeLog: includeLog === true,
115
+ includeDyninfo: includeDyninfo === true,
116
+ isAnonymous: isAnonymous === true,
117
+ };
118
+ if (typeof type === 'number')
119
+ opts.type = type; // no i18n
120
+ if (typeof message === 'string' && message.length > 0)
121
+ opts.message = message; // no i18n
122
+ if (attachments && attachments.length > 0)
123
+ opts.attachments = attachments;
124
+ if (logFiles && logFiles.length > 0)
125
+ opts.logFiles = logFiles;
126
+ feedback.init(opts);
127
+ }
128
+ function feedbackClose() {
129
+ feedback.close();
130
+ }
131
+ const feedback = {
132
+ feedbackUIHtml: feedbackUIHtml,
133
+ timerHtml: timerHtml,
134
+ uploadFileAry: [],
135
+ fileInput: null,
136
+ selectedFiles: null,
137
+ isScaled: false,
138
+ isHidden: false,
139
+ timerDisplay: null,
140
+ recordButton: null,
141
+ TOTAL_TIME: 5 * 60,
142
+ remainingTime: 5 * 60,
143
+ isRecording: false,
144
+ timerInterval: null,
145
+ uploadTotalSize: 0,
146
+ MaxFileSize: 10 * 1024 * 1024,
147
+ _opts: {},
148
+ typeObj: { 'bug': 0, 'feedback': 1, 'help': 2, 'report': 3 }, // no i18n
149
+ init: function (opts) {
150
+ feedback._opts = opts || {};
151
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
152
+ if (!isEmpty(modal)) {
153
+ return;
154
+ }
155
+ const tempContainer = document.createElement('div'); // no i18n
156
+ feedback.uploadFileAry = [];
157
+ tempContainer.id = 'zasdkFeedbackModal'; // no i18n
158
+ tempContainer.className = 'zasdk-modal'; // no i18n
159
+ tempContainer.innerHTML = feedback.feedbackUIHtml;
160
+ document.body.appendChild(tempContainer);
161
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
162
+ var defaultoption = _ZAP._defaultoptions;
163
+ var qz_ws_key = defaultoption.quartz_workspace_key;
164
+ var qz_dp_key = defaultoption.quartz_department_key;
165
+ var quartz_DC = {
166
+ "Local": "https://quartz.localzoho.com", // no i18n
167
+ "US": "https://quartz.zoho.com", // no i18n
168
+ "EU": "https://quartz.zoho.eu", // no i18n
169
+ "IN": "https://quartz.zoho.in", // no i18n
170
+ "AU": "https://quartz.zoho.com.au", // no i18n
171
+ "CN": "https://quartz.zoho.com.cn", // no i18n
172
+ "CA": "https://quartz.zohocloud.ca", // no i18n
173
+ "JP": "https://quartz.zoho.jp", // no i18n
174
+ "SA": "https://quartz.zoho.sa", // no i18n
175
+ "AE": "https://quartz.zoho.ae" // no i18n
176
+ };
177
+ var qz_dc_key = (!isEmpty(defaultoption.DC) && defaultoption.DC !== '-') ? (quartz_DC[defaultoption.DC] || '') : ''; // no i18n
178
+ var closeBtn = modal.querySelector("#appticsfeedbackclose"); // no i18n
179
+ var feedbackTypes = modal.querySelectorAll(".zasdk-feedback-type"); // no i18n
180
+ feedback.fileInput = modal.querySelector("#zasdkFileInput"); // no i18n
181
+ var quartzrecbtn = modal.querySelector("#zasdkqz_rec_button"); // no i18n
182
+ var submitbtn = modal.querySelector("#zasdk_submit_btn"); // no i18n
183
+ var submitbtncnt = modal.querySelector("#zasdk_submit_btnsubcnt"); // no i18n
184
+ const checkbox = modal.querySelector('#zasdkqz-consent'); // no i18n
185
+ const content = modal.querySelector('#zasdkqz-content'); // no i18n
186
+ const preivewButton = modal.querySelector('#preivewPlayButton'); // no i18n
187
+ const videoEditButton = modal.querySelector('#videoEditButton'); // no i18n
188
+ const deleteVideoButton = modal.querySelector('#videoDelButton'); // no i18n
189
+ const feedbackbox = modal.querySelector('#zasdkFeedbackconatiner'); // no i18n
190
+ const descriptionField = modal.querySelector('#zasdkDescription'); // no i18n
191
+ wireDrag(feedbackbox);
192
+ wireUserPicker(modal, feedback._opts.isAnonymous === true);
193
+ wireLogControls(modal, feedback._opts);
194
+ feedback.isScaled = false;
195
+ feedback.isHidden = false;
196
+ document.removeEventListener('quartz-feedback-state', feedback.bindQuartzEvent); // no i18n
197
+ document.addEventListener('quartz-feedback-state', feedback.bindQuartzEvent); // no i18n
198
+ document.removeEventListener('quartz-feedback-error', feedback.handleErrorQuartzEvent); // no i18n
199
+ document.addEventListener('quartz-feedback-error', feedback.handleErrorQuartzEvent); // no i18n
200
+ // the consent checkbox and its label only when a recording can actually be made: the Quartz
201
+ // script on the page, a DC it knows, and both keys. "-" for any of them turns it off; DC "-"
202
+ // has already become '' above. A checkbox that leads only to "unavailable" is not offered
203
+ var recordingAvailable = hasQuartz() && !isEmpty(qz_dc_key)
204
+ && !isEmpty(qz_ws_key) && qz_ws_key !== "-" && !isEmpty(qz_dp_key) && qz_dp_key !== "-"; // no i18n
205
+ modal.querySelector("#zasdkreccheckcnt").style.display = recordingAvailable ? "block" : "none"; // no i18n
206
+ feedbackbox.addEventListener('transitionend', function (event) {
207
+ if (event.propertyName === 'transform' && feedback.isScaled) { // no i18n
208
+ feedback.toggleWindowAnimation();
209
+ }
210
+ });
211
+ quartzrecbtn.onclick = function (e) {
212
+ e.stopImmediatePropagation();
213
+ let recordingDetails = {
214
+ workspaceLinkName: qz_ws_key,
215
+ departmentLinkName: qz_dp_key,
216
+ recordingDomain: qz_dc_key
217
+ };
218
+ feedback.handleStatusmsg();
219
+ // 1.x pressed on regardless and the button did nothing anyone could explain; the rest
220
+ // of the form still works, so say what is missing and leave it usable
221
+ if (!hasQuartz()) {
222
+ feedback.handleStatusmsg(false, 'Screen recording is unavailable on this page.'); // no i18n
223
+ return;
224
+ }
225
+ if (isEmpty(qz_ws_key) || isEmpty(qz_dp_key) || isEmpty(qz_dc_key)) {
226
+ feedback.handleStatusmsg(false, 'Screen recording is not configured for this app.'); // no i18n
227
+ return;
228
+ }
229
+ quartz().startRecording(recordingDetails);
230
+ };
231
+ closeBtn.onclick = function () {
232
+ feedback.close();
233
+ };
234
+ preivewButton.addEventListener('click', function () {
235
+ quartz().previewVideo();
236
+ });
237
+ videoEditButton.addEventListener('click', function () {
238
+ quartz().editVideo({ quartzBranding: false });
239
+ });
240
+ deleteVideoButton.addEventListener('click', function () {
241
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
242
+ quartz().clearFeedback();
243
+ checkbox.checked = false;
244
+ content.classList.remove('zasdkqz-show'); // no i18n
245
+ modal.querySelector("#editRecordedVideo").style.display = "none"; // no i18n
246
+ modal.querySelector("#zasdkreccheckcnt").style.display = "block"; // no i18n
247
+ feedback.validateFeedbackField();
248
+ });
249
+ submitbtn.addEventListener('click', async () => {
250
+ // Disable button and show loader
251
+ feedback.validateFeedbackField();
252
+ submitbtn.disabled = true;
253
+ submitbtncnt.classList.add('zasdkbtndisabled'); // no i18n
254
+ submitbtn.value = '';
255
+ try {
256
+ let videoElement = modal.querySelector('#previewVideoElemId'), // no i18n
257
+ videoVisible = videoElement && videoElement.offsetParent !== null;
258
+ if (videoVisible) {
259
+ feedback.submitRecording();
260
+ }
261
+ else {
262
+ let message = modal.querySelector('#zasdkDescription').value.trim(); // no i18n
263
+ if (message.length > 0) {
264
+ submitFeedback(buildFeedbackRequest(modal, message, '')); // no i18n
265
+ }
266
+ else {
267
+ feedback.handleStatusmsg(false, 'Please provide more details for us to help you better.'); // no i18n
268
+ }
269
+ }
270
+ }
271
+ catch (error) {
272
+ Console.error("sendFeedbackData : " + error); // no i18n
273
+ }
274
+ });
275
+ checkbox.addEventListener('change', function () {
276
+ if (this.checked) {
277
+ content.classList.add('zasdkqz-show'); // no i18n
278
+ }
279
+ else {
280
+ content.classList.remove('zasdkqz-show'); // no i18n
281
+ }
282
+ });
283
+ descriptionField.addEventListener('input', feedback.validateFeedbackField); // no i18n
284
+ feedbackTypes.forEach(function (type) {
285
+ type.addEventListener("click", function () {
286
+ feedbackTypes.forEach(function (t) {
287
+ t.classList.remove("zasdk-selected"); // no i18n
288
+ });
289
+ this.classList.add("zasdk-selected"); // no i18n
290
+ });
291
+ });
292
+ // what feedbackOpen() was given: select that type, fill the description
293
+ if (typeof feedback._opts.type === 'number') { // no i18n
294
+ var wanted = Object.keys(feedback.typeObj).filter(function (name) {
295
+ return feedback.typeObj[name] === feedback._opts.type;
296
+ })[0];
297
+ var wantedTab = wanted ? modal.querySelector('.zasdk-feedback-type[data-type="' + wanted + '"]') : null; // no i18n
298
+ if (wantedTab) {
299
+ feedbackTypes.forEach(function (t) { t.classList.remove("zasdk-selected"); }); // no i18n
300
+ wantedTab.classList.add("zasdk-selected"); // no i18n
301
+ }
302
+ }
303
+ if (!isEmpty(feedback._opts.message)) {
304
+ descriptionField.value = String(feedback._opts.message);
305
+ feedback.updateLeftCount();
306
+ feedback.validateFeedbackField();
307
+ }
308
+ feedback.selectedFiles = newTransfer();
309
+ feedback.fileInput.onchange = function () {
310
+ const self = this;
311
+ var chosen = feedback.selectedFiles;
312
+ if (chosen === null) {
313
+ return; // no file list on this browser; see newTransfer()
314
+ }
315
+ if (chosen.files.length + self.files.length > 5) {
316
+ feedback.handleStatusmsg(false, 'Maximum 5 attachments is allowed'); // no i18n
317
+ feedback.fileInput.files = chosen.files;
318
+ self.files = chosen.files;
319
+ return;
320
+ }
321
+ if (self.files.length > 0) {
322
+ let filesize = 0;
323
+ for (let file of self.files) {
324
+ filesize = filesize + file.size;
325
+ if (filesize > 10485760) {
326
+ feedback.handleStatusmsg(false, 'Maximum limit reached. The total file size cannot exceed 10MB.'); // no i18n
327
+ self.files = chosen.files;
328
+ return;
329
+ }
330
+ else {
331
+ chosen.items.add(file); // Add new files
332
+ }
333
+ }
334
+ self.files = chosen.files; // Update input with all files
335
+ feedback.fileAttachment(); // Update UI
336
+ }
337
+ else if (chosen.files.length > 0) {
338
+ // Restore previous files if the user cancels
339
+ self.files = chosen.files;
340
+ }
341
+ };
342
+ feedback.handleStatusmsg();
343
+ feedback.updateLeftCount();
344
+ },
345
+ updateLeftCount: function () {
346
+ document.querySelectorAll("[reqname]").forEach(function (elem) {
347
+ let val = elem.value;
348
+ let maxLength = parseInt(elem.getAttribute("maxlength") || '', 10); // no i18n
349
+ let counterElem = elem.parentElement ? elem.parentElement.querySelector(".zaleftcharcnt") : null; // no i18n
350
+ if (counterElem) {
351
+ counterElem.textContent = String(maxLength - val.length); // Update remaining count
352
+ }
353
+ });
354
+ },
355
+ handleStatusmsg: function (isSuccess, stsmsg) {
356
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
357
+ if (isEmpty(modal)) {
358
+ return;
359
+ }
360
+ var stscnt = modal.querySelector("#zasdksubmitstatus"); // no i18n
361
+ var submitbtn = modal.querySelector("#zasdk_submit_btn"); // no i18n
362
+ var submitbtncnt = modal.querySelector("#zasdk_submit_btnsubcnt"); // no i18n
363
+ var successmsgclass = ''; // no i18n
364
+ var successmsg = ''; // no i18n
365
+ stscnt.style.display = "none"; // no i18n
366
+ if (!isEmpty(isSuccess)) {
367
+ successmsgclass = isSuccess ? 'zasdkstssucs' : 'zasdkstserror'; // no i18n
368
+ successmsg = !isEmpty(stsmsg) ? stsmsg : ''; // no i18n
369
+ stscnt.textContent = successmsg;
370
+ stscnt.classList.add(successmsgclass);
371
+ stscnt.style.display = "block"; // no i18n
372
+ submitbtncnt.classList.remove('zasdkbtndisabled'); // no i18n
373
+ submitbtn.disabled = false;
374
+ submitbtn.value = 'Send'; // no i18n
375
+ }
376
+ },
377
+ handleErrorQuartzEvent: function (event) {
378
+ let errorType = event.detail.error.name;
379
+ let errorMessage = event.detail.error.message;
380
+ if (errorType == quartzConstants().ErrorType.RECORDING_INTERRUPTED || errorType == quartzConstants().ErrorType.FEEDBACK_TIMEOUT) {
381
+ feedback.stopRecording();
382
+ }
383
+ feedback.handleStatusmsg(false, errorMessage);
384
+ },
385
+ bindQuartzEvent: function (event) {
386
+ let feedbackState = event.detail.feedbackState;
387
+ if (feedbackState == quartzConstants().FeedbackState.RECORDING_IN_PROGRESS) {
388
+ var feedbacktimer = document.getElementById("zasdkrectimer"); // no i18n
389
+ if (!isEmpty(feedbacktimer)) {
390
+ feedbacktimer.remove();
391
+ }
392
+ const tempDiv = document.createElement("div"); // no i18n
393
+ tempDiv.innerHTML = feedback.timerHtml;
394
+ const node = tempDiv.firstElementChild;
395
+ document.body.appendChild(node);
396
+ var feedbacktimer = document.getElementById("zasdkrectimer"); // no i18n
397
+ feedback.timerDisplay = feedbacktimer.querySelector('#zasdkTimerDisplay'); // no i18n
398
+ feedback.recordButton = feedbacktimer;
399
+ feedback.TOTAL_TIME = 5 * 60; // 5 minutes in seconds
400
+ feedback.remainingTime = feedback.TOTAL_TIME;
401
+ feedback.isRecording = true;
402
+ feedback.recordButton.addEventListener('click', feedback.toggleRecording); // no i18n
403
+ feedback.startRecording();
404
+ feedback.toggleWindowAnimation();
405
+ }
406
+ },
407
+ close: function () {
408
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
409
+ document.removeEventListener('quartz-feedback-state', feedback.bindQuartzEvent); // no i18n
410
+ quartz().clearFeedback();
411
+ if (!isEmpty(modal)) {
412
+ modal.remove();
413
+ }
414
+ },
415
+ toggleWindowAnimation: function () {
416
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
417
+ const box = modal.querySelector('#zasdkFeedbackconatiner'); // no i18n
418
+ if (feedback.isHidden) {
419
+ modal.style.display = 'block'; // no i18n
420
+ setTimeout(() => {
421
+ box.style.transform = 'scale(1)'; // no i18n
422
+ feedback.validateFeedbackField();
423
+ }, 10);
424
+ feedback.isHidden = false;
425
+ feedback.isScaled = false;
426
+ }
427
+ else if (feedback.isScaled) {
428
+ modal.style.display = 'none'; // no i18n
429
+ feedback.isHidden = true;
430
+ }
431
+ else {
432
+ box.style.transform = 'scale(0)'; // no i18n
433
+ feedback.isScaled = true;
434
+ }
435
+ },
436
+ fileAttachment: function () {
437
+ var uploadedFiles = feedback.fileInput.files;
438
+ feedback.uploadTotalSize = 0;
439
+ feedback.MaxFileSize = 10 * 1024 * 1024; //10 MB
440
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
441
+ var sizeInfo = modal.querySelector("#zasdkfilesizeinfo"); // no i18n
442
+ var fileUl = modal.querySelector("#zasakfileList"); // no i18n
443
+ sizeInfo.textContent = ""; // no i18n
444
+ if ((uploadedFiles.length) > 5) {
445
+ feedback.fileLimitExceeded(false, true);
446
+ feedback.validateFeedbackField();
447
+ return;
448
+ }
449
+ fileUl.innerHTML = ''; // no i18n
450
+ if (uploadedFiles.length > 0) {
451
+ var totalSize = 0;
452
+ for (var i = 0; i < uploadedFiles.length; i++) {
453
+ var fileName = uploadedFiles[i].name;
454
+ var fName = fileName.substring(0, fileName.lastIndexOf('.')); // no i18n
455
+ var extension = fileName.substring(fileName.lastIndexOf('.') + 1); // no i18n
456
+ var bytes = uploadedFiles[i].size;
457
+ totalSize += bytes;
458
+ var fileLi = feedback.elementCreator("li"); // no i18n
459
+ fileLi.title = fileName;
460
+ var span1 = feedback.elementCreator("span"); // no i18n
461
+ span1.className = "zaskFdBckFlName"; // no i18n
462
+ span1.innerText = (fName.length > 10) ? fName.slice(0, 3) + "..." + fName.slice(-3) : fName; // no i18n
463
+ var span2 = feedback.elementCreator("span"); // no i18n
464
+ span2.innerText = "." + extension; // no i18n
465
+ var span3 = feedback.elementCreator("span"); // no i18n
466
+ span3.className = "zasdkFdBckFlCls"; // no i18n
467
+ span3.setAttribute("data-name", fileName); // no i18n
468
+ span3.innerHTML = "&times;"; // no i18N
469
+ fileLi.appendChild(span1);
470
+ fileLi.appendChild(span2);
471
+ fileLi.appendChild(span3);
472
+ fileUl.appendChild(fileLi);
473
+ }
474
+ var limitReached = totalSize > feedback.MaxFileSize;
475
+ feedback.fileLimitExceeded(limitReached);
476
+ sizeInfo.textContent = `${feedback.formatFileSize(totalSize)} Used / 10 MB`; // no i18n
477
+ const clearFile = modal.querySelectorAll('.zasdkFdBckFlCls'); // no i18n
478
+ Array.from(clearFile).forEach(function (element) {
479
+ element.addEventListener('click', function () {
480
+ feedback.handleStatusmsg();
481
+ feedback.removeFileFromList(this);
482
+ feedback.fileAttachment();
483
+ });
484
+ });
485
+ }
486
+ feedback.validateFeedbackField();
487
+ },
488
+ elementCreator: function (elType) {
489
+ return document.createElement(elType);
490
+ },
491
+ fileLimitExceeded: function (limitReached, filesLengthReached) {
492
+ var infoMsg = "";
493
+ if (filesLengthReached || limitReached) {
494
+ infoMsg = filesLengthReached ? 'Maximum 5 attachments is allowed' : 'Maximum limit reached. The total file size cannot exceed 10MB.'; // no i18n
495
+ }
496
+ feedback.handleStatusmsg(false, infoMsg);
497
+ },
498
+ removeFileFromList: function (elem) {
499
+ elem.getAttribute('data-name'); // no i18n
500
+ const listItem = elem.parentElement; // the <li> holding this file
501
+ // Find the index of the element in the file preview list
502
+ const indexToRemove = Array.from(listItem.parentElement.children).indexOf(listItem);
503
+ listItem.remove(); // Remove the file preview
504
+ let newFiles = newTransfer();
505
+ feedback.selectedFiles = newTransfer();
506
+ if (newFiles === null || feedback.selectedFiles === null) {
507
+ return; // no file list to rebuild; the preview row is already gone
508
+ }
509
+ for (let i = 0; i < feedback.fileInput.files.length; i++) {
510
+ if (i !== indexToRemove) {
511
+ newFiles.items.add(feedback.fileInput.files[i]);
512
+ feedback.selectedFiles.items.add(feedback.fileInput.files[i]);
513
+ }
514
+ }
515
+ feedback.fileInput.files = newFiles.files;
516
+ },
517
+ formatFileSize: function (bytes) {
518
+ if (bytes === 0)
519
+ return '0 KB'; // no i18n
520
+ const k = 1024;
521
+ const sizeInKB = bytes / k;
522
+ const sizeInMB = bytes / (k * k);
523
+ const sizeInGB = bytes / (k * k * k);
524
+ if (sizeInGB >= 1) {
525
+ return sizeInGB.toFixed(2) + ' GB'; // no i18n
526
+ }
527
+ else if (sizeInMB >= 1) {
528
+ return sizeInMB.toFixed(2) + ' MB'; // no i18n
529
+ }
530
+ else {
531
+ return sizeInKB.toFixed(2) + ' KB'; // no i18n
532
+ }
533
+ },
534
+ toggleRecording: function () {
535
+ feedback.isRecording = !feedback.isRecording;
536
+ if (feedback.isRecording) {
537
+ feedback.startRecording();
538
+ }
539
+ else {
540
+ feedback.stopRecording();
541
+ }
542
+ },
543
+ startRecording: function () {
544
+ if (!feedback.timerInterval) {
545
+ feedback.timerInterval = setInterval(feedback.updateTimer, 1000);
546
+ }
547
+ },
548
+ stopRecording: function () {
549
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
550
+ clearInterval(feedback.timerInterval || undefined);
551
+ feedback.timerInterval = null;
552
+ document.querySelector("#zasdkrectimer").remove(); // no i18n
553
+ feedback.toggleWindowAnimation();
554
+ modal.querySelector("#editRecordedVideo").style.display = "block"; // no i18n
555
+ modal.querySelector("#zasdkreccheckcnt").style.display = "none"; // no i18n
556
+ let videoElem = modal.querySelector('#previewVideoElemId'); // no i18n
557
+ quartz().endRecording();
558
+ quartz().setVideoContent(videoElem);
559
+ },
560
+ submitRecording: function () {
561
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
562
+ // the recording is filed for whoever the form's picker selected, falling back to the
563
+ // registered user; an anonymous report, a non-email id or a PII opt-out all send the
564
+ // placeholder instead, so Quartz never receives an address the user did not offer
565
+ let testEmail = 'user@example.com', // no i18n
566
+ testMessage = '-', picked = userChoice.anonymous ? '' : String(userChoice.userid || ''), // no i18n
567
+ active = !isEmpty(_ZAP._user_info.userid) ? String(_ZAP._user_info.userid) : '', // no i18n
568
+ userEmail = !isEmpty(picked) ? picked : active, subject = modal.querySelector('#zasdkDescription').value.trim() || testMessage, // no i18n
569
+ emailRegex = /^[\w]([\w\-\.\+\'=]*)@([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,22}$/;
570
+ userEmail = (emailRegex.test(userEmail) && opt_in_status() == AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII) ? userEmail : testEmail;
571
+ // Submit the recording
572
+ quartz().submitRecording({
573
+ email: userEmail,
574
+ subject: subject,
575
+ })
576
+ .then((response) => {
577
+ var zqrecid = !isEmptyObj(response) && response && response.hasOwnProperty('feedbackLink') ? (response.feedbackLink || '') : ''; // no i18n
578
+ submitFeedback(buildFeedbackRequest(modal, subject, zqrecid));
579
+ })
580
+ .catch((error) => {
581
+ // the upload is Quartz's to do; if it fails, hand the form back rather than leaving
582
+ // the submit button spinning with nothing said
583
+ Console.error("submitRecording : " + error); // no i18n
584
+ feedback.handleStatusmsg(false, 'Could not upload the recording. Please try again.'); // no i18n
585
+ });
586
+ },
587
+ updateTimer: function () {
588
+ if (feedback.remainingTime > 0) {
589
+ feedback.remainingTime--;
590
+ feedback.updateDisplay();
591
+ }
592
+ else {
593
+ feedback.stopRecording();
594
+ }
595
+ },
596
+ updateDisplay: function () {
597
+ const minutes = Math.floor(feedback.remainingTime / 60);
598
+ const seconds = feedback.remainingTime % 60;
599
+ feedback.timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; // no i18n
600
+ },
601
+ validateFeedbackField: function () {
602
+ feedback.updateLeftCount();
603
+ var modal = document.getElementById("zasdkFeedbackModal"); // no i18n
604
+ const descriptionField = modal.querySelector('#zasdkDescription'); // no i18n
605
+ const attachmentField = modal.querySelector('#zasdkFileInput'); // no i18n
606
+ const videoElement = modal.querySelector('#previewVideoElemId'); // no i18n
607
+ const sendButton = modal.querySelector('#zasdk_submit_btn'); // no i18n
608
+ const descriptionFilled = descriptionField && descriptionField.value.trim() !== '' && descriptionField.value.trim().length > 0; // no i18n
609
+ attachmentField && attachmentField.files && attachmentField.files.length > 0;
610
+ videoElement && videoElement.offsetParent !== null; // Check if visible
611
+ const errorElements = modal.querySelectorAll('.zasdkmaxerror'); // no i18n
612
+ const hasErrors = feedback.getVisibleErrorCount(errorElements) > 0;
613
+ if (!hasErrors && descriptionFilled) {
614
+ sendButton.classList.remove('zasdkbtndisableclr'); // no i18n
615
+ feedback.handleStatusmsg();
616
+ }
617
+ else {
618
+ sendButton.classList.add('zasdkbtndisableclr'); // no i18n
619
+ }
620
+ },
621
+ getVisibleErrorCount: function (elements) {
622
+ return Array.from(elements).filter(element => element.offsetParent !== null).length;
623
+ }
624
+ };
625
+
626
+ export { feedback, feedbackClose, feedbackOpen, sendFeedback };
@@ -0,0 +1,16 @@
1
+ import { enableHeatmap as enableHeatmapImpl } from './track.js';
2
+ import './send.js';
3
+ /**
4
+ * Heatmap capture, from '@zoho_apptics/apptics-js-sdk/heatmap'.
5
+ *
6
+ * Its own entry point, like the feedback modal: an app that does not want heatmaps ships none of
7
+ * this. Importing it is what makes `track_heatmap: true` do anything — the config flag on its own
8
+ * has nothing to switch on.
9
+ */
10
+ /** Starts or stops recording clicks and scrolls. */
11
+ export declare const enableHeatmap: typeof enableHeatmapImpl;
12
+ export type { HeatmapRecord } from '../types.js';
13
+ declare const heatmap: {
14
+ enableHeatmap: typeof enableHeatmapImpl;
15
+ };
16
+ export default heatmap;
@@ -0,0 +1,17 @@
1
+ /*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
2
+ import { guard } from '../core/guard.js';
3
+ import { enableHeatmap as enableHeatmap$1 } from './track.js';
4
+ import './send.js';
5
+
6
+ /**
7
+ * Heatmap capture, from '@zoho_apptics/apptics-js-sdk/heatmap'.
8
+ *
9
+ * Its own entry point, like the feedback modal: an app that does not want heatmaps ships none of
10
+ * this. Importing it is what makes `track_heatmap: true` do anything — the config flag on its own
11
+ * has nothing to switch on.
12
+ */
13
+ /** Starts or stops recording clicks and scrolls. */
14
+ const enableHeatmap = guard('enableHeatmap', enableHeatmap$1); // no i18n
15
+ const heatmap = { enableHeatmap };
16
+
17
+ export { heatmap as default, enableHeatmap };
@@ -0,0 +1,13 @@
1
+ import type { Dict, ServerResult } from '../types.js';
2
+ /**
3
+ * Sends queued heatmap records to heatmap/add.
4
+ *
5
+ * Shaped like the error and engagement senders, because the queue behaves the same way: records
6
+ * are stored first and sent on the flush timer, a failed send leaves them for the next one, and
7
+ * `forget` is used on page hide so the last batch survives the page going away.
8
+ *
9
+ * Gated on the server's own heatmap flag (getsdkconfig module 18), not on engagement: an app may
10
+ * want events while declining to have every click's coordinates recorded.
11
+ */
12
+ export declare function sendHeatmapData(forget?: boolean): Promise<void>;
13
+ export declare function requestToSendHeatmaps(_payload: Dict, forget?: boolean): Promise<ServerResult>;