@fogg/bug-reporter 1.0.0 → 1.0.2

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/index.cjs CHANGED
@@ -1,8 +1,35 @@
1
1
  'use strict';
2
2
 
3
- var chunk6TCI6T2U_cjs = require('./chunk-6TCI6T2U.cjs');
4
- var react = require('react');
3
+ var React = require('react');
5
4
  var reactDom = require('react-dom');
5
+ var html2canvas = require('html2canvas');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+ var html2canvas__default = /*#__PURE__*/_interopDefault(html2canvas);
29
+
30
+ var __defProp = Object.defineProperty;
31
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
32
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
33
 
7
34
  // src/diagnostics/ua.ts
8
35
  function detectBrowserAndOS(userAgent) {
@@ -22,12 +49,13 @@ function detectBrowserAndOS(userAgent) {
22
49
 
23
50
  // src/diagnostics/collect.ts
24
51
  function getUserAgentDataSnapshot() {
52
+ var _a;
25
53
  const userAgentData = navigator.userAgentData;
26
54
  if (!userAgentData) {
27
55
  return void 0;
28
56
  }
29
57
  return {
30
- brands: userAgentData.brands?.map((item) => ({
58
+ brands: (_a = userAgentData.brands) == null ? void 0 : _a.map((item) => ({
31
59
  brand: item.brand,
32
60
  version: item.version
33
61
  })),
@@ -56,12 +84,12 @@ function collectDiagnostics(config, options) {
56
84
  appVersion: config.appVersion,
57
85
  environment: config.environment,
58
86
  projectId: config.projectId,
59
- logs: options?.logs,
60
- requests: options?.requests,
87
+ logs: options == null ? void 0 : options.logs,
88
+ requests: options == null ? void 0 : options.requests,
61
89
  navigationTiming: {
62
- domComplete: nav?.domComplete,
63
- loadEventEnd: nav?.loadEventEnd,
64
- responseEnd: nav?.responseEnd
90
+ domComplete: nav == null ? void 0 : nav.domComplete,
91
+ loadEventEnd: nav == null ? void 0 : nav.loadEventEnd,
92
+ responseEnd: nav == null ? void 0 : nav.responseEnd
65
93
  }
66
94
  };
67
95
  }
@@ -70,13 +98,14 @@ function collectDiagnostics(config, options) {
70
98
  var ConsoleBuffer = class {
71
99
  constructor(maxEntries) {
72
100
  this.maxEntries = maxEntries;
73
- chunk6TCI6T2U_cjs.__publicField(this, "entries", []);
74
- chunk6TCI6T2U_cjs.__publicField(this, "originals", /* @__PURE__ */ new Map());
75
- chunk6TCI6T2U_cjs.__publicField(this, "installed", false);
76
- chunk6TCI6T2U_cjs.__publicField(this, "onWindowError", (event) => {
77
- this.push("error", [event.message, event.error instanceof Error ? event.error.stack ?? "" : ""]);
101
+ __publicField(this, "entries", []);
102
+ __publicField(this, "originals", /* @__PURE__ */ new Map());
103
+ __publicField(this, "installed", false);
104
+ __publicField(this, "onWindowError", (event) => {
105
+ var _a;
106
+ this.push("error", [event.message, event.error instanceof Error ? (_a = event.error.stack) != null ? _a : "" : ""]);
78
107
  });
79
- chunk6TCI6T2U_cjs.__publicField(this, "onUnhandledRejection", (event) => {
108
+ __publicField(this, "onUnhandledRejection", (event) => {
80
109
  this.push("error", ["Unhandled promise rejection", event.reason]);
81
110
  });
82
111
  }
@@ -126,7 +155,7 @@ var ConsoleBuffer = class {
126
155
  }
127
156
  try {
128
157
  return JSON.stringify(arg);
129
- } catch {
158
+ } catch (e) {
130
159
  return String(arg);
131
160
  }
132
161
  }).join(" ");
@@ -153,7 +182,7 @@ function extractUrl(input) {
153
182
  return input.url;
154
183
  }
155
184
  function extractMethod(input, init) {
156
- if (init?.method) {
185
+ if (init == null ? void 0 : init.method) {
157
186
  return String(init.method).toUpperCase();
158
187
  }
159
188
  if (typeof Request !== "undefined" && input instanceof Request) {
@@ -164,11 +193,11 @@ function extractMethod(input, init) {
164
193
  var NetworkBuffer = class {
165
194
  constructor(maxEntries) {
166
195
  this.maxEntries = maxEntries;
167
- chunk6TCI6T2U_cjs.__publicField(this, "entries", []);
168
- chunk6TCI6T2U_cjs.__publicField(this, "installed", false);
169
- chunk6TCI6T2U_cjs.__publicField(this, "originalFetch");
170
- chunk6TCI6T2U_cjs.__publicField(this, "originalXhrOpen");
171
- chunk6TCI6T2U_cjs.__publicField(this, "originalXhrSend");
196
+ __publicField(this, "entries", []);
197
+ __publicField(this, "installed", false);
198
+ __publicField(this, "originalFetch");
199
+ __publicField(this, "originalXhrOpen");
200
+ __publicField(this, "originalXhrSend");
172
201
  }
173
202
  install() {
174
203
  if (this.installed) {
@@ -243,15 +272,17 @@ var NetworkBuffer = class {
243
272
  this.originalXhrSend = XMLHttpRequest.prototype.send;
244
273
  const buffer = this;
245
274
  XMLHttpRequest.prototype.open = function patchedOpen(method, url, async, username, password) {
275
+ var _a;
246
276
  xhrMeta.set(this, {
247
277
  method: String(method || "GET").toUpperCase(),
248
278
  url: String(url),
249
279
  startedAt: 0,
250
280
  timestamp: ""
251
281
  });
252
- buffer.originalXhrOpen?.call(this, method, url, async ?? true, username ?? null, password ?? null);
282
+ (_a = buffer.originalXhrOpen) == null ? void 0 : _a.call(this, method, url, async != null ? async : true, username != null ? username : null, password != null ? password : null);
253
283
  };
254
284
  XMLHttpRequest.prototype.send = function patchedSend(body) {
285
+ var _a;
255
286
  const existing = xhrMeta.get(this);
256
287
  if (existing) {
257
288
  existing.startedAt = performance.now();
@@ -297,7 +328,7 @@ var NetworkBuffer = class {
297
328
  this.addEventListener("loadend", onLoadEnd);
298
329
  this.addEventListener("error", onError);
299
330
  }
300
- buffer.originalXhrSend?.call(this, body);
331
+ (_a = buffer.originalXhrSend) == null ? void 0 : _a.call(this, body);
301
332
  };
302
333
  }
303
334
  push(entry) {
@@ -307,7 +338,7 @@ var NetworkBuffer = class {
307
338
  }
308
339
  }
309
340
  };
310
- var BugReporterContext = react.createContext(void 0);
341
+ var BugReporterContext = React.createContext(void 0);
311
342
 
312
343
  // src/core/defaults.ts
313
344
  var DEFAULT_MASK_SELECTORS = [
@@ -315,57 +346,70 @@ var DEFAULT_MASK_SELECTORS = [
315
346
  "[data-bug-reporter-mask='true']"
316
347
  ];
317
348
  function withDefaults(config) {
349
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
318
350
  return {
319
351
  apiEndpoint: config.apiEndpoint,
320
352
  projectId: config.projectId,
321
353
  appVersion: config.appVersion,
322
354
  environment: config.environment,
323
355
  storage: {
324
- mode: config.storage?.mode ?? "proxy",
325
- s3: config.storage?.s3,
326
- local: config.storage?.local,
327
- proxy: config.storage?.proxy,
356
+ mode: (_b = (_a = config.storage) == null ? void 0 : _a.mode) != null ? _b : "proxy",
357
+ s3: (_c = config.storage) == null ? void 0 : _c.s3,
358
+ local: (_d = config.storage) == null ? void 0 : _d.local,
359
+ proxy: (_e = config.storage) == null ? void 0 : _e.proxy,
328
360
  limits: {
329
- maxVideoSeconds: config.storage?.limits?.maxVideoSeconds ?? 30,
330
- maxVideoBytes: config.storage?.limits?.maxVideoBytes ?? 50 * 1024 * 1024,
331
- maxScreenshotBytes: config.storage?.limits?.maxScreenshotBytes ?? 8 * 1024 * 1024
361
+ maxVideoSeconds: (_h = (_g = (_f = config.storage) == null ? void 0 : _f.limits) == null ? void 0 : _g.maxVideoSeconds) != null ? _h : 30,
362
+ maxVideoBytes: (_k = (_j = (_i = config.storage) == null ? void 0 : _i.limits) == null ? void 0 : _j.maxVideoBytes) != null ? _k : 50 * 1024 * 1024,
363
+ maxScreenshotBytes: (_n = (_m = (_l = config.storage) == null ? void 0 : _l.limits) == null ? void 0 : _m.maxScreenshotBytes) != null ? _n : 8 * 1024 * 1024
332
364
  }
333
365
  },
334
366
  auth: {
335
- headers: config.auth?.headers ?? {},
336
- withCredentials: config.auth?.withCredentials ?? false
367
+ headers: (_p = (_o = config.auth) == null ? void 0 : _o.headers) != null ? _p : {},
368
+ withCredentials: (_r = (_q = config.auth) == null ? void 0 : _q.withCredentials) != null ? _r : false
337
369
  },
338
370
  theme: {
339
- primaryColor: config.theme?.primaryColor ?? "#1b74e4",
340
- position: config.theme?.position ?? "bottom-right",
341
- zIndex: config.theme?.zIndex ?? 2147483e3,
342
- borderRadius: config.theme?.borderRadius ?? "999px"
371
+ primaryColor: (_t = (_s = config.theme) == null ? void 0 : _s.primaryColor) != null ? _t : "#1b74e4",
372
+ position: (_v = (_u = config.theme) == null ? void 0 : _u.position) != null ? _v : "bottom-right",
373
+ zIndex: (_x = (_w = config.theme) == null ? void 0 : _w.zIndex) != null ? _x : 2147483e3,
374
+ borderRadius: (_z = (_y = config.theme) == null ? void 0 : _y.borderRadius) != null ? _z : "999px"
343
375
  },
344
376
  features: {
345
- screenshot: config.features?.screenshot ?? true,
346
- recording: config.features?.recording ?? true,
347
- annotations: config.features?.annotations ?? true,
348
- consoleLogs: config.features?.consoleLogs ?? false,
349
- networkInfo: config.features?.networkInfo ?? false
377
+ screenshot: (_B = (_A = config.features) == null ? void 0 : _A.screenshot) != null ? _B : true,
378
+ recording: (_D = (_C = config.features) == null ? void 0 : _C.recording) != null ? _D : true,
379
+ annotations: (_F = (_E = config.features) == null ? void 0 : _E.annotations) != null ? _F : true,
380
+ consoleLogs: (_H = (_G = config.features) == null ? void 0 : _G.consoleLogs) != null ? _H : false,
381
+ networkInfo: (_J = (_I = config.features) == null ? void 0 : _I.networkInfo) != null ? _J : false
350
382
  },
351
383
  user: config.user,
352
- attributes: config.attributes ?? {},
384
+ attributes: (_K = config.attributes) != null ? _K : {},
353
385
  privacy: {
354
- maskSelectors: config.privacy?.maskSelectors ?? DEFAULT_MASK_SELECTORS,
355
- redactTextPatterns: config.privacy?.redactTextPatterns ?? []
386
+ maskSelectors: (_M = (_L = config.privacy) == null ? void 0 : _L.maskSelectors) != null ? _M : DEFAULT_MASK_SELECTORS,
387
+ redactTextPatterns: (_O = (_N = config.privacy) == null ? void 0 : _N.redactTextPatterns) != null ? _O : []
356
388
  },
357
389
  diagnostics: {
358
- consoleBufferSize: config.diagnostics?.consoleBufferSize ?? 100,
359
- requestBufferSize: config.diagnostics?.requestBufferSize ?? 200
390
+ consoleBufferSize: (_Q = (_P = config.diagnostics) == null ? void 0 : _P.consoleBufferSize) != null ? _Q : 100,
391
+ requestBufferSize: (_S = (_R = config.diagnostics) == null ? void 0 : _R.requestBufferSize) != null ? _S : 200
360
392
  },
361
393
  hooks: {
362
- beforeSubmit: config.hooks?.beforeSubmit,
363
- onSuccess: config.hooks?.onSuccess,
364
- onError: config.hooks?.onError
394
+ beforeSubmit: (_T = config.hooks) == null ? void 0 : _T.beforeSubmit,
395
+ onSuccess: (_U = config.hooks) == null ? void 0 : _U.onSuccess,
396
+ onError: (_V = config.hooks) == null ? void 0 : _V.onError
365
397
  }
366
398
  };
367
399
  }
368
400
 
401
+ // src/types/index.ts
402
+ var BugReporterError = class extends Error {
403
+ constructor(code, message, cause) {
404
+ super(message);
405
+ __publicField(this, "code");
406
+ __publicField(this, "cause");
407
+ this.name = "BugReporterError";
408
+ this.code = code;
409
+ this.cause = cause;
410
+ }
411
+ };
412
+
369
413
  // src/storage/local-public.ts
370
414
  var LocalPublicProvider = class {
371
415
  constructor(options) {
@@ -381,7 +425,7 @@ var LocalPublicProvider = class {
381
425
  }));
382
426
  }
383
427
  async upload(instruction, blob, onProgress) {
384
- onProgress?.(0);
428
+ onProgress == null ? void 0 : onProgress(0);
385
429
  const form = new FormData();
386
430
  form.append("file", blob, instruction.id);
387
431
  form.append("id", instruction.id);
@@ -393,10 +437,10 @@ var LocalPublicProvider = class {
393
437
  body: form
394
438
  });
395
439
  if (!response.ok) {
396
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Local upload failed (${response.status}).`);
440
+ throw new BugReporterError("UPLOAD_ERROR", `Local upload failed (${response.status}).`);
397
441
  }
398
442
  const payload = await response.json();
399
- onProgress?.(1);
443
+ onProgress == null ? void 0 : onProgress(1);
400
444
  return {
401
445
  id: instruction.id,
402
446
  type: instruction.type,
@@ -423,7 +467,7 @@ var ProxyProvider = class {
423
467
  }));
424
468
  }
425
469
  async upload(instruction, blob, onProgress) {
426
- onProgress?.(0);
470
+ onProgress == null ? void 0 : onProgress(0);
427
471
  const response = await fetch(instruction.uploadUrl, {
428
472
  method: "POST",
429
473
  headers: {
@@ -436,10 +480,10 @@ var ProxyProvider = class {
436
480
  body: blob
437
481
  });
438
482
  if (!response.ok) {
439
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Proxy upload failed (${response.status}).`);
483
+ throw new BugReporterError("UPLOAD_ERROR", `Proxy upload failed (${response.status}).`);
440
484
  }
441
485
  const payload = await response.json();
442
- onProgress?.(1);
486
+ onProgress == null ? void 0 : onProgress(1);
443
487
  return {
444
488
  id: instruction.id,
445
489
  type: instruction.type,
@@ -457,6 +501,7 @@ var S3PresignedProvider = class {
457
501
  this.options = options;
458
502
  }
459
503
  async prepareUploads(files) {
504
+ var _a;
460
505
  const response = await fetch(this.options.presignEndpoint, {
461
506
  method: "POST",
462
507
  headers: {
@@ -467,16 +512,17 @@ var S3PresignedProvider = class {
467
512
  body: JSON.stringify({ files })
468
513
  });
469
514
  if (!response.ok) {
470
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Failed to prepare uploads (${response.status}).`);
515
+ throw new BugReporterError("UPLOAD_ERROR", `Failed to prepare uploads (${response.status}).`);
471
516
  }
472
517
  const payload = await response.json();
473
- if (!payload.uploads?.length) {
474
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", "Presign endpoint did not return upload instructions.");
518
+ if (!((_a = payload.uploads) == null ? void 0 : _a.length)) {
519
+ throw new BugReporterError("UPLOAD_ERROR", "Presign endpoint did not return upload instructions.");
475
520
  }
476
521
  return payload.uploads;
477
522
  }
478
523
  async upload(instruction, blob, onProgress) {
479
- onProgress?.(0);
524
+ var _a;
525
+ onProgress == null ? void 0 : onProgress(0);
480
526
  if (instruction.method === "POST" && instruction.fields) {
481
527
  const formData = new FormData();
482
528
  Object.entries(instruction.fields).forEach(([key, value]) => formData.append(key, value));
@@ -486,7 +532,7 @@ var S3PresignedProvider = class {
486
532
  body: formData
487
533
  });
488
534
  if (!response.ok) {
489
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `S3 form upload failed (${response.status}).`);
535
+ throw new BugReporterError("UPLOAD_ERROR", `S3 form upload failed (${response.status}).`);
490
536
  }
491
537
  } else {
492
538
  const response = await fetch(instruction.uploadUrl, {
@@ -495,11 +541,11 @@ var S3PresignedProvider = class {
495
541
  body: blob
496
542
  });
497
543
  if (!response.ok) {
498
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `S3 upload failed (${response.status}).`);
544
+ throw new BugReporterError("UPLOAD_ERROR", `S3 upload failed (${response.status}).`);
499
545
  }
500
546
  }
501
- onProgress?.(1);
502
- const publicUrl = instruction.publicUrl ?? (this.options.publicBaseUrl && instruction.key ? `${this.options.publicBaseUrl.replace(/\/$/, "")}/${instruction.key}` : instruction.uploadUrl);
547
+ onProgress == null ? void 0 : onProgress(1);
548
+ const publicUrl = (_a = instruction.publicUrl) != null ? _a : this.options.publicBaseUrl && instruction.key ? `${this.options.publicBaseUrl.replace(/\/$/, "")}/${instruction.key}` : instruction.uploadUrl;
503
549
  return {
504
550
  id: instruction.id,
505
551
  type: instruction.type,
@@ -513,31 +559,32 @@ var S3PresignedProvider = class {
513
559
 
514
560
  // src/storage/factory.ts
515
561
  function createStorageProvider(config) {
562
+ var _a, _b, _c, _d, _e;
516
563
  if (config.storage.mode === "s3-presigned") {
517
- const presignEndpoint = config.storage.s3?.presignEndpoint;
564
+ const presignEndpoint = (_a = config.storage.s3) == null ? void 0 : _a.presignEndpoint;
518
565
  if (!presignEndpoint) {
519
566
  throw new Error("storage.s3.presignEndpoint is required for s3-presigned mode.");
520
567
  }
521
568
  return new S3PresignedProvider({
522
569
  presignEndpoint,
523
- publicBaseUrl: config.storage.s3?.publicBaseUrl,
570
+ publicBaseUrl: (_b = config.storage.s3) == null ? void 0 : _b.publicBaseUrl,
524
571
  authHeaders: config.auth.headers,
525
572
  withCredentials: config.auth.withCredentials
526
573
  });
527
574
  }
528
575
  if (config.storage.mode === "local-public") {
529
- const uploadEndpoint2 = config.storage.local?.uploadEndpoint;
576
+ const uploadEndpoint2 = (_c = config.storage.local) == null ? void 0 : _c.uploadEndpoint;
530
577
  if (!uploadEndpoint2) {
531
578
  throw new Error("storage.local.uploadEndpoint is required for local-public mode.");
532
579
  }
533
580
  return new LocalPublicProvider({
534
581
  uploadEndpoint: uploadEndpoint2,
535
- publicBaseUrl: config.storage.local?.publicBaseUrl,
582
+ publicBaseUrl: (_d = config.storage.local) == null ? void 0 : _d.publicBaseUrl,
536
583
  authHeaders: config.auth.headers,
537
584
  withCredentials: config.auth.withCredentials
538
585
  });
539
586
  }
540
- const uploadEndpoint = config.storage.proxy?.uploadEndpoint;
587
+ const uploadEndpoint = (_e = config.storage.proxy) == null ? void 0 : _e.uploadEndpoint;
541
588
  if (!uploadEndpoint) {
542
589
  throw new Error("storage.proxy.uploadEndpoint is required for proxy mode.");
543
590
  }
@@ -581,6 +628,7 @@ async function withRetry(fn, retries) {
581
628
  throw lastError;
582
629
  }
583
630
  async function uploadAssets(options) {
631
+ var _a, _b;
584
632
  const files = options.assets.map((asset) => ({
585
633
  id: asset.id,
586
634
  name: asset.filename,
@@ -595,24 +643,26 @@ async function uploadAssets(options) {
595
643
  for (const asset of options.assets) {
596
644
  const instruction = byId.get(asset.id);
597
645
  if (!instruction) {
598
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `No upload instruction for asset ${asset.id}.`);
646
+ throw new BugReporterError("UPLOAD_ERROR", `No upload instruction for asset ${asset.id}.`);
599
647
  }
600
648
  const ref = await withRetry(
601
649
  () => options.provider.upload(instruction, asset.blob, (inner) => {
650
+ var _a2;
602
651
  const aggregate = (completed + inner) / options.assets.length;
603
- options.onProgress?.(aggregate);
652
+ (_a2 = options.onProgress) == null ? void 0 : _a2.call(options, aggregate);
604
653
  }),
605
- options.retries ?? 2
654
+ (_a = options.retries) != null ? _a : 2
606
655
  );
607
656
  refs.push(ref);
608
657
  completed += 1;
609
- options.onProgress?.(completed / options.assets.length);
658
+ (_b = options.onProgress) == null ? void 0 : _b.call(options, completed / options.assets.length);
610
659
  }
611
660
  return refs;
612
661
  }
613
662
 
614
663
  // src/core/submit.ts
615
664
  async function submitReport(options) {
665
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
616
666
  const provider = createStorageProvider(options.config);
617
667
  const assetReferences = await uploadAssets({
618
668
  provider,
@@ -649,18 +699,18 @@ async function submitReport(options) {
649
699
  requests: options.diagnostics.requests
650
700
  },
651
701
  reporter: {
652
- id: options.config.user?.id,
653
- name: options.config.user?.name,
654
- email: options.config.user?.email,
655
- role: options.config.user?.role,
656
- ip: options.config.user?.ip,
657
- anonymous: options.config.user?.anonymous ?? !(options.config.user?.id || options.config.user?.email || options.config.user?.name)
702
+ id: (_a = options.config.user) == null ? void 0 : _a.id,
703
+ name: (_b = options.config.user) == null ? void 0 : _b.name,
704
+ email: (_c = options.config.user) == null ? void 0 : _c.email,
705
+ role: (_d = options.config.user) == null ? void 0 : _d.role,
706
+ ip: (_e = options.config.user) == null ? void 0 : _e.ip,
707
+ anonymous: (_j = (_f = options.config.user) == null ? void 0 : _f.anonymous) != null ? _j : !(((_g = options.config.user) == null ? void 0 : _g.id) || ((_h = options.config.user) == null ? void 0 : _h.email) || ((_i = options.config.user) == null ? void 0 : _i.name))
658
708
  },
659
709
  attributes: options.attributes
660
710
  };
661
711
  const transformed = options.config.hooks.beforeSubmit ? await options.config.hooks.beforeSubmit(payloadBase) : payloadBase;
662
712
  if (!transformed) {
663
- throw new chunk6TCI6T2U_cjs.BugReporterError("ABORTED", "Submission aborted by beforeSubmit hook.");
713
+ throw new BugReporterError("ABORTED", "Submission aborted by beforeSubmit hook.");
664
714
  }
665
715
  console.log("[bug-reporter] payload to submit", transformed);
666
716
  console.log("[bug-reporter] payload to submit (json)", JSON.stringify(transformed, null, 2));
@@ -675,7 +725,7 @@ async function submitReport(options) {
675
725
  });
676
726
  if (!response.ok) {
677
727
  const body = await response.text().catch(() => "");
678
- throw new chunk6TCI6T2U_cjs.BugReporterError("SUBMIT_ERROR", `Report submit failed (${response.status}): ${body || response.statusText}`);
728
+ throw new BugReporterError("SUBMIT_ERROR", `Report submit failed (${response.status}): ${body || response.statusText}`);
679
729
  }
680
730
  return await response.json();
681
731
  }
@@ -700,21 +750,21 @@ var BASE_STATE = {
700
750
  error: void 0
701
751
  };
702
752
  function BugReporterProvider({ config, children }) {
703
- const resolvedConfig = react.useMemo(() => withDefaults(config), [config]);
753
+ const resolvedConfig = React.useMemo(() => withDefaults(config), [config]);
704
754
  const initialDockSide = resolvedConfig.theme.position === "bottom-left" || resolvedConfig.theme.position === "top-left" ? "left" : "right";
705
- const [state, setState] = react.useState(() => ({
755
+ const [state, setState] = React.useState(() => ({
706
756
  ...BASE_STATE,
707
757
  dockSide: initialDockSide,
708
758
  attributes: { ...resolvedConfig.attributes }
709
759
  }));
710
- const [sessionActive, setSessionActive] = react.useState(false);
711
- const consoleBufferRef = react.useRef(null);
712
- const networkBufferRef = react.useRef(null);
713
- const assetsRef = react.useRef([]);
714
- const resetAssets = react.useCallback((assets) => {
760
+ const [sessionActive, setSessionActive] = React.useState(false);
761
+ const consoleBufferRef = React.useRef(null);
762
+ const networkBufferRef = React.useRef(null);
763
+ const assetsRef = React.useRef([]);
764
+ const resetAssets = React.useCallback((assets) => {
715
765
  assets.forEach((asset) => revokeObjectUrl(asset.previewUrl));
716
766
  }, []);
717
- const open = react.useCallback(() => {
767
+ const open = React.useCallback(() => {
718
768
  setSessionActive(true);
719
769
  setState((prev) => ({
720
770
  ...prev,
@@ -722,13 +772,14 @@ function BugReporterProvider({ config, children }) {
722
772
  error: void 0
723
773
  }));
724
774
  }, []);
725
- const close = react.useCallback(() => {
775
+ const close = React.useCallback(() => {
726
776
  setState((prev) => ({
727
777
  ...prev,
728
778
  isOpen: false
729
779
  }));
730
780
  }, []);
731
- const reset = react.useCallback(() => {
781
+ const reset = React.useCallback(() => {
782
+ var _a, _b;
732
783
  setSessionActive(false);
733
784
  setState((prev) => {
734
785
  resetAssets(prev.assets);
@@ -739,16 +790,16 @@ function BugReporterProvider({ config, children }) {
739
790
  isOpen: prev.isOpen
740
791
  };
741
792
  });
742
- consoleBufferRef.current?.clear();
743
- networkBufferRef.current?.clear();
793
+ (_a = consoleBufferRef.current) == null ? void 0 : _a.clear();
794
+ (_b = networkBufferRef.current) == null ? void 0 : _b.clear();
744
795
  }, [resetAssets, resolvedConfig.attributes]);
745
- const setStep = react.useCallback((step) => {
796
+ const setStep = React.useCallback((step) => {
746
797
  setState((prev) => ({ ...prev, step }));
747
798
  }, []);
748
- const setDockSide = react.useCallback((dockSide) => {
799
+ const setDockSide = React.useCallback((dockSide) => {
749
800
  setState((prev) => ({ ...prev, dockSide }));
750
801
  }, []);
751
- const updateDraft = react.useCallback((next) => {
802
+ const updateDraft = React.useCallback((next) => {
752
803
  setState((prev) => ({
753
804
  ...prev,
754
805
  draft: {
@@ -757,13 +808,13 @@ function BugReporterProvider({ config, children }) {
757
808
  }
758
809
  }));
759
810
  }, []);
760
- const setAttributes = react.useCallback((next) => {
811
+ const setAttributes = React.useCallback((next) => {
761
812
  setState((prev) => ({
762
813
  ...prev,
763
814
  attributes: next
764
815
  }));
765
816
  }, []);
766
- const updateAttribute = react.useCallback((key, value2) => {
817
+ const updateAttribute = React.useCallback((key, value2) => {
767
818
  setState((prev) => ({
768
819
  ...prev,
769
820
  attributes: {
@@ -772,7 +823,7 @@ function BugReporterProvider({ config, children }) {
772
823
  }
773
824
  }));
774
825
  }, []);
775
- const setAssetByType = react.useCallback((type, next) => {
826
+ const setAssetByType = React.useCallback((type, next) => {
776
827
  setState((prev) => {
777
828
  const previous = prev.assets.find((asset) => asset.type === type);
778
829
  if (previous) {
@@ -785,13 +836,14 @@ function BugReporterProvider({ config, children }) {
785
836
  };
786
837
  });
787
838
  }, []);
788
- const setScreenshot = react.useCallback((asset) => {
839
+ const setScreenshot = React.useCallback((asset) => {
789
840
  setAssetByType("screenshot", asset);
790
841
  }, [setAssetByType]);
791
- const setRecording = react.useCallback((asset) => {
842
+ const setRecording = React.useCallback((asset) => {
792
843
  setAssetByType("recording", asset);
793
844
  }, [setAssetByType]);
794
- const submit = react.useCallback(async () => {
845
+ const submit = React.useCallback(async () => {
846
+ var _a, _b, _c, _d, _e, _f;
795
847
  setState((prev) => ({
796
848
  ...prev,
797
849
  step: "submitting",
@@ -800,8 +852,8 @@ function BugReporterProvider({ config, children }) {
800
852
  error: void 0
801
853
  }));
802
854
  try {
803
- const logs = resolvedConfig.features.consoleLogs ? consoleBufferRef.current?.snapshot() : void 0;
804
- const requests = resolvedConfig.features.networkInfo ? networkBufferRef.current?.snapshot() : void 0;
855
+ const logs = resolvedConfig.features.consoleLogs ? (_a = consoleBufferRef.current) == null ? void 0 : _a.snapshot() : void 0;
856
+ const requests = resolvedConfig.features.networkInfo ? (_b = networkBufferRef.current) == null ? void 0 : _b.snapshot() : void 0;
805
857
  const diagnostics = collectDiagnostics(resolvedConfig, {
806
858
  logs,
807
859
  requests
@@ -823,7 +875,7 @@ function BugReporterProvider({ config, children }) {
823
875
  uploadProgress: 1,
824
876
  step: "success"
825
877
  }));
826
- resolvedConfig.hooks.onSuccess?.(response);
878
+ (_d = (_c = resolvedConfig.hooks).onSuccess) == null ? void 0 : _d.call(_c, response);
827
879
  } catch (error) {
828
880
  const message = error instanceof Error ? error.message : "Unexpected submit failure.";
829
881
  setState((prev) => ({
@@ -832,21 +884,25 @@ function BugReporterProvider({ config, children }) {
832
884
  step: "review",
833
885
  error: message
834
886
  }));
835
- resolvedConfig.hooks.onError?.(error);
887
+ (_f = (_e = resolvedConfig.hooks).onError) == null ? void 0 : _f.call(_e, error);
836
888
  }
837
889
  }, [resolvedConfig, state.assets, state.attributes, state.draft]);
838
- const retrySubmit = react.useCallback(async () => {
890
+ const retrySubmit = React.useCallback(async () => {
839
891
  await submit();
840
892
  }, [submit]);
841
- const getDiagnosticsPreview = react.useCallback(() => {
842
- const logs = resolvedConfig.features.consoleLogs ? consoleBufferRef.current?.snapshot() ?? [] : [];
843
- const requests = resolvedConfig.features.networkInfo ? networkBufferRef.current?.snapshot() ?? [] : [];
893
+ const getDiagnosticsPreview = React.useCallback(() => {
894
+ var _a, _b, _c, _d;
895
+ const logs = resolvedConfig.features.consoleLogs ? (_b = (_a = consoleBufferRef.current) == null ? void 0 : _a.snapshot()) != null ? _b : [] : [];
896
+ const requests = resolvedConfig.features.networkInfo ? (_d = (_c = networkBufferRef.current) == null ? void 0 : _c.snapshot()) != null ? _d : [] : [];
844
897
  return {
845
898
  errorLogs: logs.filter((entry) => entry.level === "error"),
846
- failedRequests: requests.filter((request) => Boolean(request.error) || request.ok === false || (request.status ?? 0) >= 400)
899
+ failedRequests: requests.filter((request) => {
900
+ var _a2;
901
+ return Boolean(request.error) || request.ok === false || ((_a2 = request.status) != null ? _a2 : 0) >= 400;
902
+ })
847
903
  };
848
904
  }, [resolvedConfig.features.consoleLogs, resolvedConfig.features.networkInfo]);
849
- react.useEffect(() => {
905
+ React.useEffect(() => {
850
906
  if (!sessionActive) {
851
907
  return;
852
908
  }
@@ -863,8 +919,8 @@ function BugReporterProvider({ config, children }) {
863
919
  networkBufferRef.current = networkBuffer;
864
920
  }
865
921
  return () => {
866
- consoleBuffer?.uninstall();
867
- networkBuffer?.uninstall();
922
+ consoleBuffer == null ? void 0 : consoleBuffer.uninstall();
923
+ networkBuffer == null ? void 0 : networkBuffer.uninstall();
868
924
  consoleBufferRef.current = null;
869
925
  networkBufferRef.current = null;
870
926
  };
@@ -875,17 +931,18 @@ function BugReporterProvider({ config, children }) {
875
931
  resolvedConfig.features.consoleLogs,
876
932
  resolvedConfig.features.networkInfo
877
933
  ]);
878
- react.useEffect(() => {
934
+ React.useEffect(() => {
879
935
  assetsRef.current = state.assets;
880
936
  }, [state.assets]);
881
- react.useEffect(() => {
937
+ React.useEffect(() => {
882
938
  return () => {
939
+ var _a, _b;
883
940
  resetAssets(assetsRef.current);
884
- consoleBufferRef.current?.uninstall();
885
- networkBufferRef.current?.uninstall();
941
+ (_a = consoleBufferRef.current) == null ? void 0 : _a.uninstall();
942
+ (_b = networkBufferRef.current) == null ? void 0 : _b.uninstall();
886
943
  };
887
944
  }, [resetAssets]);
888
- const value = react.useMemo(
945
+ const value = React.useMemo(
889
946
  () => ({
890
947
  config: resolvedConfig,
891
948
  state,
@@ -921,10 +978,10 @@ function BugReporterProvider({ config, children }) {
921
978
  getDiagnosticsPreview
922
979
  ]
923
980
  );
924
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(BugReporterContext.Provider, { value }, children);
981
+ return /* @__PURE__ */ React__namespace.createElement(BugReporterContext.Provider, { value }, children);
925
982
  }
926
983
  function useBugReporter() {
927
- const context = react.useContext(BugReporterContext);
984
+ const context = React.useContext(BugReporterContext);
928
985
  if (!context) {
929
986
  throw new Error("useBugReporter must be used inside BugReporterProvider.");
930
987
  }
@@ -938,7 +995,7 @@ function getFocusable(node) {
938
995
  ).filter((el) => !el.hasAttribute("disabled"));
939
996
  }
940
997
  function useFocusTrap(enabled, containerRef) {
941
- react.useEffect(() => {
998
+ React.useEffect(() => {
942
999
  const container = containerRef.current;
943
1000
  if (!enabled || !container) {
944
1001
  return;
@@ -946,7 +1003,7 @@ function useFocusTrap(enabled, containerRef) {
946
1003
  const focusable = getFocusable(container);
947
1004
  const first = focusable[0];
948
1005
  const last = focusable[focusable.length - 1];
949
- first?.focus();
1006
+ first == null ? void 0 : first.focus();
950
1007
  const onKeyDown = (event) => {
951
1008
  if (event.key !== "Tab") {
952
1009
  return;
@@ -1289,9 +1346,10 @@ var inlineStyles = {
1289
1346
  }
1290
1347
  };
1291
1348
  function getButtonStyle(variant, options) {
1292
- const disabled = options?.disabled ?? false;
1293
- const active = options?.active ?? false;
1294
- const fullWidth = options?.fullWidth ?? false;
1349
+ var _a, _b, _c;
1350
+ const disabled = (_a = options == null ? void 0 : options.disabled) != null ? _a : false;
1351
+ const active = (_b = options == null ? void 0 : options.active) != null ? _b : false;
1352
+ const fullWidth = (_c = options == null ? void 0 : options.fullWidth) != null ? _c : false;
1295
1353
  const base = {
1296
1354
  border: "1px solid transparent",
1297
1355
  borderRadius: "10px",
@@ -1329,6 +1387,7 @@ function getDockButtonStyle(isActive) {
1329
1387
 
1330
1388
  // src/components/LauncherButton.tsx
1331
1389
  function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1390
+ var _a;
1332
1391
  const {
1333
1392
  config,
1334
1393
  state: { isOpen },
@@ -1337,9 +1396,9 @@ function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1337
1396
  if (isOpen) {
1338
1397
  return null;
1339
1398
  }
1340
- const resolvedPosition = position ?? config.theme.position ?? "bottom-right";
1341
- const label = text ?? "Get Help";
1342
- const resolvedButtonColor = buttonColor ?? config.theme.primaryColor;
1399
+ const resolvedPosition = (_a = position != null ? position : config.theme.position) != null ? _a : "bottom-right";
1400
+ const label = text != null ? text : "Get Help";
1401
+ const resolvedButtonColor = buttonColor != null ? buttonColor : config.theme.primaryColor;
1343
1402
  const launcherStyle = getLauncherStyle({
1344
1403
  position: resolvedPosition,
1345
1404
  borderRadius: config.theme.borderRadius,
@@ -1347,7 +1406,7 @@ function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1347
1406
  buttonColor: resolvedButtonColor,
1348
1407
  themeMode
1349
1408
  });
1350
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
1409
+ return /* @__PURE__ */ React__namespace.createElement(
1351
1410
  "button",
1352
1411
  {
1353
1412
  type: "button",
@@ -1359,9 +1418,9 @@ function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1359
1418
  );
1360
1419
  }
1361
1420
  function Modal({ isOpen, dockSide, themeMode, buttonColor, title, zIndex, onRequestClose, children }) {
1362
- const dialogRef = react.useRef(null);
1421
+ const dialogRef = React.useRef(null);
1363
1422
  useFocusTrap(isOpen, dialogRef);
1364
- react.useEffect(() => {
1423
+ React.useEffect(() => {
1365
1424
  if (!isOpen) {
1366
1425
  return;
1367
1426
  }
@@ -1380,23 +1439,309 @@ function Modal({ isOpen, dockSide, themeMode, buttonColor, title, zIndex, onRequ
1380
1439
  const overlayStyle = getModalOverlayStyle({ dockSide, themeMode, zIndex });
1381
1440
  const modalStyle = getModalStyle({ dockSide, themeMode, buttonColor });
1382
1441
  return reactDom.createPortal(
1383
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: overlayStyle }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { ref: dialogRef, style: modalStyle, role: "dialog", "aria-modal": "true", "aria-label": title }, children)),
1442
+ /* @__PURE__ */ React__namespace.createElement("div", { style: overlayStyle }, /* @__PURE__ */ React__namespace.createElement("div", { ref: dialogRef, style: modalStyle, role: "dialog", "aria-modal": "true", "aria-label": title }, children)),
1384
1443
  document.body
1385
1444
  );
1386
1445
  }
1446
+ function applyMasking(selectors) {
1447
+ const masked = [];
1448
+ for (const selector of selectors) {
1449
+ document.querySelectorAll(selector).forEach((element) => {
1450
+ masked.push({ element, previous: element.style.filter });
1451
+ element.style.filter = "blur(12px)";
1452
+ });
1453
+ }
1454
+ return masked;
1455
+ }
1456
+ function resetMasking(masked) {
1457
+ masked.forEach(({ element, previous }) => {
1458
+ element.style.filter = previous;
1459
+ });
1460
+ }
1461
+ function scrubText(root, patterns) {
1462
+ var _a, _b;
1463
+ if (!patterns.length) {
1464
+ return [];
1465
+ }
1466
+ const walkers = [];
1467
+ const regexes = patterns.map((pattern) => typeof pattern === "string" ? new RegExp(pattern, "g") : pattern);
1468
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
1469
+ while (walker.nextNode()) {
1470
+ const text = walker.currentNode;
1471
+ let replaced = (_a = text.textContent) != null ? _a : "";
1472
+ for (const regex of regexes) {
1473
+ replaced = replaced.replace(regex, "[redacted]");
1474
+ }
1475
+ if (replaced !== text.textContent) {
1476
+ walkers.push({ node: text, previous: (_b = text.textContent) != null ? _b : "" });
1477
+ text.textContent = replaced;
1478
+ }
1479
+ }
1480
+ return walkers;
1481
+ }
1482
+ function restoreText(changed) {
1483
+ changed.forEach(({ node, previous }) => {
1484
+ node.textContent = previous;
1485
+ });
1486
+ }
1487
+ function createSelectionOverlay() {
1488
+ return new Promise((resolve, reject) => {
1489
+ const overlay = document.createElement("div");
1490
+ overlay.setAttribute("data-bug-reporter-overlay", "true");
1491
+ overlay.style.position = "fixed";
1492
+ overlay.style.inset = "0";
1493
+ overlay.style.background = "rgba(0,0,0,0.35)";
1494
+ overlay.style.cursor = "crosshair";
1495
+ overlay.style.zIndex = "2147483647";
1496
+ const box = document.createElement("div");
1497
+ box.style.position = "fixed";
1498
+ box.style.border = "2px solid #ffffff";
1499
+ box.style.background = "rgba(27, 116, 228, 0.2)";
1500
+ box.style.pointerEvents = "none";
1501
+ box.style.display = "none";
1502
+ overlay.appendChild(box);
1503
+ const cleanup = () => {
1504
+ overlay.removeEventListener("mousedown", onMouseDown);
1505
+ overlay.removeEventListener("mousemove", onMouseMove);
1506
+ overlay.removeEventListener("mouseup", onMouseUp);
1507
+ window.removeEventListener("keydown", onKeyDown);
1508
+ overlay.remove();
1509
+ };
1510
+ let startX = 0;
1511
+ let startY = 0;
1512
+ let isDragging = false;
1513
+ const onKeyDown = (event) => {
1514
+ if (event.key === "Escape") {
1515
+ cleanup();
1516
+ reject(new BugReporterError("ABORTED", "Screenshot capture cancelled."));
1517
+ }
1518
+ };
1519
+ const onMouseDown = (event) => {
1520
+ isDragging = true;
1521
+ startX = event.clientX;
1522
+ startY = event.clientY;
1523
+ box.style.display = "block";
1524
+ box.style.left = `${startX}px`;
1525
+ box.style.top = `${startY}px`;
1526
+ box.style.width = "0px";
1527
+ box.style.height = "0px";
1528
+ };
1529
+ const onMouseMove = (event) => {
1530
+ if (!isDragging) {
1531
+ return;
1532
+ }
1533
+ const left = Math.min(startX, event.clientX);
1534
+ const top = Math.min(startY, event.clientY);
1535
+ const width = Math.abs(startX - event.clientX);
1536
+ const height = Math.abs(startY - event.clientY);
1537
+ box.style.left = `${left}px`;
1538
+ box.style.top = `${top}px`;
1539
+ box.style.width = `${width}px`;
1540
+ box.style.height = `${height}px`;
1541
+ };
1542
+ const onMouseUp = (event) => {
1543
+ if (!isDragging) {
1544
+ return;
1545
+ }
1546
+ isDragging = false;
1547
+ const left = Math.min(startX, event.clientX);
1548
+ const top = Math.min(startY, event.clientY);
1549
+ const width = Math.abs(startX - event.clientX);
1550
+ const height = Math.abs(startY - event.clientY);
1551
+ cleanup();
1552
+ if (width < 8 || height < 8) {
1553
+ reject(new BugReporterError("CAPTURE_ERROR", "Selection area is too small."));
1554
+ return;
1555
+ }
1556
+ resolve({ left, top, width, height });
1557
+ };
1558
+ overlay.addEventListener("mousedown", onMouseDown);
1559
+ overlay.addEventListener("mousemove", onMouseMove);
1560
+ overlay.addEventListener("mouseup", onMouseUp);
1561
+ window.addEventListener("keydown", onKeyDown);
1562
+ document.body.appendChild(overlay);
1563
+ });
1564
+ }
1565
+ function canvasToBlob(canvas) {
1566
+ return new Promise((resolve, reject) => {
1567
+ canvas.toBlob((blob) => {
1568
+ if (!blob) {
1569
+ reject(new BugReporterError("CAPTURE_ERROR", "Failed to build screenshot blob."));
1570
+ return;
1571
+ }
1572
+ resolve(blob);
1573
+ }, "image/png");
1574
+ });
1575
+ }
1576
+ async function captureScreenshotArea(options) {
1577
+ const selection = await createSelectionOverlay();
1578
+ const masked = applyMasking(options.maskSelectors);
1579
+ const textChanges = scrubText(document.body, options.redactTextPatterns);
1580
+ try {
1581
+ const baseCanvas = await html2canvas__default.default(document.documentElement, {
1582
+ useCORS: true,
1583
+ scrollX: -window.scrollX,
1584
+ scrollY: -window.scrollY,
1585
+ backgroundColor: null,
1586
+ logging: false,
1587
+ windowWidth: document.documentElement.scrollWidth,
1588
+ windowHeight: document.documentElement.scrollHeight
1589
+ });
1590
+ const scaleX = baseCanvas.width / window.innerWidth;
1591
+ const scaleY = baseCanvas.height / window.innerHeight;
1592
+ const sx = Math.round(selection.left * scaleX);
1593
+ const sy = Math.round(selection.top * scaleY);
1594
+ const sw = Math.round(selection.width * scaleX);
1595
+ const sh = Math.round(selection.height * scaleY);
1596
+ const cropped = document.createElement("canvas");
1597
+ cropped.width = sw;
1598
+ cropped.height = sh;
1599
+ const context = cropped.getContext("2d");
1600
+ if (!context) {
1601
+ throw new BugReporterError("CAPTURE_ERROR", "Canvas 2D context unavailable.");
1602
+ }
1603
+ context.drawImage(baseCanvas, sx, sy, sw, sh, 0, 0, sw, sh);
1604
+ return await canvasToBlob(cropped);
1605
+ } catch (error) {
1606
+ if (error instanceof BugReporterError) {
1607
+ throw error;
1608
+ }
1609
+ throw new BugReporterError("CAPTURE_ERROR", "Screenshot capture failed.", error);
1610
+ } finally {
1611
+ resetMasking(masked);
1612
+ restoreText(textChanges);
1613
+ }
1614
+ }
1615
+
1616
+ // src/core/recording.ts
1617
+ function pickMimeType() {
1618
+ const candidates = ["video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"];
1619
+ for (const candidate of candidates) {
1620
+ if (typeof MediaRecorder !== "undefined" && MediaRecorder.isTypeSupported(candidate)) {
1621
+ return candidate;
1622
+ }
1623
+ }
1624
+ return "video/webm";
1625
+ }
1626
+ async function startScreenRecording(options) {
1627
+ var _a;
1628
+ if (!((_a = navigator.mediaDevices) == null ? void 0 : _a.getDisplayMedia)) {
1629
+ throw new BugReporterError("RECORDING_ERROR", "Screen recording is not supported by this browser.");
1630
+ }
1631
+ let stream;
1632
+ try {
1633
+ stream = await navigator.mediaDevices.getDisplayMedia({
1634
+ video: true,
1635
+ audio: false
1636
+ });
1637
+ } catch (error) {
1638
+ throw new BugReporterError("PERMISSION_DENIED", "Permission denied for screen recording.", error);
1639
+ }
1640
+ const mimeType = pickMimeType();
1641
+ let recorder;
1642
+ try {
1643
+ recorder = new MediaRecorder(stream, { mimeType });
1644
+ } catch (error) {
1645
+ stream.getTracks().forEach((track) => track.stop());
1646
+ throw new BugReporterError("RECORDING_ERROR", "Could not initialize MediaRecorder.", error);
1647
+ }
1648
+ const chunks = [];
1649
+ const startedAt = Date.now();
1650
+ let latestSize = 0;
1651
+ let tickSeconds = 0;
1652
+ let completed = false;
1653
+ let isCancelled = false;
1654
+ let resolvePromise;
1655
+ let rejectPromise;
1656
+ const promise = new Promise((resolve, reject) => {
1657
+ resolvePromise = resolve;
1658
+ rejectPromise = reject;
1659
+ });
1660
+ const tickInterval = window.setInterval(() => {
1661
+ var _a2;
1662
+ tickSeconds += 1;
1663
+ (_a2 = options.onTick) == null ? void 0 : _a2.call(options, tickSeconds);
1664
+ }, 1e3);
1665
+ const hardStop = window.setTimeout(() => {
1666
+ if (recorder.state !== "inactive") {
1667
+ recorder.stop();
1668
+ }
1669
+ }, options.maxSeconds * 1e3);
1670
+ const teardown = () => {
1671
+ if (completed) {
1672
+ return;
1673
+ }
1674
+ completed = true;
1675
+ window.clearInterval(tickInterval);
1676
+ window.clearTimeout(hardStop);
1677
+ stream.getTracks().forEach((track) => track.stop());
1678
+ };
1679
+ recorder.addEventListener("dataavailable", (event) => {
1680
+ if (!event.data || event.data.size === 0) {
1681
+ return;
1682
+ }
1683
+ chunks.push(event.data);
1684
+ latestSize += event.data.size;
1685
+ if (latestSize > options.maxBytes) {
1686
+ isCancelled = true;
1687
+ recorder.stop();
1688
+ rejectPromise(
1689
+ new BugReporterError(
1690
+ "VALIDATION_ERROR",
1691
+ `Recording exceeds max size (${Math.round(options.maxBytes / 1024 / 1024)}MB).`
1692
+ )
1693
+ );
1694
+ }
1695
+ });
1696
+ recorder.addEventListener("error", (event) => {
1697
+ teardown();
1698
+ rejectPromise(new BugReporterError("RECORDING_ERROR", "Recording failed.", event));
1699
+ });
1700
+ recorder.addEventListener("stop", () => {
1701
+ teardown();
1702
+ if (isCancelled) {
1703
+ return;
1704
+ }
1705
+ const blob = new Blob(chunks, { type: mimeType });
1706
+ resolvePromise({
1707
+ blob,
1708
+ mimeType,
1709
+ durationMs: Date.now() - startedAt
1710
+ });
1711
+ });
1712
+ recorder.start(300);
1713
+ return {
1714
+ stop: () => {
1715
+ if (recorder.state !== "inactive") {
1716
+ recorder.stop();
1717
+ }
1718
+ },
1719
+ cancel: () => {
1720
+ isCancelled = true;
1721
+ if (recorder.state !== "inactive") {
1722
+ recorder.stop();
1723
+ }
1724
+ teardown();
1725
+ rejectPromise(new BugReporterError("ABORTED", "Recording cancelled by user."));
1726
+ },
1727
+ promise
1728
+ };
1729
+ }
1387
1730
 
1388
1731
  // src/core/lazy.ts
1732
+ var screenshotCaptureModule = { captureScreenshotArea };
1733
+ var screenRecordingModule = { startScreenRecording };
1389
1734
  async function loadScreenshotCapture() {
1390
- return import('./screenshot-FRAZAS6B.cjs');
1735
+ return screenshotCaptureModule;
1391
1736
  }
1392
1737
  async function loadScreenRecording() {
1393
- return import('./recording-ML63ZQ6A.cjs');
1738
+ return screenRecordingModule;
1394
1739
  }
1395
1740
 
1396
1741
  // src/core/validation.ts
1397
1742
  function validateScreenshotSize(size, maxBytes) {
1398
1743
  if (size > maxBytes) {
1399
- throw new chunk6TCI6T2U_cjs.BugReporterError(
1744
+ throw new BugReporterError(
1400
1745
  "VALIDATION_ERROR",
1401
1746
  `Screenshot exceeds max size (${Math.round(maxBytes / 1024 / 1024)}MB).`
1402
1747
  );
@@ -1404,7 +1749,7 @@ function validateScreenshotSize(size, maxBytes) {
1404
1749
  }
1405
1750
  function validateVideoSize(size, maxBytes) {
1406
1751
  if (size > maxBytes) {
1407
- throw new chunk6TCI6T2U_cjs.BugReporterError("VALIDATION_ERROR", `Recording exceeds max size (${Math.round(maxBytes / 1024 / 1024)}MB).`);
1752
+ throw new BugReporterError("VALIDATION_ERROR", `Recording exceeds max size (${Math.round(maxBytes / 1024 / 1024)}MB).`);
1408
1753
  }
1409
1754
  }
1410
1755
  function drawArrow(ctx, start, end) {
@@ -1421,14 +1766,14 @@ function drawArrow(ctx, start, end) {
1421
1766
  ctx.closePath();
1422
1767
  ctx.fill();
1423
1768
  }
1424
- var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl }, ref) {
1425
- const canvasRef = react.useRef(null);
1426
- const imageRef = react.useRef(null);
1427
- const [tool, setTool] = react.useState("rectangle");
1428
- const [shapes, setShapes] = react.useState([]);
1429
- const [draftShape, setDraftShape] = react.useState(null);
1430
- const dragStartRef = react.useRef(null);
1431
- const redraw = react.useCallback(
1769
+ var AnnotationCanvas = React.forwardRef(function AnnotationCanvas2({ imageUrl }, ref) {
1770
+ const canvasRef = React.useRef(null);
1771
+ const imageRef = React.useRef(null);
1772
+ const [tool, setTool] = React.useState("rectangle");
1773
+ const [shapes, setShapes] = React.useState([]);
1774
+ const [draftShape, setDraftShape] = React.useState(null);
1775
+ const dragStartRef = React.useRef(null);
1776
+ const redraw = React.useCallback(
1432
1777
  (ctx) => {
1433
1778
  const canvas = canvasRef.current;
1434
1779
  const image = imageRef.current;
@@ -1457,7 +1802,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1457
1802
  },
1458
1803
  [draftShape, shapes]
1459
1804
  );
1460
- react.useEffect(() => {
1805
+ React.useEffect(() => {
1461
1806
  const image = new Image();
1462
1807
  image.crossOrigin = "anonymous";
1463
1808
  image.onload = () => {
@@ -1476,7 +1821,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1476
1821
  };
1477
1822
  image.src = imageUrl;
1478
1823
  }, [imageUrl, redraw]);
1479
- react.useEffect(() => {
1824
+ React.useEffect(() => {
1480
1825
  const canvas = canvasRef.current;
1481
1826
  if (!canvas) {
1482
1827
  return;
@@ -1487,7 +1832,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1487
1832
  }
1488
1833
  redraw(ctx);
1489
1834
  }, [redraw]);
1490
- const getCoords = react.useCallback((event) => {
1835
+ const getCoords = React.useCallback((event) => {
1491
1836
  const canvas = canvasRef.current;
1492
1837
  if (!canvas) {
1493
1838
  return { x: 0, y: 0 };
@@ -1530,7 +1875,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1530
1875
  }
1531
1876
  setDraftShape(null);
1532
1877
  };
1533
- const canvasToBlob = react.useCallback(async () => {
1878
+ const canvasToBlob2 = React.useCallback(async () => {
1534
1879
  const canvas = canvasRef.current;
1535
1880
  if (!canvas) {
1536
1881
  throw new Error("Annotation canvas unavailable.");
@@ -1543,23 +1888,23 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1543
1888
  }
1544
1889
  return blob;
1545
1890
  }, []);
1546
- react.useImperativeHandle(
1891
+ React.useImperativeHandle(
1547
1892
  ref,
1548
1893
  () => ({
1549
- exportBlob: canvasToBlob,
1894
+ exportBlob: canvasToBlob2,
1550
1895
  clear: () => setShapes([]),
1551
1896
  hasAnnotations: () => shapes.length > 0
1552
1897
  }),
1553
- [canvasToBlob, shapes.length]
1898
+ [canvasToBlob2, shapes.length]
1554
1899
  );
1555
- const toolButtons = react.useMemo(
1900
+ const toolButtons = React.useMemo(
1556
1901
  () => [
1557
1902
  { value: "rectangle", label: "Rectangle" },
1558
1903
  { value: "arrow", label: "Arrow" }
1559
1904
  ],
1560
1905
  []
1561
1906
  );
1562
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.annotation }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.annotationTools, role: "toolbar", "aria-label": "Annotation tools" }, toolButtons.map((option) => /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
1907
+ return /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.annotation }, /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.annotationTools, role: "toolbar", "aria-label": "Annotation tools" }, toolButtons.map((option) => /* @__PURE__ */ React__namespace.createElement(
1563
1908
  "button",
1564
1909
  {
1565
1910
  key: option.value,
@@ -1568,7 +1913,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1568
1913
  onClick: () => setTool(option.value)
1569
1914
  },
1570
1915
  option.label
1571
- )), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: getButtonStyle("secondary"), onClick: () => setShapes([]) }, "Clear")), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
1916
+ )), /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: getButtonStyle("secondary"), onClick: () => setShapes([]) }, "Clear")), /* @__PURE__ */ React__namespace.createElement(
1572
1917
  "canvas",
1573
1918
  {
1574
1919
  ref: canvasRef,
@@ -1586,17 +1931,18 @@ function notifySubscribers() {
1586
1931
  subscribers.forEach((handler) => handler());
1587
1932
  }
1588
1933
  function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1934
+ var _a;
1589
1935
  const {
1590
1936
  config,
1591
1937
  state: { assets },
1592
1938
  setRecording
1593
1939
  } = useBugReporter();
1594
- const recording = react.useMemo(() => assets.find((asset) => asset.type === "recording"), [assets]);
1595
- const activeRef = react.useRef(null);
1596
- const mountedRef = react.useRef(true);
1597
- const [isRecording, setIsRecording] = react.useState(Boolean(sharedRecording));
1598
- const [seconds, setSeconds] = react.useState(sharedRecording?.seconds ?? 0);
1599
- const [error, setError] = react.useState(null);
1940
+ const recording = React.useMemo(() => assets.find((asset) => asset.type === "recording"), [assets]);
1941
+ const activeRef = React.useRef(null);
1942
+ const mountedRef = React.useRef(true);
1943
+ const [isRecording, setIsRecording] = React.useState(Boolean(sharedRecording));
1944
+ const [seconds, setSeconds] = React.useState((_a = sharedRecording == null ? void 0 : sharedRecording.seconds) != null ? _a : 0);
1945
+ const [error, setError] = React.useState(null);
1600
1946
  const start = async () => {
1601
1947
  if (sharedRecording) {
1602
1948
  setError("Recording is already in progress.");
@@ -1648,18 +1994,20 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1648
1994
  }
1649
1995
  };
1650
1996
  const stop = () => {
1997
+ var _a2;
1651
1998
  if (sharedRecording) {
1652
1999
  sharedRecording.active.stop();
1653
2000
  return;
1654
2001
  }
1655
- activeRef.current?.stop();
2002
+ (_a2 = activeRef.current) == null ? void 0 : _a2.stop();
1656
2003
  };
1657
- react.useEffect(() => {
2004
+ React.useEffect(() => {
1658
2005
  mountedRef.current = true;
1659
2006
  const sync = () => {
1660
- activeRef.current = sharedRecording?.active ?? null;
2007
+ var _a2, _b;
2008
+ activeRef.current = (_a2 = sharedRecording == null ? void 0 : sharedRecording.active) != null ? _a2 : null;
1661
2009
  setIsRecording(Boolean(sharedRecording));
1662
- setSeconds(sharedRecording?.seconds ?? 0);
2010
+ setSeconds((_b = sharedRecording == null ? void 0 : sharedRecording.seconds) != null ? _b : 0);
1663
2011
  };
1664
2012
  sync();
1665
2013
  subscribers.add(sync);
@@ -1669,10 +2017,10 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1669
2017
  };
1670
2018
  }, []);
1671
2019
  if (compact) {
1672
- const compactRecordingAction = !isRecording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: { ...getButtonStyle("primary", { fullWidth: true }), ...inlineStyles.captureButton }, onClick: start }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { style: inlineStyles.captureIcon, viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("circle", { cx: "12", cy: "12", r: "4.5" }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 8.5h3l1.2-2h8.6l1.2 2h3v7h-3l-1.2 2H7.7l-1.2-2h-3z" })), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", null, recording ? "Retake recording" : "Record a video"), recording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", { style: inlineStyles.captureDone }, "Saved") : null) : /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: { ...getButtonStyle("danger", { fullWidth: true }), ...inlineStyles.captureButton }, onClick: stop }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { style: inlineStyles.captureIcon, viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("rect", { x: "7", y: "7", width: "10", height: "10" })), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", null, "Stop (", seconds, "s)"));
1673
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.captureItem }, compactRecordingAction, error ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: { ...inlineStyles.error, marginTop: "8px" } }, error) : null);
2020
+ const compactRecordingAction = !isRecording ? /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: { ...getButtonStyle("primary", { fullWidth: true }), ...inlineStyles.captureButton }, onClick: start }, /* @__PURE__ */ React__namespace.createElement("svg", { style: inlineStyles.captureIcon, viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ React__namespace.createElement("circle", { cx: "12", cy: "12", r: "4.5" }), /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 8.5h3l1.2-2h8.6l1.2 2h3v7h-3l-1.2 2H7.7l-1.2-2h-3z" })), /* @__PURE__ */ React__namespace.createElement("span", null, recording ? "Retake recording" : "Record a video"), recording ? /* @__PURE__ */ React__namespace.createElement("span", { style: inlineStyles.captureDone }, "Saved") : null) : /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: { ...getButtonStyle("danger", { fullWidth: true }), ...inlineStyles.captureButton }, onClick: stop }, /* @__PURE__ */ React__namespace.createElement("svg", { style: inlineStyles.captureIcon, viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ React__namespace.createElement("rect", { x: "7", y: "7", width: "10", height: "10" })), /* @__PURE__ */ React__namespace.createElement("span", null, "Stop (", seconds, "s)"));
2021
+ return /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.captureItem }, compactRecordingAction, error ? /* @__PURE__ */ React__namespace.createElement("p", { style: { ...inlineStyles.error, marginTop: "8px" } }, error) : null);
1674
2022
  }
1675
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: embedded ? void 0 : inlineStyles.step }, embedded ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("h3", { style: inlineStyles.h3 }, "Screen recording") : /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("h2", { style: inlineStyles.h2 }, "Screen recording"), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.p }, "Record up to ", config.storage.limits.maxVideoSeconds, " seconds. You can minimize this sidebar while recording."), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.actions }, onBack ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: getButtonStyle("secondary", { disabled: isRecording }), onClick: onBack, disabled: isRecording }, "Back") : null, !isRecording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: getButtonStyle("primary"), onClick: start }, recording ? "Retake recording" : "Record a video") : /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: getButtonStyle("danger"), onClick: stop }, "Stop (", seconds, "s)")), recording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("video", { src: recording.previewUrl, style: inlineStyles.preview, controls: true }) : null, error ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.error }, error) : null, onNext ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.actions }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: getButtonStyle("primary"), onClick: onNext }, "Continue")) : null);
2023
+ return /* @__PURE__ */ React__namespace.createElement("div", { style: embedded ? void 0 : inlineStyles.step }, embedded ? /* @__PURE__ */ React__namespace.createElement("h3", { style: inlineStyles.h3 }, "Screen recording") : /* @__PURE__ */ React__namespace.createElement("h2", { style: inlineStyles.h2 }, "Screen recording"), /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.p }, "Record up to ", config.storage.limits.maxVideoSeconds, " seconds. You can minimize this sidebar while recording."), /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.actions }, onBack ? /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: getButtonStyle("secondary", { disabled: isRecording }), onClick: onBack, disabled: isRecording }, "Back") : null, !isRecording ? /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: getButtonStyle("primary"), onClick: start }, recording ? "Retake recording" : "Record a video") : /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: getButtonStyle("danger"), onClick: stop }, "Stop (", seconds, "s)")), recording ? /* @__PURE__ */ React__namespace.createElement("video", { src: recording.previewUrl, style: inlineStyles.preview, controls: true }) : null, error ? /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.error }, error) : null, onNext ? /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.actions }, /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: getButtonStyle("primary"), onClick: onNext }, "Continue")) : null);
1676
2024
  }
1677
2025
 
1678
2026
  // src/components/StepDescribe.tsx
@@ -1685,13 +2033,13 @@ function StepDescribe({ onNext, CustomForm }) {
1685
2033
  updateAttribute,
1686
2034
  setScreenshot
1687
2035
  } = useBugReporter();
1688
- const screenshot = react.useMemo(() => assets.find((asset) => asset.type === "screenshot"), [assets]);
1689
- const recording = react.useMemo(() => assets.find((asset) => asset.type === "recording"), [assets]);
1690
- const annotationRef = react.useRef(null);
1691
- const customFormRef = react.useRef(null);
1692
- const [isCapturing, setIsCapturing] = react.useState(false);
1693
- const [error, setError] = react.useState(null);
1694
- react.useEffect(() => {
2036
+ const screenshot = React.useMemo(() => assets.find((asset) => asset.type === "screenshot"), [assets]);
2037
+ const recording = React.useMemo(() => assets.find((asset) => asset.type === "recording"), [assets]);
2038
+ const annotationRef = React.useRef(null);
2039
+ const customFormRef = React.useRef(null);
2040
+ const [isCapturing, setIsCapturing] = React.useState(false);
2041
+ const [error, setError] = React.useState(null);
2042
+ React.useEffect(() => {
1695
2043
  if (!CustomForm) {
1696
2044
  return;
1697
2045
  }
@@ -1751,12 +2099,13 @@ function StepDescribe({ onNext, CustomForm }) {
1751
2099
  }
1752
2100
  };
1753
2101
  const continueToNext = async () => {
2102
+ var _a;
1754
2103
  setError(null);
1755
2104
  if (config.features.screenshot && !screenshot) {
1756
2105
  setError("Capture a screenshot to continue.");
1757
2106
  return;
1758
2107
  }
1759
- if (config.features.screenshot && screenshot && config.features.annotations && annotationRef.current?.hasAnnotations()) {
2108
+ if (config.features.screenshot && screenshot && config.features.annotations && ((_a = annotationRef.current) == null ? void 0 : _a.hasAnnotations())) {
1760
2109
  const annotatedBlob = await annotationRef.current.exportBlob();
1761
2110
  validateScreenshotSize(annotatedBlob.size, config.storage.limits.maxScreenshotBytes);
1762
2111
  setScreenshot({
@@ -1770,7 +2119,7 @@ function StepDescribe({ onNext, CustomForm }) {
1770
2119
  onNext();
1771
2120
  };
1772
2121
  const canContinue = Boolean(draft.title.trim()) && (!config.features.screenshot || Boolean(screenshot));
1773
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: { ...inlineStyles.step, display: "flex", flexDirection: "column", minHeight: "100%" } }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("h2", { style: inlineStyles.h2 }, "Report a bug"), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.p }, "Provide enough context so engineers can reproduce what happened."), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("label", { style: inlineStyles.field }, "Title", /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2122
+ return /* @__PURE__ */ React__namespace.createElement("div", { style: { ...inlineStyles.step, display: "flex", flexDirection: "column", minHeight: "100%" } }, /* @__PURE__ */ React__namespace.createElement("h2", { style: inlineStyles.h2 }, "Report a bug"), /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.p }, "Provide enough context so engineers can reproduce what happened."), /* @__PURE__ */ React__namespace.createElement("label", { style: inlineStyles.field }, "Title", /* @__PURE__ */ React__namespace.createElement(
1774
2123
  "input",
1775
2124
  {
1776
2125
  style: inlineStyles.input,
@@ -1779,7 +2128,7 @@ function StepDescribe({ onNext, CustomForm }) {
1779
2128
  placeholder: "Short summary",
1780
2129
  required: true
1781
2130
  }
1782
- )), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("label", { style: inlineStyles.field }, "Description", /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2131
+ )), /* @__PURE__ */ React__namespace.createElement("label", { style: inlineStyles.field }, "Description", /* @__PURE__ */ React__namespace.createElement(
1783
2132
  "textarea",
1784
2133
  {
1785
2134
  style: inlineStyles.input,
@@ -1788,7 +2137,7 @@ function StepDescribe({ onNext, CustomForm }) {
1788
2137
  placeholder: "What happened?",
1789
2138
  rows: 4
1790
2139
  }
1791
- )), CustomForm ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { ref: customFormRef }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(CustomForm, { attributes, setAttributes, updateAttribute })) : null, config.features.screenshot || config.features.recording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(chunk6TCI6T2U_cjs.React.Fragment, null, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("h3", { style: inlineStyles.h3 }, "Capture"), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.captureRow }, config.features.screenshot ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.captureItem }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2140
+ )), CustomForm ? /* @__PURE__ */ React__namespace.createElement("div", { ref: customFormRef }, /* @__PURE__ */ React__namespace.createElement(CustomForm, { attributes, setAttributes, updateAttribute })) : null, config.features.screenshot || config.features.recording ? /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement("h3", { style: inlineStyles.h3 }, "Capture"), /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.captureRow }, config.features.screenshot ? /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.captureItem }, /* @__PURE__ */ React__namespace.createElement(
1792
2141
  "button",
1793
2142
  {
1794
2143
  type: "button",
@@ -1796,10 +2145,10 @@ function StepDescribe({ onNext, CustomForm }) {
1796
2145
  onClick: startCapture,
1797
2146
  disabled: isCapturing
1798
2147
  },
1799
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { style: inlineStyles.captureIcon, viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M4 8.5h3l1.2-2h7.6l1.2 2h3v9H4z" }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("circle", { cx: "12", cy: "13", r: "3.5" })),
1800
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", null, isCapturing ? "Capturing..." : screenshot ? "Retake screenshot" : "Screenshot"),
1801
- screenshot ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", { style: inlineStyles.captureDone }, "Saved") : null
1802
- )) : null, config.features.recording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(StepRecording, { embedded: true, compact: true }) : null), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.captureNote }, config.features.screenshot && config.features.recording ? `Capture a screenshot and optionally record up to ${config.storage.limits.maxVideoSeconds} seconds.` : config.features.screenshot ? "Capture the relevant area before continuing." : `Record up to ${config.storage.limits.maxVideoSeconds} seconds.`), screenshot ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.previewWrapper }, config.features.annotations ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(AnnotationCanvas, { ref: annotationRef, imageUrl: screenshot.previewUrl }) : /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("img", { src: screenshot.previewUrl, alt: "Screenshot preview", style: inlineStyles.preview })) : null, !screenshot && recording ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.captureNote }, "Recording saved.") : null) : null, error ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.error }, error) : null, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2148
+ /* @__PURE__ */ React__namespace.createElement("svg", { style: inlineStyles.captureIcon, viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false" }, /* @__PURE__ */ React__namespace.createElement("path", { d: "M4 8.5h3l1.2-2h7.6l1.2 2h3v9H4z" }), /* @__PURE__ */ React__namespace.createElement("circle", { cx: "12", cy: "13", r: "3.5" })),
2149
+ /* @__PURE__ */ React__namespace.createElement("span", null, isCapturing ? "Capturing..." : screenshot ? "Retake screenshot" : "Screenshot"),
2150
+ screenshot ? /* @__PURE__ */ React__namespace.createElement("span", { style: inlineStyles.captureDone }, "Saved") : null
2151
+ )) : null, config.features.recording ? /* @__PURE__ */ React__namespace.createElement(StepRecording, { embedded: true, compact: true }) : null), /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.captureNote }, config.features.screenshot && config.features.recording ? `Capture a screenshot and optionally record up to ${config.storage.limits.maxVideoSeconds} seconds.` : config.features.screenshot ? "Capture the relevant area before continuing." : `Record up to ${config.storage.limits.maxVideoSeconds} seconds.`), screenshot ? /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.previewWrapper }, config.features.annotations ? /* @__PURE__ */ React__namespace.createElement(AnnotationCanvas, { ref: annotationRef, imageUrl: screenshot.previewUrl }) : /* @__PURE__ */ React__namespace.createElement("img", { src: screenshot.previewUrl, alt: "Screenshot preview", style: inlineStyles.preview })) : null, !screenshot && recording ? /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.captureNote }, "Recording saved.") : null) : null, error ? /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.error }, error) : null, /* @__PURE__ */ React__namespace.createElement(
1803
2152
  "div",
1804
2153
  {
1805
2154
  style: {
@@ -1812,7 +2161,7 @@ function StepDescribe({ onNext, CustomForm }) {
1812
2161
  paddingBottom: "12px"
1813
2162
  }
1814
2163
  },
1815
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2164
+ /* @__PURE__ */ React__namespace.createElement(
1816
2165
  "button",
1817
2166
  {
1818
2167
  type: "button",
@@ -1831,7 +2180,7 @@ function StepReview({ onBack }) {
1831
2180
  state: { assets, draft, isSubmitting, uploadProgress, error },
1832
2181
  submit
1833
2182
  } = useBugReporter();
1834
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: { ...inlineStyles.step, display: "flex", flexDirection: "column", minHeight: "100%" } }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("h2", { style: inlineStyles.h2 }, "Review and submit"), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.p }, "Confirm details, then send your report."), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.summary }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("strong", null, draft.title || "Untitled bug report"), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.p }, draft.description || "No description provided.")), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.assets }, assets.map((asset) => /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { key: asset.id, style: inlineStyles.assetCard }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", { style: inlineStyles.assetType }, asset.type), asset.type === "recording" ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("video", { src: asset.previewUrl, controls: true, style: inlineStyles.preview }) : /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("img", { src: asset.previewUrl, alt: `${asset.type} preview`, style: inlineStyles.preview })))), isSubmitting ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.uploadProgress, "aria-live": "polite" }, "Uploading assets: ", Math.round(uploadProgress * 100), "%", /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.progressTrack }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: { ...inlineStyles.progressFill, width: `${Math.round(uploadProgress * 100)}%` } }))) : null, error ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.error }, error) : null, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2183
+ return /* @__PURE__ */ React__namespace.createElement("div", { style: { ...inlineStyles.step, display: "flex", flexDirection: "column", minHeight: "100%" } }, /* @__PURE__ */ React__namespace.createElement("h2", { style: inlineStyles.h2 }, "Review and submit"), /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.p }, "Confirm details, then send your report."), /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.summary }, /* @__PURE__ */ React__namespace.createElement("strong", null, draft.title || "Untitled bug report"), /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.p }, draft.description || "No description provided.")), /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.assets }, assets.map((asset) => /* @__PURE__ */ React__namespace.createElement("div", { key: asset.id, style: inlineStyles.assetCard }, /* @__PURE__ */ React__namespace.createElement("span", { style: inlineStyles.assetType }, asset.type), asset.type === "recording" ? /* @__PURE__ */ React__namespace.createElement("video", { src: asset.previewUrl, controls: true, style: inlineStyles.preview }) : /* @__PURE__ */ React__namespace.createElement("img", { src: asset.previewUrl, alt: `${asset.type} preview`, style: inlineStyles.preview })))), isSubmitting ? /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.uploadProgress, "aria-live": "polite" }, "Uploading assets: ", Math.round(uploadProgress * 100), "%", /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.progressTrack }, /* @__PURE__ */ React__namespace.createElement("div", { style: { ...inlineStyles.progressFill, width: `${Math.round(uploadProgress * 100)}%` } }))) : null, error ? /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.error }, error) : null, /* @__PURE__ */ React__namespace.createElement(
1835
2184
  "div",
1836
2185
  {
1837
2186
  style: {
@@ -1844,7 +2193,7 @@ function StepReview({ onBack }) {
1844
2193
  paddingBottom: "12px"
1845
2194
  }
1846
2195
  },
1847
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2196
+ /* @__PURE__ */ React__namespace.createElement(
1848
2197
  "button",
1849
2198
  {
1850
2199
  type: "button",
@@ -1854,7 +2203,7 @@ function StepReview({ onBack }) {
1854
2203
  },
1855
2204
  "Back"
1856
2205
  ),
1857
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2206
+ /* @__PURE__ */ React__namespace.createElement(
1858
2207
  "button",
1859
2208
  {
1860
2209
  type: "button",
@@ -1871,15 +2220,15 @@ function StepReview({ onBack }) {
1871
2220
  var DOCK_SIDES = ["left", "right", "top", "bottom"];
1872
2221
  function DockIcon({ side }) {
1873
2222
  if (side === "left") {
1874
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 5.5h4.5v13H3.5z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
2223
+ return /* @__PURE__ */ React__namespace.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 5.5h4.5v13H3.5z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
1875
2224
  }
1876
2225
  if (side === "right") {
1877
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M16 5.5h4.5v13H16z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
2226
+ return /* @__PURE__ */ React__namespace.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ React__namespace.createElement("path", { d: "M16 5.5h4.5v13H16z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
1878
2227
  }
1879
2228
  if (side === "top") {
1880
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 5.5h17v4.5h-17z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
2229
+ return /* @__PURE__ */ React__namespace.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 5.5h17v4.5h-17z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
1881
2230
  }
1882
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M3.5 14h17v4.5h-17z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
2231
+ return /* @__PURE__ */ React__namespace.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 5.5h17v13h-17z" }), /* @__PURE__ */ React__namespace.createElement("path", { d: "M3.5 14h17v4.5h-17z", fill: "currentColor", stroke: "none", opacity: "0.85" }));
1883
2232
  }
1884
2233
  function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMode, buttonColor }) {
1885
2234
  const { config, state, setDockSide, setStep, close, reset } = useBugReporter();
@@ -1893,7 +2242,7 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1893
2242
  close();
1894
2243
  };
1895
2244
  const modalTitle = state.step === "success" ? "Report submitted" : "Report a bug";
1896
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(chunk6TCI6T2U_cjs.React.Fragment, null, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(LauncherButton, { position: launcherPosition, text: launcherText, themeMode, buttonColor }), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2245
+ return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(LauncherButton, { position: launcherPosition, text: launcherText, themeMode, buttonColor }), /* @__PURE__ */ React__namespace.createElement(
1897
2246
  Modal,
1898
2247
  {
1899
2248
  isOpen: state.isOpen,
@@ -1904,9 +2253,9 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1904
2253
  zIndex: config.theme.zIndex + 1,
1905
2254
  onRequestClose: requestClose
1906
2255
  },
1907
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.modalHeader }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.dockControls, role: "group", "aria-label": "Dock side" }, DOCK_SIDES.map((side) => {
2256
+ /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.modalHeader }, /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.dockControls, role: "group", "aria-label": "Dock side" }, DOCK_SIDES.map((side) => {
1908
2257
  const isActive = state.dockSide === side;
1909
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2258
+ return /* @__PURE__ */ React__namespace.createElement(
1910
2259
  "button",
1911
2260
  {
1912
2261
  key: side,
@@ -1916,11 +2265,11 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1916
2265
  "aria-pressed": isActive,
1917
2266
  "aria-label": `Dock ${side}`
1918
2267
  },
1919
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(DockIcon, { side })
2268
+ /* @__PURE__ */ React__namespace.createElement(DockIcon, { side })
1920
2269
  );
1921
- })), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { style: inlineStyles.iconButton, type: "button", onClick: requestClose, "aria-label": "Close bug reporter" }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("path", { d: "M6 6 18 18M18 6 6 18" })))),
1922
- state.step === "describe" ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(StepDescribe, { onNext: nextFromDescribe, CustomForm }) : null,
1923
- state.step === "review" || state.step === "submitting" ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2270
+ })), /* @__PURE__ */ React__namespace.createElement("button", { style: inlineStyles.iconButton, type: "button", onClick: requestClose, "aria-label": "Close bug reporter" }, /* @__PURE__ */ React__namespace.createElement("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", style: inlineStyles.iconSvg }, /* @__PURE__ */ React__namespace.createElement("path", { d: "M6 6 18 18M18 6 6 18" })))),
2271
+ state.step === "describe" ? /* @__PURE__ */ React__namespace.createElement(StepDescribe, { onNext: nextFromDescribe, CustomForm }) : null,
2272
+ state.step === "review" || state.step === "submitting" ? /* @__PURE__ */ React__namespace.createElement(
1924
2273
  StepReview,
1925
2274
  {
1926
2275
  onBack: () => {
@@ -1928,7 +2277,7 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1928
2277
  }
1929
2278
  }
1930
2279
  ) : null,
1931
- state.step === "success" ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.step }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("h2", { style: inlineStyles.h2 }, "Thanks, report submitted"), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("p", { style: inlineStyles.p }, "Your bug report has been sent successfully."), /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("div", { style: inlineStyles.actions }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("button", { type: "button", style: getButtonStyle("primary"), onClick: requestClose }, "Close"))) : null
2280
+ state.step === "success" ? /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.step }, /* @__PURE__ */ React__namespace.createElement("h2", { style: inlineStyles.h2 }, "Thanks, report submitted"), /* @__PURE__ */ React__namespace.createElement("p", { style: inlineStyles.p }, "Your bug report has been sent successfully."), /* @__PURE__ */ React__namespace.createElement("div", { style: inlineStyles.actions }, /* @__PURE__ */ React__namespace.createElement("button", { type: "button", style: getButtonStyle("primary"), onClick: requestClose }, "Close"))) : null
1932
2281
  ));
1933
2282
  }
1934
2283
  function BugReporter({
@@ -1939,8 +2288,9 @@ function BugReporter({
1939
2288
  themeMode = "dark",
1940
2289
  buttonColor
1941
2290
  }) {
1942
- const resolvedButtonColor = buttonColor ?? config.theme?.primaryColor ?? "#3b82f6";
1943
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(BugReporterProvider, { config }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2291
+ var _a, _b;
2292
+ const resolvedButtonColor = (_b = buttonColor != null ? buttonColor : (_a = config.theme) == null ? void 0 : _a.primaryColor) != null ? _b : "#3b82f6";
2293
+ return /* @__PURE__ */ React__namespace.createElement(BugReporterProvider, { config }, /* @__PURE__ */ React__namespace.createElement(
1944
2294
  BugReporterShell,
1945
2295
  {
1946
2296
  CustomForm,
@@ -1952,11 +2302,8 @@ function BugReporter({
1952
2302
  ));
1953
2303
  }
1954
2304
 
1955
- Object.defineProperty(exports, "BugReporterError", {
1956
- enumerable: true,
1957
- get: function () { return chunk6TCI6T2U_cjs.BugReporterError; }
1958
- });
1959
2305
  exports.BugReporter = BugReporter;
2306
+ exports.BugReporterError = BugReporterError;
1960
2307
  exports.BugReporterProvider = BugReporterProvider;
1961
2308
  exports.useBugReporter = useBugReporter;
1962
2309
  //# sourceMappingURL=index.cjs.map