@sphoro/bugcatch-web-sdk 0.14.3 → 0.14.4
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.
- package/dist/bugcatch.es.js +1232 -1187
- package/dist/bugcatch.es.js.map +1 -1
- package/dist/bugcatch.umd.js +94 -65
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/widget.js +75 -5
package/dist/bugcatch.es.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Yt = (t) => {
|
|
2
2
|
throw TypeError(t);
|
|
3
3
|
};
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
const
|
|
4
|
+
var Fn = (t, e, n) => e.has(t) || Yt("Cannot " + n);
|
|
5
|
+
var Xt = (t, e, n) => e.has(t) ? Yt("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n);
|
|
6
|
+
var P = (t, e, n) => (Fn(t, e, "access private method"), n);
|
|
7
|
+
const it = "[REDACTED]", Wn = /* @__PURE__ */ new Set([
|
|
8
8
|
"auth",
|
|
9
9
|
"bearer",
|
|
10
10
|
"session",
|
|
@@ -16,7 +16,7 @@ const rt = "[REDACTED]", Pn = /* @__PURE__ */ new Set([
|
|
|
16
16
|
"pwd",
|
|
17
17
|
"sig",
|
|
18
18
|
"codeverifier"
|
|
19
|
-
]),
|
|
19
|
+
]), Yn = [
|
|
20
20
|
"token",
|
|
21
21
|
"secret",
|
|
22
22
|
"password",
|
|
@@ -28,7 +28,7 @@ const rt = "[REDACTED]", Pn = /* @__PURE__ */ new Set([
|
|
|
28
28
|
"privatekey",
|
|
29
29
|
"accesskey",
|
|
30
30
|
"authorization"
|
|
31
|
-
],
|
|
31
|
+
], Xn = /* @__PURE__ */ new Set(["key", "code", "state", "nonce", "salt", "hash"]), fn = [
|
|
32
32
|
/eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]+/g,
|
|
33
33
|
// JWT
|
|
34
34
|
/(?:AKIA|ASIA|AROA|AIDA|AGPA|ANPA|ANVA|APKA)[0-9A-Z]{16}/g,
|
|
@@ -51,61 +51,61 @@ const rt = "[REDACTED]", Pn = /* @__PURE__ */ new Set([
|
|
|
51
51
|
// GitLab
|
|
52
52
|
/shp(?:at|ss|ca|pa)_[A-Za-z0-9]{32}/g
|
|
53
53
|
// Shopify
|
|
54
|
-
],
|
|
55
|
-
function
|
|
54
|
+
], Zn = /\bBearer\s+[\w.~+/=-]{8,}/gi, Jn = /^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;
|
|
55
|
+
function gn(t) {
|
|
56
56
|
try {
|
|
57
57
|
return decodeURIComponent(t.replace(/\+/g, " "));
|
|
58
58
|
} catch {
|
|
59
59
|
return t;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
function
|
|
63
|
-
return
|
|
62
|
+
function Gn(t) {
|
|
63
|
+
return gn(t).toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
return t.length >= 20 ? !0 :
|
|
65
|
+
function ea(t) {
|
|
66
|
+
return t.length >= 20 ? !0 : fn.some((e) => (e.lastIndex = 0, e.test(t)));
|
|
67
67
|
}
|
|
68
|
-
function
|
|
69
|
-
const n =
|
|
68
|
+
function ta(t, e) {
|
|
69
|
+
const n = Gn(t);
|
|
70
70
|
if (!n) return !1;
|
|
71
|
-
if (
|
|
72
|
-
for (const
|
|
73
|
-
return
|
|
71
|
+
if (Wn.has(n)) return !0;
|
|
72
|
+
for (const a of Yn) if (n.includes(a)) return !0;
|
|
73
|
+
return Xn.has(n) ? ea(gn(e)) : !1;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
75
|
+
function wt(t) {
|
|
76
76
|
return t.split("&").map((e) => {
|
|
77
77
|
const n = e.indexOf("=");
|
|
78
78
|
if (n === -1) return e;
|
|
79
|
-
const
|
|
80
|
-
return i &&
|
|
79
|
+
const a = e.slice(0, n), i = e.slice(n + 1);
|
|
80
|
+
return i && ta(a, i) ? `${a}=${it}` : e;
|
|
81
81
|
}).join("&");
|
|
82
82
|
}
|
|
83
|
-
function
|
|
83
|
+
function mn(t) {
|
|
84
84
|
let e = t;
|
|
85
|
-
for (const n of
|
|
86
|
-
n.lastIndex = 0, e = e.replace(n,
|
|
85
|
+
for (const n of fn)
|
|
86
|
+
n.lastIndex = 0, e = e.replace(n, it);
|
|
87
87
|
return e;
|
|
88
88
|
}
|
|
89
|
-
function
|
|
89
|
+
function bn(t) {
|
|
90
90
|
if (t == null) return t;
|
|
91
91
|
let e = String(t);
|
|
92
92
|
if (!e) return e;
|
|
93
|
-
e = e.replace(
|
|
93
|
+
e = e.replace(Jn, `$1${it}@`);
|
|
94
94
|
const n = e.indexOf("#");
|
|
95
|
-
let
|
|
96
|
-
const r =
|
|
97
|
-
if (r !== -1 && (
|
|
95
|
+
let a = n === -1 ? e : e.slice(0, n), i = n === -1 ? "" : e.slice(n);
|
|
96
|
+
const r = a.indexOf("?");
|
|
97
|
+
if (r !== -1 && (a = a.slice(0, r + 1) + wt(a.slice(r + 1))), i.length > 1) {
|
|
98
98
|
const s = i.slice(1), l = s.indexOf("?");
|
|
99
|
-
l !== -1 ? i = `#${s.slice(0, l + 1)}${
|
|
99
|
+
l !== -1 ? i = `#${s.slice(0, l + 1)}${wt(s.slice(l + 1))}` : s.includes("=") && (i = `#${wt(s)}`);
|
|
100
100
|
}
|
|
101
|
-
return
|
|
101
|
+
return mn(a + i);
|
|
102
102
|
}
|
|
103
|
-
function
|
|
103
|
+
function na(t) {
|
|
104
104
|
if (t == null) return t;
|
|
105
105
|
let e = String(t);
|
|
106
|
-
return e && (e = e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g, (n) =>
|
|
106
|
+
return e && (e = e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g, (n) => bn(n)), e = e.replace(Zn, `Bearer ${it}`), mn(e));
|
|
107
107
|
}
|
|
108
|
-
function
|
|
108
|
+
function We(t) {
|
|
109
109
|
const e = [];
|
|
110
110
|
return {
|
|
111
111
|
push(n) {
|
|
@@ -120,41 +120,41 @@ function Fe(t) {
|
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
|
-
const
|
|
124
|
-
function
|
|
123
|
+
const Zt = ["log", "info", "warn", "error", "debug"];
|
|
124
|
+
function aa(t, { levels: e = ["warn", "error", "log", "info"] } = {}) {
|
|
125
125
|
const n = {};
|
|
126
|
-
for (const
|
|
127
|
-
n[
|
|
126
|
+
for (const a of Zt)
|
|
127
|
+
n[a] = console[a], e.includes(a) && (console[a] = (...i) => {
|
|
128
128
|
try {
|
|
129
129
|
t.push({
|
|
130
|
-
level:
|
|
131
|
-
text: i.map(
|
|
130
|
+
level: a,
|
|
131
|
+
text: i.map(wn).join(" ").slice(0, 2e3),
|
|
132
132
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
133
133
|
});
|
|
134
134
|
} catch {
|
|
135
135
|
}
|
|
136
|
-
n[
|
|
136
|
+
n[a].apply(console, i);
|
|
137
137
|
});
|
|
138
138
|
return () => {
|
|
139
|
-
for (const
|
|
139
|
+
for (const a of Zt) console[a] = n[a];
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
|
-
function
|
|
143
|
-
const n = window.fetch,
|
|
142
|
+
function oa(t, { slowMs: e = 2e3 } = {}) {
|
|
143
|
+
const n = window.fetch, a = XMLHttpRequest.prototype.open, i = XMLHttpRequest.prototype.send;
|
|
144
144
|
return n && (window.fetch = async function(...s) {
|
|
145
|
-
var y,
|
|
146
|
-
const l = performance.now(),
|
|
145
|
+
var y, h, b;
|
|
146
|
+
const l = performance.now(), p = typeof s[0] == "string" ? s[0] : (y = s[0]) == null ? void 0 : y.url, f = ((h = s[1]) == null ? void 0 : h.method) || (typeof s[0] == "object" ? (b = s[0]) == null ? void 0 : b.method : "GET") || "GET";
|
|
147
147
|
try {
|
|
148
|
-
const
|
|
149
|
-
return
|
|
150
|
-
} catch (
|
|
151
|
-
throw
|
|
148
|
+
const g = await n.apply(this, s);
|
|
149
|
+
return vt(t, { url: p, method: f, status: g.status, ms: Math.round(performance.now() - l), slowMs: e }), g;
|
|
150
|
+
} catch (g) {
|
|
151
|
+
throw vt(t, { url: p, method: f, status: 0, error: String((g == null ? void 0 : g.message) || g), ms: Math.round(performance.now() - l), slowMs: e }), g;
|
|
152
152
|
}
|
|
153
|
-
}), XMLHttpRequest.prototype.open = function(s, l, ...
|
|
154
|
-
return this.__bc = { method: s, url: l, started: 0 },
|
|
153
|
+
}), XMLHttpRequest.prototype.open = function(s, l, ...p) {
|
|
154
|
+
return this.__bc = { method: s, url: l, started: 0 }, a.call(this, s, l, ...p);
|
|
155
155
|
}, XMLHttpRequest.prototype.send = function(...s) {
|
|
156
156
|
return this.__bc && (this.__bc.started = performance.now(), this.addEventListener("loadend", () => {
|
|
157
|
-
|
|
157
|
+
vt(t, {
|
|
158
158
|
url: this.__bc.url,
|
|
159
159
|
method: this.__bc.method,
|
|
160
160
|
status: this.status,
|
|
@@ -163,10 +163,10 @@ function to(t, { slowMs: e = 2e3 } = {}) {
|
|
|
163
163
|
});
|
|
164
164
|
})), i.apply(this, s);
|
|
165
165
|
}, () => {
|
|
166
|
-
n && (window.fetch = n), XMLHttpRequest.prototype.open =
|
|
166
|
+
n && (window.fetch = n), XMLHttpRequest.prototype.open = a, XMLHttpRequest.prototype.send = i;
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
|
-
function
|
|
169
|
+
function vt(t, { url: e, method: n, status: a, ms: i, error: r, slowMs: s }) {
|
|
170
170
|
try {
|
|
171
171
|
t.push({
|
|
172
172
|
// Scrubbed before it is buffered, not before it is sent: a credential
|
|
@@ -175,31 +175,31 @@ function wt(t, { url: e, method: n, status: o, ms: i, error: r, slowMs: s }) {
|
|
|
175
175
|
// then truncate — truncating first would split a token into something
|
|
176
176
|
// no pattern recognises, and the fragment would still be a fragment of
|
|
177
177
|
// a live credential.
|
|
178
|
-
url:
|
|
178
|
+
url: bn(String(e)).slice(0, 500),
|
|
179
179
|
method: n,
|
|
180
|
-
status:
|
|
180
|
+
status: a,
|
|
181
181
|
ms: i,
|
|
182
|
-
error: r === void 0 ? void 0 :
|
|
182
|
+
error: r === void 0 ? void 0 : na(r),
|
|
183
183
|
// Flagged so triage can spot the interesting rows without reading everything.
|
|
184
|
-
failed:
|
|
184
|
+
failed: a === 0 || a >= 400,
|
|
185
185
|
slow: i >= s,
|
|
186
186
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
187
187
|
});
|
|
188
188
|
} catch {
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
function
|
|
192
|
-
const e = (
|
|
193
|
-
const i = String(
|
|
191
|
+
function ra(t) {
|
|
192
|
+
const e = (a) => {
|
|
193
|
+
const i = String(a.message || "Error"), r = a.filename ? ` (${a.filename}:${a.lineno}:${a.colno})` : "";
|
|
194
194
|
t.push({
|
|
195
195
|
level: "error",
|
|
196
196
|
text: (/^uncaught/i.test(i) ? i : `Uncaught ${i}`) + r,
|
|
197
197
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
198
198
|
});
|
|
199
|
-
}, n = (
|
|
199
|
+
}, n = (a) => {
|
|
200
200
|
t.push({
|
|
201
201
|
level: "error",
|
|
202
|
-
text: `Unhandled rejection: ${
|
|
202
|
+
text: `Unhandled rejection: ${wn(a.reason)}`,
|
|
203
203
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
204
204
|
});
|
|
205
205
|
};
|
|
@@ -207,8 +207,8 @@ function no(t) {
|
|
|
207
207
|
window.removeEventListener("error", e), window.removeEventListener("unhandledrejection", n);
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
|
-
async function
|
|
211
|
-
const t =
|
|
210
|
+
async function Jt() {
|
|
211
|
+
const t = yn();
|
|
212
212
|
try {
|
|
213
213
|
if (navigator.getBattery) {
|
|
214
214
|
const e = await navigator.getBattery();
|
|
@@ -218,8 +218,8 @@ async function Yt() {
|
|
|
218
218
|
}
|
|
219
219
|
return t;
|
|
220
220
|
}
|
|
221
|
-
function
|
|
222
|
-
var e, n,
|
|
221
|
+
function yn() {
|
|
222
|
+
var e, n, a, i, r, s, l, p, f;
|
|
223
223
|
const t = window.navigator || {};
|
|
224
224
|
return {
|
|
225
225
|
userAgent: t.userAgent,
|
|
@@ -233,7 +233,7 @@ function gn() {
|
|
|
233
233
|
screen: {
|
|
234
234
|
width: (e = window.screen) == null ? void 0 : e.width,
|
|
235
235
|
height: (n = window.screen) == null ? void 0 : n.height,
|
|
236
|
-
availWidth: (
|
|
236
|
+
availWidth: (a = window.screen) == null ? void 0 : a.availWidth,
|
|
237
237
|
availHeight: (i = window.screen) == null ? void 0 : i.availHeight,
|
|
238
238
|
colorDepth: (r = window.screen) == null ? void 0 : r.colorDepth,
|
|
239
239
|
orientation: ((l = (s = window.screen) == null ? void 0 : s.orientation) == null ? void 0 : l.type) || null
|
|
@@ -256,11 +256,11 @@ function gn() {
|
|
|
256
256
|
rtt: t.connection.rtt,
|
|
257
257
|
saveData: t.connection.saveData
|
|
258
258
|
} : null,
|
|
259
|
-
prefersColorScheme: (
|
|
260
|
-
prefersReducedMotion: ((
|
|
259
|
+
prefersColorScheme: (p = window.matchMedia) != null && p.call(window, "(prefers-color-scheme: dark)").matches ? "dark" : "light",
|
|
260
|
+
prefersReducedMotion: ((f = window.matchMedia) == null ? void 0 : f.call(window, "(prefers-reduced-motion: reduce)").matches) || !1
|
|
261
261
|
};
|
|
262
262
|
}
|
|
263
|
-
function
|
|
263
|
+
function wn(t) {
|
|
264
264
|
if (typeof t == "string") return t;
|
|
265
265
|
if (t instanceof Error) return `${t.name}: ${t.message}`;
|
|
266
266
|
try {
|
|
@@ -269,7 +269,7 @@ function mn(t) {
|
|
|
269
269
|
return String(t);
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
|
-
const
|
|
272
|
+
const ia = typeof window < "u" && window.fetch ? window.fetch.bind(window) : null, sa = typeof XMLHttpRequest < "u" ? XMLHttpRequest.prototype.open : null, ca = typeof XMLHttpRequest < "u" ? XMLHttpRequest.prototype.send : null, vn = [
|
|
273
273
|
"image/png",
|
|
274
274
|
"image/jpeg",
|
|
275
275
|
"image/webp",
|
|
@@ -290,27 +290,27 @@ const oo = typeof window < "u" && window.fetch ? window.fetch.bind(window) : nul
|
|
|
290
290
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
291
291
|
"application/vnd.ms-excel",
|
|
292
292
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
293
|
-
],
|
|
293
|
+
], tt = [
|
|
294
294
|
"image/png",
|
|
295
295
|
"image/jpeg",
|
|
296
296
|
"image/webp",
|
|
297
297
|
"video/webm",
|
|
298
298
|
"video/mp4"
|
|
299
|
-
],
|
|
299
|
+
], la = () => {
|
|
300
300
|
var t;
|
|
301
301
|
return !!((t = navigator == null ? void 0 : navigator.mediaDevices) != null && t.getUserMedia && typeof MediaRecorder < "u");
|
|
302
|
-
},
|
|
302
|
+
}, da = () => {
|
|
303
303
|
var t;
|
|
304
304
|
return !!((t = navigator == null ? void 0 : navigator.mediaDevices) != null && t.getDisplayMedia && typeof MediaRecorder < "u");
|
|
305
|
-
},
|
|
305
|
+
}, ua = () => {
|
|
306
306
|
var t;
|
|
307
307
|
return !!((t = navigator == null ? void 0 : navigator.mediaDevices) != null && t.getDisplayMedia);
|
|
308
308
|
};
|
|
309
|
-
function
|
|
309
|
+
function nt(t, e = vn) {
|
|
310
310
|
const n = String(t || "").split(";")[0].trim().toLowerCase();
|
|
311
311
|
return e.includes(n) ? n : null;
|
|
312
312
|
}
|
|
313
|
-
async function
|
|
313
|
+
async function pa() {
|
|
314
314
|
const t = await navigator.mediaDevices.getDisplayMedia({
|
|
315
315
|
video: { frameRate: 1 },
|
|
316
316
|
audio: !1
|
|
@@ -318,8 +318,8 @@ async function lo() {
|
|
|
318
318
|
try {
|
|
319
319
|
const e = t.getVideoTracks()[0], n = document.createElement("video");
|
|
320
320
|
n.srcObject = t, n.muted = !0, n.playsInline = !0, await n.play(), await new Promise((l) => requestAnimationFrame(() => requestAnimationFrame(l)));
|
|
321
|
-
const { width:
|
|
322
|
-
r.width =
|
|
321
|
+
const { width: a, height: i } = e.getSettings(), r = document.createElement("canvas");
|
|
322
|
+
r.width = a || n.videoWidth, r.height = i || n.videoHeight, r.getContext("2d").drawImage(n, 0, 0, r.width, r.height);
|
|
323
323
|
const s = await new Promise((l) => r.toBlob(l, "image/png"));
|
|
324
324
|
if (!s) throw new Error("The browser returned an empty screenshot.");
|
|
325
325
|
return { blob: s, mime: "image/png", kind: "SCREENSHOT" };
|
|
@@ -327,25 +327,25 @@ async function lo() {
|
|
|
327
327
|
t.getTracks().forEach((e) => e.stop());
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
|
-
async function
|
|
331
|
-
const
|
|
330
|
+
async function ha({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
|
|
331
|
+
const a = await navigator.mediaDevices.getDisplayMedia({
|
|
332
332
|
video: { frameRate: 15 },
|
|
333
333
|
audio: !1
|
|
334
|
-
}), i = ["video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"].find((
|
|
335
|
-
r.ondataavailable = (
|
|
336
|
-
|
|
334
|
+
}), i = ["video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"].find((g) => MediaRecorder.isTypeSupported(g)) || "video/webm", r = new MediaRecorder(a, { mimeType: i, videoBitsPerSecond: 25e5 }), s = [];
|
|
335
|
+
r.ondataavailable = (g) => {
|
|
336
|
+
g.data.size && s.push(g.data);
|
|
337
337
|
}, r.start(1e3);
|
|
338
|
-
const l = Date.now(),
|
|
339
|
-
clearInterval(
|
|
340
|
-
}, y = new Promise((
|
|
338
|
+
const l = Date.now(), p = setInterval(() => e == null ? void 0 : e(Math.floor((Date.now() - l) / 1e3)), 500), f = () => {
|
|
339
|
+
clearInterval(p), clearTimeout(b), a.getTracks().forEach((g) => g.stop());
|
|
340
|
+
}, y = new Promise((g) => {
|
|
341
341
|
r.onstop = () => {
|
|
342
|
-
|
|
342
|
+
f(), g(new Blob(s, { type: i }));
|
|
343
343
|
};
|
|
344
|
-
}),
|
|
344
|
+
}), h = () => {
|
|
345
345
|
r.state !== "inactive" && r.stop(), n == null || n();
|
|
346
346
|
};
|
|
347
|
-
|
|
348
|
-
const b = setTimeout(
|
|
347
|
+
a.getVideoTracks()[0].addEventListener("ended", h);
|
|
348
|
+
const b = setTimeout(h, t);
|
|
349
349
|
return {
|
|
350
350
|
mime: i,
|
|
351
351
|
maxMs: t,
|
|
@@ -353,20 +353,20 @@ async function uo({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
|
|
|
353
353
|
return clearTimeout(b), r.state !== "inactive" && r.stop(), { blob: await y, mime: i, kind: "VIDEO" };
|
|
354
354
|
},
|
|
355
355
|
cancel() {
|
|
356
|
-
|
|
356
|
+
f(), r.state !== "inactive" && r.stop();
|
|
357
357
|
}
|
|
358
358
|
};
|
|
359
359
|
}
|
|
360
|
-
async function
|
|
361
|
-
const
|
|
362
|
-
r.ondataavailable = (
|
|
363
|
-
|
|
360
|
+
async function fa({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
|
|
361
|
+
const a = await navigator.mediaDevices.getUserMedia({ audio: !0 }), i = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4", "audio/ogg"].find((g) => MediaRecorder.isTypeSupported(g)) || "", r = new MediaRecorder(a, i ? { mimeType: i } : void 0), s = [];
|
|
362
|
+
r.ondataavailable = (g) => {
|
|
363
|
+
g.data.size && s.push(g.data);
|
|
364
364
|
}, r.start(1e3);
|
|
365
|
-
const l = Date.now(),
|
|
366
|
-
clearInterval(
|
|
367
|
-
}, y = new Promise((
|
|
365
|
+
const l = Date.now(), p = setInterval(() => e == null ? void 0 : e(Math.floor((Date.now() - l) / 1e3)), 500), f = () => {
|
|
366
|
+
clearInterval(p), clearTimeout(b), a.getTracks().forEach((g) => g.stop());
|
|
367
|
+
}, y = new Promise((g) => {
|
|
368
368
|
r.onstop = () => {
|
|
369
|
-
|
|
369
|
+
f(), g(new Blob(s, { type: r.mimeType || i }));
|
|
370
370
|
};
|
|
371
371
|
}), b = setTimeout(() => {
|
|
372
372
|
r.state !== "inactive" && r.stop(), n == null || n();
|
|
@@ -376,110 +376,110 @@ async function po({ maxMs: t = 12e4, onTick: e, onAutoStop: n } = {}) {
|
|
|
376
376
|
maxMs: t,
|
|
377
377
|
async stop() {
|
|
378
378
|
clearTimeout(b), r.state !== "inactive" && r.stop();
|
|
379
|
-
const
|
|
380
|
-
return { blob:
|
|
379
|
+
const g = await y;
|
|
380
|
+
return { blob: g, mime: g.type || r.mimeType || i, kind: "AUDIO" };
|
|
381
381
|
},
|
|
382
382
|
cancel() {
|
|
383
|
-
|
|
383
|
+
f(), r.state !== "inactive" && r.stop();
|
|
384
384
|
}
|
|
385
385
|
};
|
|
386
386
|
}
|
|
387
|
-
async function
|
|
388
|
-
const r =
|
|
387
|
+
async function ga({ apiBase: t, apiKey: e, blob: n, mime: a, onProgress: i }) {
|
|
388
|
+
const r = nt(a || n.type);
|
|
389
389
|
if (!r)
|
|
390
|
-
throw new Error(`[BugCatch] ${
|
|
391
|
-
const s = await
|
|
390
|
+
throw new Error(`[BugCatch] ${a || n.type || "that file"} can't be attached.`);
|
|
391
|
+
const s = await ia(`${t}/ingest/presign`, {
|
|
392
392
|
method: "POST",
|
|
393
393
|
headers: { "Content-Type": "application/json", "X-BugCatch-Key": e },
|
|
394
394
|
body: JSON.stringify({ mime: r })
|
|
395
395
|
});
|
|
396
396
|
if (!s.ok) throw new Error(`[BugCatch] could not start the upload (HTTP ${s.status}).`);
|
|
397
|
-
const { key: l, uploadUrl:
|
|
398
|
-
return await
|
|
397
|
+
const { key: l, uploadUrl: p } = await s.json();
|
|
398
|
+
return await ma(p, n, r, i), { storageKey: l, mime: r };
|
|
399
399
|
}
|
|
400
|
-
function
|
|
400
|
+
function ma(t, e, n, a) {
|
|
401
401
|
return new Promise((i, r) => {
|
|
402
402
|
const s = new XMLHttpRequest();
|
|
403
|
-
|
|
404
|
-
l.lengthComputable && (
|
|
403
|
+
sa.call(s, "PUT", t, !0), s.setRequestHeader("Content-Type", n), s.upload.onprogress = (l) => {
|
|
404
|
+
l.lengthComputable && (a == null || a(l.loaded / l.total));
|
|
405
405
|
}, s.onload = () => {
|
|
406
406
|
s.status >= 200 && s.status < 300 ? i() : r(new Error(`[BugCatch] upload failed (HTTP ${s.status}).`));
|
|
407
407
|
}, s.onerror = () => r(new Error(
|
|
408
408
|
"[BugCatch] the browser blocked the upload to storage. If this is a new environment, the media bucket is probably missing its CORS policy."
|
|
409
|
-
)), s.onabort = () => r(new Error("[BugCatch] upload cancelled.")),
|
|
409
|
+
)), s.onabort = () => r(new Error("[BugCatch] upload cancelled.")), ca.call(s, e);
|
|
410
410
|
});
|
|
411
411
|
}
|
|
412
412
|
function je(t) {
|
|
413
413
|
return t < 1024 ? `${t} B` : t < 1024 * 1024 ? `${(t / 1024).toFixed(0)} KB` : `${(t / 1024 / 1024).toFixed(1)} MB`;
|
|
414
414
|
}
|
|
415
|
-
function
|
|
415
|
+
function Ye(t) {
|
|
416
416
|
const e = Math.floor(t / 60), n = t % 60;
|
|
417
417
|
return `${e}:${String(n).padStart(2, "0")}`;
|
|
418
418
|
}
|
|
419
|
-
const
|
|
420
|
-
let
|
|
421
|
-
function
|
|
422
|
-
return
|
|
419
|
+
const ba = 7 * 24 * 60 * 60 * 1e3;
|
|
420
|
+
let Xe;
|
|
421
|
+
function ya() {
|
|
422
|
+
return Xe || (Xe = new Promise((t, e) => {
|
|
423
423
|
const n = indexedDB.open("bugcatch-drafts", 1);
|
|
424
424
|
n.onupgradeneeded = () => n.result.createObjectStore("drafts"), n.onsuccess = () => t(n.result), n.onerror = () => e(n.error), n.onblocked = () => e(new Error("Draft storage is blocked."));
|
|
425
425
|
}).catch((t) => {
|
|
426
|
-
throw
|
|
427
|
-
})),
|
|
426
|
+
throw Xe = null, t;
|
|
427
|
+
})), Xe;
|
|
428
428
|
}
|
|
429
|
-
function
|
|
430
|
-
var n,
|
|
431
|
-
return JSON.stringify([t.apiBase, t.projectId, e || ((n = t.user) == null ? void 0 : n.email) || ((
|
|
429
|
+
function wa(t, e) {
|
|
430
|
+
var n, a;
|
|
431
|
+
return JSON.stringify([t.apiBase, t.projectId, e || ((n = t.user) == null ? void 0 : n.email) || ((a = t.user) == null ? void 0 : a.id) || "anonymous"]);
|
|
432
432
|
}
|
|
433
|
-
async function
|
|
434
|
-
const n = await
|
|
435
|
-
return new Promise((
|
|
433
|
+
async function at(t, e) {
|
|
434
|
+
const n = await ya();
|
|
435
|
+
return new Promise((a, i) => {
|
|
436
436
|
const r = n.transaction("drafts", e === void 0 ? "readonly" : "readwrite"), s = r.objectStore("drafts"), l = e === void 0 ? s.get(t) : e === null ? s.delete(t) : s.put({ ...e, savedAt: Date.now() }, t);
|
|
437
|
-
r.oncomplete = () =>
|
|
437
|
+
r.oncomplete = () => a(l.result), r.onerror = () => i(r.error), r.onabort = () => i(r.error || new Error("Draft was not saved."));
|
|
438
438
|
});
|
|
439
439
|
}
|
|
440
|
-
async function
|
|
441
|
-
const e = await
|
|
442
|
-
return e && Date.now() - e.savedAt >
|
|
440
|
+
async function va(t) {
|
|
441
|
+
const e = await at(t);
|
|
442
|
+
return e && Date.now() - e.savedAt > ba ? (await at(t, null), null) : e || null;
|
|
443
443
|
}
|
|
444
|
-
const
|
|
444
|
+
const xa = "bugcatch.session.", Tt = (t) => `${xa}${t}`, It = /* @__PURE__ */ new Map();
|
|
445
445
|
function he(t) {
|
|
446
446
|
var e;
|
|
447
447
|
if (!t) return null;
|
|
448
448
|
try {
|
|
449
|
-
const n = (e = window.localStorage) == null ? void 0 : e.getItem(
|
|
449
|
+
const n = (e = window.localStorage) == null ? void 0 : e.getItem(Tt(t));
|
|
450
450
|
if (n) {
|
|
451
|
-
const
|
|
452
|
-
if (
|
|
451
|
+
const a = JSON.parse(n);
|
|
452
|
+
if (a != null && a.token) return a;
|
|
453
453
|
}
|
|
454
454
|
} catch {
|
|
455
455
|
}
|
|
456
|
-
return
|
|
456
|
+
return It.get(t) || null;
|
|
457
457
|
}
|
|
458
|
-
function
|
|
459
|
-
var
|
|
458
|
+
function ka(t, e) {
|
|
459
|
+
var a;
|
|
460
460
|
if (!t || !(e != null && e.token)) return;
|
|
461
461
|
const n = {
|
|
462
462
|
token: e.token,
|
|
463
463
|
email: e.email || null,
|
|
464
464
|
name: e.name || null
|
|
465
465
|
};
|
|
466
|
-
|
|
466
|
+
It.set(t, n);
|
|
467
467
|
try {
|
|
468
|
-
(
|
|
468
|
+
(a = window.localStorage) == null || a.setItem(Tt(t), JSON.stringify(n));
|
|
469
469
|
} catch {
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
|
-
function
|
|
472
|
+
function St(t) {
|
|
473
473
|
var e;
|
|
474
474
|
if (t) {
|
|
475
|
-
|
|
475
|
+
It.delete(t);
|
|
476
476
|
try {
|
|
477
|
-
(e = window.localStorage) == null || e.removeItem(
|
|
477
|
+
(e = window.localStorage) == null || e.removeItem(Tt(t));
|
|
478
478
|
} catch {
|
|
479
479
|
}
|
|
480
480
|
}
|
|
481
481
|
}
|
|
482
|
-
function
|
|
482
|
+
function st({ apiKey: t, token: e }) {
|
|
483
483
|
return {
|
|
484
484
|
"Content-Type": "application/json",
|
|
485
485
|
"X-BugCatch-Key": t,
|
|
@@ -489,7 +489,7 @@ function it({ apiKey: t, token: e }) {
|
|
|
489
489
|
...e ? { "X-BugCatch-Session": e } : {}
|
|
490
490
|
};
|
|
491
491
|
}
|
|
492
|
-
async function
|
|
492
|
+
async function xn(t) {
|
|
493
493
|
try {
|
|
494
494
|
const e = await t.json(), n = Array.isArray(e.message) ? e.message.join(", ") : e.message;
|
|
495
495
|
if (n) return n;
|
|
@@ -497,12 +497,12 @@ async function yn(t) {
|
|
|
497
497
|
}
|
|
498
498
|
return `Request failed (HTTP ${t.status})`;
|
|
499
499
|
}
|
|
500
|
-
async function
|
|
500
|
+
async function Sa({ apiBase: t, apiKey: e, projectId: n, token: a }) {
|
|
501
501
|
const i = { mode: "off", signedIn: null, signedOutReason: null };
|
|
502
502
|
try {
|
|
503
503
|
const r = await fetch(
|
|
504
504
|
`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,
|
|
505
|
-
{ headers:
|
|
505
|
+
{ headers: st({ apiKey: e, token: a }) }
|
|
506
506
|
);
|
|
507
507
|
if (!r.ok) return i;
|
|
508
508
|
const s = await r.json();
|
|
@@ -515,104 +515,104 @@ async function xo({ apiBase: t, apiKey: e, projectId: n, token: o }) {
|
|
|
515
515
|
return i;
|
|
516
516
|
}
|
|
517
517
|
}
|
|
518
|
-
async function
|
|
518
|
+
async function Ca({ apiBase: t, apiKey: e, projectId: n, email: a, name: i }) {
|
|
519
519
|
const r = await fetch(`${t}/ingest/login/start`, {
|
|
520
520
|
method: "POST",
|
|
521
|
-
headers:
|
|
522
|
-
body: JSON.stringify({ projectId: n, email:
|
|
521
|
+
headers: st({ apiKey: e }),
|
|
522
|
+
body: JSON.stringify({ projectId: n, email: a, ...i ? { name: i } : {} })
|
|
523
523
|
});
|
|
524
|
-
if (!r.ok) throw new Error(await
|
|
524
|
+
if (!r.ok) throw new Error(await xn(r));
|
|
525
525
|
return r.json();
|
|
526
526
|
}
|
|
527
|
-
async function
|
|
527
|
+
async function $a({ apiBase: t, apiKey: e, projectId: n, email: a, code: i }) {
|
|
528
528
|
const r = await fetch(`${t}/ingest/login`, {
|
|
529
529
|
method: "POST",
|
|
530
|
-
headers:
|
|
531
|
-
body: JSON.stringify({ projectId: n, email:
|
|
530
|
+
headers: st({ apiKey: e }),
|
|
531
|
+
body: JSON.stringify({ projectId: n, email: a, code: i })
|
|
532
532
|
});
|
|
533
|
-
if (!r.ok) throw new Error(await
|
|
533
|
+
if (!r.ok) throw new Error(await xn(r));
|
|
534
534
|
const s = await r.json(), l = { token: s.sessionToken, email: s.email, name: s.name };
|
|
535
|
-
return
|
|
535
|
+
return ka(n, l), l;
|
|
536
536
|
}
|
|
537
|
-
async function
|
|
538
|
-
if (
|
|
537
|
+
async function Ea({ apiBase: t, apiKey: e, projectId: n, token: a }) {
|
|
538
|
+
if (St(n), !a) return { signedOut: !0 };
|
|
539
539
|
try {
|
|
540
540
|
await fetch(`${t}/ingest/logout`, {
|
|
541
541
|
method: "POST",
|
|
542
|
-
headers:
|
|
542
|
+
headers: st({ apiKey: e, token: a }),
|
|
543
543
|
body: JSON.stringify({ projectId: n })
|
|
544
544
|
});
|
|
545
545
|
} catch {
|
|
546
546
|
}
|
|
547
547
|
return { signedOut: !0 };
|
|
548
548
|
}
|
|
549
|
-
const
|
|
549
|
+
const Mt = "bugcatch.watch", Gt = [2e3, 5e3, 15e3, 3e4, 6e4], Ta = 5e3;
|
|
550
550
|
function se() {
|
|
551
551
|
var t;
|
|
552
552
|
try {
|
|
553
|
-
return ((t = window.localStorage) == null ? void 0 : t.getItem(
|
|
553
|
+
return ((t = window.localStorage) == null ? void 0 : t.getItem(Mt)) || null;
|
|
554
554
|
} catch {
|
|
555
555
|
return null;
|
|
556
556
|
}
|
|
557
557
|
}
|
|
558
|
-
function
|
|
558
|
+
function Ct(t) {
|
|
559
559
|
var e;
|
|
560
560
|
if (t)
|
|
561
561
|
try {
|
|
562
|
-
(e = window.localStorage) == null || e.setItem(
|
|
562
|
+
(e = window.localStorage) == null || e.setItem(Mt, t);
|
|
563
563
|
} catch {
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
|
-
function
|
|
566
|
+
function $e() {
|
|
567
567
|
var t;
|
|
568
568
|
try {
|
|
569
|
-
(t = window.localStorage) == null || t.removeItem(
|
|
569
|
+
(t = window.localStorage) == null || t.removeItem(Mt);
|
|
570
570
|
} catch {
|
|
571
571
|
}
|
|
572
|
-
|
|
572
|
+
kn();
|
|
573
573
|
}
|
|
574
574
|
const ot = "bugcatch.unread";
|
|
575
|
-
function
|
|
575
|
+
function Ia(t) {
|
|
576
576
|
return [(t == null ? void 0 : t.bugId) || "report", (t == null ? void 0 : t.kind) || "status", (t == null ? void 0 : t.at) || ""].join("|");
|
|
577
577
|
}
|
|
578
578
|
function Ne() {
|
|
579
579
|
var t;
|
|
580
580
|
try {
|
|
581
581
|
const e = (t = window.localStorage) == null ? void 0 : t.getItem(ot), n = e ? JSON.parse(e) : [];
|
|
582
|
-
return Array.isArray(n) ? n.filter((
|
|
582
|
+
return Array.isArray(n) ? n.filter((a) => a && typeof a.id == "string") : [];
|
|
583
583
|
} catch {
|
|
584
584
|
return [];
|
|
585
585
|
}
|
|
586
586
|
}
|
|
587
|
-
function
|
|
587
|
+
function ct(t) {
|
|
588
588
|
var e, n;
|
|
589
589
|
try {
|
|
590
590
|
t.length ? (e = window.localStorage) == null || e.setItem(ot, JSON.stringify(t)) : (n = window.localStorage) == null || n.removeItem(ot);
|
|
591
591
|
} catch {
|
|
592
592
|
}
|
|
593
593
|
}
|
|
594
|
-
function
|
|
595
|
-
const e = { ...t, id:
|
|
596
|
-
return n.push(e),
|
|
594
|
+
function Ma(t) {
|
|
595
|
+
const e = { ...t, id: Ia(t) }, n = Ne().filter((a) => a.id !== e.id);
|
|
596
|
+
return n.push(e), ct(n.slice(-20)), e;
|
|
597
597
|
}
|
|
598
|
-
function
|
|
598
|
+
function La(t) {
|
|
599
599
|
const e = Ne().filter((n) => n.id !== t);
|
|
600
|
-
return
|
|
600
|
+
return ct(e), e;
|
|
601
601
|
}
|
|
602
|
-
function
|
|
602
|
+
function Ba(t) {
|
|
603
603
|
const e = Ne().filter((n) => n.bugId !== t);
|
|
604
|
-
return
|
|
604
|
+
return ct(e), e;
|
|
605
605
|
}
|
|
606
|
-
function
|
|
607
|
-
return
|
|
606
|
+
function kn() {
|
|
607
|
+
return ct([]), [];
|
|
608
608
|
}
|
|
609
|
-
function
|
|
610
|
-
let n = t,
|
|
609
|
+
function Aa(t, e) {
|
|
610
|
+
let n = t, a = n.indexOf(`
|
|
611
611
|
|
|
612
612
|
`);
|
|
613
|
-
for (;
|
|
614
|
-
const i = n.slice(0,
|
|
615
|
-
n = n.slice(
|
|
613
|
+
for (; a !== -1; ) {
|
|
614
|
+
const i = n.slice(0, a);
|
|
615
|
+
n = n.slice(a + 2);
|
|
616
616
|
const r = i.split(`
|
|
617
617
|
`).filter((s) => s.startsWith("data:")).map((s) => s.slice(5).trim()).join(`
|
|
618
618
|
`);
|
|
@@ -621,36 +621,36 @@ function Lo(t, e) {
|
|
|
621
621
|
e(JSON.parse(r));
|
|
622
622
|
} catch {
|
|
623
623
|
}
|
|
624
|
-
|
|
624
|
+
a = n.indexOf(`
|
|
625
625
|
|
|
626
626
|
`);
|
|
627
627
|
}
|
|
628
628
|
return n;
|
|
629
629
|
}
|
|
630
|
-
async function
|
|
630
|
+
async function Ra({ apiBase: t }) {
|
|
631
631
|
const e = se();
|
|
632
632
|
if (!e) return { reporter: null, reports: [] };
|
|
633
633
|
const n = await fetch(`${t}/ingest/watch/reports`, {
|
|
634
634
|
headers: { Authorization: `Bearer ${e}` }
|
|
635
635
|
});
|
|
636
636
|
if (n.status === 401)
|
|
637
|
-
return
|
|
637
|
+
return $e(), { reporter: null, reports: [] };
|
|
638
638
|
if (!n.ok) throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);
|
|
639
639
|
return n.json();
|
|
640
640
|
}
|
|
641
|
-
async function
|
|
641
|
+
async function Qa({ apiBase: t, bugId: e }) {
|
|
642
642
|
const n = se();
|
|
643
643
|
if (!n) return null;
|
|
644
|
-
const
|
|
644
|
+
const a = await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}`, {
|
|
645
645
|
headers: { Authorization: `Bearer ${n}` }
|
|
646
646
|
});
|
|
647
|
-
if (
|
|
648
|
-
return
|
|
649
|
-
if (
|
|
650
|
-
if (!
|
|
651
|
-
return
|
|
647
|
+
if (a.status === 401)
|
|
648
|
+
return $e(), null;
|
|
649
|
+
if (a.status === 404) return null;
|
|
650
|
+
if (!a.ok) throw new Error(`[BugCatch] could not load that report (HTTP ${a.status})`);
|
|
651
|
+
return a.json();
|
|
652
652
|
}
|
|
653
|
-
async function
|
|
653
|
+
async function Sn({ apiBase: t, bugId: e, body: n, attachments: a }) {
|
|
654
654
|
const i = se();
|
|
655
655
|
if (!i) throw new Error("[BugCatch] nothing filed from this browser yet.");
|
|
656
656
|
const r = await fetch(
|
|
@@ -660,12 +660,12 @@ async function vn({ apiBase: t, bugId: e, body: n, attachments: o }) {
|
|
|
660
660
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${i}` },
|
|
661
661
|
body: JSON.stringify({
|
|
662
662
|
...n ? { body: n } : {},
|
|
663
|
-
...
|
|
663
|
+
...a != null && a.length ? { attachments: a } : {}
|
|
664
664
|
})
|
|
665
665
|
}
|
|
666
666
|
);
|
|
667
667
|
if (r.status === 401)
|
|
668
|
-
throw
|
|
668
|
+
throw $e(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
|
|
669
669
|
if (!r.ok) {
|
|
670
670
|
let s = "";
|
|
671
671
|
try {
|
|
@@ -677,21 +677,21 @@ async function vn({ apiBase: t, bugId: e, body: n, attachments: o }) {
|
|
|
677
677
|
}
|
|
678
678
|
return r.json();
|
|
679
679
|
}
|
|
680
|
-
async function
|
|
681
|
-
const
|
|
680
|
+
async function ja({ apiBase: t, apiKey: e, projectId: n }) {
|
|
681
|
+
const a = { agent: !1, live: !1 };
|
|
682
682
|
try {
|
|
683
683
|
const i = await fetch(
|
|
684
684
|
`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,
|
|
685
685
|
{ headers: { "X-BugCatch-Key": e } }
|
|
686
686
|
);
|
|
687
|
-
if (!i.ok) return
|
|
687
|
+
if (!i.ok) return a;
|
|
688
688
|
const r = await i.json();
|
|
689
|
-
return r != null && r.available ? r.kinds && typeof r.kinds == "object" ? { agent: !1, live: !!r.kinds.live } : { agent: !1, live: r.kind === "live" } :
|
|
689
|
+
return r != null && r.available ? r.kinds && typeof r.kinds == "object" ? { agent: !1, live: !!r.kinds.live } : { agent: !1, live: r.kind === "live" } : a;
|
|
690
690
|
} catch {
|
|
691
|
-
return
|
|
691
|
+
return a;
|
|
692
692
|
}
|
|
693
693
|
}
|
|
694
|
-
async function
|
|
694
|
+
async function za({ apiBase: t, apiKey: e, token: n, payload: a }) {
|
|
695
695
|
const i = await fetch(`${t}/ingest/calls`, {
|
|
696
696
|
method: "POST",
|
|
697
697
|
headers: {
|
|
@@ -703,7 +703,7 @@ async function Qo({ apiBase: t, apiKey: e, token: n, payload: o }) {
|
|
|
703
703
|
// is saying, an inch below the message, who they are signed in as.
|
|
704
704
|
...n ? { "X-BugCatch-Session": n } : {}
|
|
705
705
|
},
|
|
706
|
-
body: JSON.stringify(
|
|
706
|
+
body: JSON.stringify(a)
|
|
707
707
|
});
|
|
708
708
|
if (!i.ok) {
|
|
709
709
|
let r = "";
|
|
@@ -719,61 +719,61 @@ async function Qo({ apiBase: t, apiKey: e, token: n, payload: o }) {
|
|
|
719
719
|
}
|
|
720
720
|
return i.json();
|
|
721
721
|
}
|
|
722
|
-
async function
|
|
722
|
+
async function en({ apiBase: t, bugId: e }) {
|
|
723
723
|
const n = se();
|
|
724
724
|
if (!n) return !1;
|
|
725
725
|
try {
|
|
726
|
-
const
|
|
726
|
+
const a = await fetch(
|
|
727
727
|
`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,
|
|
728
728
|
{ headers: { Authorization: `Bearer ${n}` } }
|
|
729
729
|
);
|
|
730
|
-
if (!
|
|
731
|
-
const i = await
|
|
730
|
+
if (!a.ok) return !1;
|
|
731
|
+
const i = await a.json();
|
|
732
732
|
return !!(i != null && i.offered);
|
|
733
733
|
} catch {
|
|
734
734
|
return !1;
|
|
735
735
|
}
|
|
736
736
|
}
|
|
737
|
-
async function
|
|
737
|
+
async function Oa({ apiBase: t, bugId: e }) {
|
|
738
738
|
const n = se();
|
|
739
739
|
if (!n) throw new Error("[BugCatch] nothing filed from this browser yet.");
|
|
740
|
-
const
|
|
740
|
+
const a = await fetch(
|
|
741
741
|
`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,
|
|
742
742
|
{ method: "POST", headers: { Authorization: `Bearer ${n}` } }
|
|
743
743
|
);
|
|
744
|
-
if (
|
|
745
|
-
throw
|
|
746
|
-
if (!
|
|
744
|
+
if (a.status === 401)
|
|
745
|
+
throw $e(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
|
|
746
|
+
if (!a.ok) {
|
|
747
747
|
let i = "";
|
|
748
748
|
try {
|
|
749
|
-
const r = await
|
|
749
|
+
const r = await a.json();
|
|
750
750
|
i = Array.isArray(r.message) ? r.message.join(", ") : r.message || "";
|
|
751
751
|
} catch {
|
|
752
752
|
}
|
|
753
|
-
throw new Error(i || `[BugCatch] the call could not be started (HTTP ${
|
|
753
|
+
throw new Error(i || `[BugCatch] the call could not be started (HTTP ${a.status}).`);
|
|
754
754
|
}
|
|
755
|
-
return
|
|
755
|
+
return a.json();
|
|
756
756
|
}
|
|
757
|
-
async function
|
|
758
|
-
const
|
|
759
|
-
if (
|
|
757
|
+
async function Ha({ apiBase: t, bugId: e, callId: n }) {
|
|
758
|
+
const a = se();
|
|
759
|
+
if (a)
|
|
760
760
|
try {
|
|
761
761
|
await fetch(
|
|
762
762
|
`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,
|
|
763
|
-
{ method: "POST", headers: { Authorization: `Bearer ${
|
|
763
|
+
{ method: "POST", headers: { Authorization: `Bearer ${a}` } }
|
|
764
764
|
);
|
|
765
765
|
} catch {
|
|
766
766
|
}
|
|
767
767
|
}
|
|
768
|
-
async function
|
|
769
|
-
const
|
|
770
|
-
if (!
|
|
768
|
+
async function qa({ apiBase: t, bugId: e, callId: n }) {
|
|
769
|
+
const a = se();
|
|
770
|
+
if (!a) throw new Error("[BugCatch] nothing filed from this browser yet.");
|
|
771
771
|
const i = await fetch(
|
|
772
772
|
`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,
|
|
773
|
-
{ method: "POST", headers: { Authorization: `Bearer ${
|
|
773
|
+
{ method: "POST", headers: { Authorization: `Bearer ${a}` } }
|
|
774
774
|
);
|
|
775
775
|
if (i.status === 401)
|
|
776
|
-
throw
|
|
776
|
+
throw $e(), new Error("[BugCatch] this browser can no longer prove it filed that report.");
|
|
777
777
|
if (i.status === 409)
|
|
778
778
|
throw new Error("[BugCatch] that call is no longer ringing.");
|
|
779
779
|
if (!i.ok) {
|
|
@@ -787,19 +787,19 @@ async function Oo({ apiBase: t, bugId: e, callId: n }) {
|
|
|
787
787
|
}
|
|
788
788
|
return i.json();
|
|
789
789
|
}
|
|
790
|
-
async function
|
|
791
|
-
const
|
|
792
|
-
if (
|
|
790
|
+
async function tn({ apiBase: t, bugId: e, callId: n }) {
|
|
791
|
+
const a = se();
|
|
792
|
+
if (a)
|
|
793
793
|
try {
|
|
794
794
|
await fetch(
|
|
795
795
|
`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,
|
|
796
|
-
{ method: "POST", headers: { Authorization: `Bearer ${
|
|
796
|
+
{ method: "POST", headers: { Authorization: `Bearer ${a}` } }
|
|
797
797
|
);
|
|
798
798
|
} catch {
|
|
799
799
|
}
|
|
800
800
|
}
|
|
801
|
-
function
|
|
802
|
-
let n = !0,
|
|
801
|
+
function Da({ apiBase: t, onUpdate: e }) {
|
|
802
|
+
let n = !0, a = 0, i = null;
|
|
803
803
|
async function r() {
|
|
804
804
|
const s = se();
|
|
805
805
|
if (!s) throw new Error("nothing filed from this browser yet");
|
|
@@ -809,24 +809,24 @@ function Ho({ apiBase: t, onUpdate: e }) {
|
|
|
809
809
|
signal: i.signal
|
|
810
810
|
});
|
|
811
811
|
if (l.status === 401)
|
|
812
|
-
throw n = !1,
|
|
812
|
+
throw n = !1, $e(), new Error("subscription no longer valid");
|
|
813
813
|
if (!l.ok || !l.body) throw new Error(`stream failed (${l.status})`);
|
|
814
|
-
const
|
|
815
|
-
let
|
|
814
|
+
const p = Date.now(), f = l.body.getReader(), y = new TextDecoder();
|
|
815
|
+
let h = "";
|
|
816
816
|
try {
|
|
817
817
|
for (; ; ) {
|
|
818
|
-
const { value: b, done:
|
|
819
|
-
if (
|
|
820
|
-
|
|
821
|
-
if (
|
|
818
|
+
const { value: b, done: g } = await f.read();
|
|
819
|
+
if (g) break;
|
|
820
|
+
h += y.decode(b, { stream: !0 }), h = Aa(h, (S) => {
|
|
821
|
+
if (S.type !== "ping")
|
|
822
822
|
try {
|
|
823
|
-
e(
|
|
823
|
+
e(S);
|
|
824
824
|
} catch {
|
|
825
825
|
}
|
|
826
826
|
});
|
|
827
827
|
}
|
|
828
828
|
} finally {
|
|
829
|
-
Date.now() -
|
|
829
|
+
Date.now() - p >= Ta && (a = 0);
|
|
830
830
|
}
|
|
831
831
|
}
|
|
832
832
|
return (async () => {
|
|
@@ -837,66 +837,66 @@ function Ho({ apiBase: t, onUpdate: e }) {
|
|
|
837
837
|
if ((l == null ? void 0 : l.name) === "AbortError") return;
|
|
838
838
|
}
|
|
839
839
|
if (!n) return;
|
|
840
|
-
const s =
|
|
841
|
-
|
|
840
|
+
const s = Gt[Math.min(a, Gt.length - 1)];
|
|
841
|
+
a += 1, await new Promise((l) => setTimeout(l, s));
|
|
842
842
|
}
|
|
843
843
|
})(), () => {
|
|
844
844
|
n = !1, i == null || i.abort(), i = null;
|
|
845
845
|
};
|
|
846
846
|
}
|
|
847
|
-
const
|
|
847
|
+
const Na = {
|
|
848
848
|
OPEN: "is open",
|
|
849
849
|
IN_PROGRESS: "is being worked on",
|
|
850
850
|
RESOLVED: "has been fixed",
|
|
851
851
|
CLOSED: "has been closed"
|
|
852
|
-
},
|
|
852
|
+
}, Ua = {
|
|
853
853
|
status: null,
|
|
854
854
|
// falls back to the host's configured accent
|
|
855
855
|
severity: "#e8912a",
|
|
856
856
|
assignment: "#4da3ff",
|
|
857
857
|
reply: "#35b87f"
|
|
858
858
|
};
|
|
859
|
-
function
|
|
860
|
-
return t != null && t.summary ? t.summary : `Your report ${
|
|
859
|
+
function nn(t) {
|
|
860
|
+
return t != null && t.summary ? t.summary : `Your report ${Na[t == null ? void 0 : t.status] || "was updated"}`;
|
|
861
861
|
}
|
|
862
|
-
function
|
|
862
|
+
function Va(t) {
|
|
863
863
|
var e;
|
|
864
864
|
return (t == null ? void 0 : t.kind) === "reply" && ((e = t.reply) != null && e.body) ? `${t.reply.author ? `${t.reply.author}: ` : ""}${t.reply.body}` : (t == null ? void 0 : t.title) || "";
|
|
865
865
|
}
|
|
866
|
-
function
|
|
866
|
+
function Ka(t) {
|
|
867
867
|
const e = Date.parse(t || "");
|
|
868
868
|
if (!Number.isFinite(e)) return "";
|
|
869
869
|
const n = Math.round((Date.now() - e) / 6e4);
|
|
870
870
|
if (n < 1) return "just now";
|
|
871
871
|
if (n < 60) return `${n}m ago`;
|
|
872
|
-
const
|
|
873
|
-
if (
|
|
874
|
-
const i = Math.round(
|
|
872
|
+
const a = Math.round(n / 60);
|
|
873
|
+
if (a < 24) return `${a}h ago`;
|
|
874
|
+
const i = Math.round(a / 24);
|
|
875
875
|
return i === 1 ? "yesterday" : `${i}d ago`;
|
|
876
876
|
}
|
|
877
|
-
function
|
|
877
|
+
function Pa() {
|
|
878
878
|
var t;
|
|
879
879
|
try {
|
|
880
|
-
const e = document.querySelector('[data-bugcatch="widget"]'), n = (t = e == null ? void 0 : e.shadowRoot) == null ? void 0 : t.querySelector(".dock"),
|
|
881
|
-
return
|
|
880
|
+
const e = document.querySelector('[data-bugcatch="widget"]'), n = (t = e == null ? void 0 : e.shadowRoot) == null ? void 0 : t.querySelector(".dock"), a = (n == null ? void 0 : n.getBoundingClientRect().height) || 0;
|
|
881
|
+
return a ? Math.round(a) + 12 : 0;
|
|
882
882
|
} catch {
|
|
883
883
|
return 0;
|
|
884
884
|
}
|
|
885
885
|
}
|
|
886
|
-
function
|
|
886
|
+
function _a({
|
|
887
887
|
accent: t = "#4F46E5",
|
|
888
888
|
position: e = "bottom-right",
|
|
889
889
|
onRead: n = null,
|
|
890
|
-
onReadAll:
|
|
890
|
+
onReadAll: a = null,
|
|
891
891
|
onCall: i = null
|
|
892
892
|
} = {}) {
|
|
893
|
-
const [r, s] = String(e).split("-"), l = r === "top",
|
|
894
|
-
let y = null,
|
|
893
|
+
const [r, s] = String(e).split("-"), l = r === "top", p = s === "left", f = /* @__PURE__ */ new Map();
|
|
894
|
+
let y = null, h = null;
|
|
895
895
|
function b() {
|
|
896
896
|
return y != null && y.isConnected || (y = document.createElement("div"), y.setAttribute("data-bugcatch", "updates"), y.style.cssText = [
|
|
897
897
|
"position:fixed",
|
|
898
|
-
`${l ? "top" : "bottom"}:${20 +
|
|
899
|
-
`${
|
|
898
|
+
`${l ? "top" : "bottom"}:${20 + Pa()}px`,
|
|
899
|
+
`${p ? "left" : "right"}:20px`,
|
|
900
900
|
// Under the widget's dock and its panel scrim, both of which are higher.
|
|
901
901
|
// A notification is worth interrupting a page for, not the report being
|
|
902
902
|
// read on top of it.
|
|
@@ -904,36 +904,36 @@ function Ko({
|
|
|
904
904
|
"display:flex",
|
|
905
905
|
"flex-direction:column",
|
|
906
906
|
"gap:10px",
|
|
907
|
-
`align-items:${
|
|
907
|
+
`align-items:${p ? "flex-start" : "flex-end"}`,
|
|
908
908
|
"width:min(320px,calc(100vw - 40px))",
|
|
909
909
|
// The gaps between cards belong to the page underneath.
|
|
910
910
|
"pointer-events:none"
|
|
911
911
|
].join(";"), document.body.appendChild(y)), y;
|
|
912
912
|
}
|
|
913
|
-
function
|
|
914
|
-
if (!
|
|
915
|
-
|
|
913
|
+
function g(C) {
|
|
914
|
+
if (!C._bcShown) {
|
|
915
|
+
C.remove();
|
|
916
916
|
return;
|
|
917
917
|
}
|
|
918
|
-
|
|
918
|
+
C.style.opacity = "0", C.style.transform = `translateY(${l ? -8 : 8}px)`, setTimeout(() => C.remove(), 250);
|
|
919
919
|
}
|
|
920
|
-
function
|
|
920
|
+
function S(C, $) {
|
|
921
921
|
const T = document.createElement("button");
|
|
922
|
-
return T.type = "button", T.textContent =
|
|
922
|
+
return T.type = "button", T.textContent = C, T.style.cssText = [
|
|
923
923
|
"padding:5px 11px",
|
|
924
|
-
`border:${
|
|
924
|
+
`border:${$ ? "0" : "1px solid rgba(236,238,242,.24)"}`,
|
|
925
925
|
"border-radius:6px",
|
|
926
|
-
`background:${
|
|
927
|
-
`color:${
|
|
926
|
+
`background:${$ ? t : "transparent"}`,
|
|
927
|
+
`color:${$ ? "#fff" : "#eceef2"}`,
|
|
928
928
|
"font:600 12px/1.4 inherit",
|
|
929
929
|
"cursor:pointer",
|
|
930
930
|
"white-space:nowrap"
|
|
931
931
|
].join(";"), T;
|
|
932
932
|
}
|
|
933
|
-
function A(
|
|
934
|
-
var
|
|
935
|
-
const
|
|
936
|
-
|
|
933
|
+
function A(C) {
|
|
934
|
+
var U;
|
|
935
|
+
const $ = document.createElement("div");
|
|
936
|
+
$.setAttribute("role", "status"), $.style.cssText = [
|
|
937
937
|
"box-sizing:border-box",
|
|
938
938
|
"width:100%",
|
|
939
939
|
"padding:12px 14px",
|
|
@@ -942,30 +942,30 @@ function Ko({
|
|
|
942
942
|
"color:#eceef2",
|
|
943
943
|
'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',
|
|
944
944
|
"box-shadow:0 12px 30px rgba(0,0,0,0.45)",
|
|
945
|
-
`border-left:3px solid ${
|
|
945
|
+
`border-left:3px solid ${Ua[C == null ? void 0 : C.kind] || t}`,
|
|
946
946
|
"opacity:0",
|
|
947
947
|
`transform:translateY(${l ? -8 : 8}px)`,
|
|
948
948
|
"transition:opacity .2s ease,transform .2s ease",
|
|
949
949
|
"pointer-events:auto"
|
|
950
950
|
].join(";");
|
|
951
951
|
const T = document.createElement("div");
|
|
952
|
-
T.style.cssText = "font-weight:600;margin-bottom:2px", T.textContent =
|
|
952
|
+
T.style.cssText = "font-weight:600;margin-bottom:2px", T.textContent = nn(C);
|
|
953
953
|
const L = document.createElement("div");
|
|
954
|
-
L.style.cssText = (
|
|
954
|
+
L.style.cssText = (C == null ? void 0 : C.kind) === "reply" ? "color:#a4abba;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden" : "color:#a4abba", L.textContent = Va(C);
|
|
955
955
|
const Y = document.createElement("div");
|
|
956
956
|
Y.style.cssText = "display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap";
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
const Q =
|
|
960
|
-
if (Q.setAttribute("aria-label", `Mark as read: ${
|
|
961
|
-
const
|
|
962
|
-
|
|
957
|
+
const N = document.createElement("span");
|
|
958
|
+
N.style.cssText = "color:#7b8394;font-size:11px;margin-right:auto", N.textContent = Ka(C == null ? void 0 : C.at);
|
|
959
|
+
const Q = S("Mark as read", !1);
|
|
960
|
+
if (Q.setAttribute("aria-label", `Mark as read: ${nn(C)}`), Q.addEventListener("click", () => n == null ? void 0 : n(C.id)), Y.append(N, Q), (U = C == null ? void 0 : C.call) != null && U.offered && typeof i == "function") {
|
|
961
|
+
const E = S("Talk it through", !0);
|
|
962
|
+
E.addEventListener("click", () => i(C)), Y.insertBefore(E, Q);
|
|
963
963
|
}
|
|
964
|
-
return
|
|
964
|
+
return $.append(T, L, Y), $;
|
|
965
965
|
}
|
|
966
|
-
function
|
|
967
|
-
const
|
|
968
|
-
|
|
966
|
+
function ae(C) {
|
|
967
|
+
const $ = document.createElement("div");
|
|
968
|
+
$.style.cssText = [
|
|
969
969
|
"box-sizing:border-box",
|
|
970
970
|
"width:100%",
|
|
971
971
|
"display:flex",
|
|
@@ -980,9 +980,9 @@ function Ko({
|
|
|
980
980
|
"pointer-events:auto"
|
|
981
981
|
].join(";");
|
|
982
982
|
const T = document.createElement("span");
|
|
983
|
-
T.style.cssText = "margin-right:auto", T.textContent = `${
|
|
984
|
-
const L =
|
|
985
|
-
return L.style.cssText += ";padding:4px 9px", L.addEventListener("click", () =>
|
|
983
|
+
T.style.cssText = "margin-right:auto", T.textContent = `${C} more update${C === 1 ? "" : "s"}`;
|
|
984
|
+
const L = S("Mark all as read", !1);
|
|
985
|
+
return L.style.cssText += ";padding:4px 9px", L.addEventListener("click", () => a == null ? void 0 : a()), $.append(T, L), $;
|
|
986
986
|
}
|
|
987
987
|
return {
|
|
988
988
|
/**
|
|
@@ -992,40 +992,40 @@ function Ko({
|
|
|
992
992
|
* corner the reporter's eye is already trained on — so the stack grows away
|
|
993
993
|
* from the launcher rather than over it.
|
|
994
994
|
*/
|
|
995
|
-
render(
|
|
996
|
-
const
|
|
997
|
-
if (
|
|
998
|
-
for (const
|
|
999
|
-
|
|
995
|
+
render(C) {
|
|
996
|
+
const $ = Array.isArray(C) ? C : [];
|
|
997
|
+
if (!$.length) {
|
|
998
|
+
for (const E of f.values()) g(E);
|
|
999
|
+
f.clear(), h == null || h.remove(), h = null, y == null || y.remove(), y = null;
|
|
1000
1000
|
return;
|
|
1001
1001
|
}
|
|
1002
|
-
const T =
|
|
1003
|
-
for (const [
|
|
1004
|
-
L.has(
|
|
1005
|
-
const
|
|
1006
|
-
for (const
|
|
1007
|
-
if (
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1002
|
+
const T = $.slice(-3), L = new Set(T.map((E) => E.id)), Y = b();
|
|
1003
|
+
for (const [E, oe] of f)
|
|
1004
|
+
L.has(E) || (g(oe), f.delete(E));
|
|
1005
|
+
const N = [];
|
|
1006
|
+
for (const E of T) {
|
|
1007
|
+
if (f.has(E.id)) continue;
|
|
1008
|
+
const oe = A(E);
|
|
1009
|
+
f.set(E.id, oe), N.push(oe);
|
|
1010
1010
|
}
|
|
1011
1011
|
const Q = l ? [...T].reverse() : T;
|
|
1012
|
-
for (const
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
for (const
|
|
1016
|
-
|
|
1012
|
+
for (const E of Q) Y.appendChild(f.get(E.id));
|
|
1013
|
+
const U = $.length - T.length;
|
|
1014
|
+
U > 0 ? (h == null || h.remove(), h = ae(U), l ? Y.appendChild(h) : Y.insertBefore(h, Y.firstChild)) : (h == null || h.remove(), h = null), requestAnimationFrame(() => {
|
|
1015
|
+
for (const E of N)
|
|
1016
|
+
E.isConnected && (E._bcShown = !0, E.style.opacity = "1", E.style.transform = "translateY(0)");
|
|
1017
1017
|
});
|
|
1018
1018
|
},
|
|
1019
1019
|
destroy() {
|
|
1020
|
-
|
|
1020
|
+
f.clear(), h = null, y == null || y.remove(), y = null;
|
|
1021
1021
|
}
|
|
1022
1022
|
};
|
|
1023
1023
|
}
|
|
1024
|
-
async function
|
|
1024
|
+
async function Fa({ apiBase: t, apiKey: e, projectId: n, sessionToken: a }) {
|
|
1025
1025
|
try {
|
|
1026
1026
|
const i = await fetch(
|
|
1027
1027
|
`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,
|
|
1028
|
-
{ headers:
|
|
1028
|
+
{ headers: Lt(e, a) }
|
|
1029
1029
|
);
|
|
1030
1030
|
if (!i.ok) return [];
|
|
1031
1031
|
const r = await i.json();
|
|
@@ -1034,47 +1034,47 @@ async function Po({ apiBase: t, apiKey: e, projectId: n, sessionToken: o }) {
|
|
|
1034
1034
|
return [];
|
|
1035
1035
|
}
|
|
1036
1036
|
}
|
|
1037
|
-
async function
|
|
1037
|
+
async function Wa({ apiBase: t, apiKey: e, projectId: n, q: a, sessionToken: i, signal: r }) {
|
|
1038
1038
|
try {
|
|
1039
|
-
const s = `${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(
|
|
1039
|
+
const s = `${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(a)}`, l = await fetch(s, { headers: Lt(e, i), signal: r });
|
|
1040
1040
|
if (!l.ok) return [];
|
|
1041
|
-
const
|
|
1042
|
-
return Array.isArray(
|
|
1041
|
+
const p = await l.json();
|
|
1042
|
+
return Array.isArray(p == null ? void 0 : p.issues) ? p.issues : [];
|
|
1043
1043
|
} catch {
|
|
1044
1044
|
return [];
|
|
1045
1045
|
}
|
|
1046
1046
|
}
|
|
1047
|
-
async function
|
|
1047
|
+
async function Ya({
|
|
1048
1048
|
apiBase: t,
|
|
1049
1049
|
apiKey: e,
|
|
1050
1050
|
projectId: n,
|
|
1051
|
-
bugId:
|
|
1051
|
+
bugId: a,
|
|
1052
1052
|
reporterEmail: i,
|
|
1053
1053
|
reporterName: r,
|
|
1054
1054
|
metadata: s,
|
|
1055
1055
|
logs: l,
|
|
1056
|
-
sessionToken:
|
|
1056
|
+
sessionToken: p
|
|
1057
1057
|
}) {
|
|
1058
|
-
const
|
|
1059
|
-
`${t}/ingest/known-issues/${encodeURIComponent(
|
|
1058
|
+
const f = await fetch(
|
|
1059
|
+
`${t}/ingest/known-issues/${encodeURIComponent(a)}/join`,
|
|
1060
1060
|
{
|
|
1061
1061
|
method: "POST",
|
|
1062
|
-
headers:
|
|
1062
|
+
headers: Lt(e, p),
|
|
1063
1063
|
body: JSON.stringify({ projectId: n, reporterEmail: i, reporterName: r, metadata: s, logs: l })
|
|
1064
1064
|
}
|
|
1065
1065
|
);
|
|
1066
|
-
if (!
|
|
1067
|
-
const y = await
|
|
1068
|
-
return y != null && y.watchToken &&
|
|
1066
|
+
if (!f.ok) throw new Error(await Xa(f));
|
|
1067
|
+
const y = await f.json();
|
|
1068
|
+
return y != null && y.watchToken && Ct(y.watchToken), y;
|
|
1069
1069
|
}
|
|
1070
|
-
function
|
|
1070
|
+
function Lt(t, e) {
|
|
1071
1071
|
return {
|
|
1072
1072
|
"Content-Type": "application/json",
|
|
1073
1073
|
"X-BugCatch-Key": t,
|
|
1074
1074
|
...e ? { "X-BugCatch-Session": e } : {}
|
|
1075
1075
|
};
|
|
1076
1076
|
}
|
|
1077
|
-
async function
|
|
1077
|
+
async function Xa(t) {
|
|
1078
1078
|
try {
|
|
1079
1079
|
const e = await t.json(), n = Array.isArray(e.message) ? e.message.join(", ") : e.message;
|
|
1080
1080
|
if (n) return n;
|
|
@@ -1082,19 +1082,19 @@ async function Wo(t) {
|
|
|
1082
1082
|
}
|
|
1083
1083
|
return `Could not add you to this issue (HTTP ${t.status})`;
|
|
1084
1084
|
}
|
|
1085
|
-
async function
|
|
1086
|
-
const
|
|
1087
|
-
if (!
|
|
1085
|
+
async function Za({ apiBase: t, bugId: e, ...n }) {
|
|
1086
|
+
const a = se();
|
|
1087
|
+
if (!a) throw new Error("This browser cannot access that report.");
|
|
1088
1088
|
const i = await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`, {
|
|
1089
1089
|
method: "POST",
|
|
1090
|
-
headers: { "Content-Type": "application/json", Authorization: `Bearer ${
|
|
1090
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${a}` },
|
|
1091
1091
|
body: JSON.stringify(n)
|
|
1092
1092
|
}), r = await i.json().catch(() => ({}));
|
|
1093
1093
|
if (!i.ok) throw new Error(r.message || "Could not record feedback. Please refresh and try again.");
|
|
1094
1094
|
return r;
|
|
1095
1095
|
}
|
|
1096
|
-
const
|
|
1097
|
-
function
|
|
1096
|
+
const Ja = 2e4, Cn = 120, $n = 200;
|
|
1097
|
+
function En(t) {
|
|
1098
1098
|
if (typeof t != "string" || !t.trim() || t.length > 400) return null;
|
|
1099
1099
|
try {
|
|
1100
1100
|
return new RegExp(t.trim(), "gi");
|
|
@@ -1102,82 +1102,82 @@ function Sn(t) {
|
|
|
1102
1102
|
return null;
|
|
1103
1103
|
}
|
|
1104
1104
|
}
|
|
1105
|
-
const
|
|
1106
|
-
function
|
|
1105
|
+
const Ga = (t) => String(t).replace(/\s+/g, " ").trim().slice(0, Cn);
|
|
1106
|
+
function Tn(t) {
|
|
1107
1107
|
const e = t.length > 1 && t[1] !== void 0 ? t[1] : t[0];
|
|
1108
|
-
return typeof e != "string" || !e.trim() ? null : { value:
|
|
1108
|
+
return typeof e != "string" || !e.trim() ? null : { value: Ga(e), start: t.index, end: t.index + t[0].length };
|
|
1109
1109
|
}
|
|
1110
|
-
function
|
|
1111
|
-
const n = [],
|
|
1110
|
+
function eo(t, e) {
|
|
1111
|
+
const n = [], a = /* @__PURE__ */ new Set();
|
|
1112
1112
|
for (const i of e || []) {
|
|
1113
|
-
const r = typeof i == "string" ? i.slice(0,
|
|
1113
|
+
const r = typeof i == "string" ? i.slice(0, Ja) : "";
|
|
1114
1114
|
if (!r) continue;
|
|
1115
|
-
const s = [], l = (
|
|
1116
|
-
for (const
|
|
1117
|
-
if (!
|
|
1118
|
-
const
|
|
1119
|
-
if (!
|
|
1120
|
-
let y,
|
|
1121
|
-
for (
|
|
1115
|
+
const s = [], l = (p, f) => s.some(([y, h]) => p < h && f > y);
|
|
1116
|
+
for (const p of t || []) {
|
|
1117
|
+
if (!p || p.scan === !1) continue;
|
|
1118
|
+
const f = En(p.pattern);
|
|
1119
|
+
if (!f) continue;
|
|
1120
|
+
let y, h = 0;
|
|
1121
|
+
for (f.lastIndex = 0; (y = f.exec(r)) !== null && !(++h > $n); ) {
|
|
1122
1122
|
if (y[0] === "") {
|
|
1123
|
-
|
|
1123
|
+
f.lastIndex += 1;
|
|
1124
1124
|
continue;
|
|
1125
1125
|
}
|
|
1126
|
-
const b =
|
|
1126
|
+
const b = Tn(y);
|
|
1127
1127
|
if (b && !l(b.start, b.end)) {
|
|
1128
1128
|
s.push([b.start, b.end]);
|
|
1129
|
-
const
|
|
1130
|
-
|
|
1129
|
+
const g = `${p.key}:${b.value.toLowerCase()}`;
|
|
1130
|
+
a.has(g) || (a.add(g), n.push({ key: p.key, label: p.label, value: b.value }));
|
|
1131
1131
|
}
|
|
1132
1132
|
}
|
|
1133
1133
|
}
|
|
1134
1134
|
}
|
|
1135
1135
|
return n;
|
|
1136
1136
|
}
|
|
1137
|
-
function
|
|
1137
|
+
function to(t, e) {
|
|
1138
1138
|
const n = typeof e == "string" ? e.trim() : "";
|
|
1139
|
-
if (!n || n.length >
|
|
1140
|
-
const
|
|
1141
|
-
if (!
|
|
1139
|
+
if (!n || n.length > Cn) return null;
|
|
1140
|
+
const a = En(t && (t.valuePattern || t.pattern));
|
|
1141
|
+
if (!a) return null;
|
|
1142
1142
|
let i, r = 0;
|
|
1143
|
-
for (
|
|
1143
|
+
for (a.lastIndex = 0; (i = a.exec(n)) !== null && !(++r > $n); ) {
|
|
1144
1144
|
if (i[0] === "") {
|
|
1145
|
-
|
|
1145
|
+
a.lastIndex += 1;
|
|
1146
1146
|
continue;
|
|
1147
1147
|
}
|
|
1148
1148
|
const s = i.index + i[0].length === n.length, l = i.index === 0 || i.index === 1;
|
|
1149
1149
|
if (s && l) {
|
|
1150
|
-
const
|
|
1151
|
-
if (
|
|
1150
|
+
const p = Tn(i);
|
|
1151
|
+
if (p) return p.value;
|
|
1152
1152
|
}
|
|
1153
1153
|
}
|
|
1154
1154
|
return null;
|
|
1155
1155
|
}
|
|
1156
|
-
async function
|
|
1157
|
-
const
|
|
1156
|
+
async function no({ apiBase: t, apiKey: e, projectId: n }) {
|
|
1157
|
+
const a = { policy: "off", fields: [] };
|
|
1158
1158
|
try {
|
|
1159
1159
|
const i = await fetch(
|
|
1160
1160
|
`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,
|
|
1161
1161
|
{ headers: { "X-BugCatch-Key": e } }
|
|
1162
1162
|
);
|
|
1163
|
-
if (!i.ok) return
|
|
1163
|
+
if (!i.ok) return a;
|
|
1164
1164
|
const r = await i.json(), s = r.policy === "optional" || r.policy === "required" ? r.policy : "off", l = Array.isArray(r.fields) ? r.fields : [];
|
|
1165
|
-
return l.length ? { policy: s, fields: l } :
|
|
1165
|
+
return l.length ? { policy: s, fields: l } : a;
|
|
1166
1166
|
} catch {
|
|
1167
|
-
return
|
|
1167
|
+
return a;
|
|
1168
1168
|
}
|
|
1169
1169
|
}
|
|
1170
|
-
const
|
|
1170
|
+
const an = {
|
|
1171
1171
|
"bottom-right": "bottom:20px;right:20px;",
|
|
1172
1172
|
"bottom-left": "bottom:20px;left:20px;",
|
|
1173
1173
|
"top-right": "top:20px;right:20px;",
|
|
1174
1174
|
"top-left": "top:20px;left:20px;"
|
|
1175
|
-
},
|
|
1175
|
+
}, on = [
|
|
1176
1176
|
{ value: "LOW", label: "Low" },
|
|
1177
1177
|
{ value: "MEDIUM", label: "Medium" },
|
|
1178
1178
|
{ value: "HIGH", label: "High" },
|
|
1179
1179
|
{ value: "CRITICAL", label: "Critical" }
|
|
1180
|
-
],
|
|
1180
|
+
], O = {
|
|
1181
1181
|
camera: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',
|
|
1182
1182
|
video: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',
|
|
1183
1183
|
paperclip: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',
|
|
@@ -1194,26 +1194,26 @@ const en = {
|
|
|
1194
1194
|
sun: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',
|
|
1195
1195
|
moon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',
|
|
1196
1196
|
auto: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>'
|
|
1197
|
-
},
|
|
1198
|
-
{ value: "light", label: "Light", icon:
|
|
1199
|
-
{ value: "dark", label: "Dark", icon:
|
|
1200
|
-
{ value: "auto", label: "System default", icon:
|
|
1201
|
-
],
|
|
1202
|
-
function
|
|
1197
|
+
}, ao = '<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>', In = [
|
|
1198
|
+
{ value: "light", label: "Light", icon: O.sun },
|
|
1199
|
+
{ value: "dark", label: "Dark", icon: O.moon },
|
|
1200
|
+
{ value: "auto", label: "System default", icon: O.auto }
|
|
1201
|
+
], Mn = "bugcatch:theme";
|
|
1202
|
+
function oo() {
|
|
1203
1203
|
try {
|
|
1204
|
-
const t = localStorage.getItem(
|
|
1205
|
-
return
|
|
1204
|
+
const t = localStorage.getItem(Mn);
|
|
1205
|
+
return In.some((e) => e.value === t) ? t : null;
|
|
1206
1206
|
} catch {
|
|
1207
1207
|
return null;
|
|
1208
1208
|
}
|
|
1209
1209
|
}
|
|
1210
|
-
function
|
|
1210
|
+
function ro(t) {
|
|
1211
1211
|
try {
|
|
1212
|
-
localStorage.setItem(
|
|
1212
|
+
localStorage.setItem(Mn, t);
|
|
1213
1213
|
} catch {
|
|
1214
1214
|
}
|
|
1215
1215
|
}
|
|
1216
|
-
const
|
|
1216
|
+
const io = (t) => `
|
|
1217
1217
|
:host { all: initial; }
|
|
1218
1218
|
:host {
|
|
1219
1219
|
--bc-accent: ${t};
|
|
@@ -1747,6 +1747,27 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
1747
1747
|
.att .file .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1748
1748
|
.att .file .sz { flex: none; color: var(--bc-faint); font-size: 11px; }
|
|
1749
1749
|
|
|
1750
|
+
/* The assistant's live card, above the conversation. */
|
|
1751
|
+
.assistant { margin: 8px 12px 4px; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--bc-border); background: var(--bc-subtle); }
|
|
1752
|
+
.assistant.analyzing, .assistant.confirming, .assistant.needs_info { border-color: color-mix(in srgb, var(--bc-accent) 45%, transparent); }
|
|
1753
|
+
.as-top { display: flex; gap: 10px; align-items: flex-start; }
|
|
1754
|
+
.as-orb { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-size: 12px; background: var(--bc-accent); }
|
|
1755
|
+
.as-spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; animation: as-rot .8s linear infinite; }
|
|
1756
|
+
@keyframes as-rot { to { transform: rotate(360deg); } }
|
|
1757
|
+
.as-title { font-weight: 600; font-size: 14px; }
|
|
1758
|
+
.assistant.analyzing .as-title::after { content: ''; animation: as-dots 1.4s steps(4) infinite; }
|
|
1759
|
+
@keyframes as-dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }
|
|
1760
|
+
.as-detail { font-size: 12.5px; color: var(--bc-muted); margin-top: 2px; }
|
|
1761
|
+
.as-steps { list-style: none; display: flex; gap: 6px; margin: 10px 0 0; padding: 0; flex-wrap: wrap; font-size: 11.5px; color: var(--bc-muted); }
|
|
1762
|
+
.as-steps li { display: flex; align-items: center; gap: 4px; }
|
|
1763
|
+
.as-steps li span { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid currentColor; }
|
|
1764
|
+
.as-steps li.done { color: var(--bc-accent); }
|
|
1765
|
+
.as-steps li.done span { background: var(--bc-accent); border-color: var(--bc-accent); }
|
|
1766
|
+
.as-steps li.active { color: var(--bc-fg); font-weight: 600; }
|
|
1767
|
+
.as-steps li.active span { border-color: var(--bc-accent); animation: as-pulse 1s ease-in-out infinite; }
|
|
1768
|
+
@keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent) 25%, transparent); } }
|
|
1769
|
+
@media (prefers-reduced-motion: reduce) { .as-spin, .as-steps li.active span, .assistant.analyzing .as-title::after { animation: none; } }
|
|
1770
|
+
|
|
1750
1771
|
/* Quick answers under the confirm question — only on the latest message. */
|
|
1751
1772
|
.msg-row .quick { display: none; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
|
|
1752
1773
|
.msg-row:last-child .quick { display: flex; }
|
|
@@ -1992,63 +2013,63 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
1992
2013
|
.tool:hover, .themer button:hover { border-color: var(--bc-border); }
|
|
1993
2014
|
}
|
|
1994
2015
|
`;
|
|
1995
|
-
function
|
|
2016
|
+
function so(t) {
|
|
1996
2017
|
const e = document.createElement("div");
|
|
1997
2018
|
e.setAttribute("data-bugcatch", "widget");
|
|
1998
|
-
let n =
|
|
1999
|
-
e.className =
|
|
2000
|
-
const
|
|
2001
|
-
i.textContent =
|
|
2002
|
-
const r =
|
|
2003
|
-
s.className = `dock ${r.includes("right") ? "at-right" : "at-left"}` + (r.startsWith("top") ? " at-top" : ""), s.style.cssText =
|
|
2019
|
+
let n = oo() || co(t.config.theme);
|
|
2020
|
+
e.className = rn(n);
|
|
2021
|
+
const a = e.attachShadow({ mode: "open" }), i = document.createElement("style");
|
|
2022
|
+
i.textContent = io(t.config.accent || "#4F46E5"), a.appendChild(i);
|
|
2023
|
+
const r = an[t.config.widgetPosition] ? t.config.widgetPosition : "bottom-right", s = document.createElement("div");
|
|
2024
|
+
s.className = `dock ${r.includes("right") ? "at-right" : "at-left"}` + (r.startsWith("top") ? " at-top" : ""), s.style.cssText = an[r];
|
|
2004
2025
|
const l = document.createElement("div");
|
|
2005
|
-
l.className = "themer", l.setAttribute("role", "group"), l.setAttribute("aria-label", "Report widget theme"), l.innerHTML =
|
|
2006
|
-
const
|
|
2007
|
-
!
|
|
2026
|
+
l.className = "themer", l.setAttribute("role", "group"), l.setAttribute("aria-label", "Report widget theme"), l.innerHTML = In.map((y) => `<button type="button" data-theme="${y.value}" title="${y.label}" aria-label="${y.label}" aria-pressed="${y.value === n}">${y.icon}</button>`).join(""), l.addEventListener("click", (y) => {
|
|
2027
|
+
const h = y.target.closest("button[data-theme]");
|
|
2028
|
+
!h || h.dataset.theme === n || (n = h.dataset.theme, e.className = rn(n), ro(n), l.querySelectorAll("button").forEach((b) => {
|
|
2008
2029
|
b.setAttribute("aria-pressed", String(b.dataset.theme === n));
|
|
2009
2030
|
}));
|
|
2010
2031
|
});
|
|
2011
|
-
const
|
|
2012
|
-
|
|
2013
|
-
let
|
|
2014
|
-
return
|
|
2015
|
-
if (
|
|
2016
|
-
|
|
2032
|
+
const p = document.createElement("button");
|
|
2033
|
+
p.className = "launcher", p.type = "button", p.innerHTML = `${O.bug}<span>Report a bug</span>`, p.setAttribute("aria-haspopup", "dialog"), p.setAttribute("aria-expanded", "false");
|
|
2034
|
+
let f = null;
|
|
2035
|
+
return p.addEventListener("click", () => {
|
|
2036
|
+
if (f) {
|
|
2037
|
+
f.close();
|
|
2017
2038
|
return;
|
|
2018
2039
|
}
|
|
2019
|
-
s.classList.add("over"),
|
|
2020
|
-
root:
|
|
2040
|
+
s.classList.add("over"), p.setAttribute("aria-expanded", "true"), f = lo({
|
|
2041
|
+
root: a,
|
|
2021
2042
|
host: e,
|
|
2022
2043
|
dock: s,
|
|
2023
2044
|
client: t,
|
|
2024
2045
|
onClose: () => {
|
|
2025
|
-
|
|
2046
|
+
f = null, s.classList.remove("over"), p.setAttribute("aria-expanded", "false");
|
|
2026
2047
|
}
|
|
2027
2048
|
});
|
|
2028
|
-
}), s.append(l,
|
|
2029
|
-
|
|
2049
|
+
}), s.append(l, p), a.appendChild(s), document.body.appendChild(e), () => {
|
|
2050
|
+
f == null || f.destroy(), e.remove();
|
|
2030
2051
|
};
|
|
2031
2052
|
}
|
|
2032
|
-
function
|
|
2053
|
+
function co(t) {
|
|
2033
2054
|
return t === "dark" || t === "light" ? t : "auto";
|
|
2034
2055
|
}
|
|
2035
|
-
function
|
|
2056
|
+
function rn(t) {
|
|
2036
2057
|
return t === "dark" ? "bc-dark" : t === "light" ? "bc-light" : "bc-auto";
|
|
2037
2058
|
}
|
|
2038
|
-
function
|
|
2039
|
-
var
|
|
2040
|
-
const r =
|
|
2041
|
-
let y = "MEDIUM",
|
|
2042
|
-
const
|
|
2043
|
-
|
|
2059
|
+
function lo({ root: t, host: e, dock: n, client: a, onClose: i }) {
|
|
2060
|
+
var Ut, Vt, Kt, Pt, _t, Ft;
|
|
2061
|
+
const r = a.config, s = r.attachments !== !1, l = s && ua(), p = s && da(), f = [];
|
|
2062
|
+
let y = "MEDIUM", h = null, b = !1;
|
|
2063
|
+
const g = document.createElement("div");
|
|
2064
|
+
g.className = `scrim ${n.classList.contains("at-left") ? "at-left" : "at-right"} ${n.classList.contains("at-top") ? "at-top" : "at-bottom"}`, g.style.setProperty("--bc-dock-h", `${Math.round(n.getBoundingClientRect().height)}px`), g.innerHTML = `
|
|
2044
2065
|
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
|
|
2045
2066
|
<div class="head">
|
|
2046
|
-
<div class="mark">${
|
|
2067
|
+
<div class="mark">${O.bug}</div>
|
|
2047
2068
|
<div class="titles">
|
|
2048
2069
|
<h2 id="bc-h">Report a bug</h2>
|
|
2049
2070
|
<p>We'll attach what the page was doing, so you don't have to explain it.</p>
|
|
2050
2071
|
</div>
|
|
2051
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
2072
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${O.close}</button>
|
|
2052
2073
|
</div>
|
|
2053
2074
|
<div class="body">
|
|
2054
2075
|
<div class="slot"></div>
|
|
@@ -2071,8 +2092,8 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2071
2092
|
<div class="field">
|
|
2072
2093
|
<label id="bc-prio-l">Severity</label>
|
|
2073
2094
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
2074
|
-
${
|
|
2075
|
-
<button type="button" data-prio="${
|
|
2095
|
+
${on.map((o) => `
|
|
2096
|
+
<button type="button" data-prio="${o.value}" aria-pressed="${o.value === y}">${o.label}</button>
|
|
2076
2097
|
`).join("")}
|
|
2077
2098
|
</div>
|
|
2078
2099
|
</div>
|
|
@@ -2080,20 +2101,20 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2080
2101
|
<div class="field">
|
|
2081
2102
|
<label>Attach <span style="font-weight:450;color:var(--bc-faint)">(optional)</span></label>
|
|
2082
2103
|
<div class="tools">
|
|
2083
|
-
${l ? `<button class="tool" type="button" data-act="shot">${
|
|
2084
|
-
${
|
|
2085
|
-
<button class="tool" type="button" data-act="file">${
|
|
2104
|
+
${l ? `<button class="tool" type="button" data-act="shot">${O.camera}Screenshot</button>` : ""}
|
|
2105
|
+
${p ? `<button class="tool" type="button" data-act="rec">${O.video}Record</button>` : ""}
|
|
2106
|
+
<button class="tool" type="button" data-act="file">${O.paperclip}File</button>
|
|
2086
2107
|
</div>
|
|
2087
2108
|
<div class="thumbs"></div>
|
|
2088
|
-
<input type="file" accept="${
|
|
2109
|
+
<input type="file" accept="${tt.join(",")}" multiple hidden />
|
|
2089
2110
|
</div>` : ""}
|
|
2090
2111
|
</div>
|
|
2091
2112
|
</div>
|
|
2092
2113
|
<div class="foot">
|
|
2093
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
2114
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${ao}</a>
|
|
2094
2115
|
<span class="note"></span>
|
|
2095
2116
|
<span class="spacer"></span>
|
|
2096
|
-
${
|
|
2117
|
+
${a.hasReports() ? '<button class="ghost" type="button" data-act="history">Your reports</button>' : ""}
|
|
2097
2118
|
<button class="ghost" type="button" data-act="cancel">Cancel</button>
|
|
2098
2119
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
2099
2120
|
most cannot. Drawn here rather than as a second launcher because it
|
|
@@ -2103,40 +2124,40 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2103
2124
|
<button class="primary" type="button" data-act="send">Send report</button>
|
|
2104
2125
|
</div>
|
|
2105
2126
|
</div>`;
|
|
2106
|
-
const
|
|
2107
|
-
ee.setAttribute("role", "status"), ee.className = "note",
|
|
2108
|
-
const ze =
|
|
2109
|
-
let be = r.drafts === !1, Ue = !1, ye = Promise.resolve(),
|
|
2127
|
+
const S = (o) => g.querySelector(o), A = S("#bc-title"), ae = S(".slot"), C = S(".thumbs"), $ = g.querySelector("input[type=file]"), T = S('[data-act="send"]'), L = S('[data-act="call"]'), Y = S(".note"), N = S(".compose"), Q = S(".whoami"), U = S(".refs"), E = S(".known"), oe = S('[data-act="history"]'), ee = document.createElement("div");
|
|
2128
|
+
ee.setAttribute("role", "status"), ee.className = "note", N.prepend(ee);
|
|
2129
|
+
const ze = wa(r, (Ut = he(r.projectId)) == null ? void 0 : Ut.email);
|
|
2130
|
+
let be = r.drafts === !1, Ue = !1, ye = Promise.resolve(), V;
|
|
2110
2131
|
function te() {
|
|
2111
|
-
if (clearTimeout(
|
|
2112
|
-
const
|
|
2132
|
+
if (clearTimeout(V), !be || Ue || r.drafts === !1) return ye;
|
|
2133
|
+
const o = A.value || S("#bc-desc").value || f.length ? {
|
|
2113
2134
|
title: A.value,
|
|
2114
|
-
description:
|
|
2135
|
+
description: S("#bc-desc").value,
|
|
2115
2136
|
priority: y,
|
|
2116
|
-
items:
|
|
2137
|
+
items: f.map(({ blob: c, mime: u, kind: d }) => ({ blob: c, mime: u, kind: d }))
|
|
2117
2138
|
} : null;
|
|
2118
2139
|
return ye = ye.catch(() => {
|
|
2119
|
-
}).then(() =>
|
|
2120
|
-
ee.textContent =
|
|
2140
|
+
}).then(() => at(ze, o)).then(() => {
|
|
2141
|
+
ee.textContent = o ? "Draft saved on this device" : "";
|
|
2121
2142
|
}).catch(() => {
|
|
2122
2143
|
ee.textContent = "Draft could not be saved. Keep this tab open.";
|
|
2123
2144
|
}), ye;
|
|
2124
2145
|
}
|
|
2125
|
-
function
|
|
2126
|
-
clearTimeout(
|
|
2146
|
+
function Ee() {
|
|
2147
|
+
clearTimeout(V), V = setTimeout(te, 250);
|
|
2127
2148
|
}
|
|
2128
|
-
|
|
2149
|
+
N.addEventListener("input", Ee), N.addEventListener("change", Ee);
|
|
2129
2150
|
const Ve = () => {
|
|
2130
2151
|
te();
|
|
2131
2152
|
};
|
|
2132
2153
|
window.addEventListener("pagehide", Ve);
|
|
2133
2154
|
function Oe() {
|
|
2134
|
-
|
|
2155
|
+
f.filter((o) => o.status === "failed").forEach(Le);
|
|
2135
2156
|
}
|
|
2136
|
-
window.addEventListener("online", Oe), r.drafts !== !1 && (
|
|
2137
|
-
Ie || !
|
|
2138
|
-
A.value =
|
|
2139
|
-
for (const c of (
|
|
2157
|
+
window.addEventListener("online", Oe), r.drafts !== !1 && (N.inert = !0, va(ze).then((o) => {
|
|
2158
|
+
Ie || !o || (ee.innerHTML = 'Unfinished report on this device. <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>', ee.querySelector("[data-resume]").onclick = () => {
|
|
2159
|
+
A.value = o.title || "", S("#bc-desc").value = o.description || "", y = on.some((c) => c.value === o.priority) ? o.priority : "MEDIUM", g.querySelectorAll("[data-prio]").forEach((c) => c.setAttribute("aria-pressed", String(c.dataset.prio === y)));
|
|
2160
|
+
for (const c of (o.items || []).slice(0, r.maxAttachments ?? 5)) ve(c);
|
|
2140
2161
|
be = !0, te();
|
|
2141
2162
|
}, ee.querySelector("[data-discard]").onclick = () => {
|
|
2142
2163
|
be = !0, te();
|
|
@@ -2144,368 +2165,368 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2144
2165
|
}).catch(() => {
|
|
2145
2166
|
ee.textContent = "Draft storage is unavailable. Keep this tab open.";
|
|
2146
2167
|
}).finally(() => {
|
|
2147
|
-
|
|
2168
|
+
N.inert = !1, ee.querySelector("[data-resume]") || (be = !0);
|
|
2148
2169
|
}));
|
|
2149
|
-
const fe = document.activeElement, Te = document.documentElement.style,
|
|
2170
|
+
const fe = document.activeElement, Te = document.documentElement.style, lt = Te.overflow;
|
|
2150
2171
|
Te.overflow = "hidden";
|
|
2151
2172
|
let Ie = !1, we = null;
|
|
2152
2173
|
function He() {
|
|
2153
|
-
var
|
|
2154
|
-
Ie || (te(), Ie = !0, clearTimeout(
|
|
2174
|
+
var o;
|
|
2175
|
+
Ie || (te(), Ie = !0, clearTimeout(V), window.removeEventListener("pagehide", Ve), window.removeEventListener("online", Oe), h == null || h.cancel(), we == null || we(), f.forEach((c) => c.previewUrl && URL.revokeObjectURL(c.previewUrl)), Te.overflow = lt, document.removeEventListener("keydown", Me, !0), g.remove(), (o = t.querySelector(".recbar")) == null || o.remove(), n.hidden = !1, e.style.opacity = "", i == null || i());
|
|
2155
2176
|
}
|
|
2156
2177
|
function re() {
|
|
2157
|
-
var
|
|
2178
|
+
var o;
|
|
2158
2179
|
if (!Ie) {
|
|
2159
|
-
|
|
2180
|
+
g.classList.add("closing"), setTimeout(He, 160);
|
|
2160
2181
|
try {
|
|
2161
|
-
(
|
|
2182
|
+
(o = fe == null ? void 0 : fe.focus) == null || o.call(fe);
|
|
2162
2183
|
} catch {
|
|
2163
2184
|
}
|
|
2164
2185
|
}
|
|
2165
2186
|
}
|
|
2166
|
-
function Me(
|
|
2167
|
-
if (
|
|
2168
|
-
if (
|
|
2187
|
+
function Me(o) {
|
|
2188
|
+
if (o.key === "Escape") {
|
|
2189
|
+
if (o.stopPropagation(), h) {
|
|
2169
2190
|
Be({ keep: !1 });
|
|
2170
2191
|
return;
|
|
2171
2192
|
}
|
|
2172
2193
|
b || re();
|
|
2173
2194
|
return;
|
|
2174
2195
|
}
|
|
2175
|
-
if (
|
|
2176
|
-
const c = [...
|
|
2196
|
+
if (o.key !== "Tab" || h) return;
|
|
2197
|
+
const c = [...g.querySelectorAll(
|
|
2177
2198
|
"button:not(:disabled), input:not([hidden]), textarea, select, [href]"
|
|
2178
|
-
)].filter((
|
|
2199
|
+
)].filter((w) => w.offsetParent !== null || w === document.activeElement);
|
|
2179
2200
|
if (!c.length) return;
|
|
2180
|
-
const
|
|
2181
|
-
|
|
2182
|
-
}
|
|
2183
|
-
document.addEventListener("keydown", Me, !0),
|
|
2184
|
-
|
|
2185
|
-
}),
|
|
2186
|
-
|
|
2187
|
-
y =
|
|
2188
|
-
c.setAttribute("aria-pressed", String(c ===
|
|
2201
|
+
const u = c[0], d = c[c.length - 1], x = g.getRootNode().activeElement;
|
|
2202
|
+
o.shiftKey && x === u ? (o.preventDefault(), d.focus()) : !o.shiftKey && x === d && (o.preventDefault(), u.focus());
|
|
2203
|
+
}
|
|
2204
|
+
document.addEventListener("keydown", Me, !0), g.addEventListener("click", (o) => {
|
|
2205
|
+
o.target === g && !b && re();
|
|
2206
|
+
}), S('[data-act="close"]').addEventListener("click", re), S('[data-act="cancel"]').addEventListener("click", re), g.querySelectorAll("[data-prio]").forEach((o) => {
|
|
2207
|
+
o.addEventListener("click", () => {
|
|
2208
|
+
y = o.dataset.prio, Ee(), g.querySelectorAll("[data-prio]").forEach((c) => {
|
|
2209
|
+
c.setAttribute("aria-pressed", String(c === o));
|
|
2189
2210
|
});
|
|
2190
2211
|
});
|
|
2191
2212
|
});
|
|
2192
|
-
function
|
|
2193
|
-
|
|
2213
|
+
function H(o, c = "err") {
|
|
2214
|
+
ae.innerHTML = o ? `<div class="msg ${c}">${k(o)}</div>` : "";
|
|
2194
2215
|
}
|
|
2195
2216
|
function ce() {
|
|
2196
|
-
const
|
|
2197
|
-
T.disabled = b ||
|
|
2198
|
-
c.disabled = b ||
|
|
2217
|
+
const o = f.some((c) => c.status === "uploading");
|
|
2218
|
+
T.disabled = b || o || f.some((c) => c.status === "failed"), Y.textContent = o ? "Waiting for the upload to finish…" : f.some((c) => c.status === "failed") ? "Retry or remove failed attachments before sending." : "", g.querySelectorAll(".tool").forEach((c) => {
|
|
2219
|
+
c.disabled = b || f.length >= (r.maxAttachments ?? 5);
|
|
2199
2220
|
});
|
|
2200
2221
|
}
|
|
2201
|
-
function Ke(
|
|
2202
|
-
var
|
|
2203
|
-
const c =
|
|
2204
|
-
let
|
|
2205
|
-
|
|
2206
|
-
${
|
|
2207
|
-
<span class="kind">${
|
|
2208
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${
|
|
2209
|
-
${
|
|
2210
|
-
}
|
|
2211
|
-
function
|
|
2212
|
-
const c =
|
|
2213
|
-
c >= 0 &&
|
|
2214
|
-
}
|
|
2215
|
-
async function Le(
|
|
2216
|
-
|
|
2222
|
+
function Ke(o) {
|
|
2223
|
+
var w;
|
|
2224
|
+
const c = o.el, u = o.kind === "VIDEO" ? "Video" : "Shot", d = o.kind === "VIDEO" ? `<video src="${o.previewUrl}" muted playsinline preload="metadata"></video>` : `<img src="${o.previewUrl}" alt="" />`;
|
|
2225
|
+
let x = "";
|
|
2226
|
+
o.status === "uploading" ? x = `<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(o.progress * 100)}%"></i></div></div>` : o.status === "failed" && (x = `<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${O.retry}</button>Failed</div>`), c.innerHTML = `
|
|
2227
|
+
${d}
|
|
2228
|
+
<span class="kind">${u} · ${je(o.size)}</span>
|
|
2229
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${u.toLowerCase()}">${O.close}</button>
|
|
2230
|
+
${x}`, c.querySelector('[data-act="drop"]').addEventListener("click", () => dt(o)), (w = c.querySelector('[data-act="retry"]')) == null || w.addEventListener("click", () => Le(o));
|
|
2231
|
+
}
|
|
2232
|
+
function dt(o) {
|
|
2233
|
+
const c = f.indexOf(o);
|
|
2234
|
+
c >= 0 && f.splice(c, 1), o.previewUrl && URL.revokeObjectURL(o.previewUrl), o.el.remove(), te(), ce();
|
|
2235
|
+
}
|
|
2236
|
+
async function Le(o) {
|
|
2237
|
+
o.status = "uploading", o.progress = 0, Ke(o), ce();
|
|
2217
2238
|
try {
|
|
2218
|
-
const { storageKey: c, mime:
|
|
2219
|
-
|
|
2220
|
-
const
|
|
2221
|
-
|
|
2239
|
+
const { storageKey: c, mime: u } = await a.uploadAttachment(o.blob, o.mime, (d) => {
|
|
2240
|
+
o.progress = d;
|
|
2241
|
+
const x = o.el.querySelector(".bar i");
|
|
2242
|
+
x && (x.style.width = `${Math.round(d * 100)}%`);
|
|
2222
2243
|
});
|
|
2223
|
-
|
|
2244
|
+
o.storageKey = c, o.mime = u, o.status = "ready";
|
|
2224
2245
|
} catch (c) {
|
|
2225
|
-
|
|
2246
|
+
o.status = "failed", H(c.message.replace("[BugCatch] ", ""));
|
|
2226
2247
|
}
|
|
2227
|
-
Ke(
|
|
2248
|
+
Ke(o), ce();
|
|
2228
2249
|
}
|
|
2229
|
-
function ve({ blob:
|
|
2230
|
-
const
|
|
2231
|
-
if (
|
|
2232
|
-
|
|
2250
|
+
function ve({ blob: o, mime: c, kind: u }) {
|
|
2251
|
+
const d = r.maxAttachmentBytes ?? 26214400;
|
|
2252
|
+
if (o.size > d) {
|
|
2253
|
+
H(`That file is ${je(o.size)} — the limit is ${je(d)}.`);
|
|
2233
2254
|
return;
|
|
2234
2255
|
}
|
|
2235
|
-
const
|
|
2236
|
-
if (!
|
|
2237
|
-
|
|
2256
|
+
const x = nt(c || o.type, tt);
|
|
2257
|
+
if (!x) {
|
|
2258
|
+
H("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");
|
|
2238
2259
|
return;
|
|
2239
2260
|
}
|
|
2240
|
-
const
|
|
2241
|
-
blob:
|
|
2242
|
-
kind:
|
|
2243
|
-
mime:
|
|
2244
|
-
size:
|
|
2245
|
-
previewUrl: URL.createObjectURL(
|
|
2261
|
+
const w = {
|
|
2262
|
+
blob: o,
|
|
2263
|
+
kind: u,
|
|
2264
|
+
mime: x,
|
|
2265
|
+
size: o.size,
|
|
2266
|
+
previewUrl: URL.createObjectURL(o),
|
|
2246
2267
|
status: "uploading",
|
|
2247
2268
|
progress: 0,
|
|
2248
2269
|
storageKey: null,
|
|
2249
2270
|
el: document.createElement("div")
|
|
2250
2271
|
};
|
|
2251
|
-
|
|
2272
|
+
w.el.className = "thumb", f.push(w), C.appendChild(w.el), H(""), te(), Le(w);
|
|
2252
2273
|
}
|
|
2253
|
-
async function
|
|
2274
|
+
async function ut(o) {
|
|
2254
2275
|
e.style.opacity = "0", e.style.pointerEvents = "none", await new Promise((c) => requestAnimationFrame(() => requestAnimationFrame(c)));
|
|
2255
2276
|
try {
|
|
2256
|
-
return await
|
|
2277
|
+
return await o();
|
|
2257
2278
|
} finally {
|
|
2258
2279
|
e.style.opacity = "", e.style.pointerEvents = "";
|
|
2259
2280
|
}
|
|
2260
2281
|
}
|
|
2261
|
-
(
|
|
2282
|
+
(Vt = g.querySelector('[data-act="shot"]')) == null || Vt.addEventListener("click", async () => {
|
|
2262
2283
|
try {
|
|
2263
|
-
const
|
|
2264
|
-
ve(
|
|
2265
|
-
} catch (
|
|
2266
|
-
(
|
|
2284
|
+
const o = await ut(pa);
|
|
2285
|
+
ve(o);
|
|
2286
|
+
} catch (o) {
|
|
2287
|
+
(o == null ? void 0 : o.name) !== "NotAllowedError" && H(`Screenshot failed: ${o.message}`);
|
|
2267
2288
|
}
|
|
2268
|
-
}), (
|
|
2269
|
-
const
|
|
2270
|
-
[
|
|
2289
|
+
}), (Kt = g.querySelector('[data-act="file"]')) == null || Kt.addEventListener("click", () => $.click()), $ == null || $.addEventListener("change", () => {
|
|
2290
|
+
const o = (r.maxAttachments ?? 5) - f.length;
|
|
2291
|
+
[...$.files].slice(0, Math.max(o, 0)).forEach((c) => {
|
|
2271
2292
|
ve({
|
|
2272
2293
|
blob: c,
|
|
2273
2294
|
mime: c.type,
|
|
2274
2295
|
kind: c.type.startsWith("video/") ? "VIDEO" : "SCREENSHOT"
|
|
2275
2296
|
});
|
|
2276
|
-
}),
|
|
2277
|
-
}), (
|
|
2278
|
-
const
|
|
2297
|
+
}), $.value = "";
|
|
2298
|
+
}), (Pt = g.querySelector('[data-act="rec"]')) == null || Pt.addEventListener("click", async () => {
|
|
2299
|
+
const o = r.maxRecordingMs ?? 12e4;
|
|
2279
2300
|
let c;
|
|
2280
2301
|
try {
|
|
2281
|
-
|
|
2282
|
-
maxMs:
|
|
2283
|
-
onTick: (
|
|
2284
|
-
c && (c.querySelector(".time").textContent =
|
|
2302
|
+
h = await ha({
|
|
2303
|
+
maxMs: o,
|
|
2304
|
+
onTick: (u) => {
|
|
2305
|
+
c && (c.querySelector(".time").textContent = Ye(u));
|
|
2285
2306
|
},
|
|
2286
2307
|
onAutoStop: () => {
|
|
2287
|
-
|
|
2308
|
+
h && Be({ keep: !0 });
|
|
2288
2309
|
}
|
|
2289
2310
|
});
|
|
2290
|
-
} catch (
|
|
2291
|
-
(
|
|
2311
|
+
} catch (u) {
|
|
2312
|
+
(u == null ? void 0 : u.name) !== "NotAllowedError" && H(`Recording failed: ${u.message}`);
|
|
2292
2313
|
return;
|
|
2293
2314
|
}
|
|
2294
|
-
|
|
2315
|
+
g.style.display = "none", n.hidden = !0, c = document.createElement("div"), c.className = "recbar", c.innerHTML = `
|
|
2295
2316
|
<span class="dot"></span>
|
|
2296
2317
|
<span class="time">0:00</span>
|
|
2297
|
-
<span class="hint">Recording — up to ${
|
|
2318
|
+
<span class="hint">Recording — up to ${Ye(Math.round(o / 1e3))}</span>
|
|
2298
2319
|
<button class="stop" type="button">Stop</button>
|
|
2299
2320
|
<button class="ghost" type="button">Discard</button>`, c.querySelector(".stop").addEventListener("click", () => Be({ keep: !0 })), c.querySelector(".ghost").addEventListener("click", () => Be({ keep: !1 })), t.appendChild(c), c.querySelector(".stop").focus();
|
|
2300
2321
|
});
|
|
2301
|
-
async function Be({ keep:
|
|
2302
|
-
var
|
|
2303
|
-
const c =
|
|
2322
|
+
async function Be({ keep: o }) {
|
|
2323
|
+
var u;
|
|
2324
|
+
const c = h;
|
|
2304
2325
|
if (c) {
|
|
2305
|
-
if (
|
|
2326
|
+
if (h = null, (u = t.querySelector(".recbar")) == null || u.remove(), g.style.display = "", n.hidden = !1, !o) {
|
|
2306
2327
|
c.cancel(), A.focus();
|
|
2307
2328
|
return;
|
|
2308
2329
|
}
|
|
2309
2330
|
try {
|
|
2310
|
-
const
|
|
2311
|
-
|
|
2312
|
-
} catch (
|
|
2313
|
-
|
|
2331
|
+
const d = await c.stop();
|
|
2332
|
+
d.blob.size ? ve(d) : H("That recording came back empty — nothing was captured.");
|
|
2333
|
+
} catch (d) {
|
|
2334
|
+
H(`Recording failed: ${d.message}`);
|
|
2314
2335
|
}
|
|
2315
2336
|
A.focus();
|
|
2316
2337
|
}
|
|
2317
2338
|
}
|
|
2318
|
-
let m = { policy: "off", fields: [] },
|
|
2319
|
-
|
|
2320
|
-
m =
|
|
2339
|
+
let m = { policy: "off", fields: [] }, v = null, I = "", _ = "", F = !1, xe = !1;
|
|
2340
|
+
a.referenceFields().then((o) => {
|
|
2341
|
+
m = o;
|
|
2321
2342
|
}).catch(() => {
|
|
2322
2343
|
});
|
|
2323
2344
|
function Pe() {
|
|
2324
|
-
return m.policy === "off" || !m.fields.length ? [] :
|
|
2345
|
+
return m.policy === "off" || !m.fields.length ? [] : eo(m.fields, [A.value, S("#bc-desc").value]);
|
|
2325
2346
|
}
|
|
2326
2347
|
function ke() {
|
|
2327
|
-
return !
|
|
2348
|
+
return !v || !I.trim() ? [] : [{ key: v, value: I.trim().slice(0, 120) }];
|
|
2328
2349
|
}
|
|
2329
2350
|
function pe() {
|
|
2330
|
-
var
|
|
2331
|
-
if (!
|
|
2332
|
-
|
|
2351
|
+
var d, x;
|
|
2352
|
+
if (!v) {
|
|
2353
|
+
U.hidden = !0, U.innerHTML = "";
|
|
2333
2354
|
return;
|
|
2334
2355
|
}
|
|
2335
|
-
const
|
|
2336
|
-
|
|
2337
|
-
<p class="why">${
|
|
2356
|
+
const o = m.fields.find((w) => w.key === v) || m.fields[0], c = m.policy !== "required";
|
|
2357
|
+
U.hidden = !1, U.innerHTML = `
|
|
2358
|
+
<p class="why">${k(
|
|
2338
2359
|
c ? "One more thing, so we can find your record — this helps us answer faster." : "We need one of these to look this up."
|
|
2339
2360
|
)}</p>
|
|
2340
2361
|
<div class="row">
|
|
2341
2362
|
${m.fields.length > 1 ? `
|
|
2342
2363
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
2343
|
-
${m.fields.map((
|
|
2344
|
-
<option value="${
|
|
2364
|
+
${m.fields.map((w) => `
|
|
2365
|
+
<option value="${k(w.key)}" ${w.key === o.key ? "selected" : ""}>${k(w.label)}</option>
|
|
2345
2366
|
`).join("")}
|
|
2346
2367
|
</select>` : ""}
|
|
2347
|
-
<input class="ref-value" type="${
|
|
2348
|
-
inputmode="${
|
|
2349
|
-
value="${
|
|
2350
|
-
placeholder="${
|
|
2351
|
-
aria-label="${
|
|
2368
|
+
<input class="ref-value" type="${o.inputMode === "email" ? "email" : "text"}"
|
|
2369
|
+
inputmode="${k(o.inputMode === "numeric" || o.inputMode === "tel" ? "numeric" : "text")}"
|
|
2370
|
+
value="${k(I)}"
|
|
2371
|
+
placeholder="${k(o.placeholder || "")}"
|
|
2372
|
+
aria-label="${k(o.label)}" />
|
|
2352
2373
|
</div>
|
|
2353
|
-
${
|
|
2354
|
-
${
|
|
2374
|
+
${o.hint ? `<p class="hint">${k(o.hint)}</p>` : ""}
|
|
2375
|
+
${_ ? `<p class="after err">${k(_)}</p>` : ""}
|
|
2355
2376
|
${c ? `<button type="button" class="link" data-act="ref-skip">I don't have this</button>` : ""}`;
|
|
2356
|
-
const
|
|
2357
|
-
|
|
2358
|
-
I =
|
|
2359
|
-
}),
|
|
2360
|
-
|
|
2361
|
-
}), (
|
|
2362
|
-
var
|
|
2363
|
-
|
|
2364
|
-
}), (
|
|
2365
|
-
|
|
2366
|
-
}),
|
|
2377
|
+
const u = U.querySelector(".ref-value");
|
|
2378
|
+
u.addEventListener("input", () => {
|
|
2379
|
+
I = u.value, _ = "", xe = !1;
|
|
2380
|
+
}), u.addEventListener("keydown", (w) => {
|
|
2381
|
+
w.key === "Enter" && (w.preventDefault(), T.click());
|
|
2382
|
+
}), (d = U.querySelector(".ref-kind")) == null || d.addEventListener("change", (w) => {
|
|
2383
|
+
var j;
|
|
2384
|
+
v = w.target.value, _ = "", pe(), (j = U.querySelector(".ref-value")) == null || j.focus();
|
|
2385
|
+
}), (x = U.querySelector('[data-act="ref-skip"]')) == null || x.addEventListener("click", () => {
|
|
2386
|
+
F = !0, v = null, I = "", _ = "", xe = !1, pe(), H("");
|
|
2387
|
+
}), u.focus();
|
|
2367
2388
|
}
|
|
2368
|
-
function
|
|
2369
|
-
return m.policy === "off" || !m.fields.length || Pe().length || ke().length ? !1 : !
|
|
2389
|
+
function Hn() {
|
|
2390
|
+
return m.policy === "off" || !m.fields.length || Pe().length || ke().length ? !1 : !F || m.policy === "required";
|
|
2370
2391
|
}
|
|
2371
2392
|
T.addEventListener("click", async () => {
|
|
2372
|
-
const
|
|
2373
|
-
if (!
|
|
2374
|
-
|
|
2393
|
+
const o = A.value;
|
|
2394
|
+
if (!o.trim()) {
|
|
2395
|
+
H("Please describe what went wrong."), A.classList.add("invalid"), A.focus(), setTimeout(() => A.classList.remove("invalid"), 500);
|
|
2375
2396
|
return;
|
|
2376
2397
|
}
|
|
2377
|
-
if (
|
|
2378
|
-
|
|
2398
|
+
if (Hn()) {
|
|
2399
|
+
v = v || m.fields[0].key, pe(), H("");
|
|
2379
2400
|
return;
|
|
2380
2401
|
}
|
|
2381
|
-
if (
|
|
2382
|
-
const
|
|
2383
|
-
if (!xe &&
|
|
2384
|
-
|
|
2402
|
+
if (v && I.trim()) {
|
|
2403
|
+
const u = m.fields.find((d) => d.key === v);
|
|
2404
|
+
if (!xe && u && !to(u, I)) {
|
|
2405
|
+
_ = `That does not look like a ${u.label.toLowerCase()}. Press Send again to use it anyway.`, xe = !0, pe();
|
|
2385
2406
|
return;
|
|
2386
2407
|
}
|
|
2387
2408
|
}
|
|
2388
|
-
b = !0,
|
|
2409
|
+
b = !0, H(""), ce();
|
|
2389
2410
|
const c = T.innerHTML;
|
|
2390
2411
|
T.innerHTML = '<span class="spinner"></span>Sending…';
|
|
2391
2412
|
try {
|
|
2392
|
-
const
|
|
2393
|
-
title:
|
|
2394
|
-
description:
|
|
2413
|
+
const u = await a.report({
|
|
2414
|
+
title: o,
|
|
2415
|
+
description: S("#bc-desc").value,
|
|
2395
2416
|
priority: y,
|
|
2396
2417
|
references: ke(),
|
|
2397
|
-
attachments:
|
|
2418
|
+
attachments: f.filter((d) => d.status === "ready").map((d) => ({ type: d.kind, storageKey: d.storageKey, mime: d.mime }))
|
|
2398
2419
|
});
|
|
2399
|
-
if (
|
|
2420
|
+
if (u != null && u.cancelled) {
|
|
2400
2421
|
b = !1, T.innerHTML = c, ce();
|
|
2401
2422
|
return;
|
|
2402
2423
|
}
|
|
2403
|
-
Ue = !0, clearTimeout(
|
|
2404
|
-
}),
|
|
2405
|
-
} catch (
|
|
2406
|
-
b = !1, T.innerHTML = c,
|
|
2424
|
+
Ue = !0, clearTimeout(V), await ye, r.drafts !== !1 && await at(ze, null).catch(() => {
|
|
2425
|
+
}), zt(u);
|
|
2426
|
+
} catch (u) {
|
|
2427
|
+
b = !1, T.innerHTML = c, H(u.message.replace("[BugCatch] ", "")), ce(), X.mode !== "off" && gt().catch(() => {
|
|
2407
2428
|
});
|
|
2408
2429
|
}
|
|
2409
|
-
}), (
|
|
2410
|
-
let Ae = [], _e = "",
|
|
2411
|
-
function
|
|
2412
|
-
r.knownIssues !== !1 &&
|
|
2413
|
-
Ae =
|
|
2430
|
+
}), (_t = g.querySelector('[data-act="history"]')) == null || _t.addEventListener("click", Ht);
|
|
2431
|
+
let Ae = [], _e = "", pt = null, qe = null;
|
|
2432
|
+
function Bt() {
|
|
2433
|
+
r.knownIssues !== !1 && a.knownIssues().then((o) => {
|
|
2434
|
+
Ae = o, De();
|
|
2414
2435
|
}).catch(() => {
|
|
2415
2436
|
});
|
|
2416
2437
|
}
|
|
2417
|
-
let
|
|
2418
|
-
function
|
|
2438
|
+
let At = null;
|
|
2439
|
+
function qn(o) {
|
|
2419
2440
|
if (r.knownIssues === !1) return;
|
|
2420
|
-
clearTimeout(
|
|
2421
|
-
const c = (
|
|
2441
|
+
clearTimeout(At), qe == null || qe.abort();
|
|
2442
|
+
const c = (o || "").trim();
|
|
2422
2443
|
if (c.length < 3) {
|
|
2423
|
-
|
|
2444
|
+
Bt();
|
|
2424
2445
|
return;
|
|
2425
2446
|
}
|
|
2426
|
-
|
|
2427
|
-
qe = new AbortController(),
|
|
2428
|
-
|
|
2447
|
+
At = setTimeout(() => {
|
|
2448
|
+
qe = new AbortController(), a.matchKnownIssues(c, { signal: qe.signal }).then((u) => {
|
|
2449
|
+
u.length && (Ae = u, De());
|
|
2429
2450
|
}).catch(() => {
|
|
2430
2451
|
});
|
|
2431
2452
|
}, 250);
|
|
2432
2453
|
}
|
|
2433
2454
|
function De() {
|
|
2434
2455
|
if (!Ae.length) {
|
|
2435
|
-
|
|
2456
|
+
E.hidden = !0, E.innerHTML = "";
|
|
2436
2457
|
return;
|
|
2437
2458
|
}
|
|
2438
|
-
|
|
2459
|
+
E.hidden = !1, E.innerHTML = `
|
|
2439
2460
|
<p class="known-h">Already reported</p>
|
|
2440
|
-
${Ae.map((
|
|
2441
|
-
<div class="issue ${
|
|
2461
|
+
${Ae.map((o) => `
|
|
2462
|
+
<div class="issue ${o.joined ? "is-joined" : ""}">
|
|
2442
2463
|
<span class="who">
|
|
2443
|
-
<span class="t">${
|
|
2444
|
-
<span class="meta">${
|
|
2464
|
+
<span class="t">${k(o.title)}</span>
|
|
2465
|
+
<span class="meta">${k(Dn(o))}</span>
|
|
2445
2466
|
</span>
|
|
2446
|
-
<button class="join" type="button" data-join="${
|
|
2447
|
-
${
|
|
2467
|
+
<button class="join" type="button" data-join="${k(o.id)}"
|
|
2468
|
+
${o.joined ? "disabled" : ""}>${o.joined ? "Following" : "Me too"}</button>
|
|
2448
2469
|
</div>
|
|
2449
|
-
${
|
|
2470
|
+
${pt === o.id ? `
|
|
2450
2471
|
<div class="ask">
|
|
2451
2472
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
2452
2473
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
2453
|
-
<button class="ghost" type="button" data-join-confirm="${
|
|
2474
|
+
<button class="ghost" type="button" data-join-confirm="${k(o.id)}">Follow</button>
|
|
2454
2475
|
</div>` : ""}
|
|
2455
2476
|
`).join("")}
|
|
2456
|
-
${_e ? `<p class="err">${
|
|
2477
|
+
${_e ? `<p class="err">${k(_e)}</p>` : ""}`;
|
|
2457
2478
|
}
|
|
2458
|
-
function
|
|
2459
|
-
const c =
|
|
2460
|
-
return `${c} · reported ${
|
|
2479
|
+
function Dn(o) {
|
|
2480
|
+
const c = o.status === "IN_PROGRESS" ? "Being worked on now" : "Not fixed yet", u = o.affectedCount === 0 ? "" : ` · ${o.affectedCount} ${o.affectedCount === 1 ? "person has" : "people have"} said this is happening to them`;
|
|
2481
|
+
return `${c} · reported ${rt(o.since)}${u}`;
|
|
2461
2482
|
}
|
|
2462
|
-
|
|
2463
|
-
var
|
|
2464
|
-
const c =
|
|
2465
|
-
if (!c && !
|
|
2466
|
-
const
|
|
2483
|
+
E.addEventListener("click", async (o) => {
|
|
2484
|
+
var w, j, z, q, G;
|
|
2485
|
+
const c = o.target.closest("[data-join]"), u = o.target.closest("[data-join-confirm]");
|
|
2486
|
+
if (!c && !u) return;
|
|
2487
|
+
const d = (u || c).getAttribute(u ? "data-join-confirm" : "data-join");
|
|
2467
2488
|
_e = "";
|
|
2468
|
-
const
|
|
2469
|
-
if (!
|
|
2470
|
-
|
|
2489
|
+
const x = ((j = (w = E.querySelector(".join-email")) == null ? void 0 : w.value) == null ? void 0 : j.trim()) || ((z = a.signedInAs()) == null ? void 0 : z.email) || ((q = a.config.user) == null ? void 0 : q.email);
|
|
2490
|
+
if (!x) {
|
|
2491
|
+
pt = d, De(), (G = E.querySelector(".join-email")) == null || G.focus();
|
|
2471
2492
|
return;
|
|
2472
2493
|
}
|
|
2473
2494
|
try {
|
|
2474
|
-
const de = await
|
|
2475
|
-
|
|
2495
|
+
const de = await a.meToo(d, { email: x });
|
|
2496
|
+
pt = null, Ae = Ae.map((K) => K.id === d ? { ...K, joined: !0, affectedCount: de.affectedCount ?? K.affectedCount } : K), De();
|
|
2476
2497
|
} catch (de) {
|
|
2477
2498
|
_e = de.message.replace("[BugCatch] ", ""), De();
|
|
2478
2499
|
}
|
|
2479
|
-
}),
|
|
2480
|
-
let
|
|
2481
|
-
function
|
|
2482
|
-
|
|
2483
|
-
|
|
2500
|
+
}), Bt(), A.addEventListener("input", () => qn(A.value));
|
|
2501
|
+
let Rt = !1;
|
|
2502
|
+
function Qt() {
|
|
2503
|
+
a.callKind().then((o) => {
|
|
2504
|
+
o && (Rt = !0, L.hidden = ht());
|
|
2484
2505
|
}).catch(() => {
|
|
2485
2506
|
});
|
|
2486
2507
|
}
|
|
2487
|
-
|
|
2488
|
-
let X = { mode:
|
|
2489
|
-
const
|
|
2490
|
-
function
|
|
2491
|
-
const
|
|
2492
|
-
|
|
2508
|
+
Qt();
|
|
2509
|
+
let X = { mode: a.lastLoginMode || "off", signedIn: null }, Z = "idle", Re = ((Ft = a.config.user) == null ? void 0 : Ft.email) || "", Qe = "", J = !1, le = "";
|
|
2510
|
+
const ht = () => X.mode === "required" && !X.signedIn;
|
|
2511
|
+
function Nn() {
|
|
2512
|
+
const o = ht();
|
|
2513
|
+
N.hidden = o, T.hidden = o, oe && (oe.hidden = o), o ? L.hidden = !0 : Rt && (L.hidden = !1);
|
|
2493
2514
|
}
|
|
2494
|
-
function
|
|
2515
|
+
function Un() {
|
|
2495
2516
|
var c;
|
|
2496
2517
|
if (X.mode === "off") {
|
|
2497
2518
|
Q.hidden = !0, Q.innerHTML = "";
|
|
2498
2519
|
return;
|
|
2499
2520
|
}
|
|
2500
2521
|
Q.hidden = !1, Q.classList.toggle("asking", Z !== "idle");
|
|
2501
|
-
const
|
|
2522
|
+
const o = le ? `<div class="after err">${k(le)}</div>` : "";
|
|
2502
2523
|
if (Z === "idle") {
|
|
2503
2524
|
if (X.signedIn) {
|
|
2504
|
-
Q.innerHTML = `<span class="who">Signed in as <strong>${
|
|
2525
|
+
Q.innerHTML = `<span class="who">Signed in as <strong>${k(X.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;
|
|
2505
2526
|
return;
|
|
2506
2527
|
}
|
|
2507
|
-
const
|
|
2508
|
-
Q.innerHTML = `<span class="who">${X.mode === "required" ? "Sign in to report a bug here." :
|
|
2528
|
+
const u = (c = a.config.user) == null ? void 0 : c.email;
|
|
2529
|
+
Q.innerHTML = `<span class="who">${X.mode === "required" ? "Sign in to report a bug here." : u ? `Reporting as <strong>${k(u)}</strong>.` : "Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;
|
|
2509
2530
|
return;
|
|
2510
2531
|
}
|
|
2511
2532
|
if (Z === "email") {
|
|
@@ -2513,46 +2534,46 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2513
2534
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
2514
2535
|
It's how you hear back about this report${X.mode === "required" ? ", and this project asks for it" : ""}.</p>
|
|
2515
2536
|
<div class="row">
|
|
2516
|
-
<input type="email" data-fld="email" value="${
|
|
2537
|
+
<input type="email" data-fld="email" value="${k(Re)}"
|
|
2517
2538
|
placeholder="you@example.com" autocomplete="email" spellcheck="false"
|
|
2518
2539
|
aria-label="Your email address" ${J ? "disabled" : ""} />
|
|
2519
2540
|
<button type="button" class="tool" data-act="code" ${J ? "disabled" : ""}>
|
|
2520
2541
|
${J ? "Sending…" : "Send code"}
|
|
2521
2542
|
</button>
|
|
2522
2543
|
</div>
|
|
2523
|
-
${
|
|
2544
|
+
${o}
|
|
2524
2545
|
${X.mode === "optional" ? '<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>' : ""}`;
|
|
2525
2546
|
return;
|
|
2526
2547
|
}
|
|
2527
2548
|
Q.innerHTML = `
|
|
2528
|
-
<p class="why">We sent a code to <strong>${
|
|
2549
|
+
<p class="why">We sent a code to <strong>${k(Re)}</strong>. It expires in ten minutes.</p>
|
|
2529
2550
|
<div class="row">
|
|
2530
|
-
<input type="text" class="code" data-fld="code" value="${
|
|
2551
|
+
<input type="text" class="code" data-fld="code" value="${k(Qe)}"
|
|
2531
2552
|
placeholder="123456" inputmode="numeric" autocomplete="one-time-code"
|
|
2532
2553
|
maxlength="8" aria-label="The code we emailed you" ${J ? "disabled" : ""} />
|
|
2533
2554
|
<button type="button" class="tool" data-act="confirm" ${J ? "disabled" : ""}>
|
|
2534
2555
|
${J ? "Checking…" : "Sign in"}
|
|
2535
2556
|
</button>
|
|
2536
2557
|
</div>
|
|
2537
|
-
${
|
|
2558
|
+
${o}
|
|
2538
2559
|
<div class="after">
|
|
2539
2560
|
<button type="button" class="link" data-act="resend" ${J ? "disabled" : ""}>Send it again</button>
|
|
2540
2561
|
<button type="button" class="link" data-act="signin-back" ${J ? "disabled" : ""}>Use another address</button>
|
|
2541
2562
|
</div>`;
|
|
2542
2563
|
}
|
|
2543
|
-
function ie({ focus:
|
|
2544
|
-
var
|
|
2545
|
-
if (
|
|
2564
|
+
function ie({ focus: o = !1 } = {}) {
|
|
2565
|
+
var u;
|
|
2566
|
+
if (Un(), Nn(), !o || J) return;
|
|
2546
2567
|
const c = Q.querySelector("[data-fld]");
|
|
2547
|
-
c && (c.focus(), (
|
|
2568
|
+
c && (c.focus(), (u = c.setSelectionRange) == null || u.call(c, c.value.length, c.value.length));
|
|
2548
2569
|
}
|
|
2549
|
-
Q.addEventListener("input", (
|
|
2550
|
-
const c =
|
|
2570
|
+
Q.addEventListener("input", (o) => {
|
|
2571
|
+
const c = o.target.closest("[data-fld]");
|
|
2551
2572
|
c && (c.dataset.fld === "email" ? Re = c.value : Qe = c.value);
|
|
2552
|
-
}), Q.addEventListener("keydown", (
|
|
2553
|
-
|
|
2573
|
+
}), Q.addEventListener("keydown", (o) => {
|
|
2574
|
+
o.key !== "Enter" || !o.target.closest("[data-fld]") || (o.preventDefault(), Z === "email" ? ft() : jt());
|
|
2554
2575
|
});
|
|
2555
|
-
async function
|
|
2576
|
+
async function ft({ resent: o = !1 } = {}) {
|
|
2556
2577
|
const c = Re.trim();
|
|
2557
2578
|
if (!c) {
|
|
2558
2579
|
le = "Enter the address to send the code to.", ie({ focus: !0 });
|
|
@@ -2560,83 +2581,83 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2560
2581
|
}
|
|
2561
2582
|
J = !0, le = "", ie();
|
|
2562
2583
|
try {
|
|
2563
|
-
await
|
|
2564
|
-
} catch (
|
|
2565
|
-
le =
|
|
2584
|
+
await a.signIn(c), Re = c, o || (Qe = ""), Z = "code";
|
|
2585
|
+
} catch (u) {
|
|
2586
|
+
le = u.message;
|
|
2566
2587
|
} finally {
|
|
2567
2588
|
J = !1, ie({ focus: !0 });
|
|
2568
2589
|
}
|
|
2569
2590
|
}
|
|
2570
|
-
async function
|
|
2571
|
-
const
|
|
2572
|
-
if (!
|
|
2591
|
+
async function jt() {
|
|
2592
|
+
const o = Qe.trim();
|
|
2593
|
+
if (!o) {
|
|
2573
2594
|
le = "Enter the code we emailed you.", ie({ focus: !0 });
|
|
2574
2595
|
return;
|
|
2575
2596
|
}
|
|
2576
2597
|
J = !0, le = "", ie();
|
|
2577
2598
|
try {
|
|
2578
|
-
const c = await
|
|
2579
|
-
X.signedIn = c, Z = "idle", Qe = "",
|
|
2599
|
+
const c = await a.confirmSignIn(Re.trim(), o);
|
|
2600
|
+
X.signedIn = c, Z = "idle", Qe = "", H(""), Qt();
|
|
2580
2601
|
} catch (c) {
|
|
2581
2602
|
le = c.message;
|
|
2582
2603
|
} finally {
|
|
2583
2604
|
J = !1, ie({ focus: Z !== "idle" });
|
|
2584
2605
|
}
|
|
2585
2606
|
}
|
|
2586
|
-
Q.addEventListener("click", async (
|
|
2587
|
-
const c =
|
|
2607
|
+
Q.addEventListener("click", async (o) => {
|
|
2608
|
+
const c = o.target.closest("button[data-act]");
|
|
2588
2609
|
if (!c) return;
|
|
2589
|
-
const
|
|
2590
|
-
if (
|
|
2610
|
+
const u = c.dataset.act;
|
|
2611
|
+
if (u === "signin") {
|
|
2591
2612
|
Z = "email", le = "", ie({ focus: !0 });
|
|
2592
2613
|
return;
|
|
2593
2614
|
}
|
|
2594
|
-
if (
|
|
2615
|
+
if (u === "skip") {
|
|
2595
2616
|
Z = "idle", le = "", ie();
|
|
2596
2617
|
return;
|
|
2597
2618
|
}
|
|
2598
|
-
if (
|
|
2619
|
+
if (u === "signin-back") {
|
|
2599
2620
|
Z = "email", le = "", Qe = "", ie({ focus: !0 });
|
|
2600
2621
|
return;
|
|
2601
2622
|
}
|
|
2602
|
-
if (
|
|
2603
|
-
|
|
2623
|
+
if (u === "code") {
|
|
2624
|
+
ft();
|
|
2604
2625
|
return;
|
|
2605
2626
|
}
|
|
2606
|
-
if (
|
|
2607
|
-
|
|
2627
|
+
if (u === "resend") {
|
|
2628
|
+
ft({ resent: !0 });
|
|
2608
2629
|
return;
|
|
2609
2630
|
}
|
|
2610
|
-
if (
|
|
2611
|
-
|
|
2631
|
+
if (u === "confirm") {
|
|
2632
|
+
jt();
|
|
2612
2633
|
return;
|
|
2613
2634
|
}
|
|
2614
|
-
if (
|
|
2635
|
+
if (u === "signout") {
|
|
2615
2636
|
J = !0, ie();
|
|
2616
2637
|
try {
|
|
2617
|
-
await
|
|
2638
|
+
await a.signOut();
|
|
2618
2639
|
} finally {
|
|
2619
2640
|
X.signedIn = null, J = !1, Z = X.mode === "required" ? "email" : "idle", ie({ focus: Z !== "idle" });
|
|
2620
2641
|
}
|
|
2621
2642
|
}
|
|
2622
2643
|
});
|
|
2623
|
-
async function
|
|
2624
|
-
const c = await
|
|
2625
|
-
X = { mode: c.mode, signedIn: c.signedIn },
|
|
2644
|
+
async function gt({ announce: o = !1 } = {}) {
|
|
2645
|
+
const c = await a.loginState();
|
|
2646
|
+
X = { mode: c.mode, signedIn: c.signedIn }, a.lastLoginMode = c.mode, ht() && Z === "idle" && (Z = "email"), X.signedIn && (Z = "idle"), o && c.signedOutReason && H(c.signedOutReason, "info"), ie();
|
|
2626
2647
|
}
|
|
2627
|
-
|
|
2648
|
+
gt({ announce: !0 }).catch(() => {
|
|
2628
2649
|
}), L.addEventListener("click", async () => {
|
|
2629
|
-
b = !0,
|
|
2650
|
+
b = !0, H(""), ce(), L.disabled = !0, L.innerHTML = '<span class="spinner"></span>Ringing…';
|
|
2630
2651
|
try {
|
|
2631
|
-
const
|
|
2632
|
-
|
|
2633
|
-
} catch (
|
|
2634
|
-
b = !1, L.disabled = !1, L.textContent = "Talk to the team", ce(),
|
|
2652
|
+
const o = await a.startCall();
|
|
2653
|
+
Vn(o);
|
|
2654
|
+
} catch (o) {
|
|
2655
|
+
b = !1, L.disabled = !1, L.textContent = "Talk to the team", ce(), o.filed ? zt(o.filed, { callFailed: o.reason || "The call could not be started." }) : (H(o.message.replace("[BugCatch] ", "")), X.mode !== "off" && gt().catch(() => {
|
|
2635
2656
|
}));
|
|
2636
2657
|
}
|
|
2637
2658
|
});
|
|
2638
|
-
function
|
|
2639
|
-
const c =
|
|
2659
|
+
function Vn(o) {
|
|
2660
|
+
const c = g.querySelector(".panel"), u = o != null && o.bugId ? String(o.bugId).slice(0, 8) : null;
|
|
2640
2661
|
c.innerHTML = `
|
|
2641
2662
|
<div class="call">
|
|
2642
2663
|
<div class="call-head">
|
|
@@ -2644,262 +2665,286 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2644
2665
|
<strong class="call-state">Ringing…</strong>
|
|
2645
2666
|
</div>
|
|
2646
2667
|
<p class="call-note">
|
|
2647
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
2668
|
+
We're ringing the team now. Someone will pick up if they're free — your report${u ? ` <code>${k(u)}</code>` : ""} is already filed either way, so nothing is lost if nobody answers.
|
|
2648
2669
|
</p>
|
|
2649
2670
|
<div class="foot">
|
|
2650
2671
|
<span class="spacer"></span>
|
|
2651
2672
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
2652
2673
|
</div>
|
|
2653
2674
|
</div>`;
|
|
2654
|
-
const
|
|
2675
|
+
const d = c.querySelector(".call-state"), x = c.querySelector(".call-dot"), w = {
|
|
2655
2676
|
ringing: "Ringing the team…",
|
|
2656
2677
|
connecting: "Someone answered — connecting…",
|
|
2657
2678
|
connected: "Connected",
|
|
2658
2679
|
missed: "Nobody was free",
|
|
2659
2680
|
ended: "Call ended",
|
|
2660
2681
|
failed: "The call dropped"
|
|
2661
|
-
},
|
|
2662
|
-
if (
|
|
2682
|
+
}, j = ["ended", "failed", "missed"], z = a.on("call", ({ state: q }) => {
|
|
2683
|
+
if (d.textContent = w[q] || q, x.classList.toggle("off", j.includes(q)), j.includes(q) && (c.querySelector('[data-act="hangup"]').textContent = "Close", q === "missed")) {
|
|
2663
2684
|
const G = c.querySelector(".call-note");
|
|
2664
2685
|
G && (G.textContent = "Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.");
|
|
2665
2686
|
}
|
|
2666
2687
|
});
|
|
2667
2688
|
c.querySelector('[data-act="hangup"]').addEventListener("click", () => {
|
|
2668
|
-
|
|
2689
|
+
z(), a.endCall(), re();
|
|
2669
2690
|
});
|
|
2670
2691
|
}
|
|
2671
|
-
function
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2692
|
+
function zt(o, { callFailed: c = null } = {}) {
|
|
2693
|
+
if (o != null && o.id && !c) {
|
|
2694
|
+
mt(o.id, { fresh: !0 }).then((u) => {
|
|
2695
|
+
u || Ot(o, { callFailed: c });
|
|
2696
|
+
});
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
Ot(o, { callFailed: c });
|
|
2700
|
+
}
|
|
2701
|
+
function Ot(o, { callFailed: c = null } = {}) {
|
|
2702
|
+
var w;
|
|
2703
|
+
const u = o != null && o.id ? String(o.id).slice(0, 8) : null, d = (w = o == null ? void 0 : o.estimate) != null && w.label ? String(o.estimate.label) : null, x = c ? `<p class="eta">${k(c)} Your report is filed, and the team will reply in the chat.</p>` : "";
|
|
2704
|
+
g.querySelector(".panel").innerHTML = `
|
|
2675
2705
|
<div class="done">
|
|
2676
|
-
<div class="tick">${
|
|
2706
|
+
<div class="tick">${O.check}</div>
|
|
2677
2707
|
<h3>Thanks — that's on its way.</h3>
|
|
2678
|
-
<p>${
|
|
2679
|
-
${
|
|
2680
|
-
${
|
|
2681
|
-
</div>`, setTimeout(re,
|
|
2682
|
-
}
|
|
2683
|
-
async function
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2708
|
+
<p>${u ? `Filed as <code>${k(u)}</code>.` : "The team has what they need to reproduce it."}</p>
|
|
2709
|
+
${x}
|
|
2710
|
+
${d ? `<p class="eta">Reports like this usually take <strong>${k(d)}</strong>. We'll let you know when it moves.</p>` : ""}
|
|
2711
|
+
</div>`, setTimeout(re, x ? 6e3 : d ? 4e3 : 2e3);
|
|
2712
|
+
}
|
|
2713
|
+
async function Ht() {
|
|
2714
|
+
const o = g.querySelector(".panel");
|
|
2715
|
+
o.innerHTML = `
|
|
2686
2716
|
<div class="head">
|
|
2687
|
-
<div class="mark">${
|
|
2717
|
+
<div class="mark">${O.bug}</div>
|
|
2688
2718
|
<div class="titles">
|
|
2689
2719
|
<h2>Your reports</h2>
|
|
2690
2720
|
<p>Everything you've reported, and where each one got to.</p>
|
|
2691
2721
|
</div>
|
|
2692
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
2722
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${O.close}</button>
|
|
2693
2723
|
</div>
|
|
2694
|
-
<div class="history"><div class="empty">Loading…</div></div>`,
|
|
2724
|
+
<div class="history"><div class="empty">Loading…</div></div>`, o.querySelector('[data-act="close"]').addEventListener("click", re);
|
|
2695
2725
|
let c = [];
|
|
2696
2726
|
try {
|
|
2697
|
-
({ reports: c } = await
|
|
2727
|
+
({ reports: c } = await a.myReports());
|
|
2698
2728
|
} catch {
|
|
2699
|
-
|
|
2729
|
+
o.querySelector(".history").innerHTML = `<div class="empty">Couldn't load your reports just now.</div>`;
|
|
2700
2730
|
return;
|
|
2701
2731
|
}
|
|
2702
|
-
const
|
|
2703
|
-
if (
|
|
2704
|
-
|
|
2705
|
-
<button class="row" type="button" data-report="${
|
|
2732
|
+
const u = o.querySelector(".history");
|
|
2733
|
+
if (u) {
|
|
2734
|
+
u.innerHTML = c.length ? c.map((d) => `
|
|
2735
|
+
<button class="row" type="button" data-report="${k(d.id)}">
|
|
2706
2736
|
<span class="who">
|
|
2707
|
-
<span class="ttl">${
|
|
2708
|
-
<span class="sub">${
|
|
2737
|
+
<span class="ttl">${k(d.title)}</span>
|
|
2738
|
+
<span class="sub">${k(d.reference)} · ${k(rt(d.createdAt))}</span>
|
|
2709
2739
|
</span>
|
|
2710
|
-
<span class="pill ${
|
|
2740
|
+
<span class="pill ${k(String(d.status).toLowerCase())}">${k(kt(d.status))}</span>
|
|
2711
2741
|
</button>`).join("") : `<div class="empty">You haven't reported anything yet.</div>`;
|
|
2712
|
-
for (const
|
|
2713
|
-
|
|
2742
|
+
for (const d of u.querySelectorAll("[data-report]"))
|
|
2743
|
+
d.addEventListener("click", () => mt(d.dataset.report));
|
|
2714
2744
|
}
|
|
2715
2745
|
}
|
|
2716
|
-
async function
|
|
2717
|
-
var
|
|
2718
|
-
const
|
|
2719
|
-
|
|
2746
|
+
async function mt(o, { fresh: c = !1 } = {}) {
|
|
2747
|
+
var j;
|
|
2748
|
+
const u = g.querySelector(".panel");
|
|
2749
|
+
u.innerHTML = `
|
|
2720
2750
|
<div class="head">
|
|
2721
|
-
<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${
|
|
2751
|
+
<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${O.back}</button>
|
|
2722
2752
|
<div class="titles">
|
|
2723
|
-
<h2
|
|
2724
|
-
<p
|
|
2753
|
+
<h2>${c ? "Looking into it" : "Your report"}</h2>
|
|
2754
|
+
<p>${c ? "Our assistant is investigating — it may ask you a question." : "Everything that has happened, and a way to answer."}</p>
|
|
2725
2755
|
</div>
|
|
2726
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
2756
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${O.close}</button>
|
|
2727
2757
|
</div>
|
|
2728
|
-
<div class="history"><div class="empty">Loading…</div></div>`,
|
|
2758
|
+
<div class="history"><div class="empty">Loading…</div></div>`, u.querySelector('[data-act="close"]').addEventListener("click", re), u.querySelector('[data-act="back"]').addEventListener("click", Ht);
|
|
2729
2759
|
let d = null;
|
|
2730
2760
|
try {
|
|
2731
|
-
d = await
|
|
2761
|
+
d = await a.myReport(o);
|
|
2732
2762
|
} catch {
|
|
2733
2763
|
d = null;
|
|
2734
2764
|
}
|
|
2735
|
-
const
|
|
2736
|
-
if (!
|
|
2737
|
-
if (!d)
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
}
|
|
2741
|
-
ge = a, o.markReportRead(a), g.classList.add("chatting"), g.innerHTML = `
|
|
2765
|
+
const x = u.querySelector(".history");
|
|
2766
|
+
if (!x || !u.querySelector('[data-act="back"]')) return !1;
|
|
2767
|
+
if (!d)
|
|
2768
|
+
return c || (x.innerHTML = `<div class="empty">Couldn't load that report just now.</div>`), !1;
|
|
2769
|
+
ge = o, a.markReportRead(o), x.classList.add("chatting"), x.innerHTML = `
|
|
2742
2770
|
<div class="report-head">
|
|
2743
|
-
<span class="ttl">${
|
|
2744
|
-
<span class="sub">${
|
|
2745
|
-
<span class="pill ${
|
|
2746
|
-
${(
|
|
2771
|
+
<span class="ttl">${k(d.title)}</span>
|
|
2772
|
+
<span class="sub">${k(d.reference)} · ${k(d.project || "")}</span>
|
|
2773
|
+
<span class="pill ${k(String(d.status).toLowerCase())}">${k(kt(d.status))}</span>
|
|
2774
|
+
${(j = d.estimate) != null && j.label ? `<span class="eta-line">Usually takes ${k(String(d.estimate.label))}</span>` : ""}
|
|
2747
2775
|
</div>
|
|
2748
|
-
<div class="thread">${
|
|
2749
|
-
const
|
|
2750
|
-
|
|
2751
|
-
}
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2776
|
+
<div class="thread">${sn(d.timeline)}</div>`;
|
|
2777
|
+
const w = x.querySelector(".thread");
|
|
2778
|
+
return xt(w), Nt(x, d), d.canReply && Kn(x, w, o), Dt(x, d, o), !0;
|
|
2779
|
+
}
|
|
2780
|
+
let qt = null;
|
|
2781
|
+
function Dt(o, c, u) {
|
|
2782
|
+
var w, j, z;
|
|
2783
|
+
clearTimeout(qt);
|
|
2784
|
+
const d = c.assistant;
|
|
2785
|
+
if ((w = o.querySelector(".assistant")) == null || w.remove(), !d) return;
|
|
2786
|
+
const x = document.createElement("div");
|
|
2787
|
+
x.className = `assistant ${k(d.phase)}`, x.setAttribute("role", "status"), x.setAttribute("aria-live", "polite"), x.innerHTML = `
|
|
2788
|
+
<div class="as-top">
|
|
2789
|
+
<span class="as-orb" aria-hidden="true">${d.phase === "analyzing" ? '<span class="as-spin"></span>' : "✦"}</span>
|
|
2790
|
+
<div class="as-text">
|
|
2791
|
+
<div class="as-title">${k(d.title)}</div>
|
|
2792
|
+
<div class="as-detail">${k(d.detail)}</div>
|
|
2793
|
+
</div>
|
|
2794
|
+
</div>
|
|
2795
|
+
<ol class="as-steps">${(d.steps || []).map((q) => `<li class="${k(q.state)}"><span></span>${k(q.label)}</li>`).join("")}</ol>`, (j = o.querySelector(".report-head")) == null || j.after(x), d.phase === "analyzing" ? qt = setTimeout(() => Fe(u), 3e3) : d.phase === "needs_info" && ((z = o.querySelector(".composer textarea")) == null || z.focus());
|
|
2796
|
+
}
|
|
2797
|
+
function Nt(o, c) {
|
|
2798
|
+
var d, x;
|
|
2799
|
+
if ((d = o.querySelector(".fix-verification")) == null || d.remove(), !c.resolvedAt || !["RESOLVED", "CLOSED"].includes(c.status)) return;
|
|
2800
|
+
const u = document.createElement("div");
|
|
2801
|
+
u.className = "fix-verification", c.verification ? u.textContent = c.verification === "CONFIRMED" ? "You confirmed that this fix works." : "Your feedback was recorded." : (u.innerHTML = '<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>', u.querySelectorAll("[data-result]").forEach((w) => {
|
|
2802
|
+
w.onclick = async () => {
|
|
2803
|
+
u.querySelectorAll("button").forEach((j) => {
|
|
2804
|
+
j.disabled = !0;
|
|
2760
2805
|
});
|
|
2761
2806
|
try {
|
|
2762
|
-
await
|
|
2763
|
-
} catch (
|
|
2764
|
-
|
|
2765
|
-
|
|
2807
|
+
await a.verifyFix(c.id, { result: w.dataset.result, resolvedAt: c.resolvedAt, note: u.querySelector("textarea").value }), await mt(c.id);
|
|
2808
|
+
} catch (j) {
|
|
2809
|
+
u.querySelector(".feedback-status").textContent = j.message, u.querySelectorAll("button").forEach((z) => {
|
|
2810
|
+
z.disabled = !1;
|
|
2766
2811
|
});
|
|
2767
2812
|
}
|
|
2768
2813
|
};
|
|
2769
|
-
})), (
|
|
2814
|
+
})), (x = o.querySelector(".report-head")) == null || x.after(u);
|
|
2770
2815
|
}
|
|
2771
|
-
async function
|
|
2772
|
-
const c =
|
|
2773
|
-
if (!
|
|
2774
|
-
let
|
|
2816
|
+
async function Fe(o) {
|
|
2817
|
+
const c = g.querySelector(".history.chatting"), u = c == null ? void 0 : c.querySelector(".thread");
|
|
2818
|
+
if (!u || ge !== o) return;
|
|
2819
|
+
let d = null;
|
|
2775
2820
|
try {
|
|
2776
|
-
|
|
2821
|
+
d = await a.myReport(o);
|
|
2777
2822
|
} catch {
|
|
2778
2823
|
}
|
|
2779
|
-
if (!
|
|
2780
|
-
|
|
2781
|
-
const
|
|
2782
|
-
|
|
2783
|
-
const
|
|
2784
|
-
|
|
2785
|
-
}
|
|
2786
|
-
function
|
|
2787
|
-
const
|
|
2788
|
-
|
|
2824
|
+
if (!d || ge !== o) return;
|
|
2825
|
+
Nt(c, d), Dt(c, d, o);
|
|
2826
|
+
const x = ho(u);
|
|
2827
|
+
u.innerHTML = sn(d.timeline), x && xt(u);
|
|
2828
|
+
const w = c.querySelector(".report-head .pill");
|
|
2829
|
+
w && (w.className = `pill ${String(d.status).toLowerCase()}`, w.textContent = kt(d.status));
|
|
2830
|
+
}
|
|
2831
|
+
function Kn(o, c, u) {
|
|
2832
|
+
const d = document.createElement("div");
|
|
2833
|
+
d.className = "composer", d.innerHTML = `
|
|
2789
2834
|
<div class="staged" hidden></div>
|
|
2790
2835
|
<div class="row">
|
|
2791
2836
|
<div class="tools">
|
|
2792
|
-
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${
|
|
2793
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
2794
|
-
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${
|
|
2837
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${O.paperclip}</button>
|
|
2838
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${O.mic}</button>
|
|
2839
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${O.phone}</button>
|
|
2795
2840
|
</div>
|
|
2796
2841
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
2797
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
2842
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${O.send}</button>
|
|
2798
2843
|
</div>
|
|
2799
2844
|
<div class="note" hidden></div>
|
|
2800
|
-
<input type="file" hidden multiple accept="${
|
|
2801
|
-
const
|
|
2845
|
+
<input type="file" hidden multiple accept="${vn.join(",")}">`, o.appendChild(d);
|
|
2846
|
+
const x = d.querySelector(".staged"), w = d.querySelector("textarea"), j = d.querySelector('[data-act="send"]'), z = d.querySelector('[data-act="voice"]'), q = d.querySelector('[data-act="livecall"]'), G = d.querySelector("input[type=file]"), de = d.querySelector(".note"), K = [];
|
|
2802
2847
|
let Se = null, W = !1;
|
|
2803
2848
|
function ne(M, R = "") {
|
|
2804
2849
|
de.hidden = !M, de.className = `note ${R}`, de.textContent = M || "";
|
|
2805
2850
|
}
|
|
2806
2851
|
function Ce() {
|
|
2807
|
-
const M =
|
|
2808
|
-
|
|
2852
|
+
const M = K.filter((R) => R.storageKey);
|
|
2853
|
+
j.disabled = W || !w.value.trim() && !M.length, x.hidden = !K.length, x.innerHTML = K.map((R, ue) => `
|
|
2809
2854
|
<span class="chip ${R.storageKey ? "" : "uploading"}">
|
|
2810
|
-
<span class="nm">${
|
|
2855
|
+
<span class="nm">${k(R.name)}</span>
|
|
2811
2856
|
<span class="sz">${R.storageKey ? je(R.size) : "sending…"}</span>
|
|
2812
|
-
<button type="button" data-drop="${ue}" aria-label="Remove ${
|
|
2857
|
+
<button type="button" data-drop="${ue}" aria-label="Remove ${k(R.name)}">${O.close}</button>
|
|
2813
2858
|
</span>`).join("");
|
|
2814
|
-
for (const R of
|
|
2859
|
+
for (const R of x.querySelectorAll("[data-drop]"))
|
|
2815
2860
|
R.addEventListener("click", () => {
|
|
2816
|
-
|
|
2861
|
+
K.splice(Number(R.dataset.drop), 1), Ce();
|
|
2817
2862
|
});
|
|
2818
2863
|
}
|
|
2819
|
-
async function
|
|
2820
|
-
const
|
|
2821
|
-
|
|
2864
|
+
async function Wt(M, R, ue) {
|
|
2865
|
+
const D = { name: ue, size: M.size, storageKey: null };
|
|
2866
|
+
K.push(D), Ce();
|
|
2822
2867
|
try {
|
|
2823
|
-
const { storageKey:
|
|
2824
|
-
|
|
2825
|
-
} catch (
|
|
2826
|
-
|
|
2868
|
+
const { storageKey: yt, mime: _n } = await a.uploadAttachment(M, R);
|
|
2869
|
+
D.storageKey = yt, D.mime = _n;
|
|
2870
|
+
} catch (yt) {
|
|
2871
|
+
K.splice(K.indexOf(D), 1), ne(yt.message || "That file could not be sent.", "err");
|
|
2827
2872
|
}
|
|
2828
2873
|
Ce();
|
|
2829
2874
|
}
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
}),
|
|
2833
|
-
M.key === "Enter" && !M.shiftKey && !M.isComposing && (M.preventDefault(),
|
|
2834
|
-
}),
|
|
2875
|
+
w.addEventListener("input", () => {
|
|
2876
|
+
w.style.height = "auto", w.style.height = `${Math.min(w.scrollHeight, 120)}px`, Ce();
|
|
2877
|
+
}), w.addEventListener("keydown", (M) => {
|
|
2878
|
+
M.key === "Enter" && !M.shiftKey && !M.isComposing && (M.preventDefault(), bt());
|
|
2879
|
+
}), d.querySelector('[data-act="attach"]').addEventListener("click", () => G.click()), G.addEventListener("change", () => {
|
|
2835
2880
|
ne("");
|
|
2836
2881
|
for (const M of G.files) {
|
|
2837
|
-
if (M.size >
|
|
2838
|
-
ne(`${M.name} is larger than ${je(
|
|
2882
|
+
if (M.size > a.config.maxAttachmentBytes) {
|
|
2883
|
+
ne(`${M.name} is larger than ${je(a.config.maxAttachmentBytes)}.`, "err");
|
|
2839
2884
|
continue;
|
|
2840
2885
|
}
|
|
2841
|
-
|
|
2886
|
+
Wt(M, M.type, M.name);
|
|
2842
2887
|
}
|
|
2843
2888
|
G.value = "";
|
|
2844
|
-
}),
|
|
2889
|
+
}), la() || (z.disabled = !0, z.title = "This browser cannot record audio"), z.addEventListener("click", async () => {
|
|
2845
2890
|
if (Se) {
|
|
2846
2891
|
const M = Se;
|
|
2847
|
-
Se = null,
|
|
2892
|
+
Se = null, z.classList.remove("recording"), z.innerHTML = O.mic, ne("");
|
|
2848
2893
|
const { blob: R, mime: ue } = await M.stop();
|
|
2849
|
-
R.size &&
|
|
2894
|
+
R.size && Wt(R, ue, "Voice note");
|
|
2850
2895
|
return;
|
|
2851
2896
|
}
|
|
2852
2897
|
try {
|
|
2853
|
-
ne(""), Se = await
|
|
2854
|
-
maxMs:
|
|
2855
|
-
onTick: (M) => ne(`Recording — ${
|
|
2856
|
-
onAutoStop: () =>
|
|
2857
|
-
}),
|
|
2898
|
+
ne(""), Se = await fa({
|
|
2899
|
+
maxMs: a.config.maxRecordingMs,
|
|
2900
|
+
onTick: (M) => ne(`Recording — ${Ye(M)}. Tap the mic to stop.`),
|
|
2901
|
+
onAutoStop: () => z.click()
|
|
2902
|
+
}), z.classList.add("recording"), z.innerHTML = O.stopSquare;
|
|
2858
2903
|
} catch {
|
|
2859
2904
|
Se = null, ne("The microphone is not available — check the browser permission.", "err");
|
|
2860
2905
|
}
|
|
2861
|
-
}),
|
|
2862
|
-
M && (
|
|
2906
|
+
}), a.canCallTeam(u).then((M) => {
|
|
2907
|
+
M && (q.hidden = !1);
|
|
2863
2908
|
}).catch(() => {
|
|
2864
|
-
}),
|
|
2865
|
-
|
|
2909
|
+
}), q.addEventListener("click", async () => {
|
|
2910
|
+
q.disabled = !0, ne("");
|
|
2866
2911
|
try {
|
|
2867
|
-
const M = await
|
|
2868
|
-
|
|
2912
|
+
const M = await a.startLiveCall(u);
|
|
2913
|
+
Pn(o, c, M);
|
|
2869
2914
|
} catch (M) {
|
|
2870
2915
|
ne(M.message.replace("[BugCatch] ", ""), "err");
|
|
2871
2916
|
} finally {
|
|
2872
|
-
|
|
2917
|
+
q.disabled = !1;
|
|
2873
2918
|
}
|
|
2874
|
-
}),
|
|
2875
|
-
var ue,
|
|
2876
|
-
const R = (
|
|
2877
|
-
!R || W || (
|
|
2919
|
+
}), j.addEventListener("click", bt), c.addEventListener("click", (M) => {
|
|
2920
|
+
var ue, D;
|
|
2921
|
+
const R = (D = (ue = M.target).closest) == null ? void 0 : D.call(ue, "[data-quick]");
|
|
2922
|
+
!R || W || (w.value = R.dataset.quick, bt());
|
|
2878
2923
|
});
|
|
2879
|
-
async function
|
|
2924
|
+
async function bt() {
|
|
2880
2925
|
var ue;
|
|
2881
|
-
const M =
|
|
2926
|
+
const M = w.value.trim(), R = K.filter((D) => D.storageKey);
|
|
2882
2927
|
if (!(W || !M && !R.length)) {
|
|
2883
|
-
W = !0, Ce(), ne(""), c.insertAdjacentHTML("beforeend",
|
|
2928
|
+
W = !0, Ce(), ne(""), c.insertAdjacentHTML("beforeend", Ln({
|
|
2884
2929
|
from: "reporter",
|
|
2885
2930
|
body: M,
|
|
2886
2931
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2887
|
-
attachments: R.map((
|
|
2888
|
-
}, "pending")),
|
|
2932
|
+
attachments: R.map((D) => ({ type: "FILE", name: D.name, size: D.size }))
|
|
2933
|
+
}, "pending")), xt(c);
|
|
2889
2934
|
try {
|
|
2890
|
-
await
|
|
2891
|
-
apiBase:
|
|
2892
|
-
bugId:
|
|
2935
|
+
await Sn({
|
|
2936
|
+
apiBase: a.config.apiBase,
|
|
2937
|
+
bugId: u,
|
|
2893
2938
|
body: M,
|
|
2894
|
-
attachments: R.map((
|
|
2895
|
-
storageKey:
|
|
2896
|
-
mime:
|
|
2897
|
-
name:
|
|
2898
|
-
size:
|
|
2939
|
+
attachments: R.map((D) => ({
|
|
2940
|
+
storageKey: D.storageKey,
|
|
2941
|
+
mime: D.mime,
|
|
2942
|
+
name: D.name,
|
|
2943
|
+
size: D.size
|
|
2899
2944
|
}))
|
|
2900
|
-
}),
|
|
2901
|
-
} catch (
|
|
2902
|
-
(ue = c.querySelector(".msg-row.pending")) == null || ue.classList.replace("pending", "failed"), ne(
|
|
2945
|
+
}), w.value = "", w.style.height = "auto", K.length = 0, await Fe(u);
|
|
2946
|
+
} catch (D) {
|
|
2947
|
+
(ue = c.querySelector(".msg-row.pending")) == null || ue.classList.replace("pending", "failed"), ne(D.message || "That could not be sent — try again.", "err");
|
|
2903
2948
|
} finally {
|
|
2904
2949
|
W = !1, Ce();
|
|
2905
2950
|
}
|
|
@@ -2907,96 +2952,96 @@ function sa({ root: t, host: e, dock: n, client: o, onClose: i }) {
|
|
|
2907
2952
|
}
|
|
2908
2953
|
Ce();
|
|
2909
2954
|
}
|
|
2910
|
-
function
|
|
2911
|
-
const
|
|
2912
|
-
|
|
2955
|
+
function Pn(o, c, u) {
|
|
2956
|
+
const d = document.createElement("div");
|
|
2957
|
+
d.className = "livecall", d.innerHTML = `
|
|
2913
2958
|
<span class="call-dot" aria-hidden="true"></span>
|
|
2914
2959
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
2915
2960
|
<span class="secs" hidden></span>
|
|
2916
2961
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
2917
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
2918
|
-
const
|
|
2962
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`, o.insertBefore(d, c);
|
|
2963
|
+
const x = d.querySelector(".who"), w = d.querySelector(".secs"), j = d.querySelector(".call-dot"), z = d.querySelector('[data-act="mute"]'), q = d.querySelector('[data-act="hangup"]');
|
|
2919
2964
|
let G = null;
|
|
2920
2965
|
const de = () => {
|
|
2921
2966
|
G && (clearInterval(G), G = null);
|
|
2922
|
-
},
|
|
2923
|
-
de(),
|
|
2924
|
-
}, Se =
|
|
2925
|
-
if (W === "ringing" && (
|
|
2926
|
-
|
|
2967
|
+
}, K = (W) => {
|
|
2968
|
+
de(), j.classList.add("off"), d.classList.add("over"), x.textContent = W, w.hidden = !0, z.hidden = !0, q.textContent = "Dismiss", q.classList.remove("danger");
|
|
2969
|
+
}, Se = a.on("call", ({ state: W }) => {
|
|
2970
|
+
if (W === "ringing" && (x.textContent = "Calling the team…"), W === "connecting" && (x.textContent = "Someone answered — connecting…"), W === "connected") {
|
|
2971
|
+
x.textContent = "You're on a call with the team", z.hidden = !1, w.hidden = !1;
|
|
2927
2972
|
const ne = Date.now();
|
|
2928
2973
|
de(), G = setInterval(() => {
|
|
2929
|
-
|
|
2930
|
-
}, 1e3),
|
|
2974
|
+
w.textContent = Ye(Math.floor((Date.now() - ne) / 1e3));
|
|
2975
|
+
}, 1e3), w.textContent = "0s";
|
|
2931
2976
|
}
|
|
2932
|
-
W === "missed" &&
|
|
2977
|
+
W === "missed" && K("Nobody was free. Send a message instead and the team will pick it up."), W === "ended" && K("Call ended."), W === "failed" && K("The call dropped.");
|
|
2933
2978
|
});
|
|
2934
|
-
|
|
2935
|
-
const W =
|
|
2936
|
-
|
|
2937
|
-
}),
|
|
2938
|
-
Se(), de(),
|
|
2979
|
+
z.addEventListener("click", () => {
|
|
2980
|
+
const W = u.setMuted(!u.isMuted());
|
|
2981
|
+
z.textContent = W ? "Unmute" : "Mute", x.textContent = W ? "You're muted" : "You're on a call with the team";
|
|
2982
|
+
}), q.addEventListener("click", () => {
|
|
2983
|
+
Se(), de(), a.endCall(), d.remove(), Fe(ge);
|
|
2939
2984
|
});
|
|
2940
2985
|
}
|
|
2941
2986
|
let ge = null;
|
|
2942
|
-
return we =
|
|
2943
|
-
!ge || (
|
|
2944
|
-
}), t.appendChild(
|
|
2987
|
+
return we = a.on("update", (o) => {
|
|
2988
|
+
!ge || (o == null ? void 0 : o.bugId) !== ge || (a.markReportRead(ge), Fe(ge));
|
|
2989
|
+
}), t.appendChild(g), ce(), A.focus(), { destroy: He, close: re };
|
|
2945
2990
|
}
|
|
2946
|
-
function
|
|
2991
|
+
function sn(t) {
|
|
2947
2992
|
const e = t || [];
|
|
2948
2993
|
return e.length ? e.map((n) => {
|
|
2949
|
-
var
|
|
2950
|
-
return n.from ?
|
|
2994
|
+
var a, i, r, s;
|
|
2995
|
+
return n.from ? Ln({
|
|
2951
2996
|
from: n.from,
|
|
2952
|
-
author: (
|
|
2997
|
+
author: (a = n.reply) == null ? void 0 : a.author,
|
|
2953
2998
|
automated: (i = n.reply) == null ? void 0 : i.automated,
|
|
2954
2999
|
body: (r = n.reply) == null ? void 0 : r.body,
|
|
2955
3000
|
at: n.at,
|
|
2956
3001
|
attachments: (s = n.reply) == null ? void 0 : s.attachments
|
|
2957
|
-
}) :
|
|
3002
|
+
}) : uo(n);
|
|
2958
3003
|
}).join("") : "";
|
|
2959
3004
|
}
|
|
2960
|
-
function
|
|
3005
|
+
function uo(t) {
|
|
2961
3006
|
return `
|
|
2962
|
-
<div class="sys k-${
|
|
2963
|
-
<span class="dot" aria-hidden="true"></span>${
|
|
2964
|
-
· ${
|
|
3007
|
+
<div class="sys k-${k(t.kind)}">
|
|
3008
|
+
<span class="dot" aria-hidden="true"></span>${k(t.summary || "")}
|
|
3009
|
+
· ${k(rt(t.at))}
|
|
2965
3010
|
</div>`;
|
|
2966
3011
|
}
|
|
2967
|
-
function
|
|
2968
|
-
const n = t.from === "reporter",
|
|
2969
|
-
let
|
|
2970
|
-
r ?
|
|
2971
|
-
const
|
|
3012
|
+
function Ln(t, e = "") {
|
|
3013
|
+
const n = t.from === "reporter", a = t.body || "", i = t.attachments || [], r = !n && !!t.automated, s = a ? `<span class="msg-text">${k(a)}</span>` : "", l = i.length ? `<div class="att">${i.map(po).join("")}</div>` : "";
|
|
3014
|
+
let p = "";
|
|
3015
|
+
r ? p = '<span class="msg-who auto">Automatic reply</span>' : !n && t.author && (p = `<span class="msg-who">${k(t.author)}</span>`);
|
|
3016
|
+
const f = r && /reply "yes" or "no"/i.test(a) ? `<div class="quick" role="group" aria-label="Answer">
|
|
2972
3017
|
<button type="button" data-quick="Yes, this is the problem">Yes, that's it</button>
|
|
2973
3018
|
<button type="button" data-quick="No, that is not the problem">No, it's something else</button>
|
|
2974
3019
|
</div>` : "";
|
|
2975
3020
|
return `
|
|
2976
3021
|
<div class="msg-row ${n ? "mine" : "theirs"} ${r ? "auto" : ""} ${e}">
|
|
2977
|
-
${
|
|
2978
|
-
<div class="bubble ${
|
|
2979
|
-
${
|
|
2980
|
-
<span class="msg-when">${
|
|
3022
|
+
${p}
|
|
3023
|
+
<div class="bubble ${a ? "" : "silent"}">${s}${l}</div>
|
|
3024
|
+
${f}
|
|
3025
|
+
<span class="msg-when">${k(rt(t.at))}</span>
|
|
2981
3026
|
</div>`;
|
|
2982
3027
|
}
|
|
2983
|
-
function
|
|
2984
|
-
const e =
|
|
3028
|
+
function po(t) {
|
|
3029
|
+
const e = k(t.name || "attachment");
|
|
2985
3030
|
if (!t.url) return `<span class="file"><span class="nm">${e}</span></span>`;
|
|
2986
|
-
const n =
|
|
3031
|
+
const n = k(t.url);
|
|
2987
3032
|
return t.type === "SCREENSHOT" ? `<a href="${n}" target="_blank" rel="noopener noreferrer"><img src="${n}" alt="${e}" loading="lazy"></a>` : t.type === "AUDIO" ? `<audio controls preload="metadata" src="${n}"></audio>` : t.type === "VIDEO" ? `<video controls preload="metadata" src="${n}"></video>` : `
|
|
2988
3033
|
<a class="file" href="${n}" target="_blank" rel="noopener noreferrer" download>
|
|
2989
3034
|
<span class="nm">${e}</span>
|
|
2990
|
-
${t.size ? `<span class="sz">${
|
|
3035
|
+
${t.size ? `<span class="sz">${k(je(t.size))}</span>` : ""}
|
|
2991
3036
|
</a>`;
|
|
2992
3037
|
}
|
|
2993
|
-
function
|
|
3038
|
+
function ho(t) {
|
|
2994
3039
|
return t.scrollHeight - t.scrollTop - t.clientHeight < 40;
|
|
2995
3040
|
}
|
|
2996
|
-
function
|
|
3041
|
+
function xt(t) {
|
|
2997
3042
|
t.scrollTop = t.scrollHeight;
|
|
2998
3043
|
}
|
|
2999
|
-
function
|
|
3044
|
+
function kt(t) {
|
|
3000
3045
|
return {
|
|
3001
3046
|
OPEN: "Open",
|
|
3002
3047
|
IN_PROGRESS: "In progress",
|
|
@@ -3004,21 +3049,21 @@ function xt(t) {
|
|
|
3004
3049
|
CLOSED: "Closed"
|
|
3005
3050
|
}[t] || String(t || "").toLowerCase();
|
|
3006
3051
|
}
|
|
3007
|
-
function
|
|
3052
|
+
function rt(t) {
|
|
3008
3053
|
const e = new Date(t).getTime();
|
|
3009
3054
|
if (!Number.isFinite(e)) return "";
|
|
3010
3055
|
const n = Math.floor((Date.now() - e) / 864e5);
|
|
3011
3056
|
if (n <= 0) return "today";
|
|
3012
3057
|
if (n === 1) return "yesterday";
|
|
3013
3058
|
if (n < 30) return `${n} days ago`;
|
|
3014
|
-
const
|
|
3015
|
-
return
|
|
3059
|
+
const a = Math.floor(n / 30);
|
|
3060
|
+
return a === 1 ? "a month ago" : `${a} months ago`;
|
|
3016
3061
|
}
|
|
3017
|
-
function
|
|
3062
|
+
function k(t) {
|
|
3018
3063
|
return String(t).replace(/[&<>"']/g, (e) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[e]);
|
|
3019
3064
|
}
|
|
3020
|
-
const
|
|
3021
|
-
function
|
|
3065
|
+
const Bn = 8e3;
|
|
3066
|
+
function fo(t = Bn) {
|
|
3022
3067
|
const e = window.AudioContext || window.webkitAudioContext;
|
|
3023
3068
|
try {
|
|
3024
3069
|
return new e({ sampleRate: t });
|
|
@@ -3026,44 +3071,44 @@ function ua(t = In) {
|
|
|
3026
3071
|
return new e();
|
|
3027
3072
|
}
|
|
3028
3073
|
}
|
|
3029
|
-
async function
|
|
3074
|
+
async function go(t) {
|
|
3030
3075
|
if (t.state === "suspended")
|
|
3031
3076
|
try {
|
|
3032
3077
|
await t.resume();
|
|
3033
3078
|
} catch {
|
|
3034
3079
|
}
|
|
3035
3080
|
}
|
|
3036
|
-
function
|
|
3037
|
-
const
|
|
3081
|
+
function mo(t, e, n) {
|
|
3082
|
+
const a = e / n, i = new Float32Array(Math.floor(t.length / a));
|
|
3038
3083
|
for (let r = 0; r < i.length; r++) {
|
|
3039
|
-
const s = Math.floor(r *
|
|
3040
|
-
let
|
|
3041
|
-
for (let
|
|
3042
|
-
i[r] = l > s ?
|
|
3084
|
+
const s = Math.floor(r * a), l = Math.min(Math.floor((r + 1) * a), t.length);
|
|
3085
|
+
let p = 0;
|
|
3086
|
+
for (let f = s; f < l; f++) p += t[f];
|
|
3087
|
+
i[r] = l > s ? p / (l - s) : 0;
|
|
3043
3088
|
}
|
|
3044
3089
|
return i;
|
|
3045
3090
|
}
|
|
3046
|
-
const
|
|
3047
|
-
function
|
|
3091
|
+
const bo = 132, cn = 32635;
|
|
3092
|
+
function yo(t) {
|
|
3048
3093
|
const e = new Uint8Array(t.length);
|
|
3049
3094
|
for (let n = 0; n < t.length; n++) {
|
|
3050
|
-
const
|
|
3051
|
-
let i = Math.round(
|
|
3095
|
+
const a = Math.max(-1, Math.min(1, t[n]));
|
|
3096
|
+
let i = Math.round(a * 32767);
|
|
3052
3097
|
const r = i < 0 ? 128 : 0;
|
|
3053
|
-
r && (i = -i), i >
|
|
3098
|
+
r && (i = -i), i > cn && (i = cn), i += bo;
|
|
3054
3099
|
let s = 7;
|
|
3055
|
-
for (let
|
|
3100
|
+
for (let p = 16384; !(i & p) && s > 0; s--, p >>= 1) ;
|
|
3056
3101
|
const l = i >> s + 3 & 15;
|
|
3057
3102
|
e[n] = ~(r | s << 4 | l) & 255;
|
|
3058
3103
|
}
|
|
3059
3104
|
return e;
|
|
3060
3105
|
}
|
|
3061
|
-
const
|
|
3062
|
-
function
|
|
3063
|
-
const i = t.createMediaStreamSource(e), r = t.createScriptProcessor(
|
|
3106
|
+
const wo = 512;
|
|
3107
|
+
function vo(t, e, n, a = Bn) {
|
|
3108
|
+
const i = t.createMediaStreamSource(e), r = t.createScriptProcessor(wo, 1, 1);
|
|
3064
3109
|
r.onaudioprocess = (l) => {
|
|
3065
|
-
const
|
|
3066
|
-
n(
|
|
3110
|
+
const p = l.inputBuffer.getChannelData(0), f = t.sampleRate === a ? p : mo(p, t.sampleRate, a);
|
|
3111
|
+
n(yo(f));
|
|
3067
3112
|
}, i.connect(r);
|
|
3068
3113
|
const s = t.createGain();
|
|
3069
3114
|
return s.gain.value = 0, r.connect(s), s.connect(t.destination), {
|
|
@@ -3084,8 +3129,8 @@ function ba(t, e, n, o = In) {
|
|
|
3084
3129
|
}
|
|
3085
3130
|
};
|
|
3086
3131
|
}
|
|
3087
|
-
const
|
|
3088
|
-
function
|
|
3132
|
+
const xo = "voiceai.realtime.v1", ko = [{ urls: "stun:stun.l.google.com:19302" }];
|
|
3133
|
+
function $t() {
|
|
3089
3134
|
return navigator.mediaDevices.getUserMedia({
|
|
3090
3135
|
audio: {
|
|
3091
3136
|
// Both ends are on speakers as often as not. Without cancellation each
|
|
@@ -3102,17 +3147,17 @@ function Et() {
|
|
|
3102
3147
|
var t;
|
|
3103
3148
|
return typeof window < "u" && typeof window.RTCPeerConnection == "function" && !!((t = navigator.mediaDevices) != null && t.getUserMedia);
|
|
3104
3149
|
}
|
|
3105
|
-
async function
|
|
3150
|
+
async function ln({
|
|
3106
3151
|
realtimeUrl: t,
|
|
3107
3152
|
stream: e,
|
|
3108
3153
|
ringsUntil: n,
|
|
3109
|
-
onState:
|
|
3154
|
+
onState: a,
|
|
3110
3155
|
onAudioBlocked: i,
|
|
3111
3156
|
onMicrophone: r
|
|
3112
3157
|
}) {
|
|
3113
|
-
const s = (m,
|
|
3158
|
+
const s = (m, v) => {
|
|
3114
3159
|
try {
|
|
3115
|
-
|
|
3160
|
+
a == null || a(m, v);
|
|
3116
3161
|
} catch {
|
|
3117
3162
|
}
|
|
3118
3163
|
}, l = (m) => {
|
|
@@ -3120,7 +3165,7 @@ async function rn({
|
|
|
3120
3165
|
i == null || i(m);
|
|
3121
3166
|
} catch {
|
|
3122
3167
|
}
|
|
3123
|
-
},
|
|
3168
|
+
}, p = (m) => {
|
|
3124
3169
|
try {
|
|
3125
3170
|
r == null || r(m);
|
|
3126
3171
|
} catch {
|
|
@@ -3130,70 +3175,70 @@ async function rn({
|
|
|
3130
3175
|
const m = new Error("[BugCatch] this browser cannot make live calls.");
|
|
3131
3176
|
throw s("failed", { reason: "unsupported" }), m;
|
|
3132
3177
|
}
|
|
3133
|
-
let
|
|
3134
|
-
if (!
|
|
3178
|
+
let f = e;
|
|
3179
|
+
if (!f)
|
|
3135
3180
|
try {
|
|
3136
|
-
|
|
3181
|
+
f = await $t();
|
|
3137
3182
|
} catch (m) {
|
|
3138
3183
|
throw s("failed", { reason: "microphone", error: String((m == null ? void 0 : m.name) || m) }), m;
|
|
3139
3184
|
}
|
|
3140
3185
|
let y;
|
|
3141
3186
|
try {
|
|
3142
|
-
y = await
|
|
3187
|
+
y = await So(t);
|
|
3143
3188
|
} catch (m) {
|
|
3144
|
-
throw
|
|
3189
|
+
throw un(f), s("failed", { reason: "connect" }), m;
|
|
3145
3190
|
}
|
|
3146
|
-
let
|
|
3191
|
+
let h = null, b = null, g = !1, S = null, A = null, ae = null, C = !1, $ = null, T = null, L = !1;
|
|
3147
3192
|
const Y = [];
|
|
3148
|
-
let
|
|
3149
|
-
const ze = 2e3, be = 5e3, Ue = 3e4, ye = 4,
|
|
3150
|
-
if (!
|
|
3151
|
-
|
|
3193
|
+
let N = !1, Q = !1, U = !1, E = null, oe = null, ee = 0;
|
|
3194
|
+
const ze = 2e3, be = 5e3, Ue = 3e4, ye = 4, V = (m, v) => {
|
|
3195
|
+
if (!g) {
|
|
3196
|
+
g = !0, S && (clearTimeout(S), S = null), re(), T == null || T(), T = null, Ve(), $ == null || $(), $ = null;
|
|
3152
3197
|
try {
|
|
3153
|
-
|
|
3198
|
+
h == null || h.close();
|
|
3154
3199
|
} catch {
|
|
3155
3200
|
}
|
|
3156
|
-
|
|
3201
|
+
un(f), b && (b.srcObject = null, b.remove(), b = null);
|
|
3157
3202
|
try {
|
|
3158
3203
|
y.readyState === WebSocket.OPEN && y.close(1e3, "call over");
|
|
3159
3204
|
} catch {
|
|
3160
3205
|
}
|
|
3161
|
-
s(m,
|
|
3206
|
+
s(m, v);
|
|
3162
3207
|
}
|
|
3163
3208
|
}, te = (m) => {
|
|
3164
3209
|
y.readyState === WebSocket.OPEN && y.send(JSON.stringify(m));
|
|
3165
|
-
},
|
|
3166
|
-
if (L ||
|
|
3210
|
+
}, Ee = async () => {
|
|
3211
|
+
if (L || ae || g || !A || !A.audio && !A.transcript) return;
|
|
3167
3212
|
L = !0;
|
|
3168
3213
|
const m = A.encoding || "mulaw";
|
|
3169
3214
|
if (m !== "mulaw") {
|
|
3170
|
-
|
|
3215
|
+
dn(`this call is kept as ${m}, which this SDK cannot produce.`);
|
|
3171
3216
|
return;
|
|
3172
3217
|
}
|
|
3173
|
-
const
|
|
3218
|
+
const v = Number(A.sample_rate) || 8e3;
|
|
3174
3219
|
try {
|
|
3175
|
-
const I =
|
|
3176
|
-
if (await
|
|
3220
|
+
const I = fo(v);
|
|
3221
|
+
if (await go(I), g) {
|
|
3177
3222
|
try {
|
|
3178
3223
|
I.close();
|
|
3179
3224
|
} catch {
|
|
3180
3225
|
}
|
|
3181
3226
|
return;
|
|
3182
3227
|
}
|
|
3183
|
-
const
|
|
3184
|
-
y.readyState === WebSocket.OPEN && y.send(
|
|
3185
|
-
},
|
|
3186
|
-
|
|
3228
|
+
const _ = vo(I, f, (F) => {
|
|
3229
|
+
y.readyState === WebSocket.OPEN && y.send(F);
|
|
3230
|
+
}, v);
|
|
3231
|
+
ae = { context: I, tap: _ };
|
|
3187
3232
|
} catch (I) {
|
|
3188
|
-
|
|
3233
|
+
dn(`could not send the copy this call is keeping: ${String((I == null ? void 0 : I.message) || I)}`);
|
|
3189
3234
|
}
|
|
3190
3235
|
};
|
|
3191
3236
|
function Ve() {
|
|
3192
|
-
if (L = !1, !
|
|
3193
|
-
const { context: m, tap:
|
|
3194
|
-
|
|
3237
|
+
if (L = !1, !ae) return;
|
|
3238
|
+
const { context: m, tap: v } = ae;
|
|
3239
|
+
ae = null;
|
|
3195
3240
|
try {
|
|
3196
|
-
|
|
3241
|
+
v.stop();
|
|
3197
3242
|
} catch {
|
|
3198
3243
|
}
|
|
3199
3244
|
try {
|
|
@@ -3202,11 +3247,11 @@ async function rn({
|
|
|
3202
3247
|
}
|
|
3203
3248
|
}
|
|
3204
3249
|
function Oe() {
|
|
3205
|
-
var
|
|
3206
|
-
if (!b ||
|
|
3250
|
+
var v;
|
|
3251
|
+
if (!b || g) return;
|
|
3207
3252
|
let m;
|
|
3208
3253
|
try {
|
|
3209
|
-
m = (
|
|
3254
|
+
m = (v = b.play) == null ? void 0 : v.call(b);
|
|
3210
3255
|
} catch {
|
|
3211
3256
|
Te();
|
|
3212
3257
|
return;
|
|
@@ -3218,18 +3263,18 @@ async function rn({
|
|
|
3218
3263
|
m.then(fe, Te);
|
|
3219
3264
|
}
|
|
3220
3265
|
function fe() {
|
|
3221
|
-
|
|
3266
|
+
$ == null || $(), $ = null, C && (C = !1, l(!1));
|
|
3222
3267
|
}
|
|
3223
3268
|
function Te() {
|
|
3224
|
-
|
|
3269
|
+
g || (C || (C = !0, l(!0)), lt());
|
|
3225
3270
|
}
|
|
3226
|
-
function
|
|
3227
|
-
if (
|
|
3228
|
-
const m = () => Oe(),
|
|
3229
|
-
for (const I of
|
|
3271
|
+
function lt() {
|
|
3272
|
+
if ($ || typeof window > "u" || typeof window.addEventListener != "function") return;
|
|
3273
|
+
const m = () => Oe(), v = ["pointerdown", "keydown", "touchstart"];
|
|
3274
|
+
for (const I of v)
|
|
3230
3275
|
window.addEventListener(I, m, { capture: !0, passive: !0 });
|
|
3231
|
-
|
|
3232
|
-
for (const I of
|
|
3276
|
+
$ = () => {
|
|
3277
|
+
for (const I of v)
|
|
3233
3278
|
try {
|
|
3234
3279
|
window.removeEventListener(I, m, { capture: !0 });
|
|
3235
3280
|
} catch {
|
|
@@ -3237,21 +3282,21 @@ async function rn({
|
|
|
3237
3282
|
};
|
|
3238
3283
|
}
|
|
3239
3284
|
const Ie = (m) => {
|
|
3240
|
-
|
|
3241
|
-
for (const
|
|
3242
|
-
T = ce(),
|
|
3243
|
-
|
|
3244
|
-
},
|
|
3245
|
-
var
|
|
3246
|
-
const [I] =
|
|
3247
|
-
I && (b || (b = document.createElement("audio"), b.autoplay = !0, b.playsInline = !0, (
|
|
3248
|
-
},
|
|
3285
|
+
h = new RTCPeerConnection({ iceServers: m != null && m.length ? m : ko });
|
|
3286
|
+
for (const v of f.getAudioTracks()) h.addTrack(v, f);
|
|
3287
|
+
T = ce(), h.onicecandidate = (v) => {
|
|
3288
|
+
v.candidate && te({ type: "signal", signal: { kind: "candidate", payload: v.candidate.toJSON() } });
|
|
3289
|
+
}, h.ontrack = (v) => {
|
|
3290
|
+
var _;
|
|
3291
|
+
const [I] = v.streams;
|
|
3292
|
+
I && (b || (b = document.createElement("audio"), b.autoplay = !0, b.playsInline = !0, (_ = b.setAttribute) == null || _.call(b, "playsinline", ""), b.style.cssText = "position:fixed;width:0;height:0;opacity:0;pointer-events:none", document.body.appendChild(b)), b.srcObject = I, Oe());
|
|
3293
|
+
}, h.onconnectionstatechange = we, h.oniceconnectionstatechange = we;
|
|
3249
3294
|
};
|
|
3250
3295
|
function we() {
|
|
3251
|
-
if (!
|
|
3252
|
-
const m =
|
|
3296
|
+
if (!h || g) return;
|
|
3297
|
+
const m = h.connectionState || h.iceConnectionState;
|
|
3253
3298
|
if (m === "connected" || m === "completed") {
|
|
3254
|
-
Q = !0, ee = 0, re(),
|
|
3299
|
+
Q = !0, ee = 0, re(), U = !1, s("connected");
|
|
3255
3300
|
return;
|
|
3256
3301
|
}
|
|
3257
3302
|
if (m === "disconnected") {
|
|
@@ -3261,185 +3306,185 @@ async function rn({
|
|
|
3261
3306
|
}
|
|
3262
3307
|
if (m === "failed") {
|
|
3263
3308
|
if (!Q) {
|
|
3264
|
-
|
|
3309
|
+
V("failed", { reason: "ice" });
|
|
3265
3310
|
return;
|
|
3266
3311
|
}
|
|
3267
3312
|
He(0);
|
|
3268
3313
|
}
|
|
3269
3314
|
}
|
|
3270
3315
|
function He(m) {
|
|
3271
|
-
|
|
3316
|
+
g || (U || (U = !0, s("reconnecting"), oe = setTimeout(() => V("failed", { reason: "network" }), Ue)), !E && (E = setTimeout(Me, m)));
|
|
3272
3317
|
}
|
|
3273
3318
|
function re() {
|
|
3274
|
-
|
|
3319
|
+
E && (clearTimeout(E), E = null), oe && (clearTimeout(oe), oe = null);
|
|
3275
3320
|
}
|
|
3276
3321
|
async function Me() {
|
|
3277
|
-
if (
|
|
3278
|
-
const m =
|
|
3322
|
+
if (E = null, g || !h) return;
|
|
3323
|
+
const m = h.connectionState || h.iceConnectionState;
|
|
3279
3324
|
if (!(m === "connected" || m === "completed")) {
|
|
3280
|
-
if (!
|
|
3281
|
-
te({ type: "signal", signal: { kind: "restart", payload: {} } }),
|
|
3325
|
+
if (!N) {
|
|
3326
|
+
te({ type: "signal", signal: { kind: "restart", payload: {} } }), E = setTimeout(Me, be);
|
|
3282
3327
|
return;
|
|
3283
3328
|
}
|
|
3284
|
-
ee >= ye || (ee += 1, await
|
|
3329
|
+
ee >= ye || (ee += 1, await H(), E = setTimeout(Me, be));
|
|
3285
3330
|
}
|
|
3286
3331
|
}
|
|
3287
|
-
async function
|
|
3288
|
-
if (!(
|
|
3332
|
+
async function H() {
|
|
3333
|
+
if (!(g || !h))
|
|
3289
3334
|
try {
|
|
3290
|
-
const m = await
|
|
3291
|
-
await
|
|
3335
|
+
const m = await h.createOffer({ iceRestart: !0 });
|
|
3336
|
+
await h.setLocalDescription(m), te({ type: "signal", signal: { kind: "offer", payload: h.localDescription.toJSON() } });
|
|
3292
3337
|
} catch {
|
|
3293
3338
|
}
|
|
3294
3339
|
}
|
|
3295
3340
|
function ce() {
|
|
3296
|
-
let
|
|
3297
|
-
const
|
|
3298
|
-
if (
|
|
3341
|
+
let v = null, I = !1;
|
|
3342
|
+
const _ = (F) => {
|
|
3343
|
+
if (v && (clearTimeout(v), v = null), F) {
|
|
3299
3344
|
if (!I) return;
|
|
3300
|
-
I = !1,
|
|
3345
|
+
I = !1, p(!0);
|
|
3301
3346
|
return;
|
|
3302
3347
|
}
|
|
3303
|
-
I || (
|
|
3304
|
-
|
|
3348
|
+
I || (v = setTimeout(() => {
|
|
3349
|
+
v = null, !g && (I = !0, p(!1));
|
|
3305
3350
|
}, 600));
|
|
3306
3351
|
};
|
|
3307
|
-
for (const
|
|
3308
|
-
|
|
3309
|
-
|
|
3352
|
+
for (const F of f.getAudioTracks())
|
|
3353
|
+
F.onmute = () => _(!1), F.onunmute = () => _(!0), F.onended = () => {
|
|
3354
|
+
v && (clearTimeout(v), v = null), !I && (I = !0, p(!1));
|
|
3310
3355
|
};
|
|
3311
3356
|
return () => {
|
|
3312
|
-
|
|
3313
|
-
for (const
|
|
3314
|
-
|
|
3357
|
+
v && (clearTimeout(v), v = null);
|
|
3358
|
+
for (const F of f.getAudioTracks())
|
|
3359
|
+
F.onmute = null, F.onunmute = null, F.onended = null;
|
|
3315
3360
|
};
|
|
3316
3361
|
}
|
|
3317
3362
|
const Ke = async () => {
|
|
3318
3363
|
try {
|
|
3319
|
-
const m = await
|
|
3320
|
-
await
|
|
3364
|
+
const m = await h.createOffer();
|
|
3365
|
+
await h.setLocalDescription(m), te({ type: "signal", signal: { kind: "offer", payload: h.localDescription.toJSON() } });
|
|
3321
3366
|
} catch {
|
|
3322
|
-
|
|
3367
|
+
V("failed", { reason: "negotiation" });
|
|
3323
3368
|
}
|
|
3324
|
-
},
|
|
3369
|
+
}, dt = async (m) => {
|
|
3325
3370
|
try {
|
|
3326
|
-
await
|
|
3327
|
-
const
|
|
3328
|
-
await
|
|
3371
|
+
await h.setRemoteDescription(new RTCSessionDescription(m));
|
|
3372
|
+
const v = await h.createAnswer();
|
|
3373
|
+
await h.setLocalDescription(v), te({ type: "signal", signal: { kind: "answer", payload: h.localDescription.toJSON() } }), await Le();
|
|
3329
3374
|
} catch {
|
|
3330
|
-
|
|
3375
|
+
V("failed", { reason: "negotiation" });
|
|
3331
3376
|
}
|
|
3332
3377
|
}, Le = async () => {
|
|
3333
3378
|
for (; Y.length; ) {
|
|
3334
3379
|
const m = Y.shift();
|
|
3335
3380
|
try {
|
|
3336
|
-
await
|
|
3381
|
+
await h.addIceCandidate(new RTCIceCandidate(m));
|
|
3337
3382
|
} catch {
|
|
3338
3383
|
}
|
|
3339
3384
|
}
|
|
3340
3385
|
};
|
|
3341
3386
|
let ve = Promise.resolve();
|
|
3342
3387
|
y.onmessage = (m) => {
|
|
3343
|
-
ve = ve.then(() =>
|
|
3388
|
+
ve = ve.then(() => ut(m)).catch(() => {
|
|
3344
3389
|
});
|
|
3345
3390
|
};
|
|
3346
|
-
const
|
|
3347
|
-
var I,
|
|
3391
|
+
const ut = async (m) => {
|
|
3392
|
+
var I, _, F, xe, Pe;
|
|
3348
3393
|
if (typeof m.data != "string") return;
|
|
3349
|
-
let
|
|
3394
|
+
let v;
|
|
3350
3395
|
try {
|
|
3351
|
-
|
|
3396
|
+
v = JSON.parse(m.data);
|
|
3352
3397
|
} catch {
|
|
3353
3398
|
return;
|
|
3354
3399
|
}
|
|
3355
|
-
switch (
|
|
3400
|
+
switch (v.type) {
|
|
3356
3401
|
case "session.created": {
|
|
3357
|
-
if (Ie((I =
|
|
3358
|
-
s("connecting"),
|
|
3402
|
+
if (Ie((I = v.data) == null ? void 0 : I.ice_servers), A = ((_ = v.data) == null ? void 0 : _.capture) || null, (F = v.data) != null && F.peer_present) {
|
|
3403
|
+
s("connecting"), Ee();
|
|
3359
3404
|
break;
|
|
3360
3405
|
}
|
|
3361
3406
|
s("ringing"), Be();
|
|
3362
3407
|
break;
|
|
3363
3408
|
}
|
|
3364
3409
|
case "peer.joined": {
|
|
3365
|
-
|
|
3410
|
+
S && (clearTimeout(S), S = null), s("connecting"), N = !!((xe = v.data) != null && xe.should_offer), N && await Ke(), Ee();
|
|
3366
3411
|
break;
|
|
3367
3412
|
}
|
|
3368
3413
|
case "signal": {
|
|
3369
|
-
if (!
|
|
3370
|
-
const { kind: ke, payload: pe } =
|
|
3414
|
+
if (!h) break;
|
|
3415
|
+
const { kind: ke, payload: pe } = v.data || {};
|
|
3371
3416
|
if (ke === "offer")
|
|
3372
|
-
await
|
|
3417
|
+
await dt(pe);
|
|
3373
3418
|
else if (ke === "answer")
|
|
3374
3419
|
try {
|
|
3375
|
-
await
|
|
3420
|
+
await h.setRemoteDescription(new RTCSessionDescription(pe)), await Le();
|
|
3376
3421
|
} catch {
|
|
3377
|
-
|
|
3422
|
+
V("failed", { reason: "negotiation" });
|
|
3378
3423
|
}
|
|
3379
3424
|
else if (ke === "candidate")
|
|
3380
|
-
if (
|
|
3425
|
+
if (h.remoteDescription)
|
|
3381
3426
|
try {
|
|
3382
|
-
await
|
|
3427
|
+
await h.addIceCandidate(new RTCIceCandidate(pe));
|
|
3383
3428
|
} catch {
|
|
3384
3429
|
}
|
|
3385
3430
|
else
|
|
3386
3431
|
Y.push(pe);
|
|
3387
|
-
else ke === "restart" &&
|
|
3432
|
+
else ke === "restart" && N && await H();
|
|
3388
3433
|
break;
|
|
3389
3434
|
}
|
|
3390
3435
|
case "peer.left":
|
|
3391
|
-
|
|
3436
|
+
V("ended", { reason: "peer_left" });
|
|
3392
3437
|
break;
|
|
3393
3438
|
case "error":
|
|
3394
|
-
|
|
3439
|
+
V("failed", { reason: "server", detail: (Pe = v.error) == null ? void 0 : Pe.detail });
|
|
3395
3440
|
break;
|
|
3396
3441
|
case "session.ended":
|
|
3397
|
-
|
|
3442
|
+
V("ended", { reason: "server" });
|
|
3398
3443
|
break;
|
|
3399
3444
|
}
|
|
3400
3445
|
};
|
|
3401
|
-
y.onclose = () =>
|
|
3446
|
+
y.onclose = () => V("ended", { reason: "disconnected" }), y.onerror = () => V("failed", { reason: "socket" });
|
|
3402
3447
|
function Be() {
|
|
3403
3448
|
if (!n) return;
|
|
3404
3449
|
const m = new Date(n).getTime() - Date.now();
|
|
3405
|
-
Number.isFinite(m) && (
|
|
3450
|
+
Number.isFinite(m) && (S = setTimeout(() => V("missed"), Math.max(0, m)));
|
|
3406
3451
|
}
|
|
3407
3452
|
return {
|
|
3408
3453
|
hangUp() {
|
|
3409
|
-
te({ type: "session.end" }),
|
|
3454
|
+
te({ type: "session.end" }), V("ended", { reason: "hung_up" });
|
|
3410
3455
|
},
|
|
3411
3456
|
setMuted(m) {
|
|
3412
|
-
for (const
|
|
3457
|
+
for (const v of f.getAudioTracks()) v.enabled = !m;
|
|
3413
3458
|
return m;
|
|
3414
3459
|
},
|
|
3415
3460
|
isMuted() {
|
|
3416
|
-
return
|
|
3461
|
+
return f.getAudioTracks().every((m) => !m.enabled);
|
|
3417
3462
|
}
|
|
3418
3463
|
};
|
|
3419
3464
|
}
|
|
3420
|
-
function
|
|
3465
|
+
function So(t) {
|
|
3421
3466
|
return new Promise((e, n) => {
|
|
3422
|
-
let
|
|
3467
|
+
let a;
|
|
3423
3468
|
try {
|
|
3424
|
-
|
|
3469
|
+
a = new WebSocket(t, xo);
|
|
3425
3470
|
} catch (i) {
|
|
3426
3471
|
n(i);
|
|
3427
3472
|
return;
|
|
3428
3473
|
}
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
},
|
|
3432
|
-
|
|
3474
|
+
a.onopen = () => {
|
|
3475
|
+
a.onopen = null, a.onerror = null, e(a);
|
|
3476
|
+
}, a.onerror = () => {
|
|
3477
|
+
a.onopen = null, a.onerror = null, n(new Error("[BugCatch] could not connect the call."));
|
|
3433
3478
|
};
|
|
3434
3479
|
});
|
|
3435
3480
|
}
|
|
3436
|
-
function
|
|
3481
|
+
function dn(t) {
|
|
3437
3482
|
try {
|
|
3438
3483
|
console.warn(`[BugCatch] ${t}`);
|
|
3439
3484
|
} catch {
|
|
3440
3485
|
}
|
|
3441
3486
|
}
|
|
3442
|
-
function
|
|
3487
|
+
function un(t) {
|
|
3443
3488
|
var e;
|
|
3444
3489
|
for (const n of ((e = t == null ? void 0 : t.getTracks) == null ? void 0 : e.call(t)) ?? [])
|
|
3445
3490
|
try {
|
|
@@ -3447,7 +3492,7 @@ function cn(t) {
|
|
|
3447
3492
|
} catch {
|
|
3448
3493
|
}
|
|
3449
3494
|
}
|
|
3450
|
-
const
|
|
3495
|
+
const Ze = {
|
|
3451
3496
|
cycleMs: 3e3,
|
|
3452
3497
|
peak: 0.045,
|
|
3453
3498
|
bursts: [
|
|
@@ -3455,17 +3500,17 @@ const Xe = {
|
|
|
3455
3500
|
{ at: 0.55, seconds: 0.4, hz: [440, 660] }
|
|
3456
3501
|
]
|
|
3457
3502
|
};
|
|
3458
|
-
let
|
|
3503
|
+
let An = !1;
|
|
3459
3504
|
if (typeof window < "u" && window.addEventListener)
|
|
3460
3505
|
for (const t of ["pointerdown", "keydown", "touchstart"])
|
|
3461
3506
|
window.addEventListener(t, () => {
|
|
3462
|
-
|
|
3507
|
+
An = !0;
|
|
3463
3508
|
}, {
|
|
3464
3509
|
once: !0,
|
|
3465
3510
|
capture: !0,
|
|
3466
3511
|
passive: !0
|
|
3467
3512
|
});
|
|
3468
|
-
function
|
|
3513
|
+
function Co() {
|
|
3469
3514
|
var t;
|
|
3470
3515
|
try {
|
|
3471
3516
|
return !!((t = navigator.userActivation) != null && t.hasBeenActive);
|
|
@@ -3473,8 +3518,8 @@ function xa() {
|
|
|
3473
3518
|
return !1;
|
|
3474
3519
|
}
|
|
3475
3520
|
}
|
|
3476
|
-
function
|
|
3477
|
-
if (!
|
|
3521
|
+
function $o() {
|
|
3522
|
+
if (!An && !Co()) return () => {
|
|
3478
3523
|
};
|
|
3479
3524
|
const t = typeof window < "u" && (window.AudioContext || window.webkitAudioContext);
|
|
3480
3525
|
if (!t) return () => {
|
|
@@ -3486,29 +3531,29 @@ function ka() {
|
|
|
3486
3531
|
return () => {
|
|
3487
3532
|
};
|
|
3488
3533
|
}
|
|
3489
|
-
let n = !1,
|
|
3490
|
-
const i = [], r = ({ at:
|
|
3491
|
-
const
|
|
3492
|
-
b.connect(e.destination), b.gain.setValueAtTime(0,
|
|
3493
|
-
for (const
|
|
3494
|
-
const
|
|
3495
|
-
|
|
3534
|
+
let n = !1, a = null;
|
|
3535
|
+
const i = [], r = ({ at: p, seconds: f, hz: y }) => {
|
|
3536
|
+
const h = e.currentTime + p, b = e.createGain();
|
|
3537
|
+
b.connect(e.destination), b.gain.setValueAtTime(0, h), b.gain.linearRampToValueAtTime(Ze.peak, h + 0.02), b.gain.setValueAtTime(Ze.peak, h + f - 0.06), b.gain.linearRampToValueAtTime(0, h + f);
|
|
3538
|
+
for (const g of y) {
|
|
3539
|
+
const S = e.createOscillator();
|
|
3540
|
+
S.type = "sine", S.frequency.value = g, S.connect(b), S.start(h), S.stop(h + f + 0.02), i.push(S);
|
|
3496
3541
|
}
|
|
3497
3542
|
}, s = () => {
|
|
3498
3543
|
if (!n)
|
|
3499
3544
|
try {
|
|
3500
|
-
|
|
3545
|
+
Ze.bursts.forEach(r);
|
|
3501
3546
|
} catch {
|
|
3502
3547
|
}
|
|
3503
3548
|
}, l = () => {
|
|
3504
|
-
n || (s(),
|
|
3549
|
+
n || (s(), a = setInterval(s, Ze.cycleMs));
|
|
3505
3550
|
};
|
|
3506
3551
|
return e.state === "running" ? l() : e.resume().then(l).catch(() => {
|
|
3507
3552
|
}), () => {
|
|
3508
|
-
n = !0,
|
|
3509
|
-
for (const
|
|
3553
|
+
n = !0, a && clearInterval(a);
|
|
3554
|
+
for (const p of i)
|
|
3510
3555
|
try {
|
|
3511
|
-
|
|
3556
|
+
p.stop();
|
|
3512
3557
|
} catch {
|
|
3513
3558
|
}
|
|
3514
3559
|
try {
|
|
@@ -3517,11 +3562,11 @@ function ka() {
|
|
|
3517
3562
|
}
|
|
3518
3563
|
};
|
|
3519
3564
|
}
|
|
3520
|
-
function
|
|
3565
|
+
function Eo(t) {
|
|
3521
3566
|
const e = Date.parse(t || "");
|
|
3522
3567
|
return Number.isNaN(e) ? 0 : Math.max(0, Math.round((e - Date.now()) / 1e3));
|
|
3523
3568
|
}
|
|
3524
|
-
const
|
|
3569
|
+
const pn = [
|
|
3525
3570
|
"flex:1",
|
|
3526
3571
|
"padding:9px 12px",
|
|
3527
3572
|
"border:0",
|
|
@@ -3529,18 +3574,18 @@ const ln = [
|
|
|
3529
3574
|
"font:600 13px/1.4 inherit",
|
|
3530
3575
|
"cursor:pointer"
|
|
3531
3576
|
].join(";");
|
|
3532
|
-
function
|
|
3577
|
+
function To({
|
|
3533
3578
|
call: t,
|
|
3534
3579
|
accent: e = "#5b6ef5",
|
|
3535
3580
|
position: n = "bottom-right",
|
|
3536
|
-
onAnswer:
|
|
3581
|
+
onAnswer: a,
|
|
3537
3582
|
onDecline: i,
|
|
3538
3583
|
onExpire: r
|
|
3539
3584
|
}) {
|
|
3540
3585
|
if (typeof document > "u" || !document.body) return () => {
|
|
3541
3586
|
};
|
|
3542
|
-
const [s, l] = String(n).split("-"),
|
|
3543
|
-
|
|
3587
|
+
const [s, l] = String(n).split("-"), p = document.createElement("div");
|
|
3588
|
+
p.setAttribute("role", "alertdialog"), p.setAttribute("aria-live", "assertive"), p.setAttribute("aria-label", `${t.from || "Support"} is calling about ${t.reference}`), p.style.cssText = [
|
|
3544
3589
|
"position:fixed",
|
|
3545
3590
|
`${s === "top" ? "top" : "bottom"}:20px`,
|
|
3546
3591
|
`${l === "left" ? "left" : "right"}:20px`,
|
|
@@ -3560,56 +3605,56 @@ function Ca({
|
|
|
3560
3605
|
"transform:translateY(8px)",
|
|
3561
3606
|
"transition:opacity .2s ease,transform .2s ease"
|
|
3562
3607
|
].join(";");
|
|
3563
|
-
const
|
|
3564
|
-
|
|
3608
|
+
const f = document.createElement("div");
|
|
3609
|
+
f.style.cssText = "font-weight:600;font-size:14px;margin-bottom:2px", f.textContent = `${t.from || "Support"} is calling`;
|
|
3565
3610
|
const y = document.createElement("div");
|
|
3566
3611
|
y.style.cssText = "color:#a4abba;margin-bottom:10px", y.textContent = t.project ? `About your report ${t.reference} · ${t.project}` : `About your report ${t.reference}`;
|
|
3567
|
-
const
|
|
3568
|
-
|
|
3612
|
+
const h = document.createElement("div");
|
|
3613
|
+
h.style.cssText = "color:#7d8598;font-size:12px;margin-bottom:10px";
|
|
3569
3614
|
const b = document.createElement("button");
|
|
3570
|
-
b.type = "button", b.textContent = "Answer", b.style.cssText = `${
|
|
3571
|
-
const
|
|
3572
|
-
|
|
3573
|
-
const
|
|
3574
|
-
if (
|
|
3615
|
+
b.type = "button", b.textContent = "Answer", b.style.cssText = `${pn};background:${e};color:#fff`;
|
|
3616
|
+
const g = document.createElement("button");
|
|
3617
|
+
g.type = "button", g.textContent = "Not now", g.style.cssText = `${pn};background:#2b2f3a;color:#c8cedb`;
|
|
3618
|
+
const S = document.createElement("div");
|
|
3619
|
+
if (S.style.cssText = "display:flex;gap:8px", S.append(b, g), p.append(f, y, h), t.recorded) {
|
|
3575
3620
|
const L = document.createElement("div");
|
|
3576
|
-
L.style.cssText = "color:#7d8598;font-size:12px;margin-bottom:10px", L.textContent = "This call will be recorded.",
|
|
3621
|
+
L.style.cssText = "color:#7d8598;font-size:12px;margin-bottom:10px", L.textContent = "This call will be recorded.", p.append(L);
|
|
3577
3622
|
}
|
|
3578
|
-
|
|
3579
|
-
const A =
|
|
3580
|
-
let
|
|
3581
|
-
const
|
|
3582
|
-
|
|
3623
|
+
p.append(S), document.body.appendChild(p);
|
|
3624
|
+
const A = $o();
|
|
3625
|
+
let ae = !1, C = null;
|
|
3626
|
+
const $ = () => {
|
|
3627
|
+
ae || (ae = !0, C && clearInterval(C), A(), p.style.opacity = "0", p.style.transform = "translateY(8px)", setTimeout(() => p.remove(), 250));
|
|
3583
3628
|
}, T = () => {
|
|
3584
|
-
const L =
|
|
3585
|
-
if (
|
|
3586
|
-
|
|
3629
|
+
const L = Eo(t.ringsUntil);
|
|
3630
|
+
if (h.textContent = L ? `Ringing — ${L}s` : "The call has stopped ringing.", !L) {
|
|
3631
|
+
$();
|
|
3587
3632
|
try {
|
|
3588
3633
|
r == null || r();
|
|
3589
3634
|
} catch {
|
|
3590
3635
|
}
|
|
3591
3636
|
}
|
|
3592
3637
|
};
|
|
3593
|
-
return T(),
|
|
3594
|
-
|
|
3638
|
+
return T(), C = setInterval(T, 1e3), b.addEventListener("click", () => {
|
|
3639
|
+
$();
|
|
3595
3640
|
try {
|
|
3596
|
-
|
|
3641
|
+
a == null || a();
|
|
3597
3642
|
} catch {
|
|
3598
3643
|
}
|
|
3599
|
-
}),
|
|
3600
|
-
|
|
3644
|
+
}), g.addEventListener("click", () => {
|
|
3645
|
+
$();
|
|
3601
3646
|
try {
|
|
3602
3647
|
i == null || i();
|
|
3603
3648
|
} catch {
|
|
3604
3649
|
}
|
|
3605
3650
|
}), requestAnimationFrame(() => {
|
|
3606
|
-
|
|
3607
|
-
}),
|
|
3651
|
+
p.style.opacity = "1", p.style.transform = "translateY(0)";
|
|
3652
|
+
}), $;
|
|
3608
3653
|
}
|
|
3609
|
-
const
|
|
3654
|
+
const hn = {
|
|
3610
3655
|
name: "@sphoro/bugcatch-web-sdk",
|
|
3611
|
-
version: "0.14.
|
|
3612
|
-
},
|
|
3656
|
+
version: "0.14.4"
|
|
3657
|
+
}, Je = {
|
|
3613
3658
|
apiBase: "http://localhost:3000",
|
|
3614
3659
|
apiKey: null,
|
|
3615
3660
|
projectId: null,
|
|
@@ -3661,18 +3706,18 @@ const dn = {
|
|
|
3661
3706
|
// switch the whole thing off.
|
|
3662
3707
|
onIncomingCall: null
|
|
3663
3708
|
};
|
|
3664
|
-
var B, me,
|
|
3665
|
-
class
|
|
3709
|
+
var B, me, Ge, Qn, jn, zn, et, On;
|
|
3710
|
+
class Rn {
|
|
3666
3711
|
constructor() {
|
|
3667
|
-
|
|
3668
|
-
this.config = { ...
|
|
3712
|
+
Xt(this, B);
|
|
3713
|
+
this.config = { ...Je }, this.started = !1, this.teardown = [], this.consoleBuffer = We(Je.consoleLimit), this.networkBuffer = We(Je.networkLimit), this.stopWatching = null, this.notifier = null, this.call = null, this.callStarting = !1, this.ringing = null, this.listeners = /* @__PURE__ */ new Map();
|
|
3669
3714
|
}
|
|
3670
3715
|
init(e = {}) {
|
|
3671
3716
|
if (this.started)
|
|
3672
3717
|
return console.warn("[BugCatch] init() called twice — ignoring the second call."), this;
|
|
3673
|
-
if (this.config = { ...
|
|
3718
|
+
if (this.config = { ...Je, ...e }, !this.config.apiKey) throw new Error("[BugCatch] apiKey is required.");
|
|
3674
3719
|
if (!this.config.projectId) throw new Error("[BugCatch] projectId is required.");
|
|
3675
|
-
return this.consoleBuffer =
|
|
3720
|
+
return this.consoleBuffer = We(this.config.consoleLimit), this.networkBuffer = We(this.config.networkLimit), this.config.captureConsole && this.teardown.push(aa(this.consoleBuffer)), this.config.captureNetwork && this.teardown.push(oa(this.networkBuffer)), this.config.captureErrors && this.teardown.push(ra(this.consoleBuffer)), this.config.widget && this.teardown.push(so(this)), this.config.updates && se() && (this.startWatching(), queueMicrotask(() => P(this, B, me).call(this))), this.started = !0, this;
|
|
3676
3721
|
}
|
|
3677
3722
|
/**
|
|
3678
3723
|
* Open the update stream. Idempotent — init() and a first report both reach
|
|
@@ -3680,26 +3725,26 @@ class Ln {
|
|
|
3680
3725
|
*/
|
|
3681
3726
|
startWatching() {
|
|
3682
3727
|
if (this.stopWatching) return this;
|
|
3683
|
-
this.stopWatching =
|
|
3728
|
+
this.stopWatching = Da({
|
|
3684
3729
|
apiBase: this.config.apiBase,
|
|
3685
3730
|
onUpdate: (n) => {
|
|
3686
3731
|
if (n != null && n.incomingCall) {
|
|
3687
|
-
|
|
3732
|
+
P(this, B, zn).call(this, n);
|
|
3688
3733
|
return;
|
|
3689
3734
|
}
|
|
3690
3735
|
if (n != null && n.callWithdrawn) {
|
|
3691
|
-
|
|
3736
|
+
P(this, B, et).call(this, n.callWithdrawn.callId);
|
|
3692
3737
|
return;
|
|
3693
3738
|
}
|
|
3694
|
-
const
|
|
3695
|
-
typeof this.config.onUpdate == "function" && this.config.onUpdate(
|
|
3739
|
+
const a = Ma(n);
|
|
3740
|
+
typeof this.config.onUpdate == "function" && this.config.onUpdate(a), this.emit("update", a), P(this, B, me).call(this);
|
|
3696
3741
|
}
|
|
3697
3742
|
}), this.teardown.push(() => {
|
|
3698
3743
|
var n;
|
|
3699
3744
|
return (n = this.stopWatching) == null ? void 0 : n.call(this);
|
|
3700
|
-
}), this.teardown.push(() =>
|
|
3745
|
+
}), this.teardown.push(() => P(this, B, et).call(this));
|
|
3701
3746
|
const e = (n) => {
|
|
3702
|
-
(n.key === ot || n.key === null) &&
|
|
3747
|
+
(n.key === ot || n.key === null) && P(this, B, me).call(this);
|
|
3703
3748
|
};
|
|
3704
3749
|
return window.addEventListener("storage", e), this.teardown.push(() => window.removeEventListener("storage", e)), this;
|
|
3705
3750
|
}
|
|
@@ -3716,18 +3761,18 @@ class Ln {
|
|
|
3716
3761
|
on(e, n) {
|
|
3717
3762
|
if (typeof n != "function") return () => {
|
|
3718
3763
|
};
|
|
3719
|
-
const
|
|
3720
|
-
return
|
|
3764
|
+
const a = this.listeners.get(e) || /* @__PURE__ */ new Set();
|
|
3765
|
+
return a.add(n), this.listeners.set(e, a), () => this.off(e, n);
|
|
3721
3766
|
}
|
|
3722
3767
|
off(e, n) {
|
|
3723
|
-
var
|
|
3724
|
-
return (
|
|
3768
|
+
var a;
|
|
3769
|
+
return (a = this.listeners.get(e)) == null || a.delete(n), this;
|
|
3725
3770
|
}
|
|
3726
3771
|
/** Notify listeners; one that throws must not stop the rest. */
|
|
3727
3772
|
emit(e, n) {
|
|
3728
|
-
for (const
|
|
3773
|
+
for (const a of this.listeners.get(e) || [])
|
|
3729
3774
|
try {
|
|
3730
|
-
|
|
3775
|
+
a(n);
|
|
3731
3776
|
} catch (i) {
|
|
3732
3777
|
console.error("[BugCatch] an update listener threw:", i);
|
|
3733
3778
|
}
|
|
@@ -3756,7 +3801,7 @@ class Ln {
|
|
|
3756
3801
|
* knows when its reader has seen one, so it has to say.
|
|
3757
3802
|
*/
|
|
3758
3803
|
markUpdateRead(e) {
|
|
3759
|
-
return
|
|
3804
|
+
return La(e), P(this, B, me).call(this), this;
|
|
3760
3805
|
}
|
|
3761
3806
|
/**
|
|
3762
3807
|
* Mark everything about one report read.
|
|
@@ -3765,11 +3810,11 @@ class Ln {
|
|
|
3765
3810
|
* the thread opens; an integration with its own report view should too.
|
|
3766
3811
|
*/
|
|
3767
3812
|
markReportRead(e) {
|
|
3768
|
-
return
|
|
3813
|
+
return Ba(e), P(this, B, me).call(this), this;
|
|
3769
3814
|
}
|
|
3770
3815
|
/** Mark everything read. The "clear all" behind your own notification list. */
|
|
3771
3816
|
markUpdatesRead() {
|
|
3772
|
-
return
|
|
3817
|
+
return kn(), P(this, B, me).call(this), this;
|
|
3773
3818
|
}
|
|
3774
3819
|
/**
|
|
3775
3820
|
* One report in full, with its timeline — every step from filing to now.
|
|
@@ -3779,12 +3824,12 @@ class Ln {
|
|
|
3779
3824
|
*
|
|
3780
3825
|
* Resolves to null when this browser cannot prove it filed that report.
|
|
3781
3826
|
*/
|
|
3782
|
-
async verifyFix(e, { result: n, resolvedAt:
|
|
3783
|
-
const r = n === "STILL_HAPPENING" ? await
|
|
3784
|
-
return
|
|
3827
|
+
async verifyFix(e, { result: n, resolvedAt: a, note: i }) {
|
|
3828
|
+
const r = n === "STILL_HAPPENING" ? await P(this, B, Ge).call(this, {}) : {};
|
|
3829
|
+
return Za({ apiBase: this.config.apiBase, bugId: e, result: n, resolvedAt: a, note: i, metadata: r.metadata, logs: r.logs });
|
|
3785
3830
|
}
|
|
3786
3831
|
myReport(e) {
|
|
3787
|
-
return
|
|
3832
|
+
return Qa({ apiBase: this.config.apiBase, bugId: e });
|
|
3788
3833
|
}
|
|
3789
3834
|
/**
|
|
3790
3835
|
* Write back on a report this browser filed.
|
|
@@ -3799,8 +3844,8 @@ class Ln {
|
|
|
3799
3844
|
* integration rendering its own can too. Resolves to the stored message, so
|
|
3800
3845
|
* the caller renders what the server kept rather than what it hoped it sent.
|
|
3801
3846
|
*/
|
|
3802
|
-
replyToReport(e, { body: n, attachments:
|
|
3803
|
-
return
|
|
3847
|
+
replyToReport(e, { body: n, attachments: a } = {}) {
|
|
3848
|
+
return Sn({ apiBase: this.config.apiBase, bugId: e, body: n, attachments: a });
|
|
3804
3849
|
}
|
|
3805
3850
|
/**
|
|
3806
3851
|
* Whether this visitor can report something by talking about it instead.
|
|
@@ -3853,7 +3898,7 @@ class Ln {
|
|
|
3853
3898
|
async callKinds() {
|
|
3854
3899
|
var n;
|
|
3855
3900
|
const e = { agent: !1, live: !1 };
|
|
3856
|
-
return !this.config.voice || !((n = this.config.user) != null && n.email) ? e : this.kinds !== void 0 ? this.kinds : (this.kinds = await
|
|
3901
|
+
return !this.config.voice || !((n = this.config.user) != null && n.email) ? e : this.kinds !== void 0 ? this.kinds : (this.kinds = await ja({
|
|
3857
3902
|
apiBase: this.config.apiBase,
|
|
3858
3903
|
apiKey: this.config.apiKey,
|
|
3859
3904
|
projectId: this.config.projectId
|
|
@@ -3874,7 +3919,7 @@ class Ln {
|
|
|
3874
3919
|
* for either of them to be asking about.
|
|
3875
3920
|
*/
|
|
3876
3921
|
canCall(e) {
|
|
3877
|
-
return this.config.voice ?
|
|
3922
|
+
return this.config.voice ? en({ apiBase: this.config.apiBase, bugId: e }) : Promise.resolve(!1);
|
|
3878
3923
|
}
|
|
3879
3924
|
/**
|
|
3880
3925
|
* Ring the team.
|
|
@@ -3917,7 +3962,7 @@ class Ln {
|
|
|
3917
3962
|
try {
|
|
3918
3963
|
if (!await this.callKind())
|
|
3919
3964
|
throw new Error((n = this.config.user) != null && n.email ? "[BugCatch] calling is not available on this project." : "[BugCatch] a call needs to know who is calling — call identify() with an email first.");
|
|
3920
|
-
return await
|
|
3965
|
+
return await P(this, B, jn).call(this, e);
|
|
3921
3966
|
} finally {
|
|
3922
3967
|
this.callStarting = !1;
|
|
3923
3968
|
}
|
|
@@ -3940,7 +3985,7 @@ class Ln {
|
|
|
3940
3985
|
* For a host application drawing its own button. The widget asks this itself.
|
|
3941
3986
|
*/
|
|
3942
3987
|
canCallTeam(e) {
|
|
3943
|
-
return this.config.voice ?
|
|
3988
|
+
return this.config.voice ? en({ apiBase: this.config.apiBase, bugId: e }) : Promise.resolve(!1);
|
|
3944
3989
|
}
|
|
3945
3990
|
/**
|
|
3946
3991
|
* End the call in progress, of either kind. Does nothing when there is not
|
|
@@ -3962,7 +4007,7 @@ class Ln {
|
|
|
3962
4007
|
* nothing to look up in either case.
|
|
3963
4008
|
*/
|
|
3964
4009
|
myReports() {
|
|
3965
|
-
return
|
|
4010
|
+
return Ra({ apiBase: this.config.apiBase });
|
|
3966
4011
|
}
|
|
3967
4012
|
/** True when this browser has filed something, so a "your reports" entry
|
|
3968
4013
|
* point can be hidden until it would show anything. */
|
|
@@ -3975,7 +4020,7 @@ class Ln {
|
|
|
3975
4020
|
*/
|
|
3976
4021
|
forgetReports() {
|
|
3977
4022
|
var e;
|
|
3978
|
-
return (e = this.stopWatching) == null || e.call(this), this.stopWatching = null, this.endCall(),
|
|
4023
|
+
return (e = this.stopWatching) == null || e.call(this), this.stopWatching = null, this.endCall(), $e(), P(this, B, me).call(this), this;
|
|
3979
4024
|
}
|
|
3980
4025
|
/**
|
|
3981
4026
|
* Attach the signed-in user so reports say who hit the bug.
|
|
@@ -4002,46 +4047,46 @@ class Ln {
|
|
|
4002
4047
|
* through the API — so this is also what you call when you drive the SDK
|
|
4003
4048
|
* yourself with `widget: false`.
|
|
4004
4049
|
*/
|
|
4005
|
-
async uploadAttachment(e, n,
|
|
4050
|
+
async uploadAttachment(e, n, a) {
|
|
4006
4051
|
if (!this.started) throw new Error("[BugCatch] call init() first.");
|
|
4007
|
-
return
|
|
4052
|
+
return ga({
|
|
4008
4053
|
apiBase: this.config.apiBase,
|
|
4009
4054
|
apiKey: this.config.apiKey,
|
|
4010
4055
|
blob: e,
|
|
4011
4056
|
mime: n || (e == null ? void 0 : e.type),
|
|
4012
|
-
onProgress:
|
|
4057
|
+
onProgress: a
|
|
4013
4058
|
});
|
|
4014
4059
|
}
|
|
4015
4060
|
/** File a bug with everything captured so far. */
|
|
4016
4061
|
async report({
|
|
4017
4062
|
title: e,
|
|
4018
4063
|
description: n = "",
|
|
4019
|
-
priority:
|
|
4064
|
+
priority: a = "MEDIUM",
|
|
4020
4065
|
metadata: i = {},
|
|
4021
4066
|
attachments: r = [],
|
|
4022
4067
|
references: s = []
|
|
4023
4068
|
} = {}) {
|
|
4024
4069
|
if (!this.started) throw new Error("[BugCatch] call init() first.");
|
|
4025
4070
|
if (!e || !e.trim()) throw new Error("[BugCatch] a title is required.");
|
|
4026
|
-
const l = (r || []).filter((b) => (b == null ? void 0 : b.storageKey) &&
|
|
4071
|
+
const l = (r || []).filter((b) => (b == null ? void 0 : b.storageKey) && nt(b.mime, tt)).map((b) => ({
|
|
4027
4072
|
type: b.type === "VIDEO" ? "VIDEO" : "SCREENSHOT",
|
|
4028
4073
|
storageKey: b.storageKey,
|
|
4029
|
-
mime:
|
|
4074
|
+
mime: nt(b.mime, tt)
|
|
4030
4075
|
}));
|
|
4031
|
-
let
|
|
4076
|
+
let p = await P(this, B, Ge).call(this, {
|
|
4032
4077
|
title: e.trim(),
|
|
4033
4078
|
description: n,
|
|
4034
|
-
priority:
|
|
4079
|
+
priority: a,
|
|
4035
4080
|
metadata: i,
|
|
4036
4081
|
media: l,
|
|
4037
4082
|
references: s
|
|
4038
4083
|
});
|
|
4039
4084
|
if (typeof this.config.beforeSend == "function") {
|
|
4040
|
-
const b = this.config.beforeSend(
|
|
4085
|
+
const b = this.config.beforeSend(p);
|
|
4041
4086
|
if (b === !1) return { cancelled: !0 };
|
|
4042
|
-
b && typeof b == "object" && (
|
|
4087
|
+
b && typeof b == "object" && (p = b);
|
|
4043
4088
|
}
|
|
4044
|
-
const
|
|
4089
|
+
const f = he(this.config.projectId), y = await fetch(`${this.config.apiBase}/ingest/bugs`, {
|
|
4045
4090
|
method: "POST",
|
|
4046
4091
|
headers: {
|
|
4047
4092
|
"Content-Type": "application/json",
|
|
@@ -4050,21 +4095,21 @@ class Ln {
|
|
|
4050
4095
|
// address from here rather than from the payload when it is — on a
|
|
4051
4096
|
// project that requires sign-in, letting the page name a different
|
|
4052
4097
|
// reporter would undo the requirement.
|
|
4053
|
-
...
|
|
4098
|
+
...f != null && f.token ? { "X-BugCatch-Session": f.token } : {}
|
|
4054
4099
|
},
|
|
4055
|
-
body: JSON.stringify(
|
|
4100
|
+
body: JSON.stringify(p)
|
|
4056
4101
|
});
|
|
4057
|
-
if (y.status === 401 &&
|
|
4102
|
+
if (y.status === 401 && f && St(this.config.projectId), !y.ok) {
|
|
4058
4103
|
let b = "";
|
|
4059
4104
|
try {
|
|
4060
|
-
const
|
|
4061
|
-
b = Array.isArray(
|
|
4105
|
+
const g = await y.json();
|
|
4106
|
+
b = Array.isArray(g.message) ? g.message.join(", ") : g.message || "";
|
|
4062
4107
|
} catch {
|
|
4063
4108
|
}
|
|
4064
4109
|
throw new Error(`[BugCatch] report failed (HTTP ${y.status})${b ? ": " + b : ""}`);
|
|
4065
4110
|
}
|
|
4066
|
-
const
|
|
4067
|
-
return
|
|
4111
|
+
const h = await y.json();
|
|
4112
|
+
return h.watchToken && (Ct(h.watchToken), this.config.updates && this.startWatching()), h;
|
|
4068
4113
|
}
|
|
4069
4114
|
/**
|
|
4070
4115
|
* What this project asks of the person reporting, and who this browser is
|
|
@@ -4083,7 +4128,7 @@ class Ln {
|
|
|
4083
4128
|
*/
|
|
4084
4129
|
loginState() {
|
|
4085
4130
|
var e;
|
|
4086
|
-
return
|
|
4131
|
+
return Sa({
|
|
4087
4132
|
apiBase: this.config.apiBase,
|
|
4088
4133
|
apiKey: this.config.apiKey,
|
|
4089
4134
|
projectId: this.config.projectId,
|
|
@@ -4106,7 +4151,7 @@ class Ln {
|
|
|
4106
4151
|
* whether that form should have an identifier box on it.
|
|
4107
4152
|
*/
|
|
4108
4153
|
referenceFields() {
|
|
4109
|
-
return this.refFields ? this.refFields : (this.refFields =
|
|
4154
|
+
return this.refFields ? this.refFields : (this.refFields = no({
|
|
4110
4155
|
apiBase: this.config.apiBase,
|
|
4111
4156
|
apiKey: this.config.apiKey,
|
|
4112
4157
|
projectId: this.config.projectId
|
|
@@ -4137,14 +4182,14 @@ class Ln {
|
|
|
4137
4182
|
* address, which is all a reply-to has ever needed to be worth.
|
|
4138
4183
|
*/
|
|
4139
4184
|
signIn(e, { name: n } = {}) {
|
|
4140
|
-
var
|
|
4141
|
-
return
|
|
4185
|
+
var a;
|
|
4186
|
+
return Ca({
|
|
4142
4187
|
apiBase: this.config.apiBase,
|
|
4143
4188
|
apiKey: this.config.apiKey,
|
|
4144
4189
|
projectId: this.config.projectId,
|
|
4145
4190
|
email: e,
|
|
4146
4191
|
// The name the host app already knows beats asking for one again.
|
|
4147
|
-
name: n ?? ((
|
|
4192
|
+
name: n ?? ((a = this.config.user) == null ? void 0 : a.name) ?? null
|
|
4148
4193
|
});
|
|
4149
4194
|
}
|
|
4150
4195
|
/**
|
|
@@ -4156,14 +4201,14 @@ class Ln {
|
|
|
4156
4201
|
*/
|
|
4157
4202
|
async confirmSignIn(e, n) {
|
|
4158
4203
|
var i;
|
|
4159
|
-
const
|
|
4204
|
+
const a = await $a({
|
|
4160
4205
|
apiBase: this.config.apiBase,
|
|
4161
4206
|
apiKey: this.config.apiKey,
|
|
4162
4207
|
projectId: this.config.projectId,
|
|
4163
4208
|
email: e,
|
|
4164
4209
|
code: n
|
|
4165
4210
|
});
|
|
4166
|
-
return (i = this.config.user) != null && i.email || (this.config.user = { email:
|
|
4211
|
+
return (i = this.config.user) != null && i.email || (this.config.user = { email: a.email, name: a.name || void 0 }), this.emit("signin", { email: a.email, name: a.name }), { email: a.email, name: a.name };
|
|
4167
4212
|
}
|
|
4168
4213
|
/**
|
|
4169
4214
|
* Sign out of this project.
|
|
@@ -4173,14 +4218,14 @@ class Ln {
|
|
|
4173
4218
|
* says — sign-out on a shared machine has to mean signed out on it.
|
|
4174
4219
|
*/
|
|
4175
4220
|
async signOut() {
|
|
4176
|
-
var
|
|
4177
|
-
const e = he(this.config.projectId), n = await
|
|
4221
|
+
var a;
|
|
4222
|
+
const e = he(this.config.projectId), n = await Ea({
|
|
4178
4223
|
apiBase: this.config.apiBase,
|
|
4179
4224
|
apiKey: this.config.apiKey,
|
|
4180
4225
|
projectId: this.config.projectId,
|
|
4181
4226
|
token: e == null ? void 0 : e.token
|
|
4182
4227
|
});
|
|
4183
|
-
return e != null && e.email && ((
|
|
4228
|
+
return e != null && e.email && ((a = this.config.user) == null ? void 0 : a.email) === e.email && (this.config.user = null), this.emit("signout", { email: (e == null ? void 0 : e.email) || null }), n;
|
|
4184
4229
|
}
|
|
4185
4230
|
/** What would be sent right now — useful for debugging integrations. */
|
|
4186
4231
|
/**
|
|
@@ -4193,7 +4238,7 @@ class Ln {
|
|
|
4193
4238
|
*/
|
|
4194
4239
|
knownIssues() {
|
|
4195
4240
|
var e;
|
|
4196
|
-
return
|
|
4241
|
+
return Fa({
|
|
4197
4242
|
apiBase: this.config.apiBase,
|
|
4198
4243
|
apiKey: this.config.apiKey,
|
|
4199
4244
|
projectId: this.config.projectId,
|
|
@@ -4207,13 +4252,13 @@ class Ln {
|
|
|
4207
4252
|
* the results of whichever request happens to return last.
|
|
4208
4253
|
*/
|
|
4209
4254
|
matchKnownIssues(e, { signal: n } = {}) {
|
|
4210
|
-
var
|
|
4211
|
-
return
|
|
4255
|
+
var a;
|
|
4256
|
+
return Wa({
|
|
4212
4257
|
apiBase: this.config.apiBase,
|
|
4213
4258
|
apiKey: this.config.apiKey,
|
|
4214
4259
|
projectId: this.config.projectId,
|
|
4215
4260
|
q: e || "",
|
|
4216
|
-
sessionToken: (
|
|
4261
|
+
sessionToken: (a = he(this.config.projectId)) == null ? void 0 : a.token,
|
|
4217
4262
|
signal: n
|
|
4218
4263
|
});
|
|
4219
4264
|
}
|
|
@@ -4230,17 +4275,17 @@ class Ln {
|
|
|
4230
4275
|
* me when this is fixed", and there is no way to keep that promise to
|
|
4231
4276
|
* somebody anonymous.
|
|
4232
4277
|
*/
|
|
4233
|
-
async meToo(e, { email: n, name:
|
|
4278
|
+
async meToo(e, { email: n, name: a } = {}) {
|
|
4234
4279
|
var s, l;
|
|
4235
|
-
const i = he(this.config.projectId), r = await
|
|
4236
|
-
return
|
|
4280
|
+
const i = he(this.config.projectId), r = await Jt();
|
|
4281
|
+
return Ya({
|
|
4237
4282
|
apiBase: this.config.apiBase,
|
|
4238
4283
|
apiKey: this.config.apiKey,
|
|
4239
4284
|
projectId: this.config.projectId,
|
|
4240
4285
|
bugId: e,
|
|
4241
4286
|
reporterEmail: n || ((s = this.config.user) == null ? void 0 : s.email),
|
|
4242
|
-
reporterName:
|
|
4243
|
-
metadata: { ...r, user: this.config.user || void 0, sdk:
|
|
4287
|
+
reporterName: a || ((l = this.config.user) == null ? void 0 : l.name),
|
|
4288
|
+
metadata: { ...r, user: this.config.user || void 0, sdk: hn },
|
|
4244
4289
|
logs: {
|
|
4245
4290
|
console: { entries: this.consoleBuffer.all() },
|
|
4246
4291
|
network: { entries: this.networkBuffer.all() }
|
|
@@ -4252,7 +4297,7 @@ class Ln {
|
|
|
4252
4297
|
return {
|
|
4253
4298
|
console: this.consoleBuffer.all(),
|
|
4254
4299
|
network: this.networkBuffer.all(),
|
|
4255
|
-
environment:
|
|
4300
|
+
environment: yn()
|
|
4256
4301
|
};
|
|
4257
4302
|
}
|
|
4258
4303
|
clear() {
|
|
@@ -4280,7 +4325,7 @@ me = function() {
|
|
|
4280
4325
|
if (this.emit("unread", { count: e.length, updates: e }), !!this.config.updateToast) {
|
|
4281
4326
|
if (!this.notifier) {
|
|
4282
4327
|
if (!e.length) return;
|
|
4283
|
-
this.notifier =
|
|
4328
|
+
this.notifier = _a({
|
|
4284
4329
|
accent: this.config.accent,
|
|
4285
4330
|
position: this.config.widgetPosition,
|
|
4286
4331
|
onRead: (n) => this.markUpdateRead(n),
|
|
@@ -4299,26 +4344,26 @@ me = function() {
|
|
|
4299
4344
|
}
|
|
4300
4345
|
this.notifier.render(e);
|
|
4301
4346
|
}
|
|
4302
|
-
},
|
|
4303
|
-
var l,
|
|
4347
|
+
}, Ge = async function({ title: e, description: n = "", priority: a = "MEDIUM", metadata: i = {}, media: r = [], references: s = [] }) {
|
|
4348
|
+
var l, p;
|
|
4304
4349
|
return {
|
|
4305
4350
|
projectId: this.config.projectId,
|
|
4306
4351
|
...e ? { title: e } : {},
|
|
4307
4352
|
description: n,
|
|
4308
|
-
priority:
|
|
4353
|
+
priority: a,
|
|
4309
4354
|
url: window.location.href,
|
|
4310
4355
|
reporterEmail: (l = this.config.user) == null ? void 0 : l.email,
|
|
4311
4356
|
// Sent alongside the address so the dashboard can show a person rather
|
|
4312
4357
|
// than a mailbox, and so the resolution email can open with their name.
|
|
4313
|
-
reporterName: (
|
|
4358
|
+
reporterName: (p = this.config.user) == null ? void 0 : p.name,
|
|
4314
4359
|
metadata: {
|
|
4315
|
-
...await
|
|
4360
|
+
...await Jt(),
|
|
4316
4361
|
release: this.config.release,
|
|
4317
4362
|
environment: this.config.environment,
|
|
4318
4363
|
buildId: this.config.buildId,
|
|
4319
4364
|
...i,
|
|
4320
4365
|
user: this.config.user || void 0,
|
|
4321
|
-
sdk:
|
|
4366
|
+
sdk: hn
|
|
4322
4367
|
},
|
|
4323
4368
|
logs: {
|
|
4324
4369
|
console: { entries: this.consoleBuffer.all() },
|
|
@@ -4334,29 +4379,29 @@ me = function() {
|
|
|
4334
4379
|
// no reason to make the join key one when the source text is right here.
|
|
4335
4380
|
...s.length ? { references: s } : {}
|
|
4336
4381
|
};
|
|
4337
|
-
},
|
|
4382
|
+
}, Qn = async function() {
|
|
4338
4383
|
const e = he(this.config.projectId);
|
|
4339
4384
|
let n;
|
|
4340
4385
|
try {
|
|
4341
|
-
n = await
|
|
4386
|
+
n = await za({
|
|
4342
4387
|
apiBase: this.config.apiBase,
|
|
4343
4388
|
apiKey: this.config.apiKey,
|
|
4344
4389
|
token: e == null ? void 0 : e.token,
|
|
4345
|
-
payload: await
|
|
4390
|
+
payload: await P(this, B, Ge).call(this, {})
|
|
4346
4391
|
});
|
|
4347
|
-
} catch (
|
|
4348
|
-
throw
|
|
4392
|
+
} catch (a) {
|
|
4393
|
+
throw a.status === 401 && e && St(this.config.projectId), a;
|
|
4349
4394
|
}
|
|
4350
|
-
return n.watchToken && (
|
|
4351
|
-
},
|
|
4395
|
+
return n.watchToken && (Ct(n.watchToken), this.config.updates && this.startWatching()), n;
|
|
4396
|
+
}, jn = async function(e) {
|
|
4352
4397
|
if (!Et())
|
|
4353
4398
|
throw new Error("[BugCatch] this browser cannot make live calls.");
|
|
4354
|
-
const n = await
|
|
4355
|
-
let
|
|
4399
|
+
const n = await $t();
|
|
4400
|
+
let a, i = null;
|
|
4356
4401
|
try {
|
|
4357
4402
|
if (e)
|
|
4358
|
-
|
|
4359
|
-
else if (i = await
|
|
4403
|
+
a = await Oa({ apiBase: this.config.apiBase, bugId: e });
|
|
4404
|
+
else if (i = await P(this, B, Qn).call(this), e = i.id, a = i.live_call, !(a != null && a.realtime_url)) {
|
|
4360
4405
|
const s = new Error(`[BugCatch] the report was filed, but the team could not be rung${i.call_error ? `: ${i.call_error}` : "."}`);
|
|
4361
4406
|
throw s.filed = i, s.reason = i.call_error || null, s;
|
|
4362
4407
|
}
|
|
@@ -4364,15 +4409,15 @@ me = function() {
|
|
|
4364
4409
|
for (const l of n.getTracks()) l.stop();
|
|
4365
4410
|
throw s;
|
|
4366
4411
|
}
|
|
4367
|
-
const r = await
|
|
4368
|
-
realtimeUrl:
|
|
4412
|
+
const r = await ln({
|
|
4413
|
+
realtimeUrl: a.realtime_url,
|
|
4369
4414
|
stream: n,
|
|
4370
|
-
ringsUntil:
|
|
4415
|
+
ringsUntil: a.rings_until,
|
|
4371
4416
|
onState: (s, l) => {
|
|
4372
|
-
(s === "ended" || s === "failed" || s === "missed") && (this.call = null), s === "missed" &&
|
|
4417
|
+
(s === "ended" || s === "failed" || s === "missed") && (this.call = null), s === "missed" && Ha({ apiBase: this.config.apiBase, bugId: e, callId: a.call_id }), typeof this.config.onCallState == "function" && this.config.onCallState(s, { bugId: e, live: !0, ...l }), this.emit("call", { bugId: e, live: !0, state: s, ...l });
|
|
4373
4418
|
}
|
|
4374
4419
|
});
|
|
4375
|
-
return this.call = r, Object.assign(r, { bugId: e, callId:
|
|
4420
|
+
return this.call = r, Object.assign(r, { bugId: e, callId: a.call_id, live: !0, filed: i });
|
|
4376
4421
|
}, // --- being called ------------------------------------------------------------
|
|
4377
4422
|
/**
|
|
4378
4423
|
* Somebody on the team is ringing this page.
|
|
@@ -4388,20 +4433,20 @@ me = function() {
|
|
|
4388
4433
|
* said `voice: false` has said its customers are not to be rung, and a card
|
|
4389
4434
|
* offering a call this page could not join would be worse than none.
|
|
4390
4435
|
*/
|
|
4391
|
-
|
|
4436
|
+
zn = function(e) {
|
|
4392
4437
|
var i;
|
|
4393
4438
|
const n = e.incomingCall;
|
|
4394
4439
|
if (!this.config.voice || !Et() || ((i = this.ringing) == null ? void 0 : i.callId) === n.callId || this.call || this.callStarting) return;
|
|
4395
|
-
|
|
4396
|
-
const
|
|
4440
|
+
P(this, B, et).call(this);
|
|
4441
|
+
const a = To({
|
|
4397
4442
|
call: n,
|
|
4398
4443
|
accent: this.config.accent,
|
|
4399
4444
|
position: this.config.widgetPosition,
|
|
4400
4445
|
onAnswer: () => {
|
|
4401
|
-
|
|
4446
|
+
P(this, B, On).call(this, e.bugId, n);
|
|
4402
4447
|
},
|
|
4403
4448
|
onDecline: () => {
|
|
4404
|
-
this.ringing = null,
|
|
4449
|
+
this.ringing = null, tn({
|
|
4405
4450
|
apiBase: this.config.apiBase,
|
|
4406
4451
|
bugId: e.bugId,
|
|
4407
4452
|
callId: n.callId
|
|
@@ -4415,14 +4460,14 @@ Rn = function(e) {
|
|
|
4415
4460
|
this.ringing = null, this.emit("incoming-call", { bugId: e.bugId, callId: n.callId, state: "missed" });
|
|
4416
4461
|
}
|
|
4417
4462
|
});
|
|
4418
|
-
if (this.ringing = { callId: n.callId, dismiss:
|
|
4463
|
+
if (this.ringing = { callId: n.callId, dismiss: a }, typeof this.config.onIncomingCall == "function")
|
|
4419
4464
|
try {
|
|
4420
4465
|
this.config.onIncomingCall({ bugId: e.bugId, ...n });
|
|
4421
4466
|
} catch {
|
|
4422
4467
|
}
|
|
4423
4468
|
this.emit("incoming-call", { bugId: e.bugId, callId: n.callId, state: "ringing" });
|
|
4424
4469
|
}, /** Take the card away, whatever it is showing. */
|
|
4425
|
-
|
|
4470
|
+
et = function(e) {
|
|
4426
4471
|
if (this.ringing && !(e && this.ringing.callId !== e)) {
|
|
4427
4472
|
try {
|
|
4428
4473
|
this.ringing.dismiss();
|
|
@@ -4430,32 +4475,32 @@ Ge = function(e) {
|
|
|
4430
4475
|
}
|
|
4431
4476
|
this.ringing = null;
|
|
4432
4477
|
}
|
|
4433
|
-
},
|
|
4478
|
+
}, On = async function(e, n) {
|
|
4434
4479
|
if (this.ringing = null, this.call || this.callStarting) return;
|
|
4435
4480
|
this.callStarting = !0;
|
|
4436
|
-
let
|
|
4481
|
+
let a;
|
|
4437
4482
|
try {
|
|
4438
|
-
|
|
4483
|
+
a = await $t();
|
|
4439
4484
|
} catch (r) {
|
|
4440
|
-
this.callStarting = !1,
|
|
4485
|
+
this.callStarting = !1, tn({ apiBase: this.config.apiBase, bugId: e, callId: n.callId }), this.emit("incoming-call", { bugId: e, callId: n.callId, state: "failed", error: r });
|
|
4441
4486
|
return;
|
|
4442
4487
|
}
|
|
4443
4488
|
let i;
|
|
4444
4489
|
try {
|
|
4445
|
-
i = await
|
|
4490
|
+
i = await qa({
|
|
4446
4491
|
apiBase: this.config.apiBase,
|
|
4447
4492
|
bugId: e,
|
|
4448
4493
|
callId: n.callId
|
|
4449
4494
|
});
|
|
4450
4495
|
} catch (r) {
|
|
4451
|
-
for (const s of
|
|
4496
|
+
for (const s of a.getTracks()) s.stop();
|
|
4452
4497
|
this.callStarting = !1, this.emit("incoming-call", { bugId: e, callId: n.callId, state: "missed", error: r });
|
|
4453
4498
|
return;
|
|
4454
4499
|
}
|
|
4455
4500
|
try {
|
|
4456
|
-
const r = await
|
|
4501
|
+
const r = await ln({
|
|
4457
4502
|
realtimeUrl: i.realtime_url,
|
|
4458
|
-
stream:
|
|
4503
|
+
stream: a,
|
|
4459
4504
|
// No deadline on this side. The ringing is over — it ended when this
|
|
4460
4505
|
// browser claimed the call — and a countdown here would hang up on a
|
|
4461
4506
|
// conversation that has already started.
|
|
@@ -4465,15 +4510,15 @@ Ge = function(e) {
|
|
|
4465
4510
|
});
|
|
4466
4511
|
this.call = r, this.emit("incoming-call", { bugId: e, callId: n.callId, state: "answered" });
|
|
4467
4512
|
} catch (r) {
|
|
4468
|
-
for (const s of
|
|
4513
|
+
for (const s of a.getTracks()) s.stop();
|
|
4469
4514
|
this.emit("incoming-call", { bugId: e, callId: n.callId, state: "failed", error: r });
|
|
4470
4515
|
} finally {
|
|
4471
4516
|
this.callStarting = !1;
|
|
4472
4517
|
}
|
|
4473
4518
|
};
|
|
4474
|
-
const
|
|
4475
|
-
|
|
4519
|
+
const Io = new Rn();
|
|
4520
|
+
Io.Client = Rn;
|
|
4476
4521
|
export {
|
|
4477
|
-
|
|
4522
|
+
Io as default
|
|
4478
4523
|
};
|
|
4479
4524
|
//# sourceMappingURL=bugcatch.es.js.map
|