@firstlook-uat/sdk 0.2.0 โ†’ 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
- const y = [
1
+ const T = [
2
2
  'input[type="password"]',
3
3
  "[data-sensitive]",
4
4
  "[data-mask]",
5
5
  ".uat-mask"
6
6
  ];
7
- function S(a) {
8
- var t, e, s, i, n, o, c, l, h, d;
7
+ function C(a) {
8
+ var t, e, s, i, n, o, l, c, d, h, p;
9
9
  if (!a.endpoint)
10
10
  throw new Error("[FirstLook] 'endpoint' is required. Set your Supabase ingest-session URL.");
11
11
  return {
@@ -19,17 +19,18 @@ function S(a) {
19
19
  tapCount: ((t = a.triggers) == null ? void 0 : t.tapCount) ?? 5,
20
20
  deepLink: ((e = a.triggers) == null ? void 0 : e.deepLink) ?? !0,
21
21
  shake: ((s = a.triggers) == null ? void 0 : s.shake) ?? !0,
22
- customCheck: (i = a.triggers) == null ? void 0 : i.customCheck
22
+ keyboard: ((i = a.triggers) == null ? void 0 : i.keyboard) ?? !0,
23
+ customCheck: (n = a.triggers) == null ? void 0 : n.customCheck
23
24
  },
24
25
  security: {
25
- watermark: ((n = a.security) == null ? void 0 : n.watermark) ?? !0,
26
- maskSelectors: ((o = a.security) == null ? void 0 : o.maskSelectors) ?? y
26
+ watermark: ((o = a.security) == null ? void 0 : o.watermark) ?? !0,
27
+ maskSelectors: ((l = a.security) == null ? void 0 : l.maskSelectors) ?? T
27
28
  },
28
29
  recording: {
29
30
  domSnapshot: ((c = a.recording) == null ? void 0 : c.domSnapshot) ?? !0,
30
- voice: ((l = a.recording) == null ? void 0 : l.voice) ?? !0,
31
+ voice: ((d = a.recording) == null ? void 0 : d.voice) ?? !0,
31
32
  maxDuration: ((h = a.recording) == null ? void 0 : h.maxDuration) ?? 600,
32
- snapshotInterval: ((d = a.recording) == null ? void 0 : d.snapshotInterval) ?? 1e3
33
+ snapshotInterval: ((p = a.recording) == null ? void 0 : p.snapshotInterval) ?? 1e3
33
34
  }
34
35
  };
35
36
  }
@@ -44,7 +45,7 @@ function w() {
44
45
  touchSupport: "ontouchstart" in window || navigator.maxTouchPoints > 0
45
46
  };
46
47
  }
47
- class T {
48
+ class q {
48
49
  constructor() {
49
50
  this.listeners = /* @__PURE__ */ new Map();
50
51
  }
@@ -75,7 +76,7 @@ class T {
75
76
  this.listeners.clear();
76
77
  }
77
78
  }
78
- class C {
79
+ class I {
79
80
  constructor(t) {
80
81
  this.events = t, this.quests = [], this.results = [], this.currentIndex = -1, this.sessionStartTime = 0, this.blocked = !1, this.pendingFeedbacks = [];
81
82
  }
@@ -112,8 +113,10 @@ class C {
112
113
  status: "COMPLETED",
113
114
  timestamp: Date.now(),
114
115
  relativeTime: Date.now() - this.sessionStartTime,
115
- voiceMemoBlob: e,
116
+ voiceMemoBlob: e == null ? void 0 : e.voiceMemo,
116
117
  logs: t,
118
+ comment: e == null ? void 0 : e.comment,
119
+ concern: (e == null ? void 0 : e.concern) ?? !1,
117
120
  feedbacks: this.drainFeedbacks()
118
121
  };
119
122
  return this.results.push(i), this.events.emit({ type: "quest:completed", questId: s.id }), this.advance(), i;
@@ -129,6 +132,7 @@ class C {
129
132
  voiceMemoBlob: s,
130
133
  logs: t,
131
134
  comment: e,
135
+ concern: !1,
132
136
  feedbacks: this.drainFeedbacks()
133
137
  };
134
138
  return this.results.push(n), this.events.emit({ type: "quest:failed", questId: i.id }), i.blocking ? (this.blocked = !0, this.events.emit({ type: "quest:blocked", questId: i.id })) : this.advance(), n;
@@ -157,16 +161,19 @@ function r(a, t, e) {
157
161
  typeof i == "string" ? s.appendChild(document.createTextNode(i)) : s.appendChild(i);
158
162
  return s;
159
163
  }
160
- function I() {
164
+ function M() {
161
165
  return `fl_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
162
166
  }
163
- function q(a) {
167
+ function E(a) {
164
168
  const t = Math.floor(a / 60), e = a % 60;
165
169
  return `${t.toString().padStart(2, "0")}:${e.toString().padStart(2, "0")}`;
166
170
  }
167
- class M {
171
+ class R {
168
172
  constructor(t, e) {
169
- this.shadowRoot = t, this.callbacks = e, this.minimized = !1, this.timerInterval = null, this.startTime = 0, this.root = document.createElement("div"), this.root.className = "fl-quest-overlay", this.shadowRoot.appendChild(this.root);
173
+ this.shadowRoot = t, this.callbacks = e, this.minimized = !1, this.timerInterval = null, this.startTime = 0, this.root = document.createElement("div"), this.root.className = "fl-quest-overlay";
174
+ for (const s of ["click", "mousedown", "mouseup", "pointerdown", "pointerup", "touchstart", "touchend"])
175
+ this.root.addEventListener(s, (i) => i.stopPropagation());
176
+ this.shadowRoot.appendChild(this.root);
170
177
  }
171
178
  renderQuest(t, e, s) {
172
179
  this.minimized = !1, this.root.className = "fl-quest-overlay", this.root.innerHTML = "";
@@ -178,64 +185,95 @@ class M {
178
185
  this.createMinimizeBtn()
179
186
  ]);
180
187
  this.root.appendChild(n);
181
- const o = r("div", { className: "fl-quest-content" }), c = r("div", { className: "fl-quest-progress" });
182
- for (const f of e) {
183
- const m = f === "COMPLETED" ? "fl-completed" : f === "FAILED" ? "fl-failed" : f === "ACTIVE" ? "fl-active" : "";
184
- c.appendChild(r("div", { className: `fl-quest-progress-dot ${m}` }));
188
+ const o = r("div", { className: "fl-quest-content" }), l = r("div", { className: "fl-quest-progress" });
189
+ for (const p of e) {
190
+ const g = p === "COMPLETED" ? "fl-completed" : p === "FAILED" ? "fl-failed" : p === "ACTIVE" ? "fl-active" : "";
191
+ l.appendChild(r("div", { className: `fl-quest-progress-dot ${g}` }));
185
192
  }
186
- const l = r("div", { className: "fl-quest-body" }, [
187
- c,
193
+ const c = r("div", { className: "fl-quest-body" }, [
194
+ l,
188
195
  r("p", { className: "fl-quest-description" }, [t.description]),
189
196
  r("div", { className: "fl-quest-memo-row" }, [
190
- this.createButton("fl-btn fl-btn-memo", "๐Ÿ“ ใƒกใƒข", () => this.renderFeedbackModal(t.title))
197
+ this.createButton("fl-btn fl-btn-memo", "๐Ÿ“ ใƒกใƒขใ‚’ๆฎ‹ใ™", () => this.renderFeedbackModal(t.title))
191
198
  ]),
192
199
  r("div", { className: "fl-quest-actions" }, [
193
- this.createButton("fl-btn fl-btn-ok", "โœ“ OK", this.callbacks.onOk),
200
+ this.createButton("fl-btn fl-btn-ok", "โœ“ OK", () => this.renderFeedbackModal(t.title, "ok")),
201
+ this.createButton("fl-btn fl-btn-concern", "โš  ๆฐ—ใซใชใ‚‹", () => this.renderFeedbackModal(t.title, "concern")),
194
202
  this.createButton("fl-btn fl-btn-ng", "โœ— NG", this.callbacks.onNg)
195
203
  ])
196
204
  ]);
197
- o.appendChild(l), s && o.appendChild(
205
+ o.appendChild(c), s && o.appendChild(
198
206
  r("div", { className: "fl-voice-indicator" }, [
199
207
  r("span", { className: "fl-voice-dot" }),
200
208
  "Recording..."
201
209
  ])
202
210
  );
203
- const h = r("div", { className: "fl-status-bar" });
204
- s && h.appendChild(
211
+ const d = r("div", { className: "fl-status-bar" });
212
+ s && d.appendChild(
205
213
  r("span", { className: "fl-status-recording" }, [
206
214
  r("span", { className: "fl-voice-dot" }),
207
215
  "REC"
208
216
  ])
209
217
  );
210
- const d = r("span", { className: "fl-status-timer" }, ["00:00"]);
211
- h.appendChild(d), o.appendChild(h), this.root.appendChild(o), this.startTimer(d), this.root.onclick = () => {
212
- this.minimized && (this.minimized = !1, this.root.className = "fl-quest-overlay", this.root.innerHTML = "", this.root.appendChild(n), this.root.appendChild(o), this.startTimer(d));
218
+ const h = r("span", { className: "fl-status-timer" }, ["00:00"]);
219
+ d.appendChild(h), o.appendChild(d), this.root.appendChild(o), this.startTimer(h), this.root.onclick = () => {
220
+ this.minimized && (this.minimized = !1, this.root.className = "fl-quest-overlay", this.root.innerHTML = "", this.root.appendChild(n), this.root.appendChild(o), this.startTimer(h));
213
221
  };
214
222
  }
215
223
  renderFeedbackModal(t, e = "memo") {
216
- const s = r("div", { className: "fl-feedback-modal" }), i = e === "ng", l = r("div", { className: i ? "fl-quest-header fl-quest-header-ng" : "fl-quest-header" }, [
224
+ const s = r("div", { className: "fl-feedback-modal" }), i = {
225
+ ng: "fl-quest-header fl-quest-header-ng",
226
+ ok: "fl-quest-header fl-quest-header-ok",
227
+ concern: "fl-quest-header fl-quest-header-concern",
228
+ memo: "fl-quest-header"
229
+ }, n = {
230
+ ng: "NG",
231
+ ok: "โœ“ OK",
232
+ concern: "โš  ๆฐ—ใซใชใ‚‹",
233
+ memo: "๐Ÿ“"
234
+ }, o = {
235
+ ng: "fl-quest-badge fl-badge-ng",
236
+ ok: "fl-quest-badge fl-badge-ok",
237
+ concern: "fl-quest-badge fl-badge-concern",
238
+ memo: "fl-quest-badge"
239
+ }, l = r("div", { className: i[e] }, [
217
240
  r("div", { className: "fl-quest-header-left" }, [
218
- r("span", { className: i ? "fl-quest-badge fl-badge-ng" : "fl-quest-badge" }, [i ? "NG" : "๐Ÿ“"]),
241
+ r("span", { className: o[e] }, [n[e]]),
219
242
  r("span", { className: "fl-quest-title" }, [t])
220
243
  ])
221
244
  ]);
222
245
  s.appendChild(l);
223
- const h = r("div", { className: "fl-quest-content" }), d = document.createElement("textarea");
224
- d.className = "fl-feedback-textarea fl-feedback-textarea-modal", d.placeholder = i ? "ไฝ•ใŒใ†ใพใใ„ใ‹ใชใ‹ใฃใŸใ‹ๆ•™ใˆใฆใใ ใ•ใ„..." : "ๆฐ—ใฅใ„ใŸใ“ใจใ‚’ใƒกใƒข...๐Ÿ“", d.rows = 3, h.appendChild(d);
225
- const f = r("div", { className: "fl-quest-actions fl-feedback-modal-actions" }, [
226
- this.createButton("fl-btn fl-btn-finish", "้€ไฟก", () => {
227
- const m = d.value.trim();
228
- if (!m && !i) {
229
- s.remove();
230
- return;
231
- }
232
- i ? this.callbacks.onNgWithFeedback(m) : this.callbacks.onMemo(m), s.remove();
246
+ const c = r("div", { className: "fl-quest-content" }), d = {
247
+ ng: "ไฝ•ใŒใ†ใพใใ„ใ‹ใชใ‹ใฃใŸใ‹ๆ•™ใˆใฆใใ ใ•ใ„...",
248
+ ok: "ใ‚ณใƒกใƒณใƒˆ๏ผˆไปปๆ„๏ผ‰",
249
+ concern: "ๆฐ—ใซใชใฃใŸ็‚นใ‚’ๆ•™ใˆใฆใใ ใ•ใ„...",
250
+ memo: "ๆฐ—ใฅใ„ใŸใ“ใจใ‚’ใƒกใƒข...๐Ÿ“"
251
+ }, h = document.createElement("textarea");
252
+ h.className = "fl-feedback-textarea fl-feedback-textarea-modal", h.placeholder = d[e], h.rows = 3, c.appendChild(h);
253
+ const p = "้€ไฟก", g = e === "ok" ? "ใ‚นใ‚ญใƒƒใƒ—" : "ใ‚ญใƒฃใƒณใ‚ปใƒซ", f = r("div", { className: "fl-quest-actions fl-feedback-modal-actions" }, [
254
+ this.createButton("fl-btn fl-btn-skip", g, () => {
255
+ e === "ng" ? this.callbacks.onNgWithFeedback("") : e === "ok" && this.callbacks.onOkWithFeedback(""), s.remove();
233
256
  }),
234
- this.createButton("fl-btn fl-btn-skip", "ใ‚ญใƒฃใƒณใ‚ปใƒซ", () => {
235
- i && this.callbacks.onNgWithFeedback(""), s.remove();
257
+ this.createButton("fl-btn fl-btn-finish", p, () => {
258
+ const m = h.value.trim();
259
+ if (e === "ng")
260
+ this.callbacks.onNgWithFeedback(m);
261
+ else if (e === "ok")
262
+ this.callbacks.onOkWithFeedback(m);
263
+ else if (e === "concern") {
264
+ if (!m) return;
265
+ this.callbacks.onConcern(m);
266
+ } else {
267
+ if (!m) {
268
+ s.remove();
269
+ return;
270
+ }
271
+ this.callbacks.onMemo(m);
272
+ }
273
+ s.remove();
236
274
  })
237
275
  ]);
238
- h.appendChild(f), s.appendChild(h), this.root.appendChild(s), d.focus();
276
+ c.appendChild(f), s.appendChild(c), this.root.appendChild(s), h.focus();
239
277
  }
240
278
  renderSummary(t, e, s) {
241
279
  this.stopTimer(), this.root.className = "fl-quest-overlay", this.root.innerHTML = "";
@@ -293,14 +331,14 @@ class M {
293
331
  startTimer(t) {
294
332
  this.stopTimer(), this.startTime || (this.startTime = Date.now()), this.timerInterval = setInterval(() => {
295
333
  const e = Math.floor((Date.now() - this.startTime) / 1e3);
296
- t.textContent = q(e);
334
+ t.textContent = E(e);
297
335
  }, 1e3);
298
336
  }
299
337
  stopTimer() {
300
338
  this.timerInterval && (clearInterval(this.timerInterval), this.timerInterval = null);
301
339
  }
302
340
  }
303
- const E = 100, R = 2 * 1024 * 1024;
341
+ const L = 100, A = 2 * 1024 * 1024;
304
342
  class D {
305
343
  constructor(t, e, s) {
306
344
  this.config = t, this.events = e, this.maskSelector = s, this.actionLogs = [], this.snapshots = [], this.snapshotTimer = null, this.startTime = 0, this.running = !1, this.handleClick = this.onClick.bind(this), this.handleScroll = this.throttle(this.onScroll.bind(this), 500), this.handleInput = this.onInput.bind(this);
@@ -333,7 +371,7 @@ class D {
333
371
  const e = t.target;
334
372
  this.addLog({
335
373
  type: "click",
336
- target: x(e)
374
+ target: k(e)
337
375
  });
338
376
  }
339
377
  onScroll() {
@@ -345,12 +383,12 @@ class D {
345
383
  onInput(t) {
346
384
  const e = t.target;
347
385
  if (e.hasAttribute("data-fl-masked"))
348
- this.addLog({ type: "input", target: x(e), value: "[MASKED]" });
386
+ this.addLog({ type: "input", target: k(e), value: "[MASKED]" });
349
387
  else {
350
388
  const s = e.value;
351
389
  this.addLog({
352
390
  type: "input",
353
- target: x(e),
391
+ target: k(e),
354
392
  value: s == null ? void 0 : s.slice(0, 100)
355
393
  });
356
394
  }
@@ -368,8 +406,8 @@ class D {
368
406
  const s = t.querySelector("#firstlook-sdk-root");
369
407
  s == null || s.remove();
370
408
  const i = t.outerHTML;
371
- if (i.length > R) return;
372
- this.snapshots.length >= E && this.snapshots.shift(), this.snapshots.push({
409
+ if (i.length > A) return;
410
+ this.snapshots.length >= L && this.snapshots.shift(), this.snapshots.push({
373
411
  type: "dom-snapshot",
374
412
  timestamp: Date.now() - this.startTime,
375
413
  data: i
@@ -385,12 +423,12 @@ class D {
385
423
  };
386
424
  }
387
425
  }
388
- function x(a) {
426
+ function k(a) {
389
427
  var n;
390
428
  const t = a.tagName.toLowerCase(), e = a.id ? `#${a.id}` : "", s = a.className && typeof a.className == "string" ? `.${a.className.trim().split(/\s+/).slice(0, 2).join(".")}` : "", i = ((n = a.textContent) == null ? void 0 : n.trim().slice(0, 30)) || "";
391
429
  return `${t}${e}${s}${i ? ` "${i}"` : ""}`;
392
430
  }
393
- class L {
431
+ class N {
394
432
  constructor(t) {
395
433
  this.events = t, this.mediaRecorder = null, this.stream = null, this.chunks = [], this._recording = !1;
396
434
  }
@@ -449,7 +487,7 @@ class L {
449
487
  return "";
450
488
  }
451
489
  }
452
- class A {
490
+ class F {
453
491
  constructor(t, e) {
454
492
  this.shadowRoot = t, this.config = e, this.container = null, this.refreshInterval = null, this.cachedIp = null;
455
493
  }
@@ -471,15 +509,15 @@ class A {
471
509
  renderTiles() {
472
510
  if (!this.container) return;
473
511
  this.container.innerHTML = "";
474
- const t = this.cachedIp ?? "", e = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19), s = t ? `${this.config.userId} | ${e} | ${t}` : `${this.config.userId} | ${e}`, i = 320, n = 80, o = Math.ceil(window.innerWidth / i) + 1, c = Math.ceil(window.innerHeight / n) + 1;
475
- for (let l = 0; l < c; l++)
476
- for (let h = 0; h < o; h++) {
477
- const d = document.createElement("span");
478
- d.className = "fl-watermark-tile", d.textContent = s, d.style.left = `${h * i}px`, d.style.top = `${l * n}px`, this.container.appendChild(d);
512
+ const t = this.cachedIp ?? "", e = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19), s = t ? `${this.config.userId} | ${e} | ${t}` : `${this.config.userId} | ${e}`, i = 320, n = 80, o = Math.ceil(window.innerWidth / i) + 1, l = Math.ceil(window.innerHeight / n) + 1;
513
+ for (let c = 0; c < l; c++)
514
+ for (let d = 0; d < o; d++) {
515
+ const h = document.createElement("span");
516
+ h.className = "fl-watermark-tile", h.textContent = s, h.style.left = `${d * i}px`, h.style.top = `${c * n}px`, this.container.appendChild(h);
479
517
  }
480
518
  }
481
519
  }
482
- class N {
520
+ class z {
483
521
  constructor(t) {
484
522
  this.selectors = t, this.observer = null, this.maskedElements = /* @__PURE__ */ new Set();
485
523
  }
@@ -517,20 +555,20 @@ class N {
517
555
  }
518
556
  }
519
557
  }
520
- const F = "firstlook_uat", z = 1, u = {
558
+ const P = "firstlook_uat", O = 1, u = {
521
559
  sessions: "sessions",
522
560
  recordings: "recordings",
523
561
  annotations: "annotations",
524
562
  uploadQueue: "upload_queue"
525
563
  };
526
- class P {
564
+ class Q {
527
565
  constructor() {
528
566
  this.db = null;
529
567
  }
530
568
  async open() {
531
569
  if (!this.db)
532
570
  return new Promise((t, e) => {
533
- const s = indexedDB.open(F, z);
571
+ const s = indexedDB.open(P, O);
534
572
  s.onupgradeneeded = () => {
535
573
  const i = s.result;
536
574
  i.objectStoreNames.contains(u.sessions) || i.createObjectStore(u.sessions, { keyPath: "sessionId" }), i.objectStoreNames.contains(u.recordings) || i.createObjectStore(u.recordings, { autoIncrement: !0 }).createIndex("sessionId", "sessionId", { unique: !1 }), i.objectStoreNames.contains(u.annotations) || i.createObjectStore(u.annotations, { autoIncrement: !0 }).createIndex("sessionId", "sessionId", { unique: !1 }), i.objectStoreNames.contains(u.uploadQueue) || i.createObjectStore(u.uploadQueue, { autoIncrement: !0 });
@@ -564,15 +602,15 @@ class P {
564
602
  async getPendingUploads() {
565
603
  const t = this.ensureDb();
566
604
  return new Promise((e, s) => {
567
- const o = t.transaction(u.uploadQueue, "readonly").objectStore(u.uploadQueue).openCursor(), c = [];
605
+ const o = t.transaction(u.uploadQueue, "readonly").objectStore(u.uploadQueue).openCursor(), l = [];
568
606
  o.onsuccess = () => {
569
- const l = o.result;
570
- l ? (c.push({
571
- key: l.key,
572
- payload: l.value.payload,
573
- attempts: l.value.attempts,
574
- lastAttemptAt: l.value.lastAttemptAt
575
- }), l.continue()) : e(c);
607
+ const c = o.result;
608
+ c ? (l.push({
609
+ key: c.key,
610
+ payload: c.value.payload,
611
+ attempts: c.value.attempts,
612
+ lastAttemptAt: c.value.lastAttemptAt
613
+ }), c.continue()) : e(l);
576
614
  }, o.onerror = () => s(o.error);
577
615
  });
578
616
  }
@@ -586,10 +624,10 @@ class P {
586
624
  async incrementAttempts(t) {
587
625
  const e = this.ensureDb();
588
626
  return new Promise((s, i) => {
589
- const n = e.transaction(u.uploadQueue, "readwrite"), o = n.objectStore(u.uploadQueue), c = o.get(t);
590
- c.onsuccess = () => {
591
- const l = c.result;
592
- l && (l.attempts = (l.attempts ?? 0) + 1, l.lastAttemptAt = Date.now(), o.put(l, t));
627
+ const n = e.transaction(u.uploadQueue, "readwrite"), o = n.objectStore(u.uploadQueue), l = o.get(t);
628
+ l.onsuccess = () => {
629
+ const c = l.result;
630
+ c && (c.attempts = (c.attempts ?? 0) + 1, c.lastAttemptAt = Date.now(), o.put(c, t));
593
631
  }, n.oncomplete = () => s(), n.onerror = () => i(n.error);
594
632
  });
595
633
  }
@@ -600,10 +638,10 @@ class P {
600
638
  );
601
639
  s.objectStore(u.sessions).delete(t);
602
640
  for (const i of [u.recordings, u.annotations]) {
603
- const c = s.objectStore(i).index("sessionId").openCursor(IDBKeyRange.only(t));
604
- c.onsuccess = () => {
605
- const l = c.result;
606
- l && (l.delete(), l.continue());
641
+ const l = s.objectStore(i).index("sessionId").openCursor(IDBKeyRange.only(t));
642
+ l.onsuccess = () => {
643
+ const c = l.result;
644
+ c && (c.delete(), c.continue());
607
645
  };
608
646
  }
609
647
  return new Promise((i, n) => {
@@ -628,22 +666,22 @@ class P {
628
666
  async get(t, e) {
629
667
  const s = this.ensureDb();
630
668
  return new Promise((i, n) => {
631
- const c = s.transaction(t, "readonly").objectStore(t).get(e);
632
- c.onsuccess = () => i(c.result), c.onerror = () => n(c.error);
669
+ const l = s.transaction(t, "readonly").objectStore(t).get(e);
670
+ l.onsuccess = () => i(l.result), l.onerror = () => n(l.error);
633
671
  });
634
672
  }
635
673
  async getAllByIndex(t, e, s) {
636
674
  const i = this.ensureDb();
637
675
  return new Promise((n, o) => {
638
- const h = i.transaction(t, "readonly").objectStore(t).index(e).getAll(s);
639
- h.onsuccess = () => n(h.result), h.onerror = () => o(h.error);
676
+ const d = i.transaction(t, "readonly").objectStore(t).index(e).getAll(s);
677
+ d.onsuccess = () => n(d.result), d.onerror = () => o(d.error);
640
678
  });
641
679
  }
642
680
  }
643
- const k = ["#e17055", "#6c5ce7", "#00b894", "#fdcb6e", "#ffffff"];
644
- class O {
681
+ const y = ["#e17055", "#6c5ce7", "#00b894", "#fdcb6e", "#ffffff"];
682
+ class B {
645
683
  constructor(t) {
646
- this.shadowRoot = t, this.overlay = null, this.canvas = null, this.ctx = null, this.drawing = !1, this.currentPath = [], this.paths = [], this.selectedColor = k[0], this.screenshotDataUrl = "";
684
+ this.shadowRoot = t, this.overlay = null, this.canvas = null, this.ctx = null, this.drawing = !1, this.currentPath = [], this.paths = [], this.selectedColor = y[0], this.screenshotDataUrl = "";
647
685
  }
648
686
  async open() {
649
687
  return this.screenshotDataUrl = await this.captureScreenshot(), new Promise((t) => {
@@ -655,33 +693,33 @@ class O {
655
693
  type: "text",
656
694
  placeholder: "Add a comment..."
657
695
  }), i = r("div", { className: "fl-color-picker" });
658
- for (const l of k) {
659
- const h = r("div", { className: `fl-color-swatch ${l === this.selectedColor ? "fl-selected" : ""}` });
660
- h.style.background = l, h.onclick = () => {
661
- this.selectedColor = l, i.querySelectorAll(".fl-color-swatch").forEach((d) => d.classList.remove("fl-selected")), h.classList.add("fl-selected");
662
- }, i.appendChild(h);
696
+ for (const c of y) {
697
+ const d = r("div", { className: `fl-color-swatch ${c === this.selectedColor ? "fl-selected" : ""}` });
698
+ d.style.background = c, d.onclick = () => {
699
+ this.selectedColor = c, i.querySelectorAll(".fl-color-swatch").forEach((h) => h.classList.remove("fl-selected")), d.classList.add("fl-selected");
700
+ }, i.appendChild(d);
663
701
  }
664
702
  const n = r("button", { className: "fl-btn fl-btn-ok" }, ["Submit"]);
665
703
  n.onclick = () => {
666
- const l = {
704
+ const c = {
667
705
  screenshotDataUrl: this.getAnnotatedImage(),
668
706
  drawings: [...this.paths],
669
707
  comment: s.value,
670
708
  timestamp: Date.now()
671
709
  };
672
- this.close(), t(l);
710
+ this.close(), t(c);
673
711
  };
674
712
  const o = r("button", { className: "fl-btn fl-btn-ng" }, ["Cancel"]);
675
713
  o.onclick = () => {
676
714
  this.close(), t(null);
677
715
  };
678
- const c = r("div", { className: "fl-annotation-toolbar" }, [
716
+ const l = r("div", { className: "fl-annotation-toolbar" }, [
679
717
  i,
680
718
  s,
681
719
  n,
682
720
  o
683
721
  ]);
684
- this.overlay.appendChild(c), this.shadowRoot.appendChild(this.overlay), this.initCanvas();
722
+ this.overlay.appendChild(l), this.shadowRoot.appendChild(this.overlay), this.initCanvas();
685
723
  });
686
724
  }
687
725
  close() {
@@ -693,28 +731,28 @@ class O {
693
731
  const t = window.innerWidth, e = window.innerHeight, s = document.documentElement.cloneNode(!0), i = s.querySelector("#firstlook-sdk-root");
694
732
  i == null || i.remove();
695
733
  const n = s.querySelectorAll('[data-fl-masked], input[type="password"]');
696
- for (const p of n)
697
- (p instanceof HTMLInputElement || p instanceof HTMLTextAreaElement) && (p.value = "[MASKED]"), p.textContent = "[MASKED]";
698
- for (const p of s.querySelectorAll("script")) p.remove();
734
+ for (const f of n)
735
+ (f instanceof HTMLInputElement || f instanceof HTMLTextAreaElement) && (f.value = "[MASKED]"), f.textContent = "[MASKED]";
736
+ for (const f of s.querySelectorAll("script")) f.remove();
699
737
  const o = s.querySelector("body");
700
738
  if (o) {
701
- const p = window.getComputedStyle(document.body);
702
- o.style.backgroundColor = p.backgroundColor, o.style.color = p.color, o.style.fontFamily = p.fontFamily, o.style.margin = "0", o.style.overflow = "hidden";
739
+ const f = window.getComputedStyle(document.body);
740
+ o.style.backgroundColor = f.backgroundColor, o.style.color = f.color, o.style.fontFamily = f.fontFamily, o.style.margin = "0", o.style.overflow = "hidden";
703
741
  }
704
- const c = new XMLSerializer().serializeToString(s), l = `<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${e}">
742
+ const l = new XMLSerializer().serializeToString(s), c = `<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${e}">
705
743
  <foreignObject width="100%" height="100%">
706
- ${c}
744
+ ${l}
707
745
  </foreignObject>
708
- </svg>`, h = new Blob([l], { type: "image/svg+xml;charset=utf-8" }), d = URL.createObjectURL(h), f = document.createElement("canvas");
709
- f.width = t * window.devicePixelRatio, f.height = e * window.devicePixelRatio;
710
- const m = f.getContext("2d");
711
- return m.scale(window.devicePixelRatio, window.devicePixelRatio), new Promise((p) => {
712
- const g = new Image();
713
- g.onload = () => {
714
- m.drawImage(g, 0, 0, t, e), URL.revokeObjectURL(d), p(f.toDataURL("image/png"));
715
- }, g.onerror = () => {
716
- URL.revokeObjectURL(d), p(this.captureScreenshotFallback(t, e));
717
- }, g.src = d;
746
+ </svg>`, d = new Blob([c], { type: "image/svg+xml;charset=utf-8" }), h = URL.createObjectURL(d), p = document.createElement("canvas");
747
+ p.width = t * window.devicePixelRatio, p.height = e * window.devicePixelRatio;
748
+ const g = p.getContext("2d");
749
+ return g.scale(window.devicePixelRatio, window.devicePixelRatio), new Promise((f) => {
750
+ const m = new Image();
751
+ m.onload = () => {
752
+ g.drawImage(m, 0, 0, t, e), URL.revokeObjectURL(h), f(p.toDataURL("image/png"));
753
+ }, m.onerror = () => {
754
+ URL.revokeObjectURL(h), f(this.captureScreenshotFallback(t, e));
755
+ }, m.src = h;
718
756
  });
719
757
  } catch {
720
758
  return this.captureScreenshotFallback(window.innerWidth, window.innerHeight);
@@ -759,7 +797,7 @@ class O {
759
797
  return ((t = this.canvas) == null ? void 0 : t.toDataURL("image/png")) || this.screenshotDataUrl;
760
798
  }
761
799
  }
762
- class Q {
800
+ class H {
763
801
  constructor(t) {
764
802
  this.onShake = t, this.lastX = 0, this.lastY = 0, this.lastZ = 0, this.shakeCount = 0, this.lastShakeTime = 0, this.handler = null, this.THRESHOLD = 15, this.SHAKE_INTERVAL = 400, this.REQUIRED_SHAKES = 2;
765
803
  }
@@ -786,11 +824,11 @@ class Q {
786
824
  this.lastX = e.x, this.lastY = e.y, this.lastZ = e.z;
787
825
  }
788
826
  }
789
- class B {
827
+ class U {
790
828
  constructor(t, e) {
791
829
  this.shadowRoot = t, this.events = e, this.annotations = [], this.active = !1, this.onKeydown = (s) => {
792
830
  s.ctrlKey && s.shiftKey && s.key === "R" && (s.preventDefault(), this.trigger());
793
- }, this.annotationCanvas = new O(t), this.shakeTrigger = new Q(() => this.trigger());
831
+ }, this.annotationCanvas = new B(t), this.shakeTrigger = new H(() => this.trigger());
794
832
  }
795
833
  async start() {
796
834
  await this.shakeTrigger.start(), document.addEventListener("keydown", this.onKeydown);
@@ -813,7 +851,7 @@ class B {
813
851
  }
814
852
  }
815
853
  }
816
- class H {
854
+ class j {
817
855
  constructor(t, e) {
818
856
  this.requiredTaps = t, this.onActivate = e, this.tapCount = 0, this.tapTimer = null, this.handler = null;
819
857
  }
@@ -830,30 +868,74 @@ class H {
830
868
  this.tapCount = 0, this.tapTimer && (clearTimeout(this.tapTimer), this.tapTimer = null);
831
869
  }
832
870
  }
833
- class U {
871
+ const x = "firstlook:uat-active";
872
+ class S {
834
873
  constructor(t) {
835
874
  this.onActivate = t, this.hashHandler = null;
836
875
  }
837
876
  start() {
838
- this.checkUrl() && this.onActivate(), this.hashHandler = () => {
839
- this.checkUrl() && this.onActivate();
877
+ if (this.checkUrl()) {
878
+ this.persist(), this.onActivate();
879
+ return;
880
+ }
881
+ if (this.hasPersisted()) {
882
+ this.onActivate();
883
+ return;
884
+ }
885
+ this.hashHandler = () => {
886
+ this.checkUrl() && (this.persist(), this.onActivate());
840
887
  }, window.addEventListener("hashchange", this.hashHandler);
841
888
  }
842
889
  stop() {
843
890
  this.hashHandler && (window.removeEventListener("hashchange", this.hashHandler), this.hashHandler = null);
844
891
  }
892
+ /** Clear the persisted flag (call on session end / destroy). */
893
+ static clearPersisted() {
894
+ try {
895
+ sessionStorage.removeItem(x);
896
+ } catch {
897
+ }
898
+ }
845
899
  checkUrl() {
846
900
  const t = new URLSearchParams(window.location.search);
847
- return t.has("firstlook") || t.has("uat-mode");
901
+ return t.has("firstlook") || t.has("uat-mode") || t.get("uat") === "1";
902
+ }
903
+ persist() {
904
+ try {
905
+ sessionStorage.setItem(x, "1");
906
+ } catch {
907
+ }
908
+ }
909
+ hasPersisted() {
910
+ try {
911
+ return sessionStorage.getItem(x) === "1";
912
+ } catch {
913
+ return !1;
914
+ }
848
915
  }
849
916
  }
850
- class j {
917
+ class $ {
918
+ constructor(t) {
919
+ this.onActivate = t, this.handler = null;
920
+ }
921
+ start() {
922
+ this.handler = (t) => {
923
+ t.key === "U" && t.shiftKey && (t.ctrlKey || t.metaKey) && (t.preventDefault(), this.onActivate());
924
+ }, window.addEventListener("keydown", this.handler);
925
+ }
926
+ stop() {
927
+ this.handler && (window.removeEventListener("keydown", this.handler), this.handler = null);
928
+ }
929
+ }
930
+ class K {
851
931
  constructor(t, e) {
852
932
  this.shadowRoot = t, this.callbacks = e, this.root = null, this.outsideClickHandler = null;
853
933
  }
854
934
  show() {
855
935
  if (this.root) return;
856
936
  this.root = r("div", { className: "fl-debug-menu" });
937
+ for (const e of ["click", "mousedown", "mouseup", "pointerdown", "pointerup", "touchstart", "touchend"])
938
+ this.root.addEventListener(e, (s) => s.stopPropagation());
857
939
  const t = [
858
940
  { icon: "โ–ถ", label: "Start Session", action: this.callbacks.onStartSession },
859
941
  { icon: "๐Ÿ“ธ", label: "Report Issue", action: this.callbacks.onReportIssue },
@@ -882,7 +964,7 @@ class j {
882
964
  return this.root !== null;
883
965
  }
884
966
  }
885
- const $ = (
967
+ const _ = (
886
968
  /* css */
887
969
  `
888
970
  :host {
@@ -905,6 +987,7 @@ const $ = (
905
987
  bottom: 24px;
906
988
  right: 24px;
907
989
  z-index: 2147483647;
990
+ pointer-events: auto;
908
991
  width: 360px;
909
992
  max-width: calc(100vw - 48px);
910
993
  background: #ffffff;
@@ -1097,6 +1180,7 @@ const $ = (
1097
1180
  position: fixed;
1098
1181
  inset: 0;
1099
1182
  z-index: 2147483647;
1183
+ pointer-events: auto;
1100
1184
  background: rgba(0, 0, 0, 0.7);
1101
1185
  display: flex;
1102
1186
  flex-direction: column;
@@ -1194,6 +1278,7 @@ const $ = (
1194
1278
  bottom: 100px;
1195
1279
  right: 24px;
1196
1280
  z-index: 2147483646;
1281
+ pointer-events: auto;
1197
1282
  background: #fff;
1198
1283
  border-radius: 12px;
1199
1284
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16);
@@ -1275,10 +1360,16 @@ const $ = (
1275
1360
  box-shadow: 0 2px 8px rgba(99, 110, 114, 0.3);
1276
1361
  }
1277
1362
 
1278
- /* === NG Voice Feedback Mode === */
1363
+ /* === Feedback modal header variants === */
1279
1364
  .fl-quest-header-ng { background: linear-gradient(135deg, #e17055, #d63031); }
1280
1365
  .fl-badge-ng { background: rgba(255, 255, 255, 0.25); }
1281
1366
 
1367
+ .fl-quest-header-ok { background: linear-gradient(135deg, #00b894, #00a381); }
1368
+ .fl-badge-ok { background: rgba(255, 255, 255, 0.25); }
1369
+
1370
+ .fl-quest-header-concern { background: linear-gradient(135deg, #fdcb6e, #e17055); }
1371
+ .fl-badge-concern { background: rgba(255, 255, 255, 0.25); }
1372
+
1282
1373
  .fl-feedback-textarea {
1283
1374
  width: calc(100% - 32px);
1284
1375
  margin: 8px 16px 16px;
@@ -1294,16 +1385,25 @@ const $ = (
1294
1385
  .fl-feedback-textarea:focus { border-color: #6c5ce7; }
1295
1386
  .fl-feedback-textarea-modal { width: calc(100% - 32px); margin: 16px 16px 12px; }
1296
1387
 
1388
+ /* === Concern button === */
1389
+ .fl-btn-concern {
1390
+ background: #fdcb6e;
1391
+ color: #2d3436;
1392
+ box-shadow: 0 2px 8px rgba(253, 203, 110, 0.3);
1393
+ }
1394
+ .fl-btn-concern:hover { box-shadow: 0 4px 12px rgba(253, 203, 110, 0.4); }
1395
+
1297
1396
  /* === Memo button === */
1298
1397
  .fl-quest-memo-row { display: flex; margin-bottom: 10px; }
1299
1398
  .fl-btn-memo {
1300
- flex: none;
1399
+ flex: 1;
1301
1400
  background: #f0f0f8;
1302
1401
  color: #4a4a5a;
1303
- font-size: 12px;
1304
- padding: 6px 12px;
1402
+ font-size: 14px;
1403
+ padding: 10px 16px;
1305
1404
  box-shadow: none;
1306
- border-radius: 8px;
1405
+ border-radius: 10px;
1406
+ border: 1px dashed #c8c8d8;
1307
1407
  }
1308
1408
  .fl-btn-memo:hover { background: #e4e4f0; }
1309
1409
 
@@ -1320,10 +1420,10 @@ const $ = (
1320
1420
  }
1321
1421
  .fl-feedback-modal-actions { padding: 0 16px 16px; }
1322
1422
  `
1323
- ), K = 5;
1324
- class _ {
1423
+ ), W = 5;
1424
+ class X {
1325
1425
  constructor() {
1326
- this.config = null, this.events = new T(), this.state = "idle", this.hostElement = null, this.shadowRoot = null, this.questManager = null, this.questOverlay = null, this.sessionRecorder = null, this.voiceRecorder = null, this.watermark = null, this.fieldMasker = null, this.storage = null, this.shakeReporter = null, this.debugMenu = null, this.tapTrigger = null, this.deepLinkTrigger = null, this.sessionId = null, this.sessionStartTime = 0, this.maxDurationTimer = null, this.backupTimer = null, this.isFlushing = !1;
1426
+ this.config = null, this.events = new q(), this.state = "idle", this.hostElement = null, this.shadowRoot = null, this.questManager = null, this.questOverlay = null, this.sessionRecorder = null, this.voiceRecorder = null, this.watermark = null, this.fieldMasker = null, this.storage = null, this.shakeReporter = null, this.debugMenu = null, this.tapTrigger = null, this.deepLinkTrigger = null, this.keyboardTrigger = null, this.sessionId = null, this.sessionStartTime = 0, this.maxDurationTimer = null, this.backupTimer = null, this.isFlushing = !1;
1327
1427
  }
1328
1428
  // ----------------------------------------------------------------
1329
1429
  // Public API
@@ -1337,7 +1437,7 @@ class _ {
1337
1437
  console.warn("[FirstLook] SDK already initialized.");
1338
1438
  return;
1339
1439
  }
1340
- this.config = S(t), this.storage = new P(), await this.storage.open(), this.createShadowHost(), this.setupTriggers(), this.fieldMasker = new N(this.config.security.maskSelectors), this.state = "initialized", this.events.emit({ type: "sdk:initialized" }), this.flushUploadQueue(!0);
1440
+ this.config = C(t), this.storage = new Q(), await this.storage.open(), this.createShadowHost(), this.setupTriggers(), this.fieldMasker = new z(this.config.security.maskSelectors), this.state = "initialized", this.events.emit({ type: "sdk:initialized" }), this.flushUploadQueue(!0);
1341
1441
  }
1342
1442
  /**
1343
1443
  * Manually activate the SDK UI (bypassing triggers).
@@ -1356,12 +1456,13 @@ class _ {
1356
1456
  var s;
1357
1457
  if (this.state !== "active")
1358
1458
  throw new Error("[FirstLook] Cannot start session: SDK not active. Call activate() first.");
1359
- (s = this.debugMenu) == null || s.hide(), this.sessionId = I(), this.sessionStartTime = Date.now(), this.questManager = new C(this.events), this.questManager.loadQuests(t), this.sessionRecorder = new D(
1459
+ (s = this.debugMenu) == null || s.hide(), this.sessionId = M(), this.sessionStartTime = Date.now(), this.questManager = new I(this.events), this.questManager.loadQuests(t), this.sessionRecorder = new D(
1360
1460
  this.config,
1361
1461
  this.events,
1362
1462
  this.fieldMasker.getCombinedSelector()
1363
- ), this.voiceRecorder = new L(this.events), this.shakeReporter = new B(this.shadowRoot, this.events), await this.shakeReporter.start(), this.sessionRecorder.start(), this.fieldMasker.start(), this.config.recording.voice && await this.voiceRecorder.start(), this.config.security.watermark && (this.watermark = new A(this.shadowRoot, this.config), this.watermark.show()), this.questOverlay = new M(this.shadowRoot, {
1364
- onOk: () => this.handleQuestOk(),
1463
+ ), this.voiceRecorder = new N(this.events), this.shakeReporter = new U(this.shadowRoot, this.events), await this.shakeReporter.start(), this.sessionRecorder.start(), this.fieldMasker.start(), this.config.recording.voice && await this.voiceRecorder.start(), this.config.security.watermark && (this.watermark = new F(this.shadowRoot, this.config), this.watermark.show()), this.questOverlay = new R(this.shadowRoot, {
1464
+ onOkWithFeedback: (i) => this.handleQuestOk(i),
1465
+ onConcern: (i) => this.handleConcern(i),
1365
1466
  onNg: () => this.handleQuestNg(),
1366
1467
  onNgWithFeedback: (i) => this.handleNgFeedbackSubmit(i),
1367
1468
  onMemo: (i) => this.handleMemo(i),
@@ -1392,9 +1493,9 @@ class _ {
1392
1493
  * End the current session, persist data, and trigger upload.
1393
1494
  */
1394
1495
  async endSession() {
1395
- var i, n, o, c, l, h, d, f, m, p, g;
1496
+ var i, n, o, l, c, d, h, p, g, f, m;
1396
1497
  if (this.state !== "recording" || !this.sessionId) return null;
1397
- this.maxDurationTimer && (clearTimeout(this.maxDurationTimer), this.maxDurationTimer = null), this.backupTimer && (clearInterval(this.backupTimer), this.backupTimer = null), (i = this.sessionRecorder) == null || i.stop(), await ((n = this.voiceRecorder) == null ? void 0 : n.stopAsync()), (o = this.shakeReporter) == null || o.stop(), (c = this.fieldMasker) == null || c.stop(), (l = this.watermark) == null || l.hide();
1498
+ this.maxDurationTimer && (clearTimeout(this.maxDurationTimer), this.maxDurationTimer = null), this.backupTimer && (clearInterval(this.backupTimer), this.backupTimer = null), (i = this.sessionRecorder) == null || i.stop(), await ((n = this.voiceRecorder) == null ? void 0 : n.stopAsync()), (o = this.shakeReporter) == null || o.stop(), (l = this.fieldMasker) == null || l.stop(), (c = this.watermark) == null || c.hide();
1398
1499
  const t = this.questManager.getResults();
1399
1500
  await Promise.allSettled(
1400
1501
  t.map(async (b) => {
@@ -1428,13 +1529,13 @@ class _ {
1428
1529
  endedAt: (/* @__PURE__ */ new Date()).toISOString(),
1429
1530
  duration: Math.floor((Date.now() - this.sessionStartTime) / 1e3),
1430
1531
  quests: t,
1431
- recordings: ((h = this.sessionRecorder) == null ? void 0 : h.getSnapshots()) ?? []
1532
+ recordings: ((d = this.sessionRecorder) == null ? void 0 : d.getSnapshots()) ?? []
1432
1533
  };
1433
- await ((d = this.storage) == null ? void 0 : d.saveSession(e));
1434
- const s = ((f = this.shakeReporter) == null ? void 0 : f.getAnnotations()) ?? [];
1534
+ await ((h = this.storage) == null ? void 0 : h.saveSession(e));
1535
+ const s = ((p = this.shakeReporter) == null ? void 0 : p.getAnnotations()) ?? [];
1435
1536
  for (const b of s)
1436
- await ((m = this.storage) == null ? void 0 : m.saveAnnotation(this.sessionId, b));
1437
- return await ((p = this.storage) == null ? void 0 : p.enqueueUpload({ session: e, annotations: s })), (g = this.questOverlay) == null || g.destroy(), this.questOverlay = null, this.state = "finished", this.events.emit({ type: "session:ended", sessionId: this.sessionId }), this.flushUploadQueue(!1), e;
1537
+ await ((g = this.storage) == null ? void 0 : g.saveAnnotation(this.sessionId, b));
1538
+ return await ((f = this.storage) == null ? void 0 : f.enqueueUpload({ session: e, annotations: s })), (m = this.questOverlay) == null || m.destroy(), this.questOverlay = null, this.state = "finished", this.events.emit({ type: "session:ended", sessionId: this.sessionId }), this.flushUploadQueue(!1), e;
1438
1539
  }
1439
1540
  /**
1440
1541
  * Subscribe to SDK events.
@@ -1452,42 +1553,50 @@ class _ {
1452
1553
  * Completely destroy the SDK instance and clean up all resources.
1453
1554
  */
1454
1555
  destroy() {
1455
- var t, e, s, i, n, o, c, l, h, d;
1456
- this.maxDurationTimer && (clearTimeout(this.maxDurationTimer), this.maxDurationTimer = null), this.backupTimer && (clearInterval(this.backupTimer), this.backupTimer = null), (t = this.tapTrigger) == null || t.stop(), (e = this.deepLinkTrigger) == null || e.stop(), (s = this.sessionRecorder) == null || s.stop(), (i = this.shakeReporter) == null || i.stop(), (n = this.fieldMasker) == null || n.stop(), (o = this.watermark) == null || o.hide(), (c = this.questOverlay) == null || c.destroy(), (l = this.debugMenu) == null || l.hide(), (h = this.hostElement) == null || h.remove(), (d = this.storage) == null || d.close(), this.events.removeAll(), this.state = "idle";
1556
+ var t, e, s, i, n, o, l, c, d, h, p;
1557
+ this.maxDurationTimer && (clearTimeout(this.maxDurationTimer), this.maxDurationTimer = null), this.backupTimer && (clearInterval(this.backupTimer), this.backupTimer = null), (t = this.tapTrigger) == null || t.stop(), (e = this.deepLinkTrigger) == null || e.stop(), (s = this.keyboardTrigger) == null || s.stop(), S.clearPersisted(), (i = this.sessionRecorder) == null || i.stop(), (n = this.shakeReporter) == null || n.stop(), (o = this.fieldMasker) == null || o.stop(), (l = this.watermark) == null || l.hide(), (c = this.questOverlay) == null || c.destroy(), (d = this.debugMenu) == null || d.hide(), (h = this.hostElement) == null || h.remove(), (p = this.storage) == null || p.close(), this.events.removeAll(), this.state = "idle";
1457
1558
  }
1458
1559
  // ----------------------------------------------------------------
1459
1560
  // Private methods
1460
1561
  // ----------------------------------------------------------------
1461
1562
  createShadowHost() {
1462
- this.hostElement = document.createElement("div"), this.hostElement.id = "firstlook-sdk-root", this.hostElement.style.cssText = "position:fixed;top:0;left:0;width:0;height:0;z-index:2147483647;pointer-events:none;", document.body.appendChild(this.hostElement), this.shadowRoot = this.hostElement.attachShadow({ mode: "closed" });
1563
+ this.hostElement = document.createElement("div"), this.hostElement.id = "firstlook-sdk-root", this.hostElement.style.cssText = "position:fixed;inset:0;z-index:2147483647;pointer-events:none;", document.body.appendChild(this.hostElement), this.shadowRoot = this.hostElement.attachShadow({ mode: "closed" });
1463
1564
  const t = document.createElement("style");
1464
- t.textContent = $, this.shadowRoot.appendChild(t);
1465
- const e = document.createElement("div");
1466
- e.style.cssText = "pointer-events:auto;", this.shadowRoot.appendChild(e);
1565
+ t.textContent = _, this.shadowRoot.appendChild(t);
1467
1566
  }
1468
1567
  setupTriggers() {
1469
1568
  const t = this.config.triggers;
1470
- this.tapTrigger = new H(t.tapCount, () => this.onActivate()), this.tapTrigger.start(), t.deepLink && (this.deepLinkTrigger = new U(() => this.onActivate()), this.deepLinkTrigger.start()), t.customCheck && t.customCheck() && this.onActivate();
1569
+ this.tapTrigger = new j(t.tapCount, () => this.onActivate()), this.tapTrigger.start(), t.deepLink && (this.deepLinkTrigger = new S(() => this.onActivate()), this.deepLinkTrigger.start()), t.keyboard && (this.keyboardTrigger = new $(() => this.onActivate()), this.keyboardTrigger.start()), t.customCheck && t.customCheck() && this.onActivate();
1471
1570
  }
1472
1571
  onActivate() {
1473
- var t, e;
1474
- this.state === "initialized" && (this.state = "active", (t = this.tapTrigger) == null || t.stop(), (e = this.deepLinkTrigger) == null || e.stop(), this.events.emit({ type: "sdk:activated" }), this.debugMenu = new j(this.shadowRoot, {
1572
+ var t, e, s;
1573
+ this.state === "initialized" && (this.state = "active", (t = this.tapTrigger) == null || t.stop(), (e = this.deepLinkTrigger) == null || e.stop(), (s = this.keyboardTrigger) == null || s.stop(), this.events.emit({ type: "sdk:activated" }), this.debugMenu = new K(this.shadowRoot, {
1475
1574
  onStartSession: () => {
1476
1575
  this.events.emit({ type: "sdk:activated" });
1477
1576
  },
1478
1577
  onReportIssue: () => {
1479
- var s, i;
1480
- (i = (s = this.shakeReporter) == null ? void 0 : s.trigger) == null || i.call(s);
1578
+ var i, n;
1579
+ (n = (i = this.shakeReporter) == null ? void 0 : i.trigger) == null || n.call(i);
1481
1580
  },
1482
1581
  onClose: () => {
1483
1582
  this.destroy();
1484
1583
  }
1485
1584
  }), this.debugMenu.show());
1486
1585
  }
1487
- handleQuestOk() {
1586
+ handleQuestOk(t) {
1587
+ if (!this.questManager || !this.sessionRecorder) return;
1588
+ const e = this.sessionRecorder.getActionLogs();
1589
+ this.questManager.completeCurrentQuest(e, {
1590
+ comment: t || void 0
1591
+ }), this.renderCurrentQuest();
1592
+ }
1593
+ handleConcern(t) {
1488
1594
  if (!this.questManager || !this.sessionRecorder) return;
1489
- const t = this.sessionRecorder.getActionLogs();
1490
- this.questManager.completeCurrentQuest(t), this.renderCurrentQuest();
1595
+ const e = this.sessionRecorder.getActionLogs();
1596
+ this.questManager.completeCurrentQuest(e, {
1597
+ comment: t,
1598
+ concern: !0
1599
+ }), this.renderCurrentQuest();
1491
1600
  }
1492
1601
  handleQuestNg() {
1493
1602
  if (!this.questManager || !this.questOverlay) return;
@@ -1539,7 +1648,7 @@ class _ {
1539
1648
  }
1540
1649
  const e = await this.storage.getPendingUploads();
1541
1650
  for (const s of e) {
1542
- if (s.attempts >= K) {
1651
+ if (s.attempts >= W) {
1543
1652
  await this.storage.removeFromQueue(s.key);
1544
1653
  continue;
1545
1654
  }
@@ -1593,6 +1702,6 @@ class _ {
1593
1702
  }
1594
1703
  }
1595
1704
  export {
1596
- _ as FirstLookSDK
1705
+ X as FirstLookSDK
1597
1706
  };
1598
1707
  //# sourceMappingURL=firstlook.es.js.map