@qaiddev/thumbs-embed 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +77 -33
  2. package/dist/bootstrap.d.ts +4 -2
  3. package/dist/chunks/{annotate-CMq95aXG.js → annotate-D-o8xCV9.js} +23 -17
  4. package/dist/chunks/annotate-D-o8xCV9.js.map +1 -0
  5. package/dist/chunks/dom-DvdtcUS8.js +17 -0
  6. package/dist/chunks/dom-DvdtcUS8.js.map +1 -0
  7. package/dist/chunks/{loader-CYM1rxDH.js → loader-XbJ2b8KE.js} +229 -167
  8. package/dist/chunks/loader-XbJ2b8KE.js.map +1 -0
  9. package/dist/chunks/modal-XxYobTKE.js +213 -0
  10. package/dist/chunks/modal-XxYobTKE.js.map +1 -0
  11. package/dist/chunks/{recording-BVFd_ryf.js → recording-Dx8AX-BC.js} +103 -98
  12. package/dist/chunks/recording-Dx8AX-BC.js.map +1 -0
  13. package/dist/chunks/{screenshot-BkOCLuS2.js → screenshot-DYOKg2bS.js} +2 -2
  14. package/dist/chunks/{screenshot-BkOCLuS2.js.map → screenshot-DYOKg2bS.js.map} +1 -1
  15. package/dist/chunks/{targeting-1pK6nJI9.js → targeting-Dz6z1BYl.js} +2 -2
  16. package/dist/chunks/{targeting-1pK6nJI9.js.map → targeting-Dz6z1BYl.js.map} +1 -1
  17. package/dist/chunks/{video-BOYqf2Im.js → video-Bd_29-rK.js} +76 -71
  18. package/dist/chunks/video-Bd_29-rK.js.map +1 -0
  19. package/dist/embed.d.ts +11 -0
  20. package/dist/icons.d.ts +2 -0
  21. package/dist/index.js +599 -448
  22. package/dist/index.js.map +1 -1
  23. package/dist/loader.js +1 -1
  24. package/dist/modal.d.ts +14 -4
  25. package/dist/qaid.umd.cjs +14 -38
  26. package/dist/qaid.umd.cjs.map +1 -1
  27. package/dist/recording.d.ts +6 -0
  28. package/dist/screenshot.d.ts +1 -1
  29. package/dist/types.d.ts +14 -2
  30. package/dist/video-capture.d.ts +6 -0
  31. package/package.json +1 -1
  32. package/dist/chunks/annotate-CMq95aXG.js.map +0 -1
  33. package/dist/chunks/loader-CYM1rxDH.js.map +0 -1
  34. package/dist/chunks/modal-Br5x7m6f.js +0 -150
  35. package/dist/chunks/modal-Br5x7m6f.js.map +0 -1
  36. package/dist/chunks/recording-BVFd_ryf.js.map +0 -1
  37. package/dist/chunks/video-BOYqf2Im.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,41 +1,43 @@
1
1
  const V = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
2
2
  <path stroke-linecap="round" stroke-linejoin="round" d="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5"/>
3
- </svg>`, N = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
3
+ </svg>`, U = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
4
4
  <path stroke-linecap="round" stroke-linejoin="round" d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.737 3h4.018a2 2 0 01.485.06l3.76.94m-7 10v5a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5-10h2a2 2 0 012 2v6a2 2 0 01-2 2h-2.5"/>
5
- </svg>`, Xt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
5
+ </svg>`, re = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
6
6
  <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z"/>
7
- </svg>`, gt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
7
+ </svg>`, St = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
8
8
  <path stroke-linecap="round" stroke-linejoin="round" d="M8 10h8M8 14h5m-9 6l3.5-3.5H18a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v14z"/>
9
- </svg>`, Yt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
9
+ </svg>`, de = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
10
10
  <rect x="4" y="6" width="16" height="12" rx="1" stroke-linejoin="round"/>
11
- </svg>`, Qt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
11
+ </svg>`, ce = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
12
12
  <path stroke-linecap="round" stroke-linejoin="round" d="M5 19L19 5m0 0h-8m8 0v8"/>
13
- </svg>`, Gt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
13
+ </svg>`, le = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
14
14
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 20h9M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/>
15
- </svg>`, Jt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
15
+ </svg>`, he = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
16
16
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 3s6 6.4 6 10a6 6 0 01-12 0c0-3.6 6-10 6-10z"/>
17
- </svg>`, Zt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
17
+ </svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
18
18
  <path stroke-linecap="round" stroke-linejoin="round" d="M9 14L4 9l5-5M4 9h11a5 5 0 010 10h-4"/>
19
- </svg>`, vt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
19
+ </svg>`, Et = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
20
20
  <path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
21
- </svg>`, te = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
21
+ </svg>`, pe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
22
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v8m0 4h.01"/>
23
+ </svg>`, fe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
22
24
  <path stroke-linecap="round" stroke-linejoin="round" d="M6 6l12 12M18 6L6 18"/>
23
- </svg>`, ee = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6366f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:1rem;font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:.8125rem;line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6366f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6366f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6366f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-title{margin:0;font-size:1rem;font-weight:600;color:var(--qaid-text, #111827)}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6366f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:.875rem;color:var(--qaid-text-muted, #6b7280)}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", ie = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
24
- let I = 0;
25
- const oe = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn-feedback:hover{background:var(--qaid-marker,#6366f1);color:var(--qaid-marker-text,#fff)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", ne = {
25
+ </svg>`, me = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}:where(button.qaid-btn-structural)>svg:where(:not(.qaid-icon):not([width])){width:var(--qaid-icon-size, 24px);height:var(--qaid-icon-size, 24px)}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:var(--qaid-font-size, 16px);font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6365f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875)}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:var(--qaid-font-size, 16px);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:calc(var(--qaid-font-size, 16px) * .75);font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .875);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-error{margin:0 0 .75rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;color:light-dark(#b91c1c,#fca5a5)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .8125);line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .8125);font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6365f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6365f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-error .qaid-confirm-icon{background:var(--qaid-error, #dc2626)}.qaid-confirm-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:600;color:var(--qaid-text, light-dark(#111827, #f9fafb))}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6365f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875);color:var(--qaid-text-muted, light-dark(#6b7280, #9ca3af))}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", be = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
26
+ let D = 0;
27
+ const ge = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn-feedback:hover{background:var(--qaid-marker,#6365f1);color:var(--qaid-marker-text,#fff)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", ve = {
26
28
  small: 36,
27
29
  medium: 48,
28
30
  large: 64
29
- }, se = {
31
+ }, ye = {
30
32
  small: 18,
31
33
  medium: 24,
32
34
  large: 32
33
35
  };
34
- function ae(i, t, e) {
36
+ function we(i, t, e) {
35
37
  const [o, n, s] = [i, t, e].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
36
38
  return 0.2126 * o + 0.7152 * n + 0.0722 * s;
37
39
  }
38
- function re(i) {
40
+ function ke(i) {
39
41
  if (i.startsWith("#")) {
40
42
  const e = i.slice(1), o = e.length === 3 ? e.split("").map((s) => s + s).join("") : e, n = parseInt(o, 16);
41
43
  return {
@@ -51,21 +53,21 @@ function re(i) {
51
53
  b: parseInt(t[3])
52
54
  } : null;
53
55
  }
54
- function de(i) {
55
- const t = re(i);
56
- return t && ae(t.r, t.g, t.b) > 0.4 ? "black" : "white";
56
+ function xe(i) {
57
+ const t = ke(i);
58
+ return t && we(t.r, t.g, t.b) > 0.4 ? "black" : "white";
57
59
  }
58
- function ce(i = {}) {
60
+ function qe(i = {}) {
59
61
  const {
60
62
  positiveColor: t = "rgb(0, 200, 83)",
61
63
  negativeColor: e = "rgb(255, 0, 0)",
62
- markerColor: o = "#6366f1",
64
+ markerColor: o = "#6365f1",
63
65
  buttonSize: n = "medium",
64
66
  modalWidth: s = 400,
65
67
  backdropOpacity: a = 0.3,
66
68
  fontFamily: c = "system-ui, -apple-system, sans-serif",
67
69
  fontSize: l = 16
68
- } = i, d = ne[n], r = se[n], h = de(o);
70
+ } = i, d = ve[n], r = ye[n], h = xe(o);
69
71
  return {
70
72
  "--qaid-positive": t,
71
73
  "--qaid-negative": e,
@@ -79,22 +81,22 @@ function ce(i = {}) {
79
81
  "--qaid-font-size": `${l}px`
80
82
  };
81
83
  }
82
- function le(i, t) {
84
+ function Ce(i, t) {
83
85
  for (const [e, o] of Object.entries(t))
84
86
  i.style.setProperty(e, o);
85
87
  }
86
- function Z() {
87
- return ee + oe;
88
+ function at() {
89
+ return me + ge;
88
90
  }
89
- function he() {
90
- if (I++, I > 1) return;
91
+ function Se() {
92
+ if (D++, D > 1) return;
91
93
  const i = document.createElement("style");
92
- i.id = "qaid-styles", i.textContent = ie, document.head.appendChild(i);
94
+ i.id = "qaid-styles", i.textContent = be, document.head.appendChild(i);
93
95
  }
94
- function ue() {
95
- I <= 0 || (I--, I === 0 && document.getElementById("qaid-styles")?.remove());
96
+ function Ee() {
97
+ D <= 0 || (D--, D === 0 && document.getElementById("qaid-styles")?.remove());
96
98
  }
97
- const tt = "data-qaid-a11y-live", pe = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", fe = [
99
+ const rt = "data-qaid-a11y-live", Te = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", Ae = [
98
100
  "a[href]",
99
101
  "button",
100
102
  "input",
@@ -102,25 +104,25 @@ const tt = "data-qaid-a11y-live", pe = "position:absolute;width:1px;height:1px;m
102
104
  "select",
103
105
  "[tabindex]"
104
106
  ].join(",");
105
- function me(i) {
107
+ function Ie(i) {
106
108
  return i.ownerDocument || document;
107
109
  }
108
- function be(i, t) {
110
+ function Le(i, t) {
109
111
  const e = t ? "assertive" : "polite", o = i.querySelector(
110
- `[${tt}="${e}"]`
112
+ `[${rt}="${e}"]`
111
113
  );
112
114
  if (o) return o;
113
- const s = me(i).createElement("div");
114
- return s.setAttribute(tt, e), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = pe, i.appendChild(s), s;
115
+ const s = Ie(i).createElement("div");
116
+ return s.setAttribute(rt, e), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = Te, i.appendChild(s), s;
115
117
  }
116
- function ge(i, t, e = {}) {
117
- const o = be(i, !!e.assertive);
118
+ function De(i, t, e = {}) {
119
+ const o = Le(i, !!e.assertive);
118
120
  o.textContent = "", o.textContent = t;
119
121
  }
120
- function ve(i) {
122
+ function Me(i) {
121
123
  return i.hasAttribute("disabled") ? !0 : i.disabled === !0;
122
124
  }
123
- function ye(i) {
125
+ function Re(i) {
124
126
  let t = i;
125
127
  for (; t; ) {
126
128
  if (t.hasAttribute("hidden")) return !0;
@@ -131,52 +133,52 @@ function ye(i) {
131
133
  }
132
134
  return !1;
133
135
  }
134
- function et(i) {
136
+ function dt(i) {
135
137
  return Array.from(
136
- i.querySelectorAll(fe)
137
- ).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") || ve(e) || ye(e)));
138
+ i.querySelectorAll(Ae)
139
+ ).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") || Me(e) || Re(e)));
138
140
  }
139
- function yt(i) {
141
+ function Tt(i) {
140
142
  let t = i.activeElement;
141
143
  for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
142
144
  t = t.shadowRoot.activeElement;
143
145
  return t instanceof HTMLElement ? t : null;
144
146
  }
145
- function we(i) {
147
+ function Pe(i) {
146
148
  const t = i.ownerDocument || document;
147
149
  let e = !1;
148
150
  const o = (s) => {
149
151
  if (s.key !== "Tab") return;
150
- const a = et(i);
152
+ const a = dt(i);
151
153
  if (a.length === 0) {
152
154
  s.preventDefault(), i.focus();
153
155
  return;
154
156
  }
155
- const c = a[0], l = a[a.length - 1], d = yt(t), r = d ? a.indexOf(d) !== -1 : !1;
157
+ const c = a[0], l = a[a.length - 1], d = Tt(t), r = d ? a.indexOf(d) !== -1 : !1;
156
158
  s.shiftKey ? (!r || d === c) && (s.preventDefault(), l.focus()) : (!r || d === l) && (s.preventDefault(), c.focus());
157
159
  };
158
160
  i.addEventListener("keydown", o);
159
- const n = et(i);
161
+ const n = dt(i);
160
162
  return n.length > 0 ? n[0].focus() : (i.hasAttribute("tabindex") || (i.setAttribute("tabindex", "-1"), e = !0), i.focus()), {
161
163
  release() {
162
164
  i.removeEventListener("keydown", o), e && (i.removeAttribute("tabindex"), e = !1);
163
165
  }
164
166
  };
165
167
  }
166
- function ke() {
167
- return yt(document);
168
+ function Be() {
169
+ return Tt(document);
168
170
  }
169
- function xe(i) {
171
+ function He(i) {
170
172
  if (!(!i || typeof i.focus != "function"))
171
173
  try {
172
174
  i.focus();
173
175
  } catch {
174
176
  }
175
177
  }
176
- function qe(i, t = {}) {
178
+ function Oe(i, t = {}) {
177
179
  i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "true"), t.labelledbyId && i.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && i.setAttribute("aria-describedby", t.describedbyId), t.label && i.setAttribute("aria-label", t.label);
178
180
  }
179
- function Ce(i, t) {
181
+ function ze(i, t) {
180
182
  let e = i;
181
183
  for (; e && e !== t; ) {
182
184
  const o = e.parentNode;
@@ -190,11 +192,11 @@ function Ce(i, t) {
190
192
  }
191
193
  return null;
192
194
  }
193
- function Se(i) {
195
+ function $e(i) {
194
196
  const e = (i.ownerDocument || document).body;
195
197
  if (!e) return () => {
196
198
  };
197
- const o = Ce(i, e), n = [];
199
+ const o = ze(i, e), n = [];
198
200
  return Array.from(e.children).forEach((s) => {
199
201
  if (!(s instanceof HTMLElement) || o && s === o) return;
200
202
  const a = s.inert === !0, c = s.getAttribute("aria-hidden");
@@ -206,14 +208,14 @@ function Se(i) {
206
208
  }
207
209
  };
208
210
  }
209
- const wt = {
211
+ const At = {
210
212
  width: 400,
211
213
  height: 280,
212
214
  arrowHeight: 12,
213
215
  gap: 8,
214
216
  viewportPadding: 16
215
217
  };
216
- function Ee(i, t, e, o, n) {
218
+ function _e(i, t, e, o, n) {
217
219
  const s = i.y, a = t - (i.y + i.height);
218
220
  if (a >= e + o)
219
221
  return {
@@ -232,22 +234,22 @@ function Ee(i, t, e, o, n) {
232
234
  t - e - n
233
235
  ) : l = Math.max(n, i.y - e - o), { top: l, position: c };
234
236
  }
235
- function Te(i, t, e, o) {
237
+ function Ne(i, t, e, o) {
236
238
  let s = i.x + i.width / 2 - e / 2;
237
239
  return s = Math.max(o, Math.min(s, t - e - o)), s;
238
240
  }
239
- function Ae(i, t, e, o = 24, n = 24) {
241
+ function Fe(i, t, e, o = 24, n = 24) {
240
242
  const a = i.clickX - t - n / 2;
241
243
  return Math.max(o, Math.min(a, e - o - n / 2));
242
244
  }
243
- function Le(i, t, e, o = wt) {
244
- const n = o.height + o.arrowHeight, s = Ee(
245
+ function Ve(i, t, e, o = At) {
246
+ const n = o.height + o.arrowHeight, s = _e(
245
247
  i,
246
248
  e,
247
249
  n,
248
250
  o.gap,
249
251
  o.viewportPadding
250
- ), a = Te(
252
+ ), a = Ne(
251
253
  i,
252
254
  t,
253
255
  o.width,
@@ -259,15 +261,15 @@ function Le(i, t, e, o = wt) {
259
261
  position: s.position
260
262
  };
261
263
  }
262
- function Ie(i, t, e, o = {}) {
264
+ function Ue(i, t, e, o = {}) {
263
265
  const n = o.gap ?? 8;
264
266
  let s = i.bottom + n;
265
267
  s + t.height > e.height - n && (s = i.top - t.height - n);
266
268
  let a = i.left;
267
269
  return a < n ? a = n : a + t.width > e.width - n && (a = e.width - t.width - n), s < n ? s = n : s + t.height > e.height - n && (s = e.height - t.height - n), { top: s, left: a };
268
270
  }
269
- function De(i, t, e, o = wt) {
270
- const n = Le(i, t, e, o), s = Ae(
271
+ function je(i, t, e, o = At) {
272
+ const n = Ve(i, t, e, o), s = Fe(
271
273
  i,
272
274
  n.left,
273
275
  o.width
@@ -277,15 +279,15 @@ function De(i, t, e, o = wt) {
277
279
  arrow: { left: s }
278
280
  };
279
281
  }
280
- const Me = 20;
281
- function Re(i) {
282
+ const Ke = 20;
283
+ function We(i) {
282
284
  const t = [], e = console.error, o = console.warn, n = console.log, s = (a, c) => {
283
285
  const l = {
284
286
  message: c.map((d) => String(d)).join(" "),
285
287
  timestamp: Date.now(),
286
288
  level: a
287
289
  };
288
- t.length >= Me && t.shift(), t.push(l), i && i(l);
290
+ t.length >= Ke && t.shift(), t.push(l), i && i(l);
289
291
  };
290
292
  return console.error = function(...a) {
291
293
  s("error", a), e.apply(console, a);
@@ -307,19 +309,19 @@ function q(i, t, e) {
307
309
  n === "className" ? o.className = s : o.setAttribute(n, s);
308
310
  return o;
309
311
  }
310
- function Pe(i = 640) {
312
+ function Xe(i = 640) {
311
313
  return typeof window < "u" && window.innerWidth < i;
312
314
  }
313
- function it(i, t, e) {
315
+ function ct(i, t, e) {
314
316
  const o = e.map((s) => s.style.visibility);
315
317
  e.forEach((s) => s.style.visibility = "hidden");
316
318
  const n = document.elementFromPoint(i, t);
317
319
  return e.forEach((s, a) => s.style.visibility = o[a]), n;
318
320
  }
319
- function M(i) {
321
+ function R(i) {
320
322
  return i ? i.hasAttribute("data-qaid-embed") || i.hasAttribute("data-qaid-embed-overlay") ? !0 : !!i.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
321
323
  }
322
- function ot(i, t = 0) {
324
+ function lt(i, t = 0) {
323
325
  const e = i.getBoundingClientRect();
324
326
  return {
325
327
  x: e.left - t,
@@ -328,7 +330,7 @@ function ot(i, t = 0) {
328
330
  height: e.height + t * 2
329
331
  };
330
332
  }
331
- const Be = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", He = (i) => (
333
+ const Ye = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Qe = (i) => (
332
334
  // The URL is a runtime value, not a static specifier — keep Vite from
333
335
  // trying to analyze/bundle it.
334
336
  import(
@@ -336,19 +338,19 @@ const Be = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", He =
336
338
  i
337
339
  )
338
340
  );
339
- let Oe = He, A = null, _ = null;
340
- function $e(i) {
341
- return A && _ === i || (_ = i, A = Promise.resolve(Oe(i)).then((t) => {
341
+ let Je = Qe, I = null, N = null;
342
+ function Ge(i) {
343
+ return I && N === i || (N = i, I = Promise.resolve(Je(i)).then((t) => {
342
344
  const e = t;
343
345
  if (!e || typeof e.QaidQuests != "function")
344
346
  throw new Error("quests module has no QaidQuests export");
345
347
  return e;
346
348
  }).catch((t) => {
347
- throw A = null, _ = null, t;
348
- })), A;
349
+ throw I = null, N = null, t;
350
+ })), I;
349
351
  }
350
- async function ze(i) {
351
- const t = await $e(i.moduleUrl), e = i.base.replace(/\/+$/, ""), o = i.feedbackId != null ? { feedbackId: i.feedbackId } : void 0;
352
+ async function Ze(i) {
353
+ const t = await Ge(i.moduleUrl), e = i.base.replace(/\/+$/, ""), o = i.feedbackId != null ? { feedbackId: i.feedbackId } : void 0;
352
354
  return new t.QaidQuests({
353
355
  endpoint: `${e}/responses`,
354
356
  configUrl: `${e}/${encodeURIComponent(i.questId)}/definition`,
@@ -357,7 +359,7 @@ async function ze(i) {
357
359
  onClose: i.onClose
358
360
  });
359
361
  }
360
- const nt = "qaid_visitor_id", st = "qaid_hide_feedback", _e = [
362
+ const ht = "qaid_visitor_id", ut = "qaid_hide_feedback", ti = [
361
363
  "#ef4444",
362
364
  "#f59e0b",
363
365
  "#22c55e",
@@ -365,34 +367,46 @@ const nt = "qaid_visitor_id", st = "qaid_hide_feedback", _e = [
365
367
  "#111827",
366
368
  "#ffffff"
367
369
  ];
368
- function Fe() {
370
+ function ei() {
369
371
  return typeof window.matchMedia == "function" && window.matchMedia("(pointer: coarse)").matches;
370
372
  }
371
- function U(i) {
372
- return i ? `${st}_${i}` : st;
373
+ function j(i) {
374
+ return i ? `${ut}_${i}` : ut;
373
375
  }
374
- function Ve(i) {
376
+ function ii(i) {
375
377
  try {
376
- return localStorage.getItem(U(i)) === "1";
378
+ return localStorage.getItem(j(i)) === "1";
377
379
  } catch {
378
380
  return !1;
379
381
  }
380
382
  }
381
- function at(i, t = !0) {
383
+ function pt(i, t = !0) {
382
384
  try {
383
- t ? localStorage.setItem(U(i), "1") : localStorage.removeItem(U(i));
385
+ t ? localStorage.setItem(j(i), "1") : localStorage.removeItem(j(i));
384
386
  } catch {
385
387
  }
386
388
  }
387
- function Ne() {
389
+ function ft() {
390
+ const i = typeof crypto < "u" ? crypto : void 0;
391
+ if (i && typeof i.randomUUID == "function") return i.randomUUID();
392
+ const t = new Uint8Array(16);
393
+ if (i && typeof i.getRandomValues == "function")
394
+ i.getRandomValues(t);
395
+ else
396
+ for (let o = 0; o < t.length; o++) t[o] = Math.floor(Math.random() * 256);
397
+ t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
398
+ const e = Array.from(t, (o) => o.toString(16).padStart(2, "0")).join("");
399
+ return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
400
+ }
401
+ function oi() {
388
402
  try {
389
- let i = localStorage.getItem(nt);
390
- return i || (i = crypto.randomUUID(), localStorage.setItem(nt, i)), i;
403
+ let i = localStorage.getItem(ht);
404
+ return i || (i = ft(), localStorage.setItem(ht, i)), i;
391
405
  } catch {
392
- return crypto.randomUUID();
406
+ return ft();
393
407
  }
394
408
  }
395
- class Ue {
409
+ class ni {
396
410
  config;
397
411
  state = "IDLE";
398
412
  feedbackData = {
@@ -481,7 +495,7 @@ class Ue {
481
495
  colors: {
482
496
  positive: t.colors?.positive ?? "rgb(0, 200, 83)",
483
497
  negative: t.colors?.negative ?? "rgb(255, 0, 0)",
484
- marker: t.colors?.marker ?? "#6366f1"
498
+ marker: t.colors?.marker ?? "#6365f1"
485
499
  },
486
500
  buttonSize: t.buttonSize ?? "medium",
487
501
  text: {
@@ -498,7 +512,9 @@ class Ue {
498
512
  feedbackLabel: t.text?.feedbackLabel ?? "Send feedback",
499
513
  confirmationTitle: t.text?.confirmationTitle ?? "Thank you!",
500
514
  confirmationMessage: t.text?.confirmationMessage ?? "Your feedback has been received.",
501
- confirmationClose: t.text?.confirmationClose ?? "Close"
515
+ confirmationClose: t.text?.confirmationClose ?? "Close",
516
+ errorTitle: t.text?.errorTitle ?? "Message not sent",
517
+ errorMessage: t.text?.errorMessage ?? "Something went wrong, so we did not get your message. Please try again later."
502
518
  },
503
519
  hideConfirmation: t.hideConfirmation ?? !1,
504
520
  modalWidth: t.modalWidth ?? 400,
@@ -507,8 +523,8 @@ class Ue {
507
523
  fontSize: t.fontSize ?? 16,
508
524
  captureScreenshot: t.captureScreenshot ?? !1,
509
525
  annotate: t.annotate ?? !0,
510
- annotationColor: t.annotationColor ?? t.colors?.marker ?? "#6366f1",
511
- annotationPalette: t.annotationPalette ?? _e,
526
+ annotationColor: t.annotationColor ?? t.colors?.marker ?? "#6365f1",
527
+ annotationPalette: t.annotationPalette ?? ti,
512
528
  screenshotMethod: t.screenshotMethod ?? "permission",
513
529
  screenshotOptions: {
514
530
  quality: t.screenshotOptions?.quality ?? 0.8,
@@ -535,12 +551,12 @@ class Ue {
535
551
  video: t.quests?.video ?? "",
536
552
  // Quest service reuses the feedback API key unless overridden.
537
553
  apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
538
- moduleUrl: t.quests?.moduleUrl ?? Be
554
+ moduleUrl: t.quests?.moduleUrl ?? Ye
539
555
  }
540
- }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = Ne(), this.init();
556
+ }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = oi(), this.init();
541
557
  }
542
558
  applyVars(t) {
543
- le(t, this.cssVars);
559
+ Ce(t, this.cssVars);
544
560
  }
545
561
  /**
546
562
  * Announce a message via the shared visually-hidden live regions.
@@ -550,7 +566,7 @@ class Ue {
550
566
  */
551
567
  announceMsg(t, e = !1) {
552
568
  const o = this.overlayShadowRoot ?? this.shadowRoot;
553
- o && ge(o, t, { assertive: e });
569
+ o && De(o, t, { assertive: e });
554
570
  }
555
571
  /**
556
572
  * Turn a transient surface into an accessible modal dialog: save the
@@ -558,16 +574,16 @@ class Ue {
558
574
  * background. Paired with closeDialogA11y() on every close path.
559
575
  */
560
576
  openDialogA11y(t, e) {
561
- this.dialogTrigger = ke(), qe(t, e), this.dialogTrap = we(t), this.dialogRestoreInert = Se(t);
577
+ this.dialogTrigger = Be(), Oe(t, e), this.dialogTrap = Pe(t), this.dialogRestoreInert = $e(t);
562
578
  }
563
579
  closeDialogA11y() {
564
- this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), xe(this.dialogTrigger), this.dialogTrigger = null;
580
+ this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), He(this.dialogTrigger), this.dialogTrigger = null;
565
581
  }
566
582
  clearActiveThumb() {
567
583
  this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
568
584
  }
569
585
  init() {
570
- he(), this.cssVars = ce({
586
+ Se(), this.cssVars = qe({
571
587
  positiveColor: this.config.colors.positive,
572
588
  negativeColor: this.config.colors.negative,
573
589
  markerColor: this.config.colors.marker,
@@ -576,7 +592,7 @@ class Ue {
576
592
  backdropOpacity: this.config.backdropOpacity,
577
593
  fontFamily: this.config.fontFamily,
578
594
  fontSize: this.config.fontSize
579
- }), !this.config.hideDismiss && Ve(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = Re((t) => {
595
+ }), !this.config.hideDismiss && ii(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = We((t) => {
580
596
  this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
581
597
  }), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom(), (this.config.captureVideo && this.videoSupported() || this.config.captureScreenshot) && this.schedulePrewarm(() => {
582
598
  this.config.captureVideo && this.videoSupported() && this.prewarmVideo(), this.config.captureScreenshot && this.prewarmScreenshot();
@@ -589,13 +605,13 @@ class Ue {
589
605
  * swallowed — a failed preload just falls back to an on-demand load.
590
606
  */
591
607
  prewarmVideo() {
592
- this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => pt).catch(() => {
593
- }), Promise.resolve().then(() => St).catch(() => {
608
+ this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => kt).catch(() => {
609
+ }), Promise.resolve().then(() => Bt).catch(() => {
594
610
  }));
595
611
  }
596
612
  prewarmScreenshot() {
597
- this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() => lt) : Promise.resolve().then(() => ft)).catch(() => {
598
- }), this.config.annotate && Promise.resolve().then(() => ut).catch(() => {
613
+ this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() => vt) : Promise.resolve().then(() => xt)).catch(() => {
614
+ }), this.config.annotate && Promise.resolve().then(() => wt).catch(() => {
599
615
  }));
600
616
  }
601
617
  /** Run fn when the main thread is idle; cancelled by destroy(). */
@@ -624,7 +640,7 @@ class Ue {
624
640
  }), this.domObserver.observe(document.body, { childList: !0 });
625
641
  }
626
642
  checkMobile() {
627
- this.isMobile = Pe();
643
+ this.isMobile = Xe();
628
644
  }
629
645
  handleResize() {
630
646
  this.checkMobile();
@@ -634,7 +650,7 @@ class Ue {
634
650
  let t = null;
635
651
  this.config.container && (t = document.querySelector(this.config.container)), t ? (t.appendChild(this.shadowHost), this.isUserProvidedContainer = !0, this.config.hideDismiss = !0) : (this.shadowHost.style.position = "fixed", this.shadowHost.style.display = "block", this.shadowHost.style.inset = "0", this.shadowHost.style.pointerEvents = "none", this.shadowHost.style.zIndex = String(this.config.zIndex), document.body.appendChild(this.shadowHost)), this.shadowRoot = this.shadowHost.attachShadow({ mode: "open" });
636
652
  const e = document.createElement("style");
637
- if (e.textContent = Z(), this.shadowRoot.appendChild(e), this.config.css) {
653
+ if (e.textContent = at(), this.shadowRoot.appendChild(e), this.config.css) {
638
654
  const d = document.createElement("style");
639
655
  d.textContent = this.config.css, this.shadowRoot.appendChild(d);
640
656
  }
@@ -658,7 +674,7 @@ class Ue {
658
674
  const d = document.createElement("div");
659
675
  d.className = "qaid-tooltip-wrapper";
660
676
  const r = document.createElement("button");
661
- r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon || gt, r.addEventListener("click", (h) => this.handleThumbClick("neutral", h.currentTarget, h)), r.addEventListener("mouseenter", () => {
677
+ r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon || St, r.addEventListener("click", (h) => this.handleThumbClick("neutral", h.currentTarget, h)), r.addEventListener("mouseenter", () => {
662
678
  this.prewarmTargeting(), this.showTooltip(r);
663
679
  }), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r), this.buttonsContainer.appendChild(d);
664
680
  } else if (!this.config.hideThumbs) {
@@ -670,18 +686,18 @@ class Ue {
670
686
  }), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r);
671
687
  const h = document.createElement("div");
672
688
  h.className = "qaid-tooltip-wrapper";
673
- const p = document.createElement("button");
674
- p.type = "button", p.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", p.setAttribute("aria-label", this.config.text.negativeLabel), p.innerHTML = this.config.negativeIcon || N, p.addEventListener("click", (b) => this.handleThumbClick("down", b.currentTarget, b)), p.addEventListener("mouseenter", () => {
675
- this.prewarmTargeting(), this.showTooltip(p);
676
- }), p.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(p), this.buttonsContainer.appendChild(d), this.buttonsContainer.appendChild(h);
689
+ const f = document.createElement("button");
690
+ f.type = "button", f.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", f.setAttribute("aria-label", this.config.text.negativeLabel), f.innerHTML = this.config.negativeIcon || U, f.addEventListener("click", (b) => this.handleThumbClick("down", b.currentTarget, b)), f.addEventListener("mouseenter", () => {
691
+ this.prewarmTargeting(), this.showTooltip(f);
692
+ }), f.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(f), this.buttonsContainer.appendChild(d), this.buttonsContainer.appendChild(h);
677
693
  }
678
694
  if (this.config.captureVideo && this.videoSupported()) {
679
695
  const d = document.createElement("div");
680
696
  d.className = "qaid-tooltip-wrapper";
681
697
  const r = document.createElement("button");
682
- r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon || Xt, r.addEventListener("click", () => {
698
+ r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon || re, r.addEventListener("click", () => {
683
699
  this.ensureRecording().then(
684
- (p) => this.config.videoOptions.redaction ? p.startPicking() : p.startRecording()
700
+ (f) => this.config.videoOptions.redaction ? f.startPicking() : f.startRecording()
685
701
  );
686
702
  });
687
703
  const h = () => this.prewarmVideo();
@@ -703,7 +719,7 @@ class Ue {
703
719
  if (this.overlayShadowRoot) return this.overlayShadowRoot;
704
720
  this.overlayShadowHost = document.createElement("div"), this.overlayShadowHost.setAttribute("data-qaid-embed-overlay", ""), this.overlayShadowHost.style.position = "fixed", this.overlayShadowHost.style.inset = "0", this.overlayShadowHost.style.pointerEvents = "none", this.overlayShadowHost.style.zIndex = String(this.config.zIndex), document.body.appendChild(this.overlayShadowHost), this.overlayShadowRoot = this.overlayShadowHost.attachShadow({ mode: "open" });
705
721
  const t = document.createElement("style");
706
- if (t.textContent = Z(), this.overlayShadowRoot.appendChild(t), this.config.css) {
722
+ if (t.textContent = at(), this.overlayShadowRoot.appendChild(t), this.config.css) {
707
723
  const e = document.createElement("style");
708
724
  e.textContent = this.config.css, this.overlayShadowRoot.appendChild(e);
709
725
  }
@@ -713,7 +729,7 @@ class Ue {
713
729
  showTooltip(t) {
714
730
  const e = this.tooltipElement;
715
731
  e.style.visibility = "hidden", e.classList.add("qaid-tooltip-visible");
716
- const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Ie(
732
+ const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Ue(
717
733
  o,
718
734
  n,
719
735
  { width: window.innerWidth, height: window.innerHeight }
@@ -724,10 +740,10 @@ class Ue {
724
740
  this.tooltipElement.classList.remove("qaid-tooltip-visible");
725
741
  }
726
742
  handleDismiss() {
727
- this.buttonsContainer.classList.add("qaid-dismissed"), at(this.config.apiKey, !0);
743
+ this.buttonsContainer.classList.add("qaid-dismissed"), pt(this.config.apiKey, !0);
728
744
  }
729
745
  handleThumbClick(t, e, o) {
730
- if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), at(this.config.apiKey, !1)), this.prewarmModal(), this.config.skipTargeting || this.config.feedbackMode === "annotate")
746
+ if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), pt(this.config.apiKey, !1)), this.prewarmModal(), this.config.skipTargeting || this.config.feedbackMode === "annotate")
731
747
  this.submitDirectFeedback(t, e);
732
748
  else {
733
749
  this.activeThumbBtn = e, e.setAttribute("aria-pressed", "true");
@@ -760,7 +776,7 @@ class Ue {
760
776
  * instead of the permission-based Screen Capture API. Explicit "dom" wins;
761
777
  * otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
762
778
  shouldCaptureViaDom() {
763
- return this.config.screenshotMethod === "dom" || Fe();
779
+ return this.config.screenshotMethod === "dom" || ei();
764
780
  }
765
781
  /**
766
782
  * Open the full-screen annotation editor over the captured screenshot,
@@ -773,7 +789,7 @@ class Ue {
773
789
  const e = this.ensureOverlayHost(), o = this.overlayShadowHost, n = o.style.pointerEvents;
774
790
  o.style.pointerEvents = "auto";
775
791
  try {
776
- const { openAnnotationEditor: s } = await Promise.resolve().then(() => ut);
792
+ const { openAnnotationEditor: s } = await Promise.resolve().then(() => wt);
777
793
  return await s({
778
794
  dataUrl: t,
779
795
  root: e,
@@ -796,10 +812,10 @@ class Ue {
796
812
  if (this.config.captureScreenshot || this.config.feedbackMode === "annotate")
797
813
  try {
798
814
  if (this.shouldCaptureViaDom()) {
799
- const { captureDomScreenshot: a } = await Promise.resolve().then(() => lt);
815
+ const { captureDomScreenshot: a } = await Promise.resolve().then(() => vt);
800
816
  t = await a(this.config.screenshotOptions);
801
817
  } else {
802
- const { captureScreenshot: a } = await Promise.resolve().then(() => ft);
818
+ const { captureScreenshot: a } = await Promise.resolve().then(() => xt);
803
819
  t = await a(this.config.screenshotOptions);
804
820
  }
805
821
  t && this.announceMsg("Screenshot captured");
@@ -877,7 +893,7 @@ class Ue {
877
893
  const o = this.questIdFor(t);
878
894
  if (!o) return !1;
879
895
  try {
880
- return this.activeQuest?.destroy(), this.activeQuest = await ze({
896
+ return this.activeQuest?.destroy(), this.activeQuest = await Ze({
881
897
  questId: o,
882
898
  base: this.config.quests.base,
883
899
  apiKey: this.config.quests.apiKey || void 0,
@@ -906,7 +922,7 @@ class Ue {
906
922
  */
907
923
  async ensureModal() {
908
924
  if (!this.modal) {
909
- const { ModalController: t } = await Promise.resolve().then(() => mt);
925
+ const { ModalController: t } = await Promise.resolve().then(() => qt);
910
926
  this.modal = new t(this.makeModalHost());
911
927
  }
912
928
  return this.modal;
@@ -952,7 +968,7 @@ class Ue {
952
968
  }
953
969
  /** Warm the modal chunk while the user is targeting, so it opens instantly. */
954
970
  prewarmModal() {
955
- this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => mt).catch(() => {
971
+ this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => qt).catch(() => {
956
972
  }));
957
973
  }
958
974
  /**
@@ -962,7 +978,7 @@ class Ue {
962
978
  */
963
979
  async ensureTargeting() {
964
980
  if (!this.targeting) {
965
- const { TargetingController: t } = await Promise.resolve().then(() => bt);
981
+ const { TargetingController: t } = await Promise.resolve().then(() => Ct);
966
982
  this.targeting = new t(this.makeTargetingHost());
967
983
  }
968
984
  return this.targeting;
@@ -1007,7 +1023,7 @@ class Ue {
1007
1023
  }
1008
1024
  /** Warm the targeting chunk on thumb-button hover, before the click. */
1009
1025
  prewarmTargeting() {
1010
- this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() => bt).catch(() => {
1026
+ this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() => Ct).catch(() => {
1011
1027
  }));
1012
1028
  }
1013
1029
  // ==================== Video Recording ====================
@@ -1026,7 +1042,7 @@ class Ue {
1026
1042
  */
1027
1043
  async ensureRecording() {
1028
1044
  if (!this.recording) {
1029
- const { RecordingController: t } = await Promise.resolve().then(() => pt);
1045
+ const { RecordingController: t } = await Promise.resolve().then(() => kt);
1030
1046
  this.recording = new t(this.makeRecordingHost());
1031
1047
  }
1032
1048
  return this.recording;
@@ -1082,13 +1098,13 @@ class Ue {
1082
1098
  const t = window;
1083
1099
  this.prewarmIsTimeout ? clearTimeout(this.prewarmHandle) : t.cancelIdleCallback?.(this.prewarmHandle), this.prewarmHandle = null;
1084
1100
  }
1085
- this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.dismissBtn = null, this.tooltipElement = null, ue();
1101
+ this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.dismissBtn = null, this.tooltipElement = null, Ee();
1086
1102
  }
1087
1103
  }
1088
- function kt(i) {
1104
+ function It(i) {
1089
1105
  return document.querySelector(i)?.textContent?.trim() ?? "";
1090
1106
  }
1091
- function je() {
1107
+ function si() {
1092
1108
  const i = document.querySelector(
1093
1109
  'script[type="application/json"][data-feedback-config]'
1094
1110
  );
@@ -1097,37 +1113,78 @@ function je() {
1097
1113
  if (!t) return null;
1098
1114
  try {
1099
1115
  const e = JSON.parse(t);
1100
- return e.cssSelector && !e.css && (e.css = kt(e.cssSelector), delete e.cssSelector), e;
1116
+ return e.cssSelector && !e.css && (e.css = It(e.cssSelector), delete e.cssSelector), e;
1101
1117
  } catch {
1102
1118
  return null;
1103
1119
  }
1104
1120
  }
1105
- function Ke(i) {
1121
+ function Lt(i, t, e) {
1122
+ console.warn(`[thumbs-embed] Ignoring ${i}="${t}": expected ${e}.`);
1123
+ }
1124
+ function ai(i) {
1125
+ const t = [];
1126
+ let e = 0, o = "";
1127
+ for (const n of i)
1128
+ n === "(" && e++, n === ")" && (e = Math.max(0, e - 1)), n === "," && e === 0 ? (t.push(o.trim()), o = "") : o += n;
1129
+ return t.push(o.trim()), t;
1130
+ }
1131
+ function ri(i, t) {
1132
+ if (t === null) return;
1133
+ const e = t.trim();
1134
+ let o = null;
1135
+ if (e.startsWith("[") || e.startsWith("{"))
1136
+ try {
1137
+ o = JSON.parse(e);
1138
+ } catch {
1139
+ o = null;
1140
+ }
1141
+ else
1142
+ o = ai(e);
1143
+ if (Array.isArray(o) && o.length > 0 && o.every((n) => typeof n == "string" && n.trim() !== ""))
1144
+ return o.map((n) => n.trim());
1145
+ Lt(i, t, "a JSON array of colours or a comma-separated list");
1146
+ }
1147
+ function M(i, t) {
1148
+ if (t !== null) {
1149
+ if (t.trim() === "") {
1150
+ Lt(i, t, "a non-empty label");
1151
+ return;
1152
+ }
1153
+ return t;
1154
+ }
1155
+ }
1156
+ function di(i) {
1106
1157
  const t = i.getAttribute("data-endpoint");
1107
1158
  if (!t) return null;
1108
- const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"), p = i.getAttribute("data-feedback-mode"), b = i.getAttribute("data-incognito"), y = i.getAttribute("data-button-size"), g = i.getAttribute("data-offset-x"), w = i.getAttribute("data-offset-y"), x = i.getAttribute("data-modal-width"), u = i.getAttribute("data-backdrop-opacity"), k = i.getAttribute("data-font-family"), v = i.getAttribute("data-font-size"), C = i.getAttribute("data-tooltip"), T = i.getAttribute("data-modal-title"), S = i.getAttribute("data-confirmation-title"), f = i.getAttribute("data-confirmation-message"), D = i.getAttribute("data-confirmation-close"), j = i.getAttribute("data-modal-subtitle"), K = i.getAttribute("data-placeholder"), W = i.getAttribute("data-submit-button"), X = i.getAttribute("data-skip-button"), Dt = i.getAttribute("data-positive-icon"), Mt = i.getAttribute("data-negative-icon"), Rt = i.getAttribute("data-feedback-icon"), Y = i.getAttribute("data-feedback-label"), Pt = i.getAttribute("data-api-key"), Bt = i.getAttribute("data-capture-screenshot"), Ht = i.getAttribute("data-annotate"), Ot = i.getAttribute("data-annotation-color"), H = i.getAttribute("data-screenshot-quality"), O = i.getAttribute("data-screenshot-max-width"), $ = i.getAttribute("data-screenshot-max-height"), $t = i.getAttribute("data-capture-video"), Q = i.getAttribute("data-video-redaction"), zt = i.getAttribute("data-hide-thumbs"), _t = i.getAttribute("data-hide-dismiss"), z = i.getAttribute("data-video-max-duration"), Ft = i.getAttribute("data-screenshot-method"), Vt = i.getAttribute("data-direction"), G = i.getAttribute("data-css-selector"), J = i.getAttribute("data-quest-base"), Nt = i.getAttribute("data-quest-up"), Ut = i.getAttribute("data-quest-down"), jt = i.getAttribute("data-quest-video"), Kt = i.getAttribute("data-quest-api-key"), Wt = i.getAttribute("data-quest-module-url");
1159
+ const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"), f = i.getAttribute("data-feedback-mode"), b = i.getAttribute("data-incognito"), y = i.getAttribute("data-button-size"), g = i.getAttribute("data-offset-x"), w = i.getAttribute("data-offset-y"), x = i.getAttribute("data-modal-width"), u = i.getAttribute("data-backdrop-opacity"), k = i.getAttribute("data-font-family"), v = i.getAttribute("data-font-size"), C = i.getAttribute("data-tooltip"), A = i.getAttribute("data-modal-title"), S = i.getAttribute("data-confirmation-title"), m = i.getAttribute("data-confirmation-message"), E = i.getAttribute("data-confirmation-close"), K = i.getAttribute("data-error-title"), W = i.getAttribute("data-error-message"), X = i.getAttribute("data-modal-subtitle"), Y = i.getAttribute("data-placeholder"), Q = i.getAttribute("data-submit-button"), J = i.getAttribute("data-skip-button"), Nt = i.getAttribute("data-positive-icon"), Ft = i.getAttribute("data-negative-icon"), Vt = i.getAttribute("data-feedback-icon"), G = i.getAttribute("data-feedback-label"), Ut = i.getAttribute("data-api-key"), jt = i.getAttribute("data-capture-screenshot"), Kt = i.getAttribute("data-annotate"), Wt = i.getAttribute("data-annotation-color"), O = i.getAttribute("data-screenshot-quality"), z = i.getAttribute("data-screenshot-max-width"), $ = i.getAttribute("data-screenshot-max-height"), Xt = i.getAttribute("data-capture-video"), Z = i.getAttribute("data-video-redaction"), Yt = i.getAttribute("data-hide-thumbs"), Qt = i.getAttribute("data-hide-dismiss"), _ = i.getAttribute("data-video-max-duration"), Jt = i.getAttribute("data-screenshot-method"), Gt = i.getAttribute("data-direction"), tt = i.getAttribute("data-css-selector"), Zt = i.getAttribute("data-css"), et = M("data-positive-label", i.getAttribute("data-positive-label")), it = M("data-negative-label", i.getAttribute("data-negative-label")), ot = M("data-record-label", i.getAttribute("data-record-label")), nt = M("data-dismiss-label", i.getAttribute("data-dismiss-label")), te = ri(
1160
+ "data-annotation-palette",
1161
+ i.getAttribute("data-annotation-palette")
1162
+ ), ee = i.getAttribute("data-record-icon"), st = i.getAttribute("data-quest-base"), ie = i.getAttribute("data-quest-up"), oe = i.getAttribute("data-quest-down"), ne = i.getAttribute("data-quest-video"), se = i.getAttribute("data-quest-api-key"), ae = i.getAttribute("data-quest-module-url");
1109
1163
  return {
1110
1164
  endpoint: t,
1111
- css: G ? kt(G) : void 0,
1112
- apiKey: Pt ?? void 0,
1113
- captureScreenshot: Bt === "true" ? !0 : void 0,
1165
+ // Inline CSS wins over a selector, as `css` wins over `cssSelector` in
1166
+ // the JSON block.
1167
+ css: Zt || (tt ? It(tt) : void 0),
1168
+ apiKey: Ut ?? void 0,
1169
+ captureScreenshot: jt === "true" ? !0 : void 0,
1114
1170
  // Annotation is on by default; only an explicit "false" disables it.
1115
- annotate: Ht === "false" ? !1 : void 0,
1116
- annotationColor: Ot ?? void 0,
1117
- screenshotOptions: H || O || $ ? {
1118
- quality: H ? parseFloat(H) : void 0,
1119
- maxWidth: O ? parseInt(O, 10) : void 0,
1171
+ annotate: Kt === "false" ? !1 : void 0,
1172
+ annotationColor: Wt ?? void 0,
1173
+ annotationPalette: te,
1174
+ screenshotOptions: O || z || $ ? {
1175
+ quality: O ? parseFloat(O) : void 0,
1176
+ maxWidth: z ? parseInt(z, 10) : void 0,
1120
1177
  maxHeight: $ ? parseInt($, 10) : void 0
1121
1178
  } : void 0,
1122
1179
  container: c ?? void 0,
1123
1180
  buttonClass: l ?? void 0,
1124
- direction: Vt ?? void 0,
1181
+ direction: Gt ?? void 0,
1125
1182
  position: e ?? void 0,
1126
1183
  zIndex: o ? parseInt(o, 10) : void 0,
1127
1184
  skipTargeting: d === "true" ? !0 : void 0,
1128
1185
  hideConfirmation: r === "true" ? !0 : void 0,
1129
1186
  singleButton: h === "true" ? !0 : void 0,
1130
- feedbackMode: p ?? void 0,
1187
+ feedbackMode: f ?? void 0,
1131
1188
  incognito: b === "true" ? !0 : void 0,
1132
1189
  buttonSize: y ?? void 0,
1133
1190
  offset: g || w ? {
@@ -1143,73 +1200,80 @@ function Ke(i) {
1143
1200
  negative: s ?? void 0,
1144
1201
  marker: a ?? void 0
1145
1202
  },
1146
- text: C || T || j || K || W || X || Y || S || f || D ? {
1203
+ text: C || A || X || Y || Q || J || G || S || m || E || K || W || et || it || ot || nt ? {
1147
1204
  tooltip: C ?? void 0,
1148
- modalTitle: T ?? void 0,
1149
- modalSubtitle: j ?? void 0,
1150
- placeholder: K ?? void 0,
1151
- submitButton: W ?? void 0,
1152
- skipButton: X ?? void 0,
1153
- feedbackLabel: Y ?? void 0,
1205
+ modalTitle: A ?? void 0,
1206
+ modalSubtitle: X ?? void 0,
1207
+ placeholder: Y ?? void 0,
1208
+ submitButton: Q ?? void 0,
1209
+ skipButton: J ?? void 0,
1210
+ feedbackLabel: G ?? void 0,
1154
1211
  confirmationTitle: S ?? void 0,
1155
- confirmationMessage: f ?? void 0,
1156
- confirmationClose: D ?? void 0
1212
+ confirmationMessage: m ?? void 0,
1213
+ confirmationClose: E ?? void 0,
1214
+ errorTitle: K ?? void 0,
1215
+ errorMessage: W ?? void 0,
1216
+ positiveLabel: et,
1217
+ negativeLabel: it,
1218
+ recordLabel: ot,
1219
+ dismissLabel: nt
1157
1220
  } : void 0,
1158
- positiveIcon: Dt ?? void 0,
1159
- negativeIcon: Mt ?? void 0,
1160
- feedbackIcon: Rt ?? void 0,
1161
- screenshotMethod: Ft ?? void 0,
1162
- captureVideo: $t === "true" ? !0 : void 0,
1163
- hideThumbs: zt === "true" ? !0 : void 0,
1164
- hideDismiss: _t === "true" ? !0 : void 0,
1165
- videoOptions: z || Q ? {
1166
- maxDuration: z ? parseInt(z, 10) : void 0,
1167
- redaction: Q === "true" ? !0 : void 0
1221
+ positiveIcon: Nt ?? void 0,
1222
+ recordIcon: ee ?? void 0,
1223
+ negativeIcon: Ft ?? void 0,
1224
+ feedbackIcon: Vt ?? void 0,
1225
+ screenshotMethod: Jt ?? void 0,
1226
+ captureVideo: Xt === "true" ? !0 : void 0,
1227
+ hideThumbs: Yt === "true" ? !0 : void 0,
1228
+ hideDismiss: Qt === "true" ? !0 : void 0,
1229
+ videoOptions: _ || Z ? {
1230
+ maxDuration: _ ? parseInt(_, 10) : void 0,
1231
+ redaction: Z === "true" ? !0 : void 0
1168
1232
  } : void 0,
1169
- quests: J ? {
1170
- base: J,
1171
- up: Nt ?? void 0,
1172
- down: Ut ?? void 0,
1173
- video: jt ?? void 0,
1174
- apiKey: Kt ?? void 0,
1175
- moduleUrl: Wt ?? void 0
1233
+ quests: st ? {
1234
+ base: st,
1235
+ up: ie ?? void 0,
1236
+ down: oe ?? void 0,
1237
+ video: ne ?? void 0,
1238
+ apiKey: se ?? void 0,
1239
+ moduleUrl: ae ?? void 0
1176
1240
  } : void 0
1177
1241
  };
1178
1242
  }
1179
- function We() {
1243
+ function ci() {
1180
1244
  if (typeof document > "u") return;
1181
1245
  const i = () => {
1182
- const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e = je(), o = t ? Ke(t) : null, n = e ?? o;
1183
- n?.endpoint && new Ue(n);
1246
+ const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e = si() ?? (t ? di(t) : null);
1247
+ e?.endpoint && new ni(e);
1184
1248
  };
1185
1249
  document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", i) : i();
1186
1250
  }
1187
- const Xe = 20, rt = 4096;
1188
- function R(i) {
1251
+ const li = 20, mt = 4096;
1252
+ function P(i) {
1189
1253
  const t = typeof i == "string" ? i : JSON.stringify(i);
1190
- return t.length > rt ? t.slice(0, rt) + "…[truncated]" : t;
1254
+ return t.length > mt ? t.slice(0, mt) + "…[truncated]" : t;
1191
1255
  }
1192
- function dt(i, t) {
1193
- i.length >= Xe && i.shift(), i.push(t);
1256
+ function bt(i, t) {
1257
+ i.length >= li && i.shift(), i.push(t);
1194
1258
  }
1195
- async function Ye(i) {
1259
+ async function hi(i) {
1196
1260
  try {
1197
1261
  const t = await i.clone().text();
1198
- return R(t);
1262
+ return P(t);
1199
1263
  } catch {
1200
1264
  return;
1201
1265
  }
1202
1266
  }
1203
- function Qe() {
1267
+ function ui() {
1204
1268
  const i = [], t = window.fetch;
1205
1269
  window.fetch = async function(n, s) {
1206
1270
  const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, c = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
1207
1271
  let l;
1208
- s?.body && (l = R(s.body));
1272
+ s?.body && (l = P(s.body));
1209
1273
  const d = await t.apply(window, [n, s]);
1210
1274
  if (d.status >= 400) {
1211
- const r = await Ye(d);
1212
- dt(i, {
1275
+ const r = await hi(d);
1276
+ bt(i, {
1213
1277
  url: a,
1214
1278
  method: c.toUpperCase(),
1215
1279
  status: d.status,
@@ -1225,15 +1289,15 @@ function Qe() {
1225
1289
  return XMLHttpRequest.prototype.open = function(n, s, ...a) {
1226
1290
  return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), e.apply(this, [n, s, ...a]);
1227
1291
  }, XMLHttpRequest.prototype.send = function(n) {
1228
- const s = this, a = n ? R(n) : void 0;
1292
+ const s = this, a = n ? P(n) : void 0;
1229
1293
  return s.addEventListener("load", function() {
1230
- s.status >= 400 && dt(i, {
1294
+ s.status >= 400 && bt(i, {
1231
1295
  url: s._qaid_url,
1232
1296
  method: s._qaid_method.toUpperCase(),
1233
1297
  status: s.status,
1234
1298
  statusText: s.statusText,
1235
1299
  requestBody: a,
1236
- responseBody: R(s.responseText),
1300
+ responseBody: P(s.responseText),
1237
1301
  timestamp: Date.now()
1238
1302
  });
1239
1303
  }), o.apply(this, [n]);
@@ -1244,27 +1308,27 @@ function Qe() {
1244
1308
  }
1245
1309
  };
1246
1310
  }
1247
- function Ge() {
1311
+ function pi() {
1248
1312
  const i = navigator.userAgent || "";
1249
1313
  return /iP(hone|ad|od)/.test(i) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
1250
1314
  navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
1251
1315
  }
1252
- function Je(i, t, e, o, n) {
1316
+ function fi(i, t, e, o, n) {
1253
1317
  const s = i >= t, a = e >= o;
1254
1318
  return s === a ? { width: i, height: t, rotate: 0 } : { width: t, height: i, rotate: n === 270 ? -90 : 90 };
1255
1319
  }
1256
- function Ze(i, t, e) {
1320
+ function mi(i, t, e) {
1257
1321
  if (e.rotate === 0) {
1258
1322
  i.drawImage(t, 0, 0, e.width, e.height);
1259
1323
  return;
1260
1324
  }
1261
1325
  i.save(), e.rotate === 90 ? (i.translate(e.width, 0), i.rotate(Math.PI / 2)) : (i.translate(0, e.height), i.rotate(-Math.PI / 2)), i.drawImage(t, 0, 0, e.height, e.width), i.restore();
1262
1326
  }
1263
- function ti() {
1327
+ function bi() {
1264
1328
  const i = typeof screen < "u" ? screen.orientation : void 0;
1265
1329
  return i && typeof i.angle == "number" ? i.angle : 0;
1266
1330
  }
1267
- function xt(i) {
1331
+ function Dt(i) {
1268
1332
  return new Promise((t) => {
1269
1333
  if (i.videoWidth > 0) {
1270
1334
  t();
@@ -1273,30 +1337,30 @@ function xt(i) {
1273
1337
  i.addEventListener("loadedmetadata", () => t(), { once: !0 });
1274
1338
  });
1275
1339
  }
1276
- async function qt(i) {
1340
+ async function Mt(i) {
1277
1341
  try {
1278
1342
  await i.play();
1279
1343
  } catch {
1280
1344
  }
1281
1345
  }
1282
- async function ei(i, t = 15) {
1346
+ async function gi(i, t = 15) {
1283
1347
  const e = document.createElement("canvas");
1284
1348
  if (typeof e.captureStream != "function") return null;
1285
1349
  const o = e.getContext("2d");
1286
1350
  if (!o) return null;
1287
1351
  const n = document.createElement("video");
1288
- n.muted = !0, n.playsInline = !0, n.srcObject = i, await xt(n);
1289
- const s = Je(
1352
+ n.muted = !0, n.playsInline = !0, n.srcObject = i, await Dt(n);
1353
+ const s = fi(
1290
1354
  n.videoWidth,
1291
1355
  n.videoHeight,
1292
1356
  window.innerWidth,
1293
1357
  window.innerHeight,
1294
- ti()
1358
+ bi()
1295
1359
  );
1296
- e.width = s.width, e.height = s.height, await qt(n);
1360
+ e.width = s.width, e.height = s.height, await Mt(n);
1297
1361
  let a = 0;
1298
1362
  const c = () => {
1299
- Ze(o, n, s), a = requestAnimationFrame(c);
1363
+ mi(o, n, s), a = requestAnimationFrame(c);
1300
1364
  };
1301
1365
  c();
1302
1366
  const l = e.captureStream(t);
@@ -1307,15 +1371,15 @@ async function ei(i, t = 15) {
1307
1371
  }
1308
1372
  };
1309
1373
  }
1310
- function ii(i, t, e, o, n) {
1374
+ function vi(i, t, e, o, n) {
1311
1375
  const s = Math.max(0, Math.min(o, i.left * t)), a = Math.max(0, Math.min(n, i.top * e)), c = Math.max(0, Math.min(o, (i.left + i.width) * t)), l = Math.max(0, Math.min(n, (i.top + i.height) * e)), d = c - s, r = l - a;
1312
1376
  return d <= 0 || r <= 0 ? null : { x: s, y: a, w: d, h: r };
1313
1377
  }
1314
- function oi(i, t, e, o, n, s, a) {
1378
+ function yi(i, t, e, o, n, s, a) {
1315
1379
  i.drawImage(t, 0, 0, o, n);
1316
1380
  const c = o / Math.max(1, window.innerWidth), l = n / Math.max(1, window.innerHeight);
1317
1381
  for (const d of e) {
1318
- const r = ii(
1382
+ const r = vi(
1319
1383
  d.getBoundingClientRect(),
1320
1384
  c,
1321
1385
  l,
@@ -1325,16 +1389,16 @@ function oi(i, t, e, o, n, s, a) {
1325
1389
  r && (i.save(), a ? (i.filter = `blur(${s}px)`, i.drawImage(t, r.x, r.y, r.w, r.h, r.x, r.y, r.w, r.h)) : (i.fillStyle = "#0b0b0b", i.fillRect(r.x, r.y, r.w, r.h)), i.restore());
1326
1390
  }
1327
1391
  }
1328
- async function ni(i, t, e = {}) {
1392
+ async function wi(i, t, e = {}) {
1329
1393
  const o = e.frameRate ?? 15, n = e.blurRadius ?? 12, s = document.createElement("canvas");
1330
1394
  if (typeof s.captureStream != "function") return null;
1331
1395
  const a = s.getContext("2d");
1332
1396
  if (!a) return null;
1333
1397
  const c = "filter" in a, l = document.createElement("video");
1334
- l.muted = !0, l.playsInline = !0, l.srcObject = i, await xt(l), s.width = l.videoWidth, s.height = l.videoHeight, await qt(l);
1398
+ l.muted = !0, l.playsInline = !0, l.srcObject = i, await Dt(l), s.width = l.videoWidth, s.height = l.videoHeight, await Mt(l);
1335
1399
  let d = 0;
1336
1400
  const r = () => {
1337
- oi(
1401
+ yi(
1338
1402
  a,
1339
1403
  l,
1340
1404
  t,
@@ -1349,14 +1413,15 @@ async function ni(i, t, e = {}) {
1349
1413
  return {
1350
1414
  stream: h,
1351
1415
  stop: () => {
1352
- d && cancelAnimationFrame(d), d = 0, h.getTracks().forEach((p) => p.stop()), l.pause(), l.srcObject = null;
1416
+ d && cancelAnimationFrame(d), d = 0, h.getTracks().forEach((f) => f.stop()), l.pause(), l.srcObject = null;
1353
1417
  }
1354
1418
  };
1355
1419
  }
1356
- function si() {
1420
+ const Rt = "This browser cannot blur the areas you picked, so the recording was not started.";
1421
+ function ki() {
1357
1422
  return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
1358
1423
  }
1359
- function Ct() {
1424
+ function Pt() {
1360
1425
  if (typeof MediaRecorder > "u") return "";
1361
1426
  const i = [
1362
1427
  "video/webm;codecs=vp9",
@@ -1369,11 +1434,11 @@ function Ct() {
1369
1434
  return t;
1370
1435
  return "";
1371
1436
  }
1372
- function ai(i = {}) {
1437
+ function xi(i = {}) {
1373
1438
  const t = i.maxDuration ?? 15, e = i.videoBitsPerSecond ?? 8e5, o = i.redactionElements ?? [], n = i.redactionBlurRadius;
1374
- let s = null, a = null, c = null, l = null, d = [], r = null, h = null, p = null, b = 0, y = null, g = null, w = !1, x = null;
1439
+ let s = null, a = null, c = null, l = null, d = [], r = null, h = null, f = null, b = 0, y = null, g = null, w = !1, x = null;
1375
1440
  function u() {
1376
- p !== null && (clearInterval(p), p = null), x !== null && (clearTimeout(x), x = null), a && (a.stop(), a = null), c && (c.stop(), c = null), s && (s.getTracks().forEach((v) => v.stop()), s = null), l = null, d = [], r = null, h = null, y = null, g = null;
1441
+ f !== null && (clearInterval(f), f = null), x !== null && (clearTimeout(x), x = null), a && (a.stop(), a = null), c && (c.stop(), c = null), s && (s.getTracks().forEach((v) => v.stop()), s = null), l = null, d = [], r = null, h = null, y = null, g = null;
1377
1442
  }
1378
1443
  function k() {
1379
1444
  w || (w = !0, l && l.state !== "inactive" && l.stop());
@@ -1381,7 +1446,7 @@ function ai(i = {}) {
1381
1446
  return {
1382
1447
  async start() {
1383
1448
  w = !1, d = [];
1384
- const v = Ct();
1449
+ const v = Pt();
1385
1450
  if (!v)
1386
1451
  throw new Error("No supported video MIME type found");
1387
1452
  s = await navigator.mediaDevices.getDisplayMedia({
@@ -1396,37 +1461,40 @@ function ai(i = {}) {
1396
1461
  monitorTypeSurfaces: "exclude",
1397
1462
  surfaceSwitching: "exclude"
1398
1463
  });
1399
- const C = s.getVideoTracks()[0], T = C?.getSettings?.()?.displaySurface;
1400
- if (T === "monitor" || T === "window")
1401
- throw s.getTracks().forEach((f) => f.stop()), s = null, new Error(
1464
+ const C = s.getVideoTracks()[0], A = C?.getSettings?.()?.displaySurface;
1465
+ if (A === "monitor" || A === "window")
1466
+ throw s.getTracks().forEach((m) => m.stop()), s = null, new Error(
1402
1467
  "qaid records only the current tab — please share this tab, not a window or your whole screen."
1403
1468
  );
1404
1469
  C && C.addEventListener("ended", () => {
1405
1470
  k();
1406
1471
  });
1407
1472
  let S = s;
1408
- if (Ge()) {
1409
- const f = await ei(s);
1410
- f && (a = f, S = f.stream);
1411
- } else if (o.length > 0) {
1412
- const f = await ni(s, o, {
1473
+ if (pi()) {
1474
+ const m = await gi(s);
1475
+ m && (a = m, S = m.stream);
1476
+ }
1477
+ if (o.length > 0) {
1478
+ const m = await wi(S, o, {
1413
1479
  blurRadius: n
1414
1480
  });
1415
- f && (c = f, S = f.stream);
1481
+ if (!m)
1482
+ throw a && (a.stop(), a = null), s.getTracks().forEach((E) => E.stop()), s = null, new Error(Rt);
1483
+ c = m, S = m.stream;
1416
1484
  }
1417
1485
  l = new MediaRecorder(S, {
1418
1486
  mimeType: v,
1419
1487
  videoBitsPerSecond: e
1420
- }), l.ondataavailable = (f) => {
1421
- f.data.size > 0 && d.push(f.data);
1488
+ }), l.ondataavailable = (m) => {
1489
+ m.data.size > 0 && d.push(m.data);
1422
1490
  }, l.onstop = () => {
1423
- const f = new Blob(d, { type: v });
1424
- y && y(f), h && h(f), a && (a.stop(), a = null), c && (c.stop(), c = null), s && s.getTracks().forEach((D) => D.stop());
1491
+ const m = new Blob(d, { type: v });
1492
+ y && y(m), h && h(m), a && (a.stop(), a = null), c && (c.stop(), c = null), s && s.getTracks().forEach((E) => E.stop());
1425
1493
  }, l.onerror = () => {
1426
1494
  g && g(new Error("MediaRecorder error"));
1427
- }, l.start(1e3), b = Date.now(), p = setInterval(() => {
1428
- const f = Math.floor((Date.now() - b) / 1e3);
1429
- r && r(f);
1495
+ }, l.start(1e3), b = Date.now(), f = setInterval(() => {
1496
+ const m = Math.floor((Date.now() - b) / 1e3);
1497
+ r && r(m);
1430
1498
  }, 1e3), x = setTimeout(() => {
1431
1499
  k();
1432
1500
  }, t * 1e3);
@@ -1447,45 +1515,46 @@ function ai(i = {}) {
1447
1515
  }
1448
1516
  };
1449
1517
  }
1450
- const St = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1518
+ const Bt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1451
1519
  __proto__: null,
1452
- createVideoRecorder: ai,
1453
- getSupportedMimeType: Ct,
1454
- isVideoRecordingSupported: si
1455
- }, Symbol.toStringTag, { value: "Module" })), ct = "https://qaid.dev/lib/html2canvas.min.js", ri = 1e4, di = 50;
1520
+ REDACTION_UNAVAILABLE: Rt,
1521
+ createVideoRecorder: xi,
1522
+ getSupportedMimeType: Pt,
1523
+ isVideoRecordingSupported: ki
1524
+ }, Symbol.toStringTag, { value: "Module" })), gt = "https://qaid.dev/lib/html2canvas.min.js", qi = 1e4, Ci = 50;
1456
1525
  let L = null;
1457
- function ci() {
1526
+ function Si() {
1458
1527
  if (typeof document > "u" || typeof window > "u")
1459
1528
  return !1;
1460
1529
  const i = document.createElement("canvas");
1461
1530
  return typeof i.getContext == "function" && !!i.getContext("2d");
1462
1531
  }
1463
- function li() {
1532
+ function Ei() {
1464
1533
  return window.html2canvas ? Promise.resolve(!0) : L || (L = new Promise((i) => {
1465
1534
  if (!document.querySelector(
1466
- `script[src="${ct}"]`
1535
+ `script[src="${gt}"]`
1467
1536
  )) {
1468
1537
  const n = document.createElement("script");
1469
- n.src = ct, n.async = !0, document.head.appendChild(n);
1538
+ n.src = gt, n.async = !0, document.head.appendChild(n);
1470
1539
  }
1471
1540
  const e = Date.now(), o = () => {
1472
1541
  if (window.html2canvas) {
1473
1542
  i(!0);
1474
1543
  return;
1475
1544
  }
1476
- if (Date.now() - e > ri) {
1545
+ if (Date.now() - e > qi) {
1477
1546
  L = null, i(!1);
1478
1547
  return;
1479
1548
  }
1480
- setTimeout(o, di);
1549
+ setTimeout(o, Ci);
1481
1550
  };
1482
1551
  o();
1483
1552
  }), L);
1484
1553
  }
1485
- async function hi(i = {}) {
1554
+ async function Ti(i = {}) {
1486
1555
  const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
1487
1556
  try {
1488
- if (!await li() || !window.html2canvas)
1557
+ if (!await Ei() || !window.html2canvas)
1489
1558
  return console.warn("html2canvas failed to load"), null;
1490
1559
  const s = await window.html2canvas(document.body, {
1491
1560
  useCORS: !0,
@@ -1502,31 +1571,34 @@ async function hi(i = {}) {
1502
1571
  if (l < 1) {
1503
1572
  const d = Math.round(a * l), r = Math.round(c * l), h = document.createElement("canvas");
1504
1573
  h.width = d, h.height = r;
1505
- const p = h.getContext("2d");
1506
- return p ? (p.drawImage(s, 0, 0, d, r), h.toDataURL("image/webp", t)) : null;
1574
+ const f = h.getContext("2d");
1575
+ return f ? (f.drawImage(s, 0, 0, d, r), h.toDataURL("image/webp", t)) : null;
1507
1576
  }
1508
1577
  return s.toDataURL("image/webp", t);
1509
1578
  } catch (n) {
1510
1579
  return console.warn("DOM screenshot capture failed:", n), null;
1511
1580
  }
1512
1581
  }
1513
- const lt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1582
+ const vt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1514
1583
  __proto__: null,
1515
- captureDomScreenshot: hi,
1516
- isDomScreenshotSupported: ci
1517
- }, Symbol.toStringTag, { value: "Module" })), E = 12, ui = "#ef4444", pi = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#111827", "#ffffff"], fi = {
1584
+ captureDomScreenshot: Ti,
1585
+ isDomScreenshotSupported: Si
1586
+ }, Symbol.toStringTag, { value: "Module" })), T = 12, Ai = "#ef4444", Ii = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#111827", "#ffffff"], Li = {
1518
1587
  "#ef4444": "red",
1519
1588
  "#f59e0b": "amber",
1520
1589
  "#22c55e": "green",
1521
1590
  "#3b82f6": "blue",
1522
1591
  "#111827": "black",
1523
1592
  "#ffffff": "white",
1593
+ // The default marker (nudged from #6366f1 so white text on it clears 4.5:1);
1594
+ // the old value keeps its name for sites that pass it explicitly.
1595
+ "#6365f1": "indigo",
1524
1596
  "#6366f1": "indigo"
1525
1597
  };
1526
- function ht(i) {
1527
- return fi[i.toLowerCase()] ?? i;
1598
+ function yt(i) {
1599
+ return Li[i.toLowerCase()] ?? i;
1528
1600
  }
1529
- const mi = 4, bi = 0.8, gi = {
1601
+ const Di = 4, Mi = 0.8, Ri = {
1530
1602
  title: "Annotate screenshot",
1531
1603
  instructions: "Draw on the screenshot to highlight or hide details, then choose Done to attach it or Skip to send the original.",
1532
1604
  rectangle: "Rectangle",
@@ -1538,7 +1610,7 @@ const mi = 4, bi = 0.8, gi = {
1538
1610
  done: "Done",
1539
1611
  colors: "Drawing colour"
1540
1612
  };
1541
- function P(i, t) {
1613
+ function B(i, t) {
1542
1614
  return {
1543
1615
  x: Math.min(i.x, t.x),
1544
1616
  y: Math.min(i.y, t.y),
@@ -1546,12 +1618,12 @@ function P(i, t) {
1546
1618
  h: Math.abs(i.y - t.y)
1547
1619
  };
1548
1620
  }
1549
- function vi(i) {
1621
+ function Pi(i) {
1550
1622
  if (i.type === "pen") return i.points.length < 2;
1551
- const t = P(i.points[0], i.points[1]);
1623
+ const t = B(i.points[0], i.points[1]);
1552
1624
  return t.w < 3 && t.h < 3;
1553
1625
  }
1554
- function yi(i, t, e, o) {
1626
+ function Bi(i, t, e, o) {
1555
1627
  i.beginPath(), i.moveTo(t.x, t.y), i.lineTo(e.x, e.y), i.stroke();
1556
1628
  const n = Math.atan2(e.y - t.y, e.x - t.x), s = Math.max(10, o * 3);
1557
1629
  i.beginPath(), i.moveTo(e.x, e.y), i.lineTo(
@@ -1562,7 +1634,7 @@ function yi(i, t, e, o) {
1562
1634
  e.y - s * Math.sin(n + Math.PI / 6)
1563
1635
  ), i.stroke();
1564
1636
  }
1565
- function wi(i, t) {
1637
+ function Hi(i, t) {
1566
1638
  if (t.length !== 0) {
1567
1639
  i.beginPath(), i.moveTo(t[0].x, t[0].y);
1568
1640
  for (let e = 1; e < t.length; e++)
@@ -1570,49 +1642,49 @@ function wi(i, t) {
1570
1642
  i.stroke();
1571
1643
  }
1572
1644
  }
1573
- function ki(i, t, e, o, n) {
1645
+ function Oi(i, t, e, o, n) {
1574
1646
  i.fillStyle = "rgb(15, 23, 42)", i.fillRect(t, e, o, n), i.fillStyle = "rgb(37, 47, 63)";
1575
- for (let s = e; s < e + n; s += E)
1576
- for (let a = t; a < t + o; a += E)
1577
- (Math.floor((a - t) / E) + Math.floor((s - e) / E)) % 2 === 0 && i.fillRect(
1647
+ for (let s = e; s < e + n; s += T)
1648
+ for (let a = t; a < t + o; a += T)
1649
+ (Math.floor((a - t) / T) + Math.floor((s - e) / T)) % 2 === 0 && i.fillRect(
1578
1650
  a,
1579
1651
  s,
1580
- Math.min(E, t + o - a),
1581
- Math.min(E, e + n - s)
1652
+ Math.min(T, t + o - a),
1653
+ Math.min(T, e + n - s)
1582
1654
  );
1583
1655
  }
1584
- function B(i, t) {
1656
+ function H(i, t) {
1585
1657
  switch (i.save(), i.strokeStyle = t.color, i.fillStyle = t.color, i.lineWidth = t.strokeWidth, i.lineJoin = "round", i.lineCap = "round", t.type) {
1586
1658
  case "rect": {
1587
- const e = P(t.points[0], t.points[1]);
1659
+ const e = B(t.points[0], t.points[1]);
1588
1660
  i.strokeRect(e.x, e.y, e.w, e.h);
1589
1661
  break;
1590
1662
  }
1591
1663
  case "arrow":
1592
- yi(i, t.points[0], t.points[1], t.strokeWidth);
1664
+ Bi(i, t.points[0], t.points[1], t.strokeWidth);
1593
1665
  break;
1594
1666
  case "pen":
1595
- wi(i, t.points);
1667
+ Hi(i, t.points);
1596
1668
  break;
1597
1669
  case "blur": {
1598
- const e = P(t.points[0], t.points[1]);
1599
- ki(i, e.x, e.y, e.w, e.h);
1670
+ const e = B(t.points[0], t.points[1]);
1671
+ Oi(i, e.x, e.y, e.w, e.h);
1600
1672
  break;
1601
1673
  }
1602
1674
  }
1603
1675
  i.restore();
1604
1676
  }
1605
- function Et(i) {
1677
+ function Ht(i) {
1606
1678
  return new Promise((t, e) => {
1607
1679
  const o = new Image();
1608
1680
  o.onload = () => t(o), o.onerror = () => e(new Error("Failed to load screenshot")), o.src = i;
1609
1681
  });
1610
1682
  }
1611
- async function Tt(i, t, e = {}) {
1612
- const o = e.quality ?? bi;
1683
+ async function Ot(i, t, e = {}) {
1684
+ const o = e.quality ?? Mi;
1613
1685
  let n;
1614
1686
  try {
1615
- n = await Et(i);
1687
+ n = await Ht(i);
1616
1688
  } catch {
1617
1689
  return i;
1618
1690
  }
@@ -1622,11 +1694,11 @@ async function Tt(i, t, e = {}) {
1622
1694
  if (!a) return i;
1623
1695
  a.drawImage(n, 0, 0, s.width, s.height);
1624
1696
  for (const c of t)
1625
- B(a, c);
1697
+ H(a, c);
1626
1698
  return s.toDataURL("image/webp", o);
1627
1699
  }
1628
- let xi = 0;
1629
- class At {
1700
+ let zi = 0;
1701
+ class zt {
1630
1702
  shapes = [];
1631
1703
  tool = "rect";
1632
1704
  opts;
@@ -1634,7 +1706,7 @@ class At {
1634
1706
  color;
1635
1707
  palette;
1636
1708
  strokeWidth;
1637
- uid = `qaid-annotate-${++xi}`;
1709
+ uid = `qaid-annotate-${++zi}`;
1638
1710
  container;
1639
1711
  canvas;
1640
1712
  ctx = null;
@@ -1648,7 +1720,7 @@ class At {
1648
1720
  // after the editor is mounted).
1649
1721
  resolveResult;
1650
1722
  constructor(t) {
1651
- this.opts = t, this.labels = { ...gi, ...t.labels ?? {} }, this.color = t.color ?? ui, this.palette = (t.palette && t.palette.length ? t.palette : pi).slice(), this.palette.some((e) => e.toLowerCase() === this.color.toLowerCase()) || this.palette.unshift(this.color), this.strokeWidth = t.strokeWidth ?? mi;
1723
+ this.opts = t, this.labels = { ...Ri, ...t.labels ?? {} }, this.color = t.color ?? Ai, this.palette = (t.palette && t.palette.length ? t.palette : Ii).slice(), this.palette.some((e) => e.toLowerCase() === this.color.toLowerCase()) || this.palette.unshift(this.color), this.strokeWidth = t.strokeWidth ?? Di;
1652
1724
  }
1653
1725
  /** Mount the editor and resolve when the user commits (Done) or skips. */
1654
1726
  open() {
@@ -1670,7 +1742,7 @@ class At {
1670
1742
  }
1671
1743
  /** A round colour swatch button for the toolbar's colour group. */
1672
1744
  swatchButton(t) {
1673
- const e = ht(t), o = q("button", {
1745
+ const e = yt(t), o = q("button", {
1674
1746
  type: "button",
1675
1747
  class: "qaid-annotate-swatch",
1676
1748
  "data-qaid-color": t,
@@ -1710,19 +1782,19 @@ class At {
1710
1782
  "aria-label": this.labels.title
1711
1783
  });
1712
1784
  const a = q("div", { class: "qaid-annotate-tools" });
1713
- a.appendChild(this.toolButton("rect", Yt, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", Qt, this.labels.arrow)), a.appendChild(this.toolButton("pen", Gt, this.labels.pen)), a.appendChild(this.toolButton("blur", Jt, this.labels.blur));
1785
+ a.appendChild(this.toolButton("rect", de, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", ce, this.labels.arrow)), a.appendChild(this.toolButton("pen", le, this.labels.pen)), a.appendChild(this.toolButton("blur", he, this.labels.blur));
1714
1786
  const c = q("div", {
1715
1787
  class: "qaid-annotate-colors",
1716
1788
  role: "group",
1717
1789
  "aria-label": this.labels.colors
1718
1790
  });
1719
1791
  for (const h of this.palette) c.appendChild(this.swatchButton(h));
1720
- this.undoBtn = this.actionButton("undo", Zt, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
1721
- const l = this.actionButton("skip", te, this.labels.skip, "qaid-annotate-skip"), d = this.actionButton("done", vt, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
1792
+ this.undoBtn = this.actionButton("undo", ue, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
1793
+ const l = this.actionButton("skip", fe, this.labels.skip, "qaid-annotate-skip"), d = this.actionButton("done", Et, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
1722
1794
  r.appendChild(this.undoBtn), r.appendChild(l), r.appendChild(d), this.toolbar.appendChild(a), this.toolbar.appendChild(c), this.toolbar.appendChild(r), this.container.appendChild(o), this.container.appendChild(n), this.container.appendChild(s), this.container.appendChild(this.toolbar), this.opts.root.appendChild(this.container), this.toolbar.addEventListener("click", this.onToolbarClick), this.canvas.addEventListener("pointerdown", this.onPointerDown), this.container.addEventListener("pointermove", this.onPointerMove), this.container.addEventListener("pointerup", this.onPointerUp), this.container.addEventListener("keydown", this.onKeyDown), this.opts.openDialog?.(this.container, {
1723
1795
  labelledbyId: t,
1724
1796
  describedbyId: e
1725
- }), this.opts.announce?.(this.labels.instructions), Et(this.opts.dataUrl).then((h) => {
1797
+ }), this.opts.announce?.(this.labels.instructions), Ht(this.opts.dataUrl).then((h) => {
1726
1798
  this.img = h, this.canvas.width = h.naturalWidth || h.width || 1, this.canvas.height = h.naturalHeight || h.height || 1, this.redraw();
1727
1799
  }).catch(() => {
1728
1800
  this.img = null, this.redraw();
@@ -1742,8 +1814,8 @@ class At {
1742
1814
  if (t) {
1743
1815
  t.clearRect(0, 0, this.canvas.width, this.canvas.height), this.img && t.drawImage(this.img, 0, 0, this.canvas.width, this.canvas.height);
1744
1816
  for (const e of this.shapes)
1745
- B(t, e);
1746
- this.current && B(t, this.current);
1817
+ H(t, e);
1818
+ this.current && H(t, this.current);
1747
1819
  }
1748
1820
  }
1749
1821
  /** Select the active drawing tool and reflect it on the toolbar. */
@@ -1754,7 +1826,7 @@ class At {
1754
1826
  n.getAttribute("data-qaid-tool") === t ? "true" : "false"
1755
1827
  );
1756
1828
  });
1757
- const o = this.labels[qi[t]];
1829
+ const o = this.labels[$i[t]];
1758
1830
  this.opts.announce?.(`${o} tool selected`);
1759
1831
  }
1760
1832
  /** Set the active drawing colour; subsequent shapes use it. */
@@ -1764,7 +1836,7 @@ class At {
1764
1836
  "aria-pressed",
1765
1837
  (o.getAttribute("data-qaid-color") ?? "").toLowerCase() === t.toLowerCase() ? "true" : "false"
1766
1838
  );
1767
- }), this.opts.announce?.(`${ht(t)} colour selected`);
1839
+ }), this.opts.announce?.(`${yt(t)} colour selected`);
1768
1840
  }
1769
1841
  onToolbarClick = (t) => {
1770
1842
  const o = t.target?.closest(
@@ -1803,7 +1875,7 @@ class At {
1803
1875
  if (!this.drawing || !this.current) return;
1804
1876
  this.drawing = !1;
1805
1877
  const t = this.current;
1806
- if (this.current = null, vi(t)) {
1878
+ if (this.current = null, Pi(t)) {
1807
1879
  this.redraw();
1808
1880
  return;
1809
1881
  }
@@ -1832,7 +1904,7 @@ class At {
1832
1904
  /** Composite the annotations and resolve with the new WebP data URL. */
1833
1905
  async done() {
1834
1906
  if (this.settled) return;
1835
- const t = await Tt(this.opts.dataUrl, this.shapes, {
1907
+ const t = await Ot(this.opts.dataUrl, this.shapes, {
1836
1908
  quality: this.opts.quality
1837
1909
  });
1838
1910
  this.opts.announce?.("Annotated screenshot attached"), this.settle(t);
@@ -1848,27 +1920,27 @@ class At {
1848
1920
  this.toolbar.removeEventListener("click", this.onToolbarClick), this.canvas.removeEventListener("pointerdown", this.onPointerDown), this.container.removeEventListener("pointermove", this.onPointerMove), this.container.removeEventListener("pointerup", this.onPointerUp), this.container.removeEventListener("keydown", this.onKeyDown), this.opts.closeDialog?.(), this.container.remove();
1849
1921
  }
1850
1922
  }
1851
- const qi = {
1923
+ const $i = {
1852
1924
  rect: "rectangle",
1853
1925
  arrow: "arrow",
1854
1926
  pen: "pen",
1855
1927
  blur: "blur"
1856
1928
  };
1857
- function Ci(i) {
1858
- return new At(i).open();
1929
+ function _i(i) {
1930
+ return new zt(i).open();
1859
1931
  }
1860
- const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1932
+ const wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1861
1933
  __proto__: null,
1862
- AnnotationEditor: At,
1863
- compositeAnnotations: Tt,
1864
- drawShape: B,
1865
- openAnnotationEditor: Ci,
1866
- rectFromPoints: P
1934
+ AnnotationEditor: zt,
1935
+ compositeAnnotations: Ot,
1936
+ drawShape: H,
1937
+ openAnnotationEditor: _i,
1938
+ rectFromPoints: B
1867
1939
  }, Symbol.toStringTag, { value: "Module" }));
1868
- We();
1869
- const Si = document;
1870
- function m(i, t, ...e) {
1871
- const o = Si.createElement(i);
1940
+ ci();
1941
+ const Ni = document;
1942
+ function p(i, t, ...e) {
1943
+ const o = Ni.createElement(i);
1872
1944
  if (t) {
1873
1945
  if (t.class && (o.className = t.class), t.style && (o.style.cssText = t.style), t.html != null && (o.innerHTML = t.html), t.text != null && (o.textContent = t.text), t.attrs)
1874
1946
  for (const n in t.attrs) o.setAttribute(n, t.attrs[n]);
@@ -1879,7 +1951,7 @@ function m(i, t, ...e) {
1879
1951
  n != null && n !== !1 && o.append(n);
1880
1952
  return o;
1881
1953
  }
1882
- class Ei {
1954
+ class Fi {
1883
1955
  constructor(t) {
1884
1956
  this.host = t;
1885
1957
  }
@@ -1906,8 +1978,8 @@ class Ei {
1906
1978
  async startRecording(t = []) {
1907
1979
  if (!(this.isRecording || this.host.state !== "IDLE"))
1908
1980
  try {
1909
- this.networkCapture = Qe();
1910
- const { createVideoRecorder: e } = await Promise.resolve().then(() => St);
1981
+ this.networkCapture = ui();
1982
+ const { createVideoRecorder: e } = await Promise.resolve().then(() => Bt);
1911
1983
  this.videoRecorder = e({
1912
1984
  maxDuration: this.host.config.videoOptions.maxDuration,
1913
1985
  redactionElements: t
@@ -1917,7 +1989,7 @@ class Ei {
1917
1989
  this.isRecording && (this.recordedBlob = o, this.isRecording = !1, this.host.announceMsg("Recording stopped"), this.removeRecordingIndicator(), document.removeEventListener("keydown", this.host.boundKeyDown), this.host.setButtonsDisabled(!1), o && o.size > 0 ? this.showRecordingPreview() : this.cleanupRecording());
1918
1990
  }), await this.videoRecorder.start(), this.isRecording = !0, this.host.announceMsg("Recording started"), this.host.setButtonsDisabled(!0), this.showRecordingIndicator(), document.addEventListener("keydown", this.host.boundKeyDown);
1919
1991
  } catch (e) {
1920
- e instanceof Error && /current tab/i.test(e.message) && this.host.announceMsg(e.message), this.cleanupRecording();
1992
+ e instanceof Error && /current tab|cannot blur/i.test(e.message) && this.host.announceMsg(e.message), this.cleanupRecording();
1921
1993
  }
1922
1994
  }
1923
1995
  async stopRecording() {
@@ -1937,27 +2009,27 @@ class Ei {
1937
2009
  startPicking() {
1938
2010
  if (this.isRecording || this.host.state !== "IDLE") return;
1939
2011
  this.host.setState("REDACT_PICKING"), this.redactPicks = [];
1940
- const t = this.host.ensureOverlayHost(), e = m("div", { style: "position:absolute;inset:0;" }), o = m(
2012
+ const t = this.host.ensureOverlayHost(), e = p("div", { style: "position:absolute;inset:0;" }), o = p(
1941
2013
  "div",
1942
2014
  { class: "qaid-redact-picker", style: "position:fixed;inset:0;pointer-events:none;" },
1943
2015
  e,
1944
2016
  // Control bar — the only pointer-interactive part of the overlay.
1945
- m(
2017
+ p(
1946
2018
  "div",
1947
2019
  {
1948
2020
  style: "position:fixed;left:50%;bottom:24px;transform:translateX(-50%);display:flex;gap:12px;align-items:center;pointer-events:auto;background:#0b1220;color:#fff;border:1px solid #ff6b6b;border-radius:9999px;padding:10px 16px;font:600 13px system-ui,sans-serif;box-shadow:0 8px 30px rgba(0,0,0,.5);"
1949
2021
  },
1950
- m("span", {
2022
+ p("span", {
1951
2023
  text: "Click sensitive areas to blur",
1952
2024
  attrs: { "data-qaid-redact-label": "" }
1953
2025
  }),
1954
- m("button", {
2026
+ p("button", {
1955
2027
  text: "Start recording",
1956
2028
  attrs: { type: "button" },
1957
2029
  style: "cursor:pointer;border:0;border-radius:9999px;padding:8px 14px;background:#ff6b6b;color:#0b1220;font:inherit;",
1958
2030
  on: { click: () => this.finishRedactionPicking(!0) }
1959
2031
  }),
1960
- m("button", {
2032
+ p("button", {
1961
2033
  text: "Cancel",
1962
2034
  attrs: { type: "button" },
1963
2035
  style: "cursor:pointer;border:0;background:transparent;color:#9fb3c8;font:inherit;",
@@ -1973,7 +2045,7 @@ class Ei {
1973
2045
  }
1974
2046
  handleRedactPickClick(t) {
1975
2047
  const e = t.target instanceof Element ? t.target : null;
1976
- if (!e || M(e) || this.redactPickerRoot?.contains(e)) return;
2048
+ if (!e || R(e) || this.redactPickerRoot?.contains(e)) return;
1977
2049
  t.preventDefault(), t.stopPropagation();
1978
2050
  const o = this.redactPicks.indexOf(e);
1979
2051
  o >= 0 ? this.redactPicks.splice(o, 1) : this.redactPicks.push(e);
@@ -1988,7 +2060,7 @@ class Ei {
1988
2060
  for (const e of this.redactPicks) {
1989
2061
  const o = e.getBoundingClientRect();
1990
2062
  o.width <= 0 || o.height <= 0 || t.appendChild(
1991
- m("div", {
2063
+ p("div", {
1992
2064
  style: `position:fixed;left:${o.left}px;top:${o.top}px;width:${o.width}px;height:${o.height}px;border:2px solid #ff6b6b;border-radius:4px;background:rgba(255,107,107,.18);pointer-events:none;`
1993
2065
  })
1994
2066
  );
@@ -2001,15 +2073,15 @@ class Ei {
2001
2073
  }
2002
2074
  showRecordingIndicator() {
2003
2075
  const t = this.host.ensureOverlayHost();
2004
- this.recordingIndicator = m(
2076
+ this.recordingIndicator = p(
2005
2077
  "div",
2006
2078
  { class: "qaid-recording-indicator", style: `z-index:${this.host.config.zIndex + 100}` },
2007
- m("div", { class: "qaid-recording-dot" }),
2008
- m("span", {
2079
+ p("div", { class: "qaid-recording-dot" }),
2080
+ p("span", {
2009
2081
  class: "qaid-recording-time",
2010
2082
  text: this.formatTime(this.host.config.videoOptions.maxDuration)
2011
2083
  }),
2012
- m("button", {
2084
+ p("button", {
2013
2085
  class: "qaid-recording-stop",
2014
2086
  text: "Stop",
2015
2087
  attrs: { type: "button" },
@@ -2033,34 +2105,34 @@ class Ei {
2033
2105
  this.recordingIndicator && (this.recordingIndicator.remove(), this.recordingIndicator = null);
2034
2106
  }
2035
2107
  showRecordingPreview() {
2036
- const t = this.host.ensureOverlayHost(), e = URL.createObjectURL(this.recordedBlob), o = `qaid-video-title-${this.host.uid}`, n = m("h3", { text: "Review your recording", attrs: { id: o } }), s = m("video");
2108
+ const t = this.host.ensureOverlayHost(), e = URL.createObjectURL(this.recordedBlob), o = `qaid-video-title-${this.host.uid}`, n = p("h3", { text: "Review your recording", attrs: { id: o } }), s = p("video");
2037
2109
  s.src = e, s.controls = !0, s.autoplay = !0, s.muted = !0;
2038
- const a = m("textarea", {
2110
+ const a = p("textarea", {
2039
2111
  attrs: {
2040
2112
  placeholder: "Optional: Describe the issue you recorded...",
2041
2113
  "aria-label": "Describe the issue you recorded"
2042
2114
  }
2043
- }), c = m("button", {
2115
+ }), c = p("button", {
2044
2116
  class: "qaid-video-btn qaid-video-btn-send",
2045
2117
  text: "Send",
2046
2118
  attrs: { type: "button" },
2047
2119
  on: { click: () => this.submitVideoFeedback(a.value.trim() || null, c) }
2048
- }), l = m(
2120
+ }), l = p(
2049
2121
  "div",
2050
2122
  { class: "qaid-video-preview-box" },
2051
2123
  n,
2052
2124
  s,
2053
2125
  a,
2054
- m(
2126
+ p(
2055
2127
  "div",
2056
2128
  { class: "qaid-video-preview-actions" },
2057
- m("button", {
2129
+ p("button", {
2058
2130
  class: "qaid-video-btn qaid-video-btn-cancel",
2059
2131
  text: "Cancel",
2060
2132
  attrs: { type: "button" },
2061
2133
  on: { click: () => this.cancelRecordingPreview() }
2062
2134
  }),
2063
- m("button", {
2135
+ p("button", {
2064
2136
  class: "qaid-video-btn qaid-video-btn-rerecord",
2065
2137
  text: "Re-record",
2066
2138
  attrs: { type: "button" },
@@ -2073,7 +2145,7 @@ class Ei {
2073
2145
  c
2074
2146
  )
2075
2147
  );
2076
- this.videoPreview = m(
2148
+ this.videoPreview = p(
2077
2149
  "div",
2078
2150
  { class: "qaid-video-preview", style: `z-index:${this.host.config.zIndex + 100}` },
2079
2151
  l
@@ -2094,35 +2166,52 @@ class Ei {
2094
2166
  this.isSendingVideo = !0, e.disabled = !0, e.textContent = "Sending...";
2095
2167
  const o = new FormData();
2096
2168
  o.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), o.append("pageUrl", window.location.href), o.append("visitorId", this.host.visitorId), this.host.config.apiKey && o.append("apiKey", this.host.config.apiKey), t && o.append("message", t), this.host.consoleCapture && o.append("consoleErrors", JSON.stringify(this.host.consoleCapture.errors)), this.networkCapture && o.append("networkErrors", JSON.stringify(this.networkCapture.errors));
2097
- let n = null;
2169
+ let n = null, s = null;
2098
2170
  try {
2099
- const s = await fetch(`${this.host.config.endpoint}/video`, {
2171
+ const a = await fetch(`${this.host.config.endpoint}/video`, {
2100
2172
  method: "POST",
2101
2173
  body: o
2102
2174
  });
2103
- if (s.ok) {
2175
+ if (a.ok) {
2104
2176
  this.host.announceMsg("Recording sent");
2105
2177
  try {
2106
- n = (await s.json())?.id ?? null;
2178
+ n = (await a.json())?.id ?? null;
2107
2179
  } catch {
2108
2180
  }
2109
2181
  } else
2110
- console.error("Failed to submit video feedback:", await s.text()), this.host.announceMsg("Failed to send recording", !0);
2111
- } catch (s) {
2112
- console.error("Failed to submit video feedback:", s), this.host.announceMsg("Failed to send recording", !0);
2182
+ console.error("Failed to submit video feedback:", await a.text()), s = a.status === 413 ? "This recording is too large to send. Try a shorter one." : "Your recording could not be sent.";
2183
+ } catch (a) {
2184
+ console.error("Failed to submit video feedback:", a), s = "Your recording could not be sent. Check your connection and try again.";
2185
+ }
2186
+ if (this.isSendingVideo = !1, s) {
2187
+ this.showSendError(s, e);
2188
+ return;
2189
+ }
2190
+ this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
2191
+ }
2192
+ /**
2193
+ * Keep the preview open and say the upload failed. Closing it, as a success
2194
+ * does, told the visitor their recording had arrived when it had not. Send
2195
+ * is re-enabled for another try; Cancel and Re-record still work.
2196
+ */
2197
+ showSendError(t, e) {
2198
+ this.host.announceMsg(`Failed to send recording. ${t}`, !0), e.disabled = !1, e.textContent = "Send";
2199
+ const o = this.videoPreview?.querySelector(".qaid-video-preview-actions");
2200
+ if (o) {
2201
+ let n = this.videoPreview.querySelector(".qaid-video-error");
2202
+ n || (n = p("p", { class: "qaid-video-error" }), o.before(n)), n.textContent = t;
2113
2203
  }
2114
- this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
2115
2204
  }
2116
2205
  cleanupRecording() {
2117
2206
  this.isRecording = !1, this.removeRecordingIndicator(), this.videoRecorder && (this.videoRecorder.destroy(), this.videoRecorder = null), this.networkCapture && (this.networkCapture.restore(), this.networkCapture = null), this.recordedBlob && (this.recordedBlob = null), this.host.setButtonsDisabled(!1), this.host.overlayShadowHost && this.host.state === "IDLE" && (this.host.overlayShadowHost.style.pointerEvents = "none");
2118
2207
  }
2119
2208
  }
2120
- const pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2209
+ const kt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2121
2210
  __proto__: null,
2122
- RecordingController: Ei
2211
+ RecordingController: Fi
2123
2212
  }, Symbol.toStringTag, { value: "Module" }));
2124
- async function Ti(i = {}) {
2125
- const { quality: t = 1, maxWidth: e = 1280, maxHeight: o = 800 } = i;
2213
+ async function Vi(i = {}) {
2214
+ const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
2126
2215
  try {
2127
2216
  if (!navigator.mediaDevices?.getDisplayMedia)
2128
2217
  return console.warn("Screen Capture API not available"), null;
@@ -2142,19 +2231,19 @@ async function Ti(i = {}) {
2142
2231
  };
2143
2232
  w();
2144
2233
  }), await new Promise((g) => setTimeout(g, 100));
2145
- const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r), p = Math.round(d * r), b = document.createElement("canvas");
2146
- b.width = h, b.height = p;
2234
+ const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r), f = Math.round(d * r), b = document.createElement("canvas");
2235
+ b.width = h, b.height = f;
2147
2236
  const y = b.getContext("2d");
2148
- return y ? (y.drawImage(c, 0, 0, h, p), s.stop(), b.toDataURL("image/webp", t)) : (s.stop(), null);
2237
+ return y ? (y.drawImage(c, 0, 0, h, f), s.stop(), b.toDataURL("image/webp", t)) : (s.stop(), null);
2149
2238
  } catch (n) {
2150
2239
  return console.warn("Screenshot capture failed:", n), null;
2151
2240
  }
2152
2241
  }
2153
- const ft = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2242
+ const xt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2154
2243
  __proto__: null,
2155
- captureScreenshot: Ti
2244
+ captureScreenshot: Vi
2156
2245
  }, Symbol.toStringTag, { value: "Module" }));
2157
- class Ai {
2246
+ class Ui {
2158
2247
  constructor(t) {
2159
2248
  this.host = t;
2160
2249
  }
@@ -2182,15 +2271,17 @@ class Ai {
2182
2271
  }
2183
2272
  showBottomSheet() {
2184
2273
  const t = this.host.ensureOverlayHost(), e = document.createElement("div");
2185
- e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.innerHTML = `
2186
- <div class="qaid-bottom-sheet-content">
2187
- <div class="qaid-bottom-sheet-handle"></div>
2188
- ${this.getModalContent()}
2189
- </div>
2190
- `, this.host.applyVars(e), t.appendChild(e), this.modalContainer = e, this.setupModalInteractions();
2274
+ e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.appendChild(
2275
+ p(
2276
+ "div",
2277
+ { class: "qaid-bottom-sheet-content" },
2278
+ p("div", { class: "qaid-bottom-sheet-handle" }),
2279
+ this.buildModalContent()
2280
+ )
2281
+ ), this.host.applyVars(e), t.appendChild(e), this.modalContainer = e, this.setupModalInteractions();
2191
2282
  }
2192
2283
  showPositionedModal() {
2193
- const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = De(
2284
+ const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = je(
2194
2285
  this.host.selectedBounds,
2195
2286
  window.innerWidth,
2196
2287
  window.innerHeight,
@@ -2206,25 +2297,65 @@ class Ai {
2206
2297
  const n = document.createElement("div");
2207
2298
  n.className = "qaid-modal-arrow", n.style.left = `${o.left}px`;
2208
2299
  const s = document.createElement("div");
2209
- s.className = "qaid-modal-box", s.innerHTML = this.getModalContent(), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.host.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
2210
- }
2211
- getModalContent() {
2212
- const t = this.host.feedbackData.feedbackType, e = t === "up", o = this.host.config.positiveIcon || V, n = this.host.config.negativeIcon || N, s = this.host.config.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${this.host.config.buttonClass} ${e ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${e ? "qaid-type-up" : "qaid-type-down"}`;
2213
- return `
2214
- <div class="qaid-modal-header">
2215
- ${t === "neutral" ? `<span class="qaid-type-static" aria-hidden="true">${this.host.config.feedbackIcon || gt}</span>` : `<button type="button" class="${s}" title="Click to switch" aria-pressed="${e}" aria-label="${e ? "Feedback type: positive" : "Feedback type: negative"}">
2216
- ${e ? o : n}
2217
- </button>`}
2218
- <div class="qaid-modal-header-text">
2219
- <h3 class="qaid-modal-title" id="qaid-modal-title-${this.host.uid}">${this.host.config.text.modalTitle}</h3>
2220
- <p class="qaid-modal-subtitle" id="qaid-modal-subtitle-${this.host.uid}">${this.host.config.text.modalSubtitle}</p>
2221
- </div>
2222
- </div>
2223
- <textarea class="qaid-textarea" aria-label="${this.host.config.text.modalSubtitle}" placeholder="${this.host.config.text.placeholder}"></textarea>
2224
- <div class="qaid-btn-row">
2225
- <button type="button" class="qaid-btn-submit">${this.host.config.text.skipButton}</button>
2226
- </div>
2227
- `;
2300
+ s.className = "qaid-modal-box", s.appendChild(this.buildModalContent()), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.host.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
2301
+ }
2302
+ /**
2303
+ * The modal's contents, built as nodes rather than an HTML string.
2304
+ *
2305
+ * Every piece of copy (title, subtitle, placeholder, button) goes in as
2306
+ * text, so a `<`, `&` or `"` in a translation shows as written instead of
2307
+ * being parsed as markup or cutting an attribute short. Only the icons are
2308
+ * markup, because they are documented as SVG/HTML strings.
2309
+ */
2310
+ buildModalContent() {
2311
+ const { config: t, uid: e } = this.host, o = t.text, n = this.host.feedbackData.feedbackType, s = n === "up", a = t.positiveIcon || V, c = t.negativeIcon || U, l = t.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${t.buttonClass} ${s ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${s ? "qaid-type-up" : "qaid-type-down"}`, d = s ? "Feedback type: positive" : "Feedback type: negative", r = n === "neutral" ? p("span", {
2312
+ class: "qaid-type-static",
2313
+ html: t.feedbackIcon || St,
2314
+ attrs: { "aria-hidden": "true" }
2315
+ }) : p("button", {
2316
+ class: l,
2317
+ html: s ? a : c,
2318
+ attrs: {
2319
+ type: "button",
2320
+ title: "Click to switch",
2321
+ "aria-pressed": String(s),
2322
+ "aria-label": d
2323
+ }
2324
+ }), h = document.createDocumentFragment();
2325
+ return h.append(
2326
+ p(
2327
+ "div",
2328
+ { class: "qaid-modal-header" },
2329
+ r,
2330
+ p(
2331
+ "div",
2332
+ { class: "qaid-modal-header-text" },
2333
+ p("h3", {
2334
+ class: "qaid-modal-title",
2335
+ text: o.modalTitle,
2336
+ attrs: { id: `qaid-modal-title-${e}` }
2337
+ }),
2338
+ p("p", {
2339
+ class: "qaid-modal-subtitle",
2340
+ text: o.modalSubtitle,
2341
+ attrs: { id: `qaid-modal-subtitle-${e}` }
2342
+ })
2343
+ )
2344
+ ),
2345
+ p("textarea", {
2346
+ class: "qaid-textarea",
2347
+ attrs: { "aria-label": o.modalSubtitle, placeholder: o.placeholder }
2348
+ }),
2349
+ p(
2350
+ "div",
2351
+ { class: "qaid-btn-row" },
2352
+ p("button", {
2353
+ class: "qaid-btn-submit",
2354
+ text: o.skipButton,
2355
+ attrs: { type: "button" }
2356
+ })
2357
+ )
2358
+ ), h;
2228
2359
  }
2229
2360
  setupModalInteractions() {
2230
2361
  this.host.openDialogA11y(this.modalContainer, {
@@ -2242,7 +2373,7 @@ class Ai {
2242
2373
  o && o.addEventListener("click", () => {
2243
2374
  const n = this.host.feedbackData.feedbackType === "up" ? "down" : "up";
2244
2375
  this.host.feedbackData.feedbackType = n, this.host.config.buttonClass ? (o.classList.toggle("qaid-btn-up", n === "up"), o.classList.toggle("qaid-btn-down", n === "down")) : (o.classList.toggle("qaid-type-up", n === "up"), o.classList.toggle("qaid-type-down", n === "down"));
2245
- const s = this.host.config.positiveIcon || V, a = this.host.config.negativeIcon || N;
2376
+ const s = this.host.config.positiveIcon || V, a = this.host.config.negativeIcon || U;
2246
2377
  o.innerHTML = n === "up" ? s : a;
2247
2378
  const c = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
2248
2379
  o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", c), this.host.announceMsg(c), this.host.feedbackId && fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
@@ -2253,59 +2384,79 @@ class Ai {
2253
2384
  });
2254
2385
  }
2255
2386
  async submitMessage(t) {
2256
- let e = !1;
2387
+ let e = null;
2257
2388
  if (this.host.feedbackId) {
2258
2389
  try {
2259
- await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
2390
+ const o = await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
2260
2391
  method: "PATCH",
2261
2392
  headers: { "Content-Type": "application/json" },
2262
2393
  body: JSON.stringify({ message: t })
2263
- }), e = !0;
2394
+ });
2395
+ e = o.ok, o.ok || console.error("Failed to submit feedback message: HTTP", o.status);
2264
2396
  } catch (o) {
2265
- console.error("Failed to submit feedback message:", o);
2397
+ console.error("Failed to submit feedback message:", o), e = !1;
2266
2398
  }
2267
2399
  this.host.setFeedbackId(null);
2268
2400
  }
2401
+ if (e === !1) {
2402
+ this.showResult(!1);
2403
+ return;
2404
+ }
2269
2405
  if (e && !this.host.config.hideConfirmation) {
2270
- this.showConfirmation();
2406
+ this.showResult(!0);
2271
2407
  return;
2272
2408
  }
2273
2409
  this.close();
2274
2410
  }
2275
2411
  /**
2276
- * Replace the modal's contents with a checkmark and a short acknowledgement.
2412
+ * Replace the modal's contents with the outcome: a checkmark and a short
2413
+ * acknowledgement, or an error mark and a "not sent" notice.
2277
2414
  *
2278
2415
  * The submit button that had focus is gone by this point, so focus moves to
2279
2416
  * the heading (WCAG 2.4.3) and the message is announced. Mirrors the quests
2280
- * embed's thank-you screen so the two products confirm the same way.
2417
+ * embed's thank-you screen so the two products confirm the same way. Copy
2418
+ * goes in as text, never markup.
2281
2419
  */
2282
- showConfirmation() {
2283
- const t = this.modalContainer?.querySelector(".qaid-modal-box") ?? this.modalContainer?.querySelector(".qaid-bottom-sheet-content") ?? this.modalContainer;
2284
- if (!t) {
2420
+ showResult(t) {
2421
+ const e = this.modalContainer?.querySelector(".qaid-modal-box") ?? this.modalContainer?.querySelector(".qaid-bottom-sheet-content") ?? this.modalContainer;
2422
+ if (!e) {
2285
2423
  this.close();
2286
2424
  return;
2287
2425
  }
2288
- const e = this.host.config.text, o = `qaid-confirm-title-${this.host.uid}`;
2289
- t.innerHTML = `
2290
- <div class="qaid-confirm">
2291
- <span class="qaid-confirm-icon" aria-hidden="true">${vt}</span>
2292
- <h3 class="qaid-confirm-title" id="${o}" tabindex="-1">${e.confirmationTitle}</h3>
2293
- <p class="qaid-confirm-message">${e.confirmationMessage}</p>
2294
- <button type="button" class="qaid-btn-submit qaid-confirm-close">${e.confirmationClose}</button>
2295
- </div>
2296
- `, t.querySelector(".qaid-confirm-close")?.addEventListener("click", () => this.close());
2297
- const n = t.querySelector(`#${CSS.escape(o)}`);
2298
- requestAnimationFrame(() => n?.focus()), this.host.announceMsg(`${e.confirmationTitle} ${e.confirmationMessage}`, !0);
2299
- }
2300
- }
2301
- const mt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2426
+ const o = this.host.config.text, n = t ? o.confirmationTitle : o.errorTitle, s = t ? o.confirmationMessage : o.errorMessage, a = p("h3", {
2427
+ class: "qaid-confirm-title",
2428
+ text: n,
2429
+ attrs: { id: `qaid-confirm-title-${this.host.uid}`, tabindex: "-1" }
2430
+ });
2431
+ e.textContent = "", e.appendChild(
2432
+ p(
2433
+ "div",
2434
+ { class: t ? "qaid-confirm" : "qaid-confirm qaid-confirm-error" },
2435
+ p("span", {
2436
+ class: "qaid-confirm-icon",
2437
+ html: t ? Et : pe,
2438
+ attrs: { "aria-hidden": "true" }
2439
+ }),
2440
+ a,
2441
+ p("p", { class: "qaid-confirm-message", text: s }),
2442
+ p("button", {
2443
+ class: "qaid-btn-submit qaid-confirm-close",
2444
+ text: o.confirmationClose,
2445
+ attrs: { type: "button" },
2446
+ on: { click: () => this.close() }
2447
+ })
2448
+ )
2449
+ ), requestAnimationFrame(() => a.focus()), this.host.announceMsg(`${n} ${s}`, !0);
2450
+ }
2451
+ }
2452
+ const qt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2302
2453
  __proto__: null,
2303
- ModalController: Ai
2304
- }, Symbol.toStringTag, { value: "Module" })), Lt = ["data-comp", "data-qa", "data-testid", "data-id"];
2305
- function It(i, t = document.body) {
2454
+ ModalController: Ui
2455
+ }, Symbol.toStringTag, { value: "Module" })), $t = ["data-comp", "data-qa", "data-testid", "data-id"];
2456
+ function _t(i, t = document.body) {
2306
2457
  let e = i;
2307
2458
  for (; e && e !== t; ) {
2308
- for (const o of Lt) {
2459
+ for (const o of $t) {
2309
2460
  const n = e.getAttribute(o);
2310
2461
  if (n)
2311
2462
  return `${o}="${n}"`;
@@ -2314,37 +2465,37 @@ function It(i, t = document.body) {
2314
2465
  }
2315
2466
  return null;
2316
2467
  }
2317
- function Li(i, t = 100) {
2468
+ function ji(i, t = 100) {
2318
2469
  const e = i.textContent?.trim().slice(0, t) || "";
2319
2470
  return e.length === t ? e + "..." : e;
2320
2471
  }
2321
- function Ii(i) {
2472
+ function Ki(i) {
2322
2473
  let t = 1, e = i.previousElementSibling;
2323
2474
  for (; e; )
2324
2475
  t++, e = e.previousElementSibling;
2325
2476
  return t;
2326
2477
  }
2327
- function Di(i) {
2478
+ function Wi(i) {
2328
2479
  const t = [];
2329
2480
  let e = i;
2330
2481
  for (; e && e !== document.body && e !== document.documentElement; ) {
2331
- const o = e.tagName.toLowerCase(), n = Ii(e);
2482
+ const o = e.tagName.toLowerCase(), n = Ki(e);
2332
2483
  t.unshift(`${o}:nth-child(${n})`), e = e.parentElement;
2333
2484
  }
2334
2485
  return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
2335
2486
  }
2336
- function Mi(i) {
2487
+ function Xi(i) {
2337
2488
  return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
2338
2489
  }
2339
- function Ri(i) {
2340
- const t = It(i);
2341
- return t ? `[${t}]` : i.id ? `#${Mi(i.id)}` : Di(i);
2490
+ function Yi(i) {
2491
+ const t = _t(i);
2492
+ return t ? `[${t}]` : i.id ? `#${Xi(i.id)}` : Wi(i);
2342
2493
  }
2343
2494
  function F(i) {
2344
- const t = Li(i), e = It(i);
2345
- return { selector: Ri(i), text: t, dataAttr: e };
2495
+ const t = ji(i), e = _t(i);
2496
+ return { selector: Yi(i), text: t, dataAttr: e };
2346
2497
  }
2347
- const Pi = [
2498
+ const Qi = [
2348
2499
  "a[href]",
2349
2500
  "button",
2350
2501
  "input:not([type=hidden])",
@@ -2363,9 +2514,9 @@ const Pi = [
2363
2514
  "p",
2364
2515
  "li",
2365
2516
  "label",
2366
- ...Lt.map((i) => `[${i}]`)
2367
- ].join(","), Bi = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
2368
- function Hi(i) {
2517
+ ...$t.map((i) => `[${i}]`)
2518
+ ].join(","), Ji = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
2519
+ function Gi(i) {
2369
2520
  if (i.hasAttribute("hidden") || i.getAttribute("aria-hidden") === "true") return !1;
2370
2521
  const t = i.ownerDocument?.defaultView;
2371
2522
  if (t && typeof t.getComputedStyle == "function") {
@@ -2374,14 +2525,14 @@ function Hi(i) {
2374
2525
  }
2375
2526
  return !0;
2376
2527
  }
2377
- function Oi(i = {}) {
2378
- const t = i.root ?? document.body, e = i.selector ?? Pi, o = i.isExcluded ?? (() => !1), n = i.isVisible ?? Hi;
2528
+ function Zi(i = {}) {
2529
+ const t = i.root ?? document.body, e = i.selector ?? Qi, o = i.isExcluded ?? (() => !1), n = i.isVisible ?? Gi;
2379
2530
  return Array.from(t.querySelectorAll(e)).filter(
2380
2531
  (s) => !o(s) && n(s)
2381
2532
  );
2382
2533
  }
2383
- function $i(i) {
2384
- const t = i.candidates ?? Oi({
2534
+ function to(i) {
2535
+ const t = i.candidates ?? Zi({
2385
2536
  root: i.root,
2386
2537
  selector: i.selector,
2387
2538
  isExcluded: i.isExcluded,
@@ -2398,7 +2549,7 @@ function $i(i) {
2398
2549
  if (!e) return;
2399
2550
  const k = u;
2400
2551
  if (typeof k.focus == "function") {
2401
- u.getAttribute("tabindex") === null && !Bi.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
2552
+ u.getAttribute("tabindex") === null && !Ji.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
2402
2553
  try {
2403
2554
  k.focus();
2404
2555
  } catch {
@@ -2417,7 +2568,7 @@ function $i(i) {
2417
2568
  function h() {
2418
2569
  r(s + 1);
2419
2570
  }
2420
- function p() {
2571
+ function f() {
2421
2572
  r(s - 1);
2422
2573
  }
2423
2574
  function b() {
@@ -2438,7 +2589,7 @@ function $i(i) {
2438
2589
  if (!a)
2439
2590
  switch (u.key) {
2440
2591
  case "Tab":
2441
- u.preventDefault(), u.stopPropagation(), u.shiftKey ? p() : h();
2592
+ u.preventDefault(), u.stopPropagation(), u.shiftKey ? f() : h();
2442
2593
  break;
2443
2594
  case "ArrowDown":
2444
2595
  case "ArrowRight":
@@ -2446,7 +2597,7 @@ function $i(i) {
2446
2597
  break;
2447
2598
  case "ArrowUp":
2448
2599
  case "ArrowLeft":
2449
- u.preventDefault(), u.stopPropagation(), p();
2600
+ u.preventDefault(), u.stopPropagation(), f();
2450
2601
  break;
2451
2602
  case "Enter":
2452
2603
  case " ":
@@ -2464,7 +2615,7 @@ function $i(i) {
2464
2615
  getIndex: () => s,
2465
2616
  getCurrent: b,
2466
2617
  next: h,
2467
- prev: p,
2618
+ prev: f,
2468
2619
  moveTo: r,
2469
2620
  select: g,
2470
2621
  cancel: w,
@@ -2472,8 +2623,8 @@ function $i(i) {
2472
2623
  stop: y
2473
2624
  };
2474
2625
  }
2475
- const zi = 12;
2476
- class _i {
2626
+ const eo = 12;
2627
+ class io {
2477
2628
  constructor(t) {
2478
2629
  this.host = t;
2479
2630
  }
@@ -2502,8 +2653,8 @@ class _i {
2502
2653
  * KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
2503
2654
  */
2504
2655
  startKeyboard(t) {
2505
- this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController = $i({
2506
- isExcluded: (e) => M(e),
2656
+ this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController = to({
2657
+ isExcluded: (e) => R(e),
2507
2658
  onHighlight: (e) => {
2508
2659
  const o = e.getBoundingClientRect(), n = this.highlightBox;
2509
2660
  n && (n.style.transform = `translate(${o.left}px, ${o.top}px)`, n.style.width = `${o.width}px`, n.style.height = `${o.height}px`, n.style.display = "block");
@@ -2515,7 +2666,7 @@ class _i {
2515
2666
  });
2516
2667
  }
2517
2668
  selectKeyboardTarget(t) {
2518
- const e = ot(t, 8);
2669
+ const e = lt(t, 8);
2519
2670
  Object.assign(this.host.selectedBounds, e, {
2520
2671
  clickX: e.x + e.width / 2,
2521
2672
  clickY: e.y + e.height / 2,
@@ -2540,8 +2691,8 @@ class _i {
2540
2691
  /** Move the crosshair/scope reticle and highlight the element under (x, y). */
2541
2692
  updateReticleAt(t, e) {
2542
2693
  if (this.mousePos.x = t, this.mousePos.y = e, this.crosshairH && (this.crosshairH.style.top = `${e}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${e}px`), this.captureLayer && this.host.shadowHost) {
2543
- const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = it(t, e, o);
2544
- if (n && !M(n)) {
2694
+ const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ct(t, e, o);
2695
+ if (n && !R(n)) {
2545
2696
  if (this.highlightBox) {
2546
2697
  const s = n.getBoundingClientRect();
2547
2698
  this.highlightBox.style.transform = `translate(${s.left}px, ${s.top}px)`, this.highlightBox.style.width = `${s.width}px`, this.highlightBox.style.height = `${s.height}px`, this.highlightBox.style.display = "block";
@@ -2559,14 +2710,14 @@ class _i {
2559
2710
  }
2560
2711
  handleTouchEnd(t) {
2561
2712
  const e = t.changedTouches[0], o = this.touchStartPos;
2562
- this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) > zi) && (t.preventDefault(), this.selectAt(e.clientX, e.clientY));
2713
+ this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) > eo) && (t.preventDefault(), this.selectAt(e.clientX, e.clientY));
2563
2714
  }
2564
2715
  /** Select the element under (x, y) and tear down targeting. */
2565
2716
  selectAt(t, e) {
2566
- const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = it(t, e, o);
2567
- if (!n || M(n))
2717
+ const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ct(t, e, o);
2718
+ if (!n || R(n))
2568
2719
  return;
2569
- const s = ot(n, 8);
2720
+ const s = lt(n, 8);
2570
2721
  Object.assign(this.host.selectedBounds, s, { clickX: t, clickY: e, visible: !0 });
2571
2722
  const { selector: a, text: c } = F(n);
2572
2723
  this.host.feedbackData.elementSelector = a, this.host.feedbackData.elementText = c, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.host.setState("SELECTED"), this.host.clearActiveThumb(), this.showSelectedMarker(), this.host.submitFeedback();
@@ -2592,22 +2743,22 @@ class _i {
2592
2743
  this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), this.hideMarker();
2593
2744
  }
2594
2745
  }
2595
- const bt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2746
+ const Ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2596
2747
  __proto__: null,
2597
- TargetingController: _i
2748
+ TargetingController: io
2598
2749
  }, Symbol.toStringTag, { value: "Module" }));
2599
2750
  export {
2600
- At as AnnotationEditor,
2601
- Ue as QaidFeedback,
2602
- hi as captureDomScreenshot,
2603
- Qe as captureNetworkErrors,
2604
- Tt as compositeAnnotations,
2605
- ai as createVideoRecorder,
2606
- B as drawShape,
2607
- Ct as getSupportedMimeType,
2608
- ci as isDomScreenshotSupported,
2609
- si as isVideoRecordingSupported,
2610
- Ci as openAnnotationEditor,
2611
- P as rectFromPoints
2751
+ zt as AnnotationEditor,
2752
+ ni as QaidFeedback,
2753
+ Ti as captureDomScreenshot,
2754
+ ui as captureNetworkErrors,
2755
+ Ot as compositeAnnotations,
2756
+ xi as createVideoRecorder,
2757
+ H as drawShape,
2758
+ Pt as getSupportedMimeType,
2759
+ Si as isDomScreenshotSupported,
2760
+ ki as isVideoRecordingSupported,
2761
+ _i as openAnnotationEditor,
2762
+ B as rectFromPoints
2612
2763
  };
2613
2764
  //# sourceMappingURL=index.js.map