@fogg/bug-reporter 1.0.1 → 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) {
@@ -71,14 +98,14 @@ function collectDiagnostics(config, options) {
71
98
  var ConsoleBuffer = class {
72
99
  constructor(maxEntries) {
73
100
  this.maxEntries = maxEntries;
74
- chunk6TCI6T2U_cjs.__publicField(this, "entries", []);
75
- chunk6TCI6T2U_cjs.__publicField(this, "originals", /* @__PURE__ */ new Map());
76
- chunk6TCI6T2U_cjs.__publicField(this, "installed", false);
77
- chunk6TCI6T2U_cjs.__publicField(this, "onWindowError", (event) => {
101
+ __publicField(this, "entries", []);
102
+ __publicField(this, "originals", /* @__PURE__ */ new Map());
103
+ __publicField(this, "installed", false);
104
+ __publicField(this, "onWindowError", (event) => {
78
105
  var _a;
79
106
  this.push("error", [event.message, event.error instanceof Error ? (_a = event.error.stack) != null ? _a : "" : ""]);
80
107
  });
81
- chunk6TCI6T2U_cjs.__publicField(this, "onUnhandledRejection", (event) => {
108
+ __publicField(this, "onUnhandledRejection", (event) => {
82
109
  this.push("error", ["Unhandled promise rejection", event.reason]);
83
110
  });
84
111
  }
@@ -166,11 +193,11 @@ function extractMethod(input, init) {
166
193
  var NetworkBuffer = class {
167
194
  constructor(maxEntries) {
168
195
  this.maxEntries = maxEntries;
169
- chunk6TCI6T2U_cjs.__publicField(this, "entries", []);
170
- chunk6TCI6T2U_cjs.__publicField(this, "installed", false);
171
- chunk6TCI6T2U_cjs.__publicField(this, "originalFetch");
172
- chunk6TCI6T2U_cjs.__publicField(this, "originalXhrOpen");
173
- 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");
174
201
  }
175
202
  install() {
176
203
  if (this.installed) {
@@ -311,7 +338,7 @@ var NetworkBuffer = class {
311
338
  }
312
339
  }
313
340
  };
314
- var BugReporterContext = react.createContext(void 0);
341
+ var BugReporterContext = React.createContext(void 0);
315
342
 
316
343
  // src/core/defaults.ts
317
344
  var DEFAULT_MASK_SELECTORS = [
@@ -371,6 +398,18 @@ function withDefaults(config) {
371
398
  };
372
399
  }
373
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
+
374
413
  // src/storage/local-public.ts
375
414
  var LocalPublicProvider = class {
376
415
  constructor(options) {
@@ -398,7 +437,7 @@ var LocalPublicProvider = class {
398
437
  body: form
399
438
  });
400
439
  if (!response.ok) {
401
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Local upload failed (${response.status}).`);
440
+ throw new BugReporterError("UPLOAD_ERROR", `Local upload failed (${response.status}).`);
402
441
  }
403
442
  const payload = await response.json();
404
443
  onProgress == null ? void 0 : onProgress(1);
@@ -441,7 +480,7 @@ var ProxyProvider = class {
441
480
  body: blob
442
481
  });
443
482
  if (!response.ok) {
444
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `Proxy upload failed (${response.status}).`);
483
+ throw new BugReporterError("UPLOAD_ERROR", `Proxy upload failed (${response.status}).`);
445
484
  }
446
485
  const payload = await response.json();
447
486
  onProgress == null ? void 0 : onProgress(1);
@@ -473,11 +512,11 @@ var S3PresignedProvider = class {
473
512
  body: JSON.stringify({ files })
474
513
  });
475
514
  if (!response.ok) {
476
- 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}).`);
477
516
  }
478
517
  const payload = await response.json();
479
518
  if (!((_a = payload.uploads) == null ? void 0 : _a.length)) {
480
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", "Presign endpoint did not return upload instructions.");
519
+ throw new BugReporterError("UPLOAD_ERROR", "Presign endpoint did not return upload instructions.");
481
520
  }
482
521
  return payload.uploads;
483
522
  }
@@ -493,7 +532,7 @@ var S3PresignedProvider = class {
493
532
  body: formData
494
533
  });
495
534
  if (!response.ok) {
496
- 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}).`);
497
536
  }
498
537
  } else {
499
538
  const response = await fetch(instruction.uploadUrl, {
@@ -502,7 +541,7 @@ var S3PresignedProvider = class {
502
541
  body: blob
503
542
  });
504
543
  if (!response.ok) {
505
- throw new chunk6TCI6T2U_cjs.BugReporterError("UPLOAD_ERROR", `S3 upload failed (${response.status}).`);
544
+ throw new BugReporterError("UPLOAD_ERROR", `S3 upload failed (${response.status}).`);
506
545
  }
507
546
  }
508
547
  onProgress == null ? void 0 : onProgress(1);
@@ -604,7 +643,7 @@ async function uploadAssets(options) {
604
643
  for (const asset of options.assets) {
605
644
  const instruction = byId.get(asset.id);
606
645
  if (!instruction) {
607
- 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}.`);
608
647
  }
609
648
  const ref = await withRetry(
610
649
  () => options.provider.upload(instruction, asset.blob, (inner) => {
@@ -671,7 +710,7 @@ async function submitReport(options) {
671
710
  };
672
711
  const transformed = options.config.hooks.beforeSubmit ? await options.config.hooks.beforeSubmit(payloadBase) : payloadBase;
673
712
  if (!transformed) {
674
- throw new chunk6TCI6T2U_cjs.BugReporterError("ABORTED", "Submission aborted by beforeSubmit hook.");
713
+ throw new BugReporterError("ABORTED", "Submission aborted by beforeSubmit hook.");
675
714
  }
676
715
  console.log("[bug-reporter] payload to submit", transformed);
677
716
  console.log("[bug-reporter] payload to submit (json)", JSON.stringify(transformed, null, 2));
@@ -686,7 +725,7 @@ async function submitReport(options) {
686
725
  });
687
726
  if (!response.ok) {
688
727
  const body = await response.text().catch(() => "");
689
- 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}`);
690
729
  }
691
730
  return await response.json();
692
731
  }
@@ -711,21 +750,21 @@ var BASE_STATE = {
711
750
  error: void 0
712
751
  };
713
752
  function BugReporterProvider({ config, children }) {
714
- const resolvedConfig = react.useMemo(() => withDefaults(config), [config]);
753
+ const resolvedConfig = React.useMemo(() => withDefaults(config), [config]);
715
754
  const initialDockSide = resolvedConfig.theme.position === "bottom-left" || resolvedConfig.theme.position === "top-left" ? "left" : "right";
716
- const [state, setState] = react.useState(() => ({
755
+ const [state, setState] = React.useState(() => ({
717
756
  ...BASE_STATE,
718
757
  dockSide: initialDockSide,
719
758
  attributes: { ...resolvedConfig.attributes }
720
759
  }));
721
- const [sessionActive, setSessionActive] = react.useState(false);
722
- const consoleBufferRef = react.useRef(null);
723
- const networkBufferRef = react.useRef(null);
724
- const assetsRef = react.useRef([]);
725
- 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) => {
726
765
  assets.forEach((asset) => revokeObjectUrl(asset.previewUrl));
727
766
  }, []);
728
- const open = react.useCallback(() => {
767
+ const open = React.useCallback(() => {
729
768
  setSessionActive(true);
730
769
  setState((prev) => ({
731
770
  ...prev,
@@ -733,13 +772,13 @@ function BugReporterProvider({ config, children }) {
733
772
  error: void 0
734
773
  }));
735
774
  }, []);
736
- const close = react.useCallback(() => {
775
+ const close = React.useCallback(() => {
737
776
  setState((prev) => ({
738
777
  ...prev,
739
778
  isOpen: false
740
779
  }));
741
780
  }, []);
742
- const reset = react.useCallback(() => {
781
+ const reset = React.useCallback(() => {
743
782
  var _a, _b;
744
783
  setSessionActive(false);
745
784
  setState((prev) => {
@@ -754,13 +793,13 @@ function BugReporterProvider({ config, children }) {
754
793
  (_a = consoleBufferRef.current) == null ? void 0 : _a.clear();
755
794
  (_b = networkBufferRef.current) == null ? void 0 : _b.clear();
756
795
  }, [resetAssets, resolvedConfig.attributes]);
757
- const setStep = react.useCallback((step) => {
796
+ const setStep = React.useCallback((step) => {
758
797
  setState((prev) => ({ ...prev, step }));
759
798
  }, []);
760
- const setDockSide = react.useCallback((dockSide) => {
799
+ const setDockSide = React.useCallback((dockSide) => {
761
800
  setState((prev) => ({ ...prev, dockSide }));
762
801
  }, []);
763
- const updateDraft = react.useCallback((next) => {
802
+ const updateDraft = React.useCallback((next) => {
764
803
  setState((prev) => ({
765
804
  ...prev,
766
805
  draft: {
@@ -769,13 +808,13 @@ function BugReporterProvider({ config, children }) {
769
808
  }
770
809
  }));
771
810
  }, []);
772
- const setAttributes = react.useCallback((next) => {
811
+ const setAttributes = React.useCallback((next) => {
773
812
  setState((prev) => ({
774
813
  ...prev,
775
814
  attributes: next
776
815
  }));
777
816
  }, []);
778
- const updateAttribute = react.useCallback((key, value2) => {
817
+ const updateAttribute = React.useCallback((key, value2) => {
779
818
  setState((prev) => ({
780
819
  ...prev,
781
820
  attributes: {
@@ -784,7 +823,7 @@ function BugReporterProvider({ config, children }) {
784
823
  }
785
824
  }));
786
825
  }, []);
787
- const setAssetByType = react.useCallback((type, next) => {
826
+ const setAssetByType = React.useCallback((type, next) => {
788
827
  setState((prev) => {
789
828
  const previous = prev.assets.find((asset) => asset.type === type);
790
829
  if (previous) {
@@ -797,13 +836,13 @@ function BugReporterProvider({ config, children }) {
797
836
  };
798
837
  });
799
838
  }, []);
800
- const setScreenshot = react.useCallback((asset) => {
839
+ const setScreenshot = React.useCallback((asset) => {
801
840
  setAssetByType("screenshot", asset);
802
841
  }, [setAssetByType]);
803
- const setRecording = react.useCallback((asset) => {
842
+ const setRecording = React.useCallback((asset) => {
804
843
  setAssetByType("recording", asset);
805
844
  }, [setAssetByType]);
806
- const submit = react.useCallback(async () => {
845
+ const submit = React.useCallback(async () => {
807
846
  var _a, _b, _c, _d, _e, _f;
808
847
  setState((prev) => ({
809
848
  ...prev,
@@ -848,10 +887,10 @@ function BugReporterProvider({ config, children }) {
848
887
  (_f = (_e = resolvedConfig.hooks).onError) == null ? void 0 : _f.call(_e, error);
849
888
  }
850
889
  }, [resolvedConfig, state.assets, state.attributes, state.draft]);
851
- const retrySubmit = react.useCallback(async () => {
890
+ const retrySubmit = React.useCallback(async () => {
852
891
  await submit();
853
892
  }, [submit]);
854
- const getDiagnosticsPreview = react.useCallback(() => {
893
+ const getDiagnosticsPreview = React.useCallback(() => {
855
894
  var _a, _b, _c, _d;
856
895
  const logs = resolvedConfig.features.consoleLogs ? (_b = (_a = consoleBufferRef.current) == null ? void 0 : _a.snapshot()) != null ? _b : [] : [];
857
896
  const requests = resolvedConfig.features.networkInfo ? (_d = (_c = networkBufferRef.current) == null ? void 0 : _c.snapshot()) != null ? _d : [] : [];
@@ -863,7 +902,7 @@ function BugReporterProvider({ config, children }) {
863
902
  })
864
903
  };
865
904
  }, [resolvedConfig.features.consoleLogs, resolvedConfig.features.networkInfo]);
866
- react.useEffect(() => {
905
+ React.useEffect(() => {
867
906
  if (!sessionActive) {
868
907
  return;
869
908
  }
@@ -892,10 +931,10 @@ function BugReporterProvider({ config, children }) {
892
931
  resolvedConfig.features.consoleLogs,
893
932
  resolvedConfig.features.networkInfo
894
933
  ]);
895
- react.useEffect(() => {
934
+ React.useEffect(() => {
896
935
  assetsRef.current = state.assets;
897
936
  }, [state.assets]);
898
- react.useEffect(() => {
937
+ React.useEffect(() => {
899
938
  return () => {
900
939
  var _a, _b;
901
940
  resetAssets(assetsRef.current);
@@ -903,7 +942,7 @@ function BugReporterProvider({ config, children }) {
903
942
  (_b = networkBufferRef.current) == null ? void 0 : _b.uninstall();
904
943
  };
905
944
  }, [resetAssets]);
906
- const value = react.useMemo(
945
+ const value = React.useMemo(
907
946
  () => ({
908
947
  config: resolvedConfig,
909
948
  state,
@@ -939,10 +978,10 @@ function BugReporterProvider({ config, children }) {
939
978
  getDiagnosticsPreview
940
979
  ]
941
980
  );
942
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(BugReporterContext.Provider, { value }, children);
981
+ return /* @__PURE__ */ React__namespace.createElement(BugReporterContext.Provider, { value }, children);
943
982
  }
944
983
  function useBugReporter() {
945
- const context = react.useContext(BugReporterContext);
984
+ const context = React.useContext(BugReporterContext);
946
985
  if (!context) {
947
986
  throw new Error("useBugReporter must be used inside BugReporterProvider.");
948
987
  }
@@ -956,7 +995,7 @@ function getFocusable(node) {
956
995
  ).filter((el) => !el.hasAttribute("disabled"));
957
996
  }
958
997
  function useFocusTrap(enabled, containerRef) {
959
- react.useEffect(() => {
998
+ React.useEffect(() => {
960
999
  const container = containerRef.current;
961
1000
  if (!enabled || !container) {
962
1001
  return;
@@ -1367,7 +1406,7 @@ function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1367
1406
  buttonColor: resolvedButtonColor,
1368
1407
  themeMode
1369
1408
  });
1370
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
1409
+ return /* @__PURE__ */ React__namespace.createElement(
1371
1410
  "button",
1372
1411
  {
1373
1412
  type: "button",
@@ -1379,9 +1418,9 @@ function LauncherButton({ position, text, themeMode = "dark", buttonColor }) {
1379
1418
  );
1380
1419
  }
1381
1420
  function Modal({ isOpen, dockSide, themeMode, buttonColor, title, zIndex, onRequestClose, children }) {
1382
- const dialogRef = react.useRef(null);
1421
+ const dialogRef = React.useRef(null);
1383
1422
  useFocusTrap(isOpen, dialogRef);
1384
- react.useEffect(() => {
1423
+ React.useEffect(() => {
1385
1424
  if (!isOpen) {
1386
1425
  return;
1387
1426
  }
@@ -1400,23 +1439,309 @@ function Modal({ isOpen, dockSide, themeMode, buttonColor, title, zIndex, onRequ
1400
1439
  const overlayStyle = getModalOverlayStyle({ dockSide, themeMode, zIndex });
1401
1440
  const modalStyle = getModalStyle({ dockSide, themeMode, buttonColor });
1402
1441
  return reactDom.createPortal(
1403
- /* @__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)),
1404
1443
  document.body
1405
1444
  );
1406
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
+ }
1407
1730
 
1408
1731
  // src/core/lazy.ts
1732
+ var screenshotCaptureModule = { captureScreenshotArea };
1733
+ var screenRecordingModule = { startScreenRecording };
1409
1734
  async function loadScreenshotCapture() {
1410
- return import('./screenshot-AWRHVVWJ.cjs');
1735
+ return screenshotCaptureModule;
1411
1736
  }
1412
1737
  async function loadScreenRecording() {
1413
- return import('./recording-DZREYVVL.cjs');
1738
+ return screenRecordingModule;
1414
1739
  }
1415
1740
 
1416
1741
  // src/core/validation.ts
1417
1742
  function validateScreenshotSize(size, maxBytes) {
1418
1743
  if (size > maxBytes) {
1419
- throw new chunk6TCI6T2U_cjs.BugReporterError(
1744
+ throw new BugReporterError(
1420
1745
  "VALIDATION_ERROR",
1421
1746
  `Screenshot exceeds max size (${Math.round(maxBytes / 1024 / 1024)}MB).`
1422
1747
  );
@@ -1424,7 +1749,7 @@ function validateScreenshotSize(size, maxBytes) {
1424
1749
  }
1425
1750
  function validateVideoSize(size, maxBytes) {
1426
1751
  if (size > maxBytes) {
1427
- 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).`);
1428
1753
  }
1429
1754
  }
1430
1755
  function drawArrow(ctx, start, end) {
@@ -1441,14 +1766,14 @@ function drawArrow(ctx, start, end) {
1441
1766
  ctx.closePath();
1442
1767
  ctx.fill();
1443
1768
  }
1444
- var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl }, ref) {
1445
- const canvasRef = react.useRef(null);
1446
- const imageRef = react.useRef(null);
1447
- const [tool, setTool] = react.useState("rectangle");
1448
- const [shapes, setShapes] = react.useState([]);
1449
- const [draftShape, setDraftShape] = react.useState(null);
1450
- const dragStartRef = react.useRef(null);
1451
- 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(
1452
1777
  (ctx) => {
1453
1778
  const canvas = canvasRef.current;
1454
1779
  const image = imageRef.current;
@@ -1477,7 +1802,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1477
1802
  },
1478
1803
  [draftShape, shapes]
1479
1804
  );
1480
- react.useEffect(() => {
1805
+ React.useEffect(() => {
1481
1806
  const image = new Image();
1482
1807
  image.crossOrigin = "anonymous";
1483
1808
  image.onload = () => {
@@ -1496,7 +1821,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1496
1821
  };
1497
1822
  image.src = imageUrl;
1498
1823
  }, [imageUrl, redraw]);
1499
- react.useEffect(() => {
1824
+ React.useEffect(() => {
1500
1825
  const canvas = canvasRef.current;
1501
1826
  if (!canvas) {
1502
1827
  return;
@@ -1507,7 +1832,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1507
1832
  }
1508
1833
  redraw(ctx);
1509
1834
  }, [redraw]);
1510
- const getCoords = react.useCallback((event) => {
1835
+ const getCoords = React.useCallback((event) => {
1511
1836
  const canvas = canvasRef.current;
1512
1837
  if (!canvas) {
1513
1838
  return { x: 0, y: 0 };
@@ -1550,7 +1875,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1550
1875
  }
1551
1876
  setDraftShape(null);
1552
1877
  };
1553
- const canvasToBlob = react.useCallback(async () => {
1878
+ const canvasToBlob2 = React.useCallback(async () => {
1554
1879
  const canvas = canvasRef.current;
1555
1880
  if (!canvas) {
1556
1881
  throw new Error("Annotation canvas unavailable.");
@@ -1563,23 +1888,23 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1563
1888
  }
1564
1889
  return blob;
1565
1890
  }, []);
1566
- react.useImperativeHandle(
1891
+ React.useImperativeHandle(
1567
1892
  ref,
1568
1893
  () => ({
1569
- exportBlob: canvasToBlob,
1894
+ exportBlob: canvasToBlob2,
1570
1895
  clear: () => setShapes([]),
1571
1896
  hasAnnotations: () => shapes.length > 0
1572
1897
  }),
1573
- [canvasToBlob, shapes.length]
1898
+ [canvasToBlob2, shapes.length]
1574
1899
  );
1575
- const toolButtons = react.useMemo(
1900
+ const toolButtons = React.useMemo(
1576
1901
  () => [
1577
1902
  { value: "rectangle", label: "Rectangle" },
1578
1903
  { value: "arrow", label: "Arrow" }
1579
1904
  ],
1580
1905
  []
1581
1906
  );
1582
- 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(
1583
1908
  "button",
1584
1909
  {
1585
1910
  key: option.value,
@@ -1588,7 +1913,7 @@ var AnnotationCanvas = react.forwardRef(function AnnotationCanvas2({ imageUrl },
1588
1913
  onClick: () => setTool(option.value)
1589
1914
  },
1590
1915
  option.label
1591
- )), /* @__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(
1592
1917
  "canvas",
1593
1918
  {
1594
1919
  ref: canvasRef,
@@ -1612,12 +1937,12 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1612
1937
  state: { assets },
1613
1938
  setRecording
1614
1939
  } = useBugReporter();
1615
- const recording = react.useMemo(() => assets.find((asset) => asset.type === "recording"), [assets]);
1616
- const activeRef = react.useRef(null);
1617
- const mountedRef = react.useRef(true);
1618
- const [isRecording, setIsRecording] = react.useState(Boolean(sharedRecording));
1619
- const [seconds, setSeconds] = react.useState((_a = sharedRecording == null ? void 0 : sharedRecording.seconds) != null ? _a : 0);
1620
- 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);
1621
1946
  const start = async () => {
1622
1947
  if (sharedRecording) {
1623
1948
  setError("Recording is already in progress.");
@@ -1676,7 +2001,7 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1676
2001
  }
1677
2002
  (_a2 = activeRef.current) == null ? void 0 : _a2.stop();
1678
2003
  };
1679
- react.useEffect(() => {
2004
+ React.useEffect(() => {
1680
2005
  mountedRef.current = true;
1681
2006
  const sync = () => {
1682
2007
  var _a2, _b;
@@ -1692,10 +2017,10 @@ function StepRecording({ onBack, onNext, embedded = false, compact = false }) {
1692
2017
  };
1693
2018
  }, []);
1694
2019
  if (compact) {
1695
- 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)"));
1696
- 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);
1697
2022
  }
1698
- 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);
1699
2024
  }
1700
2025
 
1701
2026
  // src/components/StepDescribe.tsx
@@ -1708,13 +2033,13 @@ function StepDescribe({ onNext, CustomForm }) {
1708
2033
  updateAttribute,
1709
2034
  setScreenshot
1710
2035
  } = useBugReporter();
1711
- const screenshot = react.useMemo(() => assets.find((asset) => asset.type === "screenshot"), [assets]);
1712
- const recording = react.useMemo(() => assets.find((asset) => asset.type === "recording"), [assets]);
1713
- const annotationRef = react.useRef(null);
1714
- const customFormRef = react.useRef(null);
1715
- const [isCapturing, setIsCapturing] = react.useState(false);
1716
- const [error, setError] = react.useState(null);
1717
- 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(() => {
1718
2043
  if (!CustomForm) {
1719
2044
  return;
1720
2045
  }
@@ -1794,7 +2119,7 @@ function StepDescribe({ onNext, CustomForm }) {
1794
2119
  onNext();
1795
2120
  };
1796
2121
  const canContinue = Boolean(draft.title.trim()) && (!config.features.screenshot || Boolean(screenshot));
1797
- 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(
1798
2123
  "input",
1799
2124
  {
1800
2125
  style: inlineStyles.input,
@@ -1803,7 +2128,7 @@ function StepDescribe({ onNext, CustomForm }) {
1803
2128
  placeholder: "Short summary",
1804
2129
  required: true
1805
2130
  }
1806
- )), /* @__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(
1807
2132
  "textarea",
1808
2133
  {
1809
2134
  style: inlineStyles.input,
@@ -1812,7 +2137,7 @@ function StepDescribe({ onNext, CustomForm }) {
1812
2137
  placeholder: "What happened?",
1813
2138
  rows: 4
1814
2139
  }
1815
- )), 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(
1816
2141
  "button",
1817
2142
  {
1818
2143
  type: "button",
@@ -1820,10 +2145,10 @@ function StepDescribe({ onNext, CustomForm }) {
1820
2145
  onClick: startCapture,
1821
2146
  disabled: isCapturing
1822
2147
  },
1823
- /* @__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" })),
1824
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", null, isCapturing ? "Capturing..." : screenshot ? "Retake screenshot" : "Screenshot"),
1825
- screenshot ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement("span", { style: inlineStyles.captureDone }, "Saved") : null
1826
- )) : 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(
1827
2152
  "div",
1828
2153
  {
1829
2154
  style: {
@@ -1836,7 +2161,7 @@ function StepDescribe({ onNext, CustomForm }) {
1836
2161
  paddingBottom: "12px"
1837
2162
  }
1838
2163
  },
1839
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2164
+ /* @__PURE__ */ React__namespace.createElement(
1840
2165
  "button",
1841
2166
  {
1842
2167
  type: "button",
@@ -1855,7 +2180,7 @@ function StepReview({ onBack }) {
1855
2180
  state: { assets, draft, isSubmitting, uploadProgress, error },
1856
2181
  submit
1857
2182
  } = useBugReporter();
1858
- 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(
1859
2184
  "div",
1860
2185
  {
1861
2186
  style: {
@@ -1868,7 +2193,7 @@ function StepReview({ onBack }) {
1868
2193
  paddingBottom: "12px"
1869
2194
  }
1870
2195
  },
1871
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2196
+ /* @__PURE__ */ React__namespace.createElement(
1872
2197
  "button",
1873
2198
  {
1874
2199
  type: "button",
@@ -1878,7 +2203,7 @@ function StepReview({ onBack }) {
1878
2203
  },
1879
2204
  "Back"
1880
2205
  ),
1881
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2206
+ /* @__PURE__ */ React__namespace.createElement(
1882
2207
  "button",
1883
2208
  {
1884
2209
  type: "button",
@@ -1895,15 +2220,15 @@ function StepReview({ onBack }) {
1895
2220
  var DOCK_SIDES = ["left", "right", "top", "bottom"];
1896
2221
  function DockIcon({ side }) {
1897
2222
  if (side === "left") {
1898
- 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" }));
1899
2224
  }
1900
2225
  if (side === "right") {
1901
- 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" }));
1902
2227
  }
1903
2228
  if (side === "top") {
1904
- 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" }));
1905
2230
  }
1906
- 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" }));
1907
2232
  }
1908
2233
  function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMode, buttonColor }) {
1909
2234
  const { config, state, setDockSide, setStep, close, reset } = useBugReporter();
@@ -1917,7 +2242,7 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1917
2242
  close();
1918
2243
  };
1919
2244
  const modalTitle = state.step === "success" ? "Report submitted" : "Report a bug";
1920
- 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(
1921
2246
  Modal,
1922
2247
  {
1923
2248
  isOpen: state.isOpen,
@@ -1928,9 +2253,9 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1928
2253
  zIndex: config.theme.zIndex + 1,
1929
2254
  onRequestClose: requestClose
1930
2255
  },
1931
- /* @__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) => {
1932
2257
  const isActive = state.dockSide === side;
1933
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2258
+ return /* @__PURE__ */ React__namespace.createElement(
1934
2259
  "button",
1935
2260
  {
1936
2261
  key: side,
@@ -1940,11 +2265,11 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1940
2265
  "aria-pressed": isActive,
1941
2266
  "aria-label": `Dock ${side}`
1942
2267
  },
1943
- /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(DockIcon, { side })
2268
+ /* @__PURE__ */ React__namespace.createElement(DockIcon, { side })
1944
2269
  );
1945
- })), /* @__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" })))),
1946
- state.step === "describe" ? /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(StepDescribe, { onNext: nextFromDescribe, CustomForm }) : null,
1947
- 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(
1948
2273
  StepReview,
1949
2274
  {
1950
2275
  onBack: () => {
@@ -1952,7 +2277,7 @@ function BugReporterShell({ CustomForm, launcherPosition, launcherText, themeMod
1952
2277
  }
1953
2278
  }
1954
2279
  ) : null,
1955
- 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
1956
2281
  ));
1957
2282
  }
1958
2283
  function BugReporter({
@@ -1965,7 +2290,7 @@ function BugReporter({
1965
2290
  }) {
1966
2291
  var _a, _b;
1967
2292
  const resolvedButtonColor = (_b = buttonColor != null ? buttonColor : (_a = config.theme) == null ? void 0 : _a.primaryColor) != null ? _b : "#3b82f6";
1968
- return /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(BugReporterProvider, { config }, /* @__PURE__ */ chunk6TCI6T2U_cjs.React.createElement(
2293
+ return /* @__PURE__ */ React__namespace.createElement(BugReporterProvider, { config }, /* @__PURE__ */ React__namespace.createElement(
1969
2294
  BugReporterShell,
1970
2295
  {
1971
2296
  CustomForm,
@@ -1977,11 +2302,8 @@ function BugReporter({
1977
2302
  ));
1978
2303
  }
1979
2304
 
1980
- Object.defineProperty(exports, "BugReporterError", {
1981
- enumerable: true,
1982
- get: function () { return chunk6TCI6T2U_cjs.BugReporterError; }
1983
- });
1984
2305
  exports.BugReporter = BugReporter;
2306
+ exports.BugReporterError = BugReporterError;
1985
2307
  exports.BugReporterProvider = BugReporterProvider;
1986
2308
  exports.useBugReporter = useBugReporter;
1987
2309
  //# sourceMappingURL=index.cjs.map