@qaiddev/thumbs-embed 1.2.1 → 1.3.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.
package/dist/qaid.js CHANGED
@@ -1,25 +1,39 @@
1
- const I = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
1
+ const D = `<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>`, A = `<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>`, M = `<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>`, bt = `<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>`, xt = `<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 = "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-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)}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}}", vt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
8
- let k = 0;
9
- const yt = "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 svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", wt = {
7
+ </svg>`, kt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
8
+ <rect x="4" y="6" width="16" height="12" rx="1" stroke-linejoin="round"/>
9
+ </svg>`, Ct = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
10
+ <path stroke-linecap="round" stroke-linejoin="round" d="M5 19L19 5m0 0h-8m8 0v8"/>
11
+ </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">
12
+ <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"/>
13
+ </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">
14
+ <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"/>
15
+ </svg>`, Tt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
16
+ <path stroke-linecap="round" stroke-linejoin="round" d="M9 14L4 9l5-5M4 9h11a5 5 0 010 10h-4"/>
17
+ </svg>`, Lt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
18
+ <path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
19
+ </svg>`, It = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
20
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 6l12 12M18 6L6 18"/>
21
+ </svg>`, At = "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-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{padding:0}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}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}}", Dt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
22
+ let E = 0;
23
+ const Mt = "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 svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", Rt = {
10
24
  small: 36,
11
25
  medium: 48,
12
26
  large: 64
13
- }, xt = {
27
+ }, Bt = {
14
28
  small: 18,
15
29
  medium: 24,
16
30
  large: 32
17
31
  };
18
- function qt(e, t, i) {
32
+ function Ht(e, t, i) {
19
33
  const [o, n, s] = [e, t, i].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
20
34
  return 0.2126 * o + 0.7152 * n + 0.0722 * s;
21
35
  }
22
- function kt(e) {
36
+ function Pt(e) {
23
37
  if (e.startsWith("#")) {
24
38
  const i = e.slice(1), o = i.length === 3 ? i.split("").map((s) => s + s).join("") : i, n = parseInt(o, 16);
25
39
  return {
@@ -35,11 +49,11 @@ function kt(e) {
35
49
  b: parseInt(t[3])
36
50
  } : null;
37
51
  }
38
- function Ct(e) {
39
- const t = kt(e);
40
- return t && qt(t.r, t.g, t.b) > 0.4 ? "black" : "white";
52
+ function Ot(e) {
53
+ const t = Pt(e);
54
+ return t && Ht(t.r, t.g, t.b) > 0.4 ? "black" : "white";
41
55
  }
42
- function St(e = {}) {
56
+ function zt(e = {}) {
43
57
  const {
44
58
  positiveColor: t = "rgb(0, 200, 83)",
45
59
  negativeColor: i = "rgb(255, 0, 0)",
@@ -48,41 +62,41 @@ function St(e = {}) {
48
62
  modalWidth: s = 400,
49
63
  backdropOpacity: a = 0.3,
50
64
  fontFamily: d = "system-ui, -apple-system, sans-serif",
51
- fontSize: l = 16
52
- } = e, r = wt[n], c = xt[n], p = Ct(o);
65
+ fontSize: c = 16
66
+ } = e, r = Rt[n], l = Bt[n], p = Ot(o);
53
67
  return {
54
68
  "--qaid-positive": t,
55
69
  "--qaid-negative": i,
56
70
  "--qaid-marker": o,
57
71
  "--qaid-marker-text": p,
58
72
  "--qaid-btn-size": `${r}px`,
59
- "--qaid-icon-size": `${c}px`,
73
+ "--qaid-icon-size": `${l}px`,
60
74
  "--qaid-modal-width": `${s}px`,
61
75
  "--qaid-backdrop-opacity": String(a),
62
76
  "--qaid-font-family": d,
63
- "--qaid-font-size": `${l}px`
77
+ "--qaid-font-size": `${c}px`
64
78
  };
65
79
  }
66
- function Et(e, t) {
80
+ function $t(e, t) {
67
81
  for (const [i, o] of Object.entries(t))
68
82
  e.style.setProperty(i, o);
69
83
  }
70
- function N() {
71
- return gt + yt;
84
+ function _() {
85
+ return At + Mt;
72
86
  }
73
- function Tt() {
74
- if (k++, k > 1) return;
87
+ function Nt() {
88
+ if (E++, E > 1) return;
75
89
  const e = document.createElement("style");
76
- e.id = "qaid-styles", e.textContent = vt, document.head.appendChild(e);
90
+ e.id = "qaid-styles", e.textContent = Dt, document.head.appendChild(e);
77
91
  }
78
- function Lt() {
79
- k <= 0 || (k--, k === 0 && document.getElementById("qaid-styles").remove());
92
+ function Ut() {
93
+ E <= 0 || (E--, E === 0 && document.getElementById("qaid-styles").remove());
80
94
  }
81
- const G = ["data-comp", "data-qa", "data-testid", "data-id"];
82
- function J(e, t = document.body) {
95
+ const et = ["data-comp", "data-qa", "data-testid", "data-id"];
96
+ function it(e, t = document.body) {
83
97
  let i = e;
84
98
  for (; i && i !== t; ) {
85
- for (const o of G) {
99
+ for (const o of et) {
86
100
  const n = i.getAttribute(o);
87
101
  if (n)
88
102
  return `${o}="${n}"`;
@@ -91,37 +105,37 @@ function J(e, t = document.body) {
91
105
  }
92
106
  return null;
93
107
  }
94
- function It(e, t = 100) {
108
+ function Ft(e, t = 100) {
95
109
  const i = e.textContent?.trim().slice(0, t) || "";
96
110
  return i.length === t ? i + "..." : i;
97
111
  }
98
- function At(e) {
112
+ function Vt(e) {
99
113
  let t = 1, i = e.previousElementSibling;
100
114
  for (; i; )
101
115
  t++, i = i.previousElementSibling;
102
116
  return t;
103
117
  }
104
- function Dt(e) {
118
+ function _t(e) {
105
119
  const t = [];
106
120
  let i = e;
107
121
  for (; i && i !== document.body && i !== document.documentElement; ) {
108
- const o = i.tagName.toLowerCase(), n = At(i);
122
+ const o = i.tagName.toLowerCase(), n = Vt(i);
109
123
  t.unshift(`${o}:nth-child(${n})`), i = i.parentElement;
110
124
  }
111
125
  return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
112
126
  }
113
- function Mt(e) {
127
+ function Kt(e) {
114
128
  return e.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
115
129
  }
116
- function Rt(e) {
117
- const t = J(e);
118
- return t ? `[${t}]` : e.id ? `#${Mt(e.id)}` : Dt(e);
130
+ function jt(e) {
131
+ const t = it(e);
132
+ return t ? `[${t}]` : e.id ? `#${Kt(e.id)}` : _t(e);
119
133
  }
120
- function D(e) {
121
- const t = It(e), i = J(e);
122
- return { selector: Rt(e), text: t, dataAttr: i };
134
+ function R(e) {
135
+ const t = Ft(e), i = it(e);
136
+ return { selector: jt(e), text: t, dataAttr: i };
123
137
  }
124
- const Ht = [
138
+ const Wt = [
125
139
  "a[href]",
126
140
  "button",
127
141
  "input:not([type=hidden])",
@@ -140,9 +154,9 @@ const Ht = [
140
154
  "p",
141
155
  "li",
142
156
  "label",
143
- ...G.map((e) => `[${e}]`)
144
- ].join(","), Bt = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
145
- function Pt(e) {
157
+ ...et.map((e) => `[${e}]`)
158
+ ].join(","), Xt = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
159
+ function Yt(e) {
146
160
  if (e.hasAttribute("hidden") || e.getAttribute("aria-hidden") === "true") return !1;
147
161
  const t = e.ownerDocument?.defaultView;
148
162
  if (t && typeof t.getComputedStyle == "function") {
@@ -151,14 +165,14 @@ function Pt(e) {
151
165
  }
152
166
  return !0;
153
167
  }
154
- function zt(e = {}) {
155
- const t = e.root ?? document.body, i = e.selector ?? Ht, o = e.isExcluded ?? (() => !1), n = e.isVisible ?? Pt;
168
+ function Qt(e = {}) {
169
+ const t = e.root ?? document.body, i = e.selector ?? Wt, o = e.isExcluded ?? (() => !1), n = e.isVisible ?? Yt;
156
170
  return Array.from(t.querySelectorAll(i)).filter(
157
171
  (s) => !o(s) && n(s)
158
172
  );
159
173
  }
160
- function Ot(e) {
161
- const t = e.candidates ?? zt({
174
+ function Gt(e) {
175
+ const t = e.candidates ?? Qt({
162
176
  root: e.root,
163
177
  selector: e.selector,
164
178
  isExcluded: e.isExcluded,
@@ -171,11 +185,11 @@ function Ot(e) {
171
185
  h >= 0 && (s = h);
172
186
  }
173
187
  s < 0 && t.length > 0 && (s = 0);
174
- function l(h) {
188
+ function c(h) {
175
189
  if (!i) return;
176
190
  const w = h;
177
191
  if (typeof w.focus == "function") {
178
- h.getAttribute("tabindex") === null && !Bt.test(h.tagName) && (h.setAttribute("tabindex", "-1"), n.add(h));
192
+ h.getAttribute("tabindex") === null && !Xt.test(h.tagName) && (h.setAttribute("tabindex", "-1"), n.add(h));
179
193
  try {
180
194
  w.focus();
181
195
  } catch {
@@ -184,34 +198,34 @@ function Ot(e) {
184
198
  }
185
199
  function r() {
186
200
  const h = t[s];
187
- h && (l(h), e.onHighlight?.(h, s));
201
+ h && (c(h), e.onHighlight?.(h, s));
188
202
  }
189
- function c(h) {
203
+ function l(h) {
190
204
  if (a || t.length === 0) return;
191
205
  const w = t.length;
192
206
  s = (h % w + w) % w, r();
193
207
  }
194
208
  function p() {
195
- c(s + 1);
209
+ l(s + 1);
196
210
  }
197
211
  function u() {
198
- c(s - 1);
212
+ l(s - 1);
199
213
  }
200
- function m() {
214
+ function f() {
201
215
  return t[s] ?? null;
202
216
  }
203
217
  function b() {
204
- a || (a = !0, o.removeEventListener("keydown", f, !0), n.forEach((h) => h.removeAttribute("tabindex")), n.clear());
218
+ a || (a = !0, o.removeEventListener("keydown", m, !0), n.forEach((h) => h.removeAttribute("tabindex")), n.clear());
205
219
  }
206
220
  function v() {
207
221
  if (a) return;
208
- const h = m();
222
+ const h = f();
209
223
  b(), h && e.onSelect(h);
210
224
  }
211
225
  function y() {
212
226
  a || (b(), e.onCancel?.());
213
227
  }
214
- function f(h) {
228
+ function m(h) {
215
229
  if (!a)
216
230
  switch (h.key) {
217
231
  case "Tab":
@@ -236,20 +250,20 @@ function Ot(e) {
236
250
  break;
237
251
  }
238
252
  }
239
- return o.addEventListener("keydown", f, !0), s >= 0 && r(), {
253
+ return o.addEventListener("keydown", m, !0), s >= 0 && r(), {
240
254
  candidates: t,
241
255
  getIndex: () => s,
242
- getCurrent: m,
256
+ getCurrent: f,
243
257
  next: p,
244
258
  prev: u,
245
- moveTo: c,
259
+ moveTo: l,
246
260
  select: v,
247
261
  cancel: y,
248
- handleKey: f,
262
+ handleKey: m,
249
263
  stop: b
250
264
  };
251
265
  }
252
- const F = "data-qaid-a11y-live", $t = "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;", Nt = [
266
+ const K = "data-qaid-a11y-live", Jt = "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;", Zt = [
253
267
  "a[href]",
254
268
  "button",
255
269
  "input",
@@ -257,25 +271,25 @@ const F = "data-qaid-a11y-live", $t = "position:absolute;width:1px;height:1px;ma
257
271
  "select",
258
272
  "[tabindex]"
259
273
  ].join(",");
260
- function Ft(e) {
274
+ function te(e) {
261
275
  return e.ownerDocument || document;
262
276
  }
263
- function Vt(e, t) {
277
+ function ee(e, t) {
264
278
  const i = t ? "assertive" : "polite", o = e.querySelector(
265
- `[${F}="${i}"]`
279
+ `[${K}="${i}"]`
266
280
  );
267
281
  if (o) return o;
268
- const s = Ft(e).createElement("div");
269
- return s.setAttribute(F, i), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = $t, e.appendChild(s), s;
282
+ const s = te(e).createElement("div");
283
+ return s.setAttribute(K, i), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = Jt, e.appendChild(s), s;
270
284
  }
271
- function Ut(e, t, i = {}) {
272
- const o = Vt(e, !!i.assertive);
285
+ function ie(e, t, i = {}) {
286
+ const o = ee(e, !!i.assertive);
273
287
  o.textContent = "", o.textContent = t;
274
288
  }
275
- function _t(e) {
289
+ function oe(e) {
276
290
  return e.hasAttribute("disabled") ? !0 : e.disabled === !0;
277
291
  }
278
- function Kt(e) {
292
+ function ne(e) {
279
293
  let t = e;
280
294
  for (; t; ) {
281
295
  if (t.hasAttribute("hidden")) return !0;
@@ -286,52 +300,52 @@ function Kt(e) {
286
300
  }
287
301
  return !1;
288
302
  }
289
- function V(e) {
303
+ function j(e) {
290
304
  return Array.from(
291
- e.querySelectorAll(Nt)
292
- ).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") || _t(i) || Kt(i)));
305
+ e.querySelectorAll(Zt)
306
+ ).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") || oe(i) || ne(i)));
293
307
  }
294
- function Z(e) {
308
+ function ot(e) {
295
309
  let t = e.activeElement;
296
310
  for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
297
311
  t = t.shadowRoot.activeElement;
298
312
  return t instanceof HTMLElement ? t : null;
299
313
  }
300
- function jt(e) {
314
+ function se(e) {
301
315
  const t = e.ownerDocument || document;
302
316
  let i = !1;
303
317
  const o = (s) => {
304
318
  if (s.key !== "Tab") return;
305
- const a = V(e);
319
+ const a = j(e);
306
320
  if (a.length === 0) {
307
321
  s.preventDefault(), e.focus();
308
322
  return;
309
323
  }
310
- const d = a[0], l = a[a.length - 1], r = Z(t), c = r ? a.indexOf(r) !== -1 : !1;
311
- s.shiftKey ? (!c || r === d) && (s.preventDefault(), l.focus()) : (!c || r === l) && (s.preventDefault(), d.focus());
324
+ const d = a[0], c = a[a.length - 1], r = ot(t), l = r ? a.indexOf(r) !== -1 : !1;
325
+ s.shiftKey ? (!l || r === d) && (s.preventDefault(), c.focus()) : (!l || r === c) && (s.preventDefault(), d.focus());
312
326
  };
313
327
  e.addEventListener("keydown", o);
314
- const n = V(e);
328
+ const n = j(e);
315
329
  return n.length > 0 ? n[0].focus() : (e.hasAttribute("tabindex") || (e.setAttribute("tabindex", "-1"), i = !0), e.focus()), {
316
330
  release() {
317
331
  e.removeEventListener("keydown", o), i && (e.removeAttribute("tabindex"), i = !1);
318
332
  }
319
333
  };
320
334
  }
321
- function Xt() {
322
- return Z(document);
335
+ function ae() {
336
+ return ot(document);
323
337
  }
324
- function Wt(e) {
338
+ function re(e) {
325
339
  if (!(!e || typeof e.focus != "function"))
326
340
  try {
327
341
  e.focus();
328
342
  } catch {
329
343
  }
330
344
  }
331
- function Yt(e, t = {}) {
345
+ function de(e, t = {}) {
332
346
  e.setAttribute("role", "dialog"), e.setAttribute("aria-modal", "true"), t.labelledbyId && e.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && e.setAttribute("aria-describedby", t.describedbyId), t.label && e.setAttribute("aria-label", t.label);
333
347
  }
334
- function Qt(e, t) {
348
+ function le(e, t) {
335
349
  let i = e;
336
350
  for (; i && i !== t; ) {
337
351
  const o = i.parentNode;
@@ -345,11 +359,11 @@ function Qt(e, t) {
345
359
  }
346
360
  return null;
347
361
  }
348
- function Gt(e) {
362
+ function ce(e) {
349
363
  const i = (e.ownerDocument || document).body;
350
364
  if (!i) return () => {
351
365
  };
352
- const o = Qt(e, i), n = [];
366
+ const o = le(e, i), n = [];
353
367
  return Array.from(i.children).forEach((s) => {
354
368
  if (!(s instanceof HTMLElement) || o && s === o) return;
355
369
  const a = s.inert === !0, d = s.getAttribute("aria-hidden");
@@ -361,14 +375,14 @@ function Gt(e) {
361
375
  }
362
376
  };
363
377
  }
364
- const tt = {
378
+ const nt = {
365
379
  width: 400,
366
380
  height: 280,
367
381
  arrowHeight: 12,
368
382
  gap: 8,
369
383
  viewportPadding: 16
370
384
  };
371
- function Jt(e, t, i, o, n) {
385
+ function he(e, t, i, o, n) {
372
386
  const s = e.y, a = t - (e.y + e.height);
373
387
  if (a >= i + o)
374
388
  return {
@@ -381,28 +395,28 @@ function Jt(e, t, i, o, n) {
381
395
  position: "above"
382
396
  };
383
397
  const d = a > s ? "below" : "above";
384
- let l;
385
- return d === "below" ? l = Math.min(
398
+ let c;
399
+ return d === "below" ? c = Math.min(
386
400
  e.y + e.height + o,
387
401
  t - i - n
388
- ) : l = Math.max(n, e.y - i - o), { top: l, position: d };
402
+ ) : c = Math.max(n, e.y - i - o), { top: c, position: d };
389
403
  }
390
- function Zt(e, t, i, o) {
404
+ function ue(e, t, i, o) {
391
405
  let s = e.x + e.width / 2 - i / 2;
392
406
  return s = Math.max(o, Math.min(s, t - i - o)), s;
393
407
  }
394
- function te(e, t, i, o = 24, n = 24) {
408
+ function pe(e, t, i, o = 24, n = 24) {
395
409
  const a = e.clickX - t - n / 2;
396
410
  return Math.max(o, Math.min(a, i - o - n / 2));
397
411
  }
398
- function ee(e, t, i, o = tt) {
399
- const n = o.height + o.arrowHeight, s = Jt(
412
+ function fe(e, t, i, o = nt) {
413
+ const n = o.height + o.arrowHeight, s = he(
400
414
  e,
401
415
  i,
402
416
  n,
403
417
  o.gap,
404
418
  o.viewportPadding
405
- ), a = Zt(
419
+ ), a = ue(
406
420
  e,
407
421
  t,
408
422
  o.width,
@@ -414,15 +428,15 @@ function ee(e, t, i, o = tt) {
414
428
  position: s.position
415
429
  };
416
430
  }
417
- function ie(e, t, i, o = {}) {
431
+ function me(e, t, i, o = {}) {
418
432
  const n = o.gap ?? 8;
419
433
  let s = e.bottom + n;
420
434
  s + t.height > i.height - n && (s = e.top - t.height - n);
421
435
  let a = e.left;
422
436
  return a < n ? a = n : a + t.width > i.width - n && (a = i.width - t.width - n), s < n ? s = n : s + t.height > i.height - n && (s = i.height - t.height - n), { top: s, left: a };
423
437
  }
424
- function oe(e, t, i, o = tt) {
425
- const n = ee(e, t, i, o), s = te(
438
+ function be(e, t, i, o = nt) {
439
+ const n = fe(e, t, i, o), s = pe(
426
440
  e,
427
441
  n.left,
428
442
  o.width
@@ -432,15 +446,15 @@ function oe(e, t, i, o = tt) {
432
446
  arrow: { left: s }
433
447
  };
434
448
  }
435
- const ne = 20;
436
- function se(e) {
449
+ const ge = 20;
450
+ function ve(e) {
437
451
  const t = [], i = console.error, o = console.warn, n = console.log, s = (a, d) => {
438
- const l = {
452
+ const c = {
439
453
  message: d.map((r) => String(r)).join(" "),
440
454
  timestamp: Date.now(),
441
455
  level: a
442
456
  };
443
- t.length >= ne && t.shift(), t.push(l), e && e(l);
457
+ t.length >= ge && t.shift(), t.push(c), e && e(c);
444
458
  };
445
459
  return console.error = function(...a) {
446
460
  s("error", a), i.apply(console, a);
@@ -455,38 +469,38 @@ function se(e) {
455
469
  }
456
470
  };
457
471
  }
458
- const ae = 20, U = 4096;
459
- function S(e) {
472
+ const ye = 20, W = 4096;
473
+ function T(e) {
460
474
  const t = typeof e == "string" ? e : JSON.stringify(e);
461
- return t.length > U ? t.slice(0, U) + "…[truncated]" : t;
475
+ return t.length > W ? t.slice(0, W) + "…[truncated]" : t;
462
476
  }
463
- function _(e, t) {
464
- e.length >= ae && e.shift(), e.push(t);
477
+ function X(e, t) {
478
+ e.length >= ye && e.shift(), e.push(t);
465
479
  }
466
- async function re(e) {
480
+ async function we(e) {
467
481
  try {
468
482
  const t = await e.clone().text();
469
- return S(t);
483
+ return T(t);
470
484
  } catch {
471
485
  return;
472
486
  }
473
487
  }
474
- function de() {
488
+ function qe() {
475
489
  const e = [], t = window.fetch;
476
490
  window.fetch = async function(n, s) {
477
491
  const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, d = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
478
- let l;
479
- s?.body && (l = S(s.body));
492
+ let c;
493
+ s?.body && (c = T(s.body));
480
494
  const r = await t.apply(window, [n, s]);
481
495
  if (r.status >= 400) {
482
- const c = await re(r);
483
- _(e, {
496
+ const l = await we(r);
497
+ X(e, {
484
498
  url: a,
485
499
  method: d.toUpperCase(),
486
500
  status: r.status,
487
501
  statusText: r.statusText,
488
- requestBody: l,
489
- responseBody: c,
502
+ requestBody: c,
503
+ responseBody: l,
490
504
  timestamp: Date.now()
491
505
  });
492
506
  }
@@ -496,15 +510,15 @@ function de() {
496
510
  return XMLHttpRequest.prototype.open = function(n, s, ...a) {
497
511
  return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), i.apply(this, [n, s, ...a]);
498
512
  }, XMLHttpRequest.prototype.send = function(n) {
499
- const s = this, a = n ? S(n) : void 0;
513
+ const s = this, a = n ? T(n) : void 0;
500
514
  return s.addEventListener("load", function() {
501
- s.status >= 400 && _(e, {
515
+ s.status >= 400 && X(e, {
502
516
  url: s._qaid_url,
503
517
  method: s._qaid_method.toUpperCase(),
504
518
  status: s.status,
505
519
  statusText: s.statusText,
506
520
  requestBody: a,
507
- responseBody: S(s.responseText),
521
+ responseBody: T(s.responseText),
508
522
  timestamp: Date.now()
509
523
  });
510
524
  }), o.apply(this, [n]);
@@ -515,27 +529,27 @@ function de() {
515
529
  }
516
530
  };
517
531
  }
518
- function ce() {
532
+ function xe() {
519
533
  const e = navigator.userAgent || "";
520
534
  return /iP(hone|ad|od)/.test(e) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
521
535
  navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
522
536
  }
523
- function le(e, t, i, o, n) {
537
+ function ke(e, t, i, o, n) {
524
538
  const s = e >= t, a = i >= o;
525
539
  return s === a ? { width: e, height: t, rotate: 0 } : { width: t, height: e, rotate: n === 270 ? -90 : 90 };
526
540
  }
527
- function he(e, t, i) {
541
+ function Ce(e, t, i) {
528
542
  if (i.rotate === 0) {
529
543
  e.drawImage(t, 0, 0, i.width, i.height);
530
544
  return;
531
545
  }
532
546
  e.save(), i.rotate === 90 ? (e.translate(i.width, 0), e.rotate(Math.PI / 2)) : (e.translate(0, i.height), e.rotate(-Math.PI / 2)), e.drawImage(t, 0, 0, i.height, i.width), e.restore();
533
547
  }
534
- function ue() {
548
+ function Ee() {
535
549
  const e = typeof screen < "u" ? screen.orientation : void 0;
536
550
  return e && typeof e.angle == "number" ? e.angle : 0;
537
551
  }
538
- function pe(e) {
552
+ function Se(e) {
539
553
  return new Promise((t) => {
540
554
  if (e.videoWidth > 0) {
541
555
  t();
@@ -544,44 +558,44 @@ function pe(e) {
544
558
  e.addEventListener("loadedmetadata", () => t(), { once: !0 });
545
559
  });
546
560
  }
547
- async function me(e) {
561
+ async function Te(e) {
548
562
  try {
549
563
  await e.play();
550
564
  } catch {
551
565
  }
552
566
  }
553
- async function fe(e, t = 15) {
567
+ async function Le(e, t = 15) {
554
568
  const i = document.createElement("canvas");
555
569
  if (typeof i.captureStream != "function") return null;
556
570
  const o = i.getContext("2d");
557
571
  if (!o) return null;
558
572
  const n = document.createElement("video");
559
- n.muted = !0, n.playsInline = !0, n.srcObject = e, await pe(n);
560
- const s = le(
573
+ n.muted = !0, n.playsInline = !0, n.srcObject = e, await Se(n);
574
+ const s = ke(
561
575
  n.videoWidth,
562
576
  n.videoHeight,
563
577
  window.innerWidth,
564
578
  window.innerHeight,
565
- ue()
579
+ Ee()
566
580
  );
567
- i.width = s.width, i.height = s.height, await me(n);
581
+ i.width = s.width, i.height = s.height, await Te(n);
568
582
  let a = 0;
569
583
  const d = () => {
570
- he(o, n, s), a = requestAnimationFrame(d);
584
+ Ce(o, n, s), a = requestAnimationFrame(d);
571
585
  };
572
586
  d();
573
- const l = i.captureStream(t);
587
+ const c = i.captureStream(t);
574
588
  return {
575
- stream: l,
589
+ stream: c,
576
590
  stop: () => {
577
- a && cancelAnimationFrame(a), a = 0, l.getTracks().forEach((r) => r.stop()), n.pause(), n.srcObject = null;
591
+ a && cancelAnimationFrame(a), a = 0, c.getTracks().forEach((r) => r.stop()), n.pause(), n.srcObject = null;
578
592
  }
579
593
  };
580
594
  }
581
- function be() {
595
+ function Ie() {
582
596
  return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
583
597
  }
584
- function ge() {
598
+ function Ae() {
585
599
  if (typeof MediaRecorder > "u") return "";
586
600
  const e = [
587
601
  "video/webm;codecs=vp9",
@@ -594,20 +608,20 @@ function ge() {
594
608
  return t;
595
609
  return "";
596
610
  }
597
- function ve(e = {}) {
611
+ function De(e = {}) {
598
612
  const t = e.maxDuration ?? 15, i = e.videoBitsPerSecond ?? 8e5;
599
- let o = null, n = null, s = null, a = [], d = null, l = null, r = null, c = 0, p = null, u = null, m = !1, b = null;
613
+ let o = null, n = null, s = null, a = [], d = null, c = null, r = null, l = 0, p = null, u = null, f = !1, b = null;
600
614
  function v() {
601
- r !== null && (clearInterval(r), r = null), b !== null && (clearTimeout(b), b = null), n && (n.stop(), n = null), o && (o.getTracks().forEach((f) => f.stop()), o = null), s = null, a = [], d = null, l = null, p = null, u = null;
615
+ r !== null && (clearInterval(r), r = null), b !== null && (clearTimeout(b), b = null), n && (n.stop(), n = null), o && (o.getTracks().forEach((m) => m.stop()), o = null), s = null, a = [], d = null, c = null, p = null, u = null;
602
616
  }
603
617
  function y() {
604
- m || (m = !0, s && s.state !== "inactive" && s.stop());
618
+ f || (f = !0, s && s.state !== "inactive" && s.stop());
605
619
  }
606
620
  return {
607
621
  async start() {
608
- m = !1, a = [];
609
- const f = ge();
610
- if (!f)
622
+ f = !1, a = [];
623
+ const m = Ae();
624
+ if (!m)
611
625
  throw new Error("No supported video MIME type found");
612
626
  o = await navigator.mediaDevices.getDisplayMedia({
613
627
  video: {
@@ -622,56 +636,63 @@ function ve(e = {}) {
622
636
  y();
623
637
  });
624
638
  let w = o;
625
- if (ce()) {
626
- const g = await fe(o);
639
+ if (xe()) {
640
+ const g = await Le(o);
627
641
  g && (n = g, w = g.stream);
628
642
  }
629
643
  s = new MediaRecorder(w, {
630
- mimeType: f,
644
+ mimeType: m,
631
645
  videoBitsPerSecond: i
632
646
  }), s.ondataavailable = (g) => {
633
647
  g.data.size > 0 && a.push(g.data);
634
648
  }, s.onstop = () => {
635
- const g = new Blob(a, { type: f });
636
- p && p(g), l && l(g), n && (n.stop(), n = null), o && o.getTracks().forEach((C) => C.stop());
649
+ const g = new Blob(a, { type: m });
650
+ p && p(g), c && c(g), n && (n.stop(), n = null), o && o.getTracks().forEach((S) => S.stop());
637
651
  }, s.onerror = () => {
638
652
  u && u(new Error("MediaRecorder error"));
639
- }, s.start(1e3), c = Date.now(), r = setInterval(() => {
640
- const g = Math.floor((Date.now() - c) / 1e3);
653
+ }, s.start(1e3), l = Date.now(), r = setInterval(() => {
654
+ const g = Math.floor((Date.now() - l) / 1e3);
641
655
  d && d(g);
642
656
  }, 1e3), b = setTimeout(() => {
643
657
  y();
644
658
  }, t * 1e3);
645
659
  },
646
660
  stop() {
647
- return new Promise((f, h) => {
648
- p = f, u = h, y();
661
+ return new Promise((m, h) => {
662
+ p = m, u = h, y();
649
663
  });
650
664
  },
651
- onTick(f) {
652
- d = f;
665
+ onTick(m) {
666
+ d = m;
653
667
  },
654
- onStop(f) {
655
- l = f;
668
+ onStop(m) {
669
+ c = m;
656
670
  },
657
671
  destroy() {
658
672
  y(), v();
659
673
  }
660
674
  };
661
675
  }
662
- function ye(e = 640) {
676
+ function q(e, t, i) {
677
+ const o = document.createElement(e);
678
+ if (t)
679
+ for (const [n, s] of Object.entries(t))
680
+ n === "className" ? o.className = s : o.setAttribute(n, s);
681
+ return o;
682
+ }
683
+ function Me(e = 640) {
663
684
  return typeof window < "u" && window.innerWidth < e;
664
685
  }
665
- function K(e, t, i) {
686
+ function Y(e, t, i) {
666
687
  const o = i.map((s) => s.style.visibility);
667
688
  i.forEach((s) => s.style.visibility = "hidden");
668
689
  const n = document.elementFromPoint(e, t);
669
690
  return i.forEach((s, a) => s.style.visibility = o[a]), n;
670
691
  }
671
- function M(e) {
692
+ function B(e) {
672
693
  return e ? e.hasAttribute("data-qaid-embed") || e.hasAttribute("data-qaid-embed-overlay") ? !0 : !!e.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
673
694
  }
674
- function j(e, t = 0) {
695
+ function Q(e, t = 0) {
675
696
  const i = e.getBoundingClientRect();
676
697
  return {
677
698
  x: i.left - t,
@@ -680,7 +701,7 @@ function j(e, t = 0) {
680
701
  height: i.height + t * 2
681
702
  };
682
703
  }
683
- async function we(e = {}) {
704
+ async function Re(e = {}) {
684
705
  const { quality: t = 1, maxWidth: i = 1280, maxHeight: o = 800 } = e;
685
706
  try {
686
707
  if (!navigator.mediaDevices?.getDisplayMedia)
@@ -701,48 +722,48 @@ async function we(e = {}) {
701
722
  };
702
723
  y();
703
724
  }), await new Promise((v) => setTimeout(v, 100));
704
- const l = a.width || d.videoWidth, r = a.height || d.videoHeight, c = Math.min(i / l, o / r, 1), p = Math.round(l * c), u = Math.round(r * c), m = document.createElement("canvas");
705
- m.width = p, m.height = u;
706
- const b = m.getContext("2d");
707
- return b ? (b.drawImage(d, 0, 0, p, u), s.stop(), m.toDataURL("image/webp", t)) : (s.stop(), null);
725
+ const c = a.width || d.videoWidth, r = a.height || d.videoHeight, l = Math.min(i / c, o / r, 1), p = Math.round(c * l), u = Math.round(r * l), f = document.createElement("canvas");
726
+ f.width = p, f.height = u;
727
+ const b = f.getContext("2d");
728
+ return b ? (b.drawImage(d, 0, 0, p, u), s.stop(), f.toDataURL("image/webp", t)) : (s.stop(), null);
708
729
  } catch (n) {
709
730
  return console.warn("Screenshot capture failed:", n), null;
710
731
  }
711
732
  }
712
- const X = "https://qaid.dev/lib/html2canvas.min.js", xe = 1e4, qe = 50;
713
- let x = null;
714
- function Pe() {
733
+ const G = "https://qaid.dev/lib/html2canvas.min.js", Be = 1e4, He = 50;
734
+ let k = null;
735
+ function li() {
715
736
  if (typeof document > "u" || typeof window > "u")
716
737
  return !1;
717
738
  const e = document.createElement("canvas");
718
739
  return typeof e.getContext == "function" && !!e.getContext("2d");
719
740
  }
720
- function ke() {
721
- return window.html2canvas ? Promise.resolve(!0) : x || (x = new Promise((e) => {
741
+ function Pe() {
742
+ return window.html2canvas ? Promise.resolve(!0) : k || (k = new Promise((e) => {
722
743
  if (!document.querySelector(
723
- `script[src="${X}"]`
744
+ `script[src="${G}"]`
724
745
  )) {
725
746
  const n = document.createElement("script");
726
- n.src = X, n.async = !0, document.head.appendChild(n);
747
+ n.src = G, n.async = !0, document.head.appendChild(n);
727
748
  }
728
749
  const i = Date.now(), o = () => {
729
750
  if (window.html2canvas) {
730
751
  e(!0);
731
752
  return;
732
753
  }
733
- if (Date.now() - i > xe) {
734
- x = null, e(!1);
754
+ if (Date.now() - i > Be) {
755
+ k = null, e(!1);
735
756
  return;
736
757
  }
737
- setTimeout(o, qe);
758
+ setTimeout(o, He);
738
759
  };
739
760
  o();
740
- }), x);
761
+ }), k);
741
762
  }
742
- async function Ce(e = {}) {
763
+ async function Oe(e = {}) {
743
764
  const { quality: t = 0.8, maxWidth: i = 1280, maxHeight: o = 800 } = e;
744
765
  try {
745
- if (!await ke() || !window.html2canvas)
766
+ if (!await Pe() || !window.html2canvas)
746
767
  return console.warn("html2canvas failed to load"), null;
747
768
  const s = await window.html2canvas(document.body, {
748
769
  useCORS: !0,
@@ -755,19 +776,313 @@ async function Ce(e = {}) {
755
776
  x: window.scrollX,
756
777
  y: window.scrollY,
757
778
  ignoreElements: (r) => r instanceof HTMLElement ? r.classList.contains("qaid-buttons") || r.classList.contains("qaid-targeting-overlay") || r.classList.contains("qaid-modal-container") || r.classList.contains("qaid-bottom-sheet") || r.classList.contains("qaid-backdrop") || r.classList.contains("qaid-selected-marker") || r.classList.contains("qaid-tooltip-text") || r.classList.contains("qaid-recording-indicator") || r.classList.contains("qaid-video-preview") || r.className?.toString().startsWith?.("qaid-") : !1
758
- }), a = s.width, d = s.height, l = Math.min(i / a, o / d, 1);
759
- if (l < 1) {
760
- const r = Math.round(a * l), c = Math.round(d * l), p = document.createElement("canvas");
761
- p.width = r, p.height = c;
779
+ }), a = s.width, d = s.height, c = Math.min(i / a, o / d, 1);
780
+ if (c < 1) {
781
+ const r = Math.round(a * c), l = Math.round(d * c), p = document.createElement("canvas");
782
+ p.width = r, p.height = l;
762
783
  const u = p.getContext("2d");
763
- return u ? (u.drawImage(s, 0, 0, r, c), p.toDataURL("image/webp", t)) : null;
784
+ return u ? (u.drawImage(s, 0, 0, r, l), p.toDataURL("image/webp", t)) : null;
764
785
  }
765
786
  return s.toDataURL("image/webp", t);
766
787
  } catch (n) {
767
788
  return console.warn("DOM screenshot capture failed:", n), null;
768
789
  }
769
790
  }
770
- const Se = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Ee = (e) => (
791
+ const x = 12, ze = "#ef4444", $e = 4, Ne = 0.8, Ue = {
792
+ title: "Annotate screenshot",
793
+ instructions: "Draw on the screenshot to highlight or hide details, then choose Done to attach it or Skip to send the original.",
794
+ rectangle: "Rectangle",
795
+ arrow: "Arrow",
796
+ pen: "Pen",
797
+ blur: "Blur or redact",
798
+ undo: "Undo last",
799
+ skip: "Skip annotation",
800
+ done: "Done"
801
+ };
802
+ function P(e, t) {
803
+ return {
804
+ x: Math.min(e.x, t.x),
805
+ y: Math.min(e.y, t.y),
806
+ w: Math.abs(e.x - t.x),
807
+ h: Math.abs(e.y - t.y)
808
+ };
809
+ }
810
+ function Fe(e) {
811
+ if (e.type === "pen") return e.points.length < 2;
812
+ const t = P(e.points[0], e.points[1]);
813
+ return t.w < 3 && t.h < 3;
814
+ }
815
+ function Ve(e, t, i, o) {
816
+ e.beginPath(), e.moveTo(t.x, t.y), e.lineTo(i.x, i.y), e.stroke();
817
+ const n = Math.atan2(i.y - t.y, i.x - t.x), s = Math.max(10, o * 3);
818
+ e.beginPath(), e.moveTo(i.x, i.y), e.lineTo(
819
+ i.x - s * Math.cos(n - Math.PI / 6),
820
+ i.y - s * Math.sin(n - Math.PI / 6)
821
+ ), e.moveTo(i.x, i.y), e.lineTo(
822
+ i.x - s * Math.cos(n + Math.PI / 6),
823
+ i.y - s * Math.sin(n + Math.PI / 6)
824
+ ), e.stroke();
825
+ }
826
+ function _e(e, t) {
827
+ if (t.length !== 0) {
828
+ e.beginPath(), e.moveTo(t[0].x, t[0].y);
829
+ for (let i = 1; i < t.length; i++)
830
+ e.lineTo(t[i].x, t[i].y);
831
+ e.stroke();
832
+ }
833
+ }
834
+ function Ke(e, t, i, o, n) {
835
+ e.fillStyle = "rgb(15, 23, 42)", e.fillRect(t, i, o, n), e.fillStyle = "rgb(37, 47, 63)";
836
+ for (let s = i; s < i + n; s += x)
837
+ for (let a = t; a < t + o; a += x)
838
+ (Math.floor((a - t) / x) + Math.floor((s - i) / x)) % 2 === 0 && e.fillRect(
839
+ a,
840
+ s,
841
+ Math.min(x, t + o - a),
842
+ Math.min(x, i + n - s)
843
+ );
844
+ }
845
+ function O(e, t) {
846
+ switch (e.save(), e.strokeStyle = t.color, e.fillStyle = t.color, e.lineWidth = t.strokeWidth, e.lineJoin = "round", e.lineCap = "round", t.type) {
847
+ case "rect": {
848
+ const i = P(t.points[0], t.points[1]);
849
+ e.strokeRect(i.x, i.y, i.w, i.h);
850
+ break;
851
+ }
852
+ case "arrow":
853
+ Ve(e, t.points[0], t.points[1], t.strokeWidth);
854
+ break;
855
+ case "pen":
856
+ _e(e, t.points);
857
+ break;
858
+ case "blur": {
859
+ const i = P(t.points[0], t.points[1]);
860
+ Ke(e, i.x, i.y, i.w, i.h);
861
+ break;
862
+ }
863
+ }
864
+ e.restore();
865
+ }
866
+ function st(e) {
867
+ return new Promise((t, i) => {
868
+ const o = new Image();
869
+ o.onload = () => t(o), o.onerror = () => i(new Error("Failed to load screenshot")), o.src = e;
870
+ });
871
+ }
872
+ async function je(e, t, i = {}) {
873
+ const o = i.quality ?? Ne;
874
+ let n;
875
+ try {
876
+ n = await st(e);
877
+ } catch {
878
+ return e;
879
+ }
880
+ const s = document.createElement("canvas");
881
+ s.width = n.naturalWidth || n.width || 1, s.height = n.naturalHeight || n.height || 1;
882
+ const a = s.getContext("2d");
883
+ if (!a) return e;
884
+ a.drawImage(n, 0, 0, s.width, s.height);
885
+ for (const d of t)
886
+ O(a, d);
887
+ return s.toDataURL("image/webp", o);
888
+ }
889
+ let We = 0;
890
+ class Xe {
891
+ shapes = [];
892
+ tool = "rect";
893
+ opts;
894
+ labels;
895
+ color;
896
+ strokeWidth;
897
+ uid = `qaid-annotate-${++We}`;
898
+ container;
899
+ canvas;
900
+ ctx = null;
901
+ toolbar;
902
+ undoBtn;
903
+ img = null;
904
+ drawing = !1;
905
+ current = null;
906
+ settled = !1;
907
+ // Assigned in open() before any settle() is reachable (done/skip only fire
908
+ // after the editor is mounted).
909
+ resolveResult;
910
+ constructor(t) {
911
+ this.opts = t, this.labels = { ...Ue, ...t.labels ?? {} }, this.color = t.color ?? ze, this.strokeWidth = t.strokeWidth ?? $e;
912
+ }
913
+ /** Mount the editor and resolve when the user commits (Done) or skips. */
914
+ open() {
915
+ const t = new Promise((i) => {
916
+ this.resolveResult = i;
917
+ });
918
+ return this.mount(), t;
919
+ }
920
+ toolButton(t, i, o) {
921
+ const n = q("button", {
922
+ type: "button",
923
+ class: "qaid-annotate-tool",
924
+ "data-qaid-tool": t,
925
+ "aria-pressed": t === this.tool ? "true" : "false",
926
+ "aria-label": `${o} tool`,
927
+ title: o
928
+ });
929
+ return n.innerHTML = i, n;
930
+ }
931
+ actionButton(t, i, o, n) {
932
+ const s = q("button", {
933
+ type: "button",
934
+ class: `qaid-annotate-action ${n}`,
935
+ "data-qaid-action": t,
936
+ "aria-label": o,
937
+ title: o
938
+ });
939
+ return s.innerHTML = `${i}<span class="qaid-annotate-btn-text">${o}</span>`, s;
940
+ }
941
+ mount() {
942
+ const t = `${this.uid}-title`, i = `${this.uid}-desc`;
943
+ this.container = q("div", { class: "qaid-annotate" }), this.opts.applyVars?.(this.container);
944
+ const o = q("h2", {
945
+ id: t,
946
+ class: "qaid-annotate-title"
947
+ });
948
+ o.textContent = this.labels.title;
949
+ const n = q("p", {
950
+ id: i,
951
+ class: "qaid-annotate-desc"
952
+ });
953
+ n.textContent = this.labels.instructions;
954
+ const s = q("div", { class: "qaid-annotate-stage" });
955
+ this.canvas = document.createElement("canvas"), this.canvas.className = "qaid-annotate-canvas", this.canvas.width = 1, this.canvas.height = 1, this.canvas.setAttribute("role", "img"), this.canvas.setAttribute("aria-label", this.labels.title), this.ctx = this.canvas.getContext("2d"), s.appendChild(this.canvas), this.toolbar = q("div", {
956
+ class: "qaid-annotate-toolbar",
957
+ role: "toolbar",
958
+ "aria-label": this.labels.title
959
+ });
960
+ const a = q("div", { class: "qaid-annotate-tools" });
961
+ a.appendChild(this.toolButton("rect", kt, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", Ct, this.labels.arrow)), a.appendChild(this.toolButton("pen", Et, this.labels.pen)), a.appendChild(this.toolButton("blur", St, this.labels.blur)), this.undoBtn = this.actionButton("undo", Tt, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
962
+ const d = this.actionButton("skip", It, this.labels.skip, "qaid-annotate-skip"), c = this.actionButton("done", Lt, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
963
+ r.appendChild(this.undoBtn), r.appendChild(d), r.appendChild(c), this.toolbar.appendChild(a), 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, {
964
+ labelledbyId: t,
965
+ describedbyId: i
966
+ }), this.opts.announce?.(this.labels.instructions), st(this.opts.dataUrl).then((l) => {
967
+ this.img = l, this.canvas.width = l.naturalWidth || l.width || 1, this.canvas.height = l.naturalHeight || l.height || 1, this.redraw();
968
+ }).catch(() => {
969
+ this.img = null, this.redraw();
970
+ });
971
+ }
972
+ /** Convert a pointer event's client coordinates into natural image pixels. */
973
+ toImageCoords(t) {
974
+ const i = this.canvas.getBoundingClientRect(), o = this.canvas.width / (i.width || this.canvas.width), n = this.canvas.height / (i.height || this.canvas.height);
975
+ return {
976
+ x: (t.clientX - i.left) * o,
977
+ y: (t.clientY - i.top) * n
978
+ };
979
+ }
980
+ /** Repaint the display canvas: base image (if loaded) then every shape. */
981
+ redraw() {
982
+ const t = this.ctx;
983
+ if (t) {
984
+ t.clearRect(0, 0, this.canvas.width, this.canvas.height), this.img && t.drawImage(this.img, 0, 0, this.canvas.width, this.canvas.height);
985
+ for (const i of this.shapes)
986
+ O(t, i);
987
+ this.current && O(t, this.current);
988
+ }
989
+ }
990
+ /** Select the active drawing tool and reflect it on the toolbar. */
991
+ selectTool(t) {
992
+ this.tool = t, this.toolbar.querySelectorAll("[data-qaid-tool]").forEach((n) => {
993
+ n.setAttribute(
994
+ "aria-pressed",
995
+ n.getAttribute("data-qaid-tool") === t ? "true" : "false"
996
+ );
997
+ });
998
+ const o = this.labels[Ye[t]];
999
+ this.opts.announce?.(`${o} tool selected`);
1000
+ }
1001
+ onToolbarClick = (t) => {
1002
+ const o = t.target?.closest("[data-qaid-tool],[data-qaid-action]");
1003
+ if (!o) return;
1004
+ const n = o.getAttribute("data-qaid-tool");
1005
+ if (n) {
1006
+ this.selectTool(n);
1007
+ return;
1008
+ }
1009
+ const s = o.getAttribute("data-qaid-action");
1010
+ s === "undo" ? this.undo() : s === "skip" ? this.skip() : s === "done" && this.done();
1011
+ };
1012
+ onPointerDown = (t) => {
1013
+ t.preventDefault?.(), this.drawing = !0;
1014
+ const i = this.toImageCoords(t);
1015
+ this.current = {
1016
+ type: this.tool,
1017
+ color: this.color,
1018
+ strokeWidth: this.strokeWidth,
1019
+ points: this.tool === "pen" ? [i] : [i, { ...i }]
1020
+ }, this.redraw();
1021
+ };
1022
+ onPointerMove = (t) => {
1023
+ if (!this.drawing || !this.current) return;
1024
+ const i = this.toImageCoords(t);
1025
+ this.current.type === "pen" ? this.current.points.push(i) : this.current.points[1] = i, this.redraw();
1026
+ };
1027
+ onPointerUp = () => {
1028
+ if (!this.drawing || !this.current) return;
1029
+ this.drawing = !1;
1030
+ const t = this.current;
1031
+ if (this.current = null, Fe(t)) {
1032
+ this.redraw();
1033
+ return;
1034
+ }
1035
+ this.shapes.push(t), this.undoBtn.disabled = !1, this.opts.announce?.("Annotation added"), this.redraw();
1036
+ };
1037
+ onKeyDown = (t) => {
1038
+ if (t.key === "Escape") {
1039
+ t.preventDefault(), this.skip();
1040
+ return;
1041
+ }
1042
+ if (t.key === "Enter") {
1043
+ const i = t.target;
1044
+ if (i?.getAttribute("data-qaid-tool") || i?.getAttribute("data-qaid-action"))
1045
+ return;
1046
+ t.preventDefault(), this.done();
1047
+ }
1048
+ };
1049
+ /** Remove the most recently added shape. */
1050
+ undo() {
1051
+ if (this.shapes.length === 0) {
1052
+ this.opts.announce?.("Nothing to undo");
1053
+ return;
1054
+ }
1055
+ this.shapes.pop(), this.undoBtn.disabled = this.shapes.length === 0, this.opts.announce?.("Removed last annotation"), this.redraw();
1056
+ }
1057
+ /** Composite the annotations and resolve with the new WebP data URL. */
1058
+ async done() {
1059
+ if (this.settled) return;
1060
+ const t = await je(this.opts.dataUrl, this.shapes, {
1061
+ quality: this.opts.quality
1062
+ });
1063
+ this.opts.announce?.("Annotated screenshot attached"), this.settle(t);
1064
+ }
1065
+ /** Discard annotations and resolve with `null` (caller keeps the original). */
1066
+ skip() {
1067
+ this.settled || (this.opts.announce?.("Annotation skipped"), this.settle(null));
1068
+ }
1069
+ settle(t) {
1070
+ this.settled = !0, this.teardown(), this.resolveResult(t);
1071
+ }
1072
+ teardown() {
1073
+ 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();
1074
+ }
1075
+ }
1076
+ const Ye = {
1077
+ rect: "rectangle",
1078
+ arrow: "arrow",
1079
+ pen: "pen",
1080
+ blur: "blur"
1081
+ };
1082
+ function Qe(e) {
1083
+ return new Xe(e).open();
1084
+ }
1085
+ const Ge = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Je = (e) => (
771
1086
  // The URL is a runtime value, not a static specifier — keep Vite from
772
1087
  // trying to analyze/bundle it.
773
1088
  import(
@@ -775,19 +1090,19 @@ const Se = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Ee =
775
1090
  e
776
1091
  )
777
1092
  );
778
- let Te = Ee, q = null, R = null;
779
- function Le(e) {
780
- return q && R === e || (R = e, q = Promise.resolve(Te(e)).then((t) => {
1093
+ let Ze = Je, C = null, H = null;
1094
+ function ti(e) {
1095
+ return C && H === e || (H = e, C = Promise.resolve(Ze(e)).then((t) => {
781
1096
  const i = t;
782
1097
  if (!i || typeof i.QaidQuests != "function")
783
1098
  throw new Error("quests module has no QaidQuests export");
784
1099
  return i;
785
1100
  }).catch((t) => {
786
- throw q = null, R = null, t;
787
- })), q;
1101
+ throw C = null, H = null, t;
1102
+ })), C;
788
1103
  }
789
- async function Ie(e) {
790
- const t = await Le(e.moduleUrl), i = e.base.replace(/\/+$/, ""), o = e.feedbackId != null ? { feedbackId: e.feedbackId } : void 0;
1104
+ async function ei(e) {
1105
+ const t = await ti(e.moduleUrl), i = e.base.replace(/\/+$/, ""), o = e.feedbackId != null ? { feedbackId: e.feedbackId } : void 0;
791
1106
  return new t.QaidQuests({
792
1107
  endpoint: `${i}/responses`,
793
1108
  configUrl: `${i}/${encodeURIComponent(e.questId)}/definition`,
@@ -796,32 +1111,35 @@ async function Ie(e) {
796
1111
  onClose: e.onClose
797
1112
  });
798
1113
  }
799
- const W = "qaid_visitor_id", Y = "qaid_hide_feedback", Ae = 12;
800
- function H(e) {
801
- return e ? `${Y}_${e}` : Y;
1114
+ const J = "qaid_visitor_id", Z = "qaid_hide_feedback", ii = 12;
1115
+ function oi() {
1116
+ return typeof window.matchMedia == "function" && window.matchMedia("(pointer: coarse)").matches;
802
1117
  }
803
- function De(e) {
1118
+ function z(e) {
1119
+ return e ? `${Z}_${e}` : Z;
1120
+ }
1121
+ function ni(e) {
804
1122
  try {
805
- return localStorage.getItem(H(e)) === "1";
1123
+ return localStorage.getItem(z(e)) === "1";
806
1124
  } catch {
807
1125
  return !1;
808
1126
  }
809
1127
  }
810
- function Q(e, t = !0) {
1128
+ function tt(e, t = !0) {
811
1129
  try {
812
- t ? localStorage.setItem(H(e), "1") : localStorage.removeItem(H(e));
1130
+ t ? localStorage.setItem(z(e), "1") : localStorage.removeItem(z(e));
813
1131
  } catch {
814
1132
  }
815
1133
  }
816
- function Me() {
1134
+ function si() {
817
1135
  try {
818
- let e = localStorage.getItem(W);
819
- return e || (e = crypto.randomUUID(), localStorage.setItem(W, e)), e;
1136
+ let e = localStorage.getItem(J);
1137
+ return e || (e = crypto.randomUUID(), localStorage.setItem(J, e)), e;
820
1138
  } catch {
821
1139
  return crypto.randomUUID();
822
1140
  }
823
1141
  }
824
- class Re {
1142
+ class ai {
825
1143
  config;
826
1144
  state = "IDLE";
827
1145
  feedbackData = {
@@ -943,6 +1261,7 @@ class Re {
943
1261
  fontFamily: t.fontFamily ?? "system-ui, -apple-system, sans-serif",
944
1262
  fontSize: t.fontSize ?? 16,
945
1263
  captureScreenshot: t.captureScreenshot ?? !1,
1264
+ annotate: t.annotate ?? !0,
946
1265
  screenshotMethod: t.screenshotMethod ?? "permission",
947
1266
  screenshotOptions: {
948
1267
  quality: t.screenshotOptions?.quality ?? 0.8,
@@ -967,12 +1286,12 @@ class Re {
967
1286
  video: t.quests?.video ?? "",
968
1287
  // Quest service reuses the feedback API key unless overridden.
969
1288
  apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
970
- moduleUrl: t.quests?.moduleUrl ?? Se
1289
+ moduleUrl: t.quests?.moduleUrl ?? Ge
971
1290
  }
972
- }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundMouseMove = this.handleMouseMove.bind(this), this.boundClick = this.handleClick.bind(this), this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = Me(), this.init();
1291
+ }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundMouseMove = this.handleMouseMove.bind(this), this.boundClick = this.handleClick.bind(this), this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = si(), this.init();
973
1292
  }
974
1293
  applyVars(t) {
975
- Et(t, this.cssVars);
1294
+ $t(t, this.cssVars);
976
1295
  }
977
1296
  /**
978
1297
  * Announce a message via the shared visually-hidden live regions.
@@ -982,7 +1301,7 @@ class Re {
982
1301
  */
983
1302
  announceMsg(t, i = !1) {
984
1303
  const o = this.overlayShadowRoot ?? this.shadowRoot;
985
- o && Ut(o, t, { assertive: i });
1304
+ o && ie(o, t, { assertive: i });
986
1305
  }
987
1306
  /**
988
1307
  * Turn a transient surface into an accessible modal dialog: save the
@@ -990,16 +1309,16 @@ class Re {
990
1309
  * background. Paired with closeDialogA11y() on every close path.
991
1310
  */
992
1311
  openDialogA11y(t, i) {
993
- this.dialogTrigger = Xt(), Yt(t, i), this.dialogTrap = jt(t), this.dialogRestoreInert = Gt(t);
1312
+ this.dialogTrigger = ae(), de(t, i), this.dialogTrap = se(t), this.dialogRestoreInert = ce(t);
994
1313
  }
995
1314
  closeDialogA11y() {
996
- this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), Wt(this.dialogTrigger), this.dialogTrigger = null;
1315
+ this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), re(this.dialogTrigger), this.dialogTrigger = null;
997
1316
  }
998
1317
  clearActiveThumb() {
999
1318
  this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
1000
1319
  }
1001
1320
  init() {
1002
- Tt(), this.cssVars = St({
1321
+ Nt(), this.cssVars = zt({
1003
1322
  positiveColor: this.config.colors.positive,
1004
1323
  negativeColor: this.config.colors.negative,
1005
1324
  markerColor: this.config.colors.marker,
@@ -1008,7 +1327,7 @@ class Re {
1008
1327
  backdropOpacity: this.config.backdropOpacity,
1009
1328
  fontFamily: this.config.fontFamily,
1010
1329
  fontSize: this.config.fontSize
1011
- }), !this.config.hideDismiss && De(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = se((t) => {
1330
+ }), !this.config.hideDismiss && ni(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = ve((t) => {
1012
1331
  this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
1013
1332
  }), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom();
1014
1333
  }
@@ -1031,7 +1350,7 @@ class Re {
1031
1350
  }), this.domObserver.observe(document.body, { childList: !0 });
1032
1351
  }
1033
1352
  checkMobile() {
1034
- this.isMobile = ye();
1353
+ this.isMobile = Me();
1035
1354
  }
1036
1355
  handleResize() {
1037
1356
  this.checkMobile();
@@ -1041,7 +1360,7 @@ class Re {
1041
1360
  let t = null;
1042
1361
  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" });
1043
1362
  const i = document.createElement("style");
1044
- if (i.textContent = N(), this.shadowRoot.appendChild(i), this.config.css) {
1363
+ if (i.textContent = _(), this.shadowRoot.appendChild(i), this.config.css) {
1045
1364
  const r = document.createElement("style");
1046
1365
  r.textContent = this.config.css, this.shadowRoot.appendChild(r);
1047
1366
  }
@@ -1050,8 +1369,8 @@ class Re {
1050
1369
  this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-${this.config.position} ${o}`.trim(), this.config.incognito && this.buttonsContainer.classList.add("qaid-incognito");
1051
1370
  else {
1052
1371
  this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-auto-container qaid-${this.config.position} ${o}${this.config.incognito ? " qaid-incognito" : ""}`.trim(), this.buttonsContainer.style.pointerEvents = "auto";
1053
- const { x: r, y: c } = this.config.offset;
1054
- this.config.position.includes("right") ? this.buttonsContainer.style.right = `${r}px` : this.buttonsContainer.style.left = `${r}px`, this.config.position.includes("bottom") ? this.buttonsContainer.style.bottom = `${c}px` : this.buttonsContainer.style.top = `${c}px`;
1372
+ const { x: r, y: l } = this.config.offset;
1373
+ this.config.position.includes("right") ? this.buttonsContainer.style.right = `${r}px` : this.buttonsContainer.style.left = `${r}px`, this.config.position.includes("bottom") ? this.buttonsContainer.style.bottom = `${l}px` : this.buttonsContainer.style.top = `${l}px`;
1055
1374
  }
1056
1375
  this.applyVars(this.buttonsContainer), this.shadowRoot.appendChild(this.buttonsContainer), this.buttonsContainer.addEventListener("keydown", (r) => {
1057
1376
  (r.key === "Enter" || r.key === " " || r.key === "Spacebar") && (this.keyboardActivation = !0);
@@ -1060,22 +1379,22 @@ class Re {
1060
1379
  }), this.buttonsContainer.addEventListener("pointerdown", () => {
1061
1380
  this.keyboardActivation = !1;
1062
1381
  });
1063
- const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", d = this.config.text.tooltip || "Feedback for us?", l = document.createElement("div");
1064
- if (l.className = "qaid-tooltip-text", l.textContent = d, this.applyVars(l), this.shadowRoot.appendChild(l), this.tooltipElement = l, !this.config.hideThumbs) {
1382
+ const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", d = this.config.text.tooltip || "Feedback for us?", c = document.createElement("div");
1383
+ if (c.className = "qaid-tooltip-text", c.textContent = d, this.applyVars(c), this.shadowRoot.appendChild(c), this.tooltipElement = c, !this.config.hideThumbs) {
1065
1384
  const r = document.createElement("div");
1066
1385
  r.className = "qaid-tooltip-wrapper";
1067
- const c = document.createElement("button");
1068
- c.type = "button", c.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", c.setAttribute("aria-label", this.config.text.positiveLabel), c.innerHTML = this.config.positiveIcon || I, c.addEventListener("click", (m) => this.handleThumbClick("up", m.currentTarget, m)), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c);
1386
+ const l = document.createElement("button");
1387
+ l.type = "button", l.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", l.setAttribute("aria-label", this.config.text.positiveLabel), l.innerHTML = this.config.positiveIcon || D, l.addEventListener("click", (f) => this.handleThumbClick("up", f.currentTarget, f)), l.addEventListener("mouseenter", () => this.showTooltip(l)), l.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(l);
1069
1388
  const p = document.createElement("div");
1070
1389
  p.className = "qaid-tooltip-wrapper";
1071
1390
  const u = document.createElement("button");
1072
- u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.setAttribute("aria-label", this.config.text.negativeLabel), u.innerHTML = this.config.negativeIcon || A, u.addEventListener("click", (m) => this.handleThumbClick("down", m.currentTarget, m)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), p.appendChild(u), this.buttonsContainer.appendChild(r), this.buttonsContainer.appendChild(p);
1391
+ u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.setAttribute("aria-label", this.config.text.negativeLabel), u.innerHTML = this.config.negativeIcon || M, u.addEventListener("click", (f) => this.handleThumbClick("down", f.currentTarget, f)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), p.appendChild(u), this.buttonsContainer.appendChild(r), this.buttonsContainer.appendChild(p);
1073
1392
  }
1074
- if (this.config.captureVideo && be()) {
1393
+ if (this.config.captureVideo && Ie()) {
1075
1394
  const r = document.createElement("div");
1076
1395
  r.className = "qaid-tooltip-wrapper";
1077
- const c = document.createElement("button");
1078
- c.type = "button", c.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", c.setAttribute("aria-label", this.config.text.recordLabel), c.innerHTML = this.config.recordIcon || bt, c.addEventListener("click", () => this.startRecording()), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c), this.buttonsContainer.appendChild(r);
1396
+ const l = document.createElement("button");
1397
+ l.type = "button", l.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", l.setAttribute("aria-label", this.config.text.recordLabel), l.innerHTML = this.config.recordIcon || xt, l.addEventListener("click", () => this.startRecording()), l.addEventListener("mouseenter", () => this.showTooltip(l)), l.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(l), this.buttonsContainer.appendChild(r);
1079
1398
  }
1080
1399
  this.config.hideDismiss || (this.dismissBtn = document.createElement("button"), this.dismissBtn.type = "button", this.dismissBtn.className = "qaid-dismiss-btn", this.dismissBtn.setAttribute("aria-label", this.config.text.dismissLabel), this.dismissBtn.title = this.config.text.dismissLabel, this.dismissBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', this.dismissBtn.addEventListener("click", (r) => {
1081
1400
  r.stopPropagation(), this.handleDismiss();
@@ -1091,7 +1410,7 @@ class Re {
1091
1410
  if (this.overlayShadowRoot) return this.overlayShadowRoot;
1092
1411
  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" });
1093
1412
  const t = document.createElement("style");
1094
- if (t.textContent = N(), this.overlayShadowRoot.appendChild(t), this.config.css) {
1413
+ if (t.textContent = _(), this.overlayShadowRoot.appendChild(t), this.config.css) {
1095
1414
  const i = document.createElement("style");
1096
1415
  i.textContent = this.config.css, this.overlayShadowRoot.appendChild(i);
1097
1416
  }
@@ -1101,7 +1420,7 @@ class Re {
1101
1420
  showTooltip(t) {
1102
1421
  const i = this.tooltipElement;
1103
1422
  i.style.visibility = "hidden", i.classList.add("qaid-tooltip-visible");
1104
- const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } = ie(
1423
+ const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } = me(
1105
1424
  o,
1106
1425
  n,
1107
1426
  { width: window.innerWidth, height: window.innerHeight }
@@ -1112,10 +1431,10 @@ class Re {
1112
1431
  this.tooltipElement.classList.remove("qaid-tooltip-visible");
1113
1432
  }
1114
1433
  handleDismiss() {
1115
- this.buttonsContainer.classList.add("qaid-dismissed"), Q(this.config.apiKey, !0);
1434
+ this.buttonsContainer.classList.add("qaid-dismissed"), tt(this.config.apiKey, !0);
1116
1435
  }
1117
1436
  handleThumbClick(t, i, o) {
1118
- if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), Q(this.config.apiKey, !1)), this.config.skipTargeting)
1437
+ if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), tt(this.config.apiKey, !1)), this.config.skipTargeting)
1119
1438
  this.submitDirectFeedback(t, i);
1120
1439
  else {
1121
1440
  this.activeThumbBtn = i, i.setAttribute("aria-pressed", "true");
@@ -1146,12 +1465,12 @@ class Re {
1146
1465
  * The KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
1147
1466
  */
1148
1467
  startKeyboardTargetingFlow(t) {
1149
- this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.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 = Ot({
1150
- isExcluded: (i) => M(i),
1468
+ this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.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 = Gt({
1469
+ isExcluded: (i) => B(i),
1151
1470
  onHighlight: (i) => {
1152
1471
  const o = i.getBoundingClientRect(), n = this.highlightBox;
1153
1472
  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");
1154
- const { text: s } = D(i);
1473
+ const { text: s } = R(i);
1155
1474
  this.announceMsg(`Targeting ${s || i.tagName.toLowerCase()}`);
1156
1475
  },
1157
1476
  onSelect: (i) => this.selectKeyboardTarget(i),
@@ -1159,14 +1478,14 @@ class Re {
1159
1478
  });
1160
1479
  }
1161
1480
  selectKeyboardTarget(t) {
1162
- const i = j(t, 8);
1481
+ const i = Q(t, 8);
1163
1482
  this.selectedBounds = {
1164
1483
  ...i,
1165
1484
  clickX: i.x + i.width / 2,
1166
1485
  clickY: i.y + i.height / 2,
1167
1486
  visible: !0
1168
1487
  };
1169
- const { selector: o, text: n } = D(t);
1488
+ const { selector: o, text: n } = R(t);
1170
1489
  this.feedbackData.elementSelector = o, this.feedbackData.elementText = n, this.removeTargetingOverlay(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.keyboardController = null, this.clearActiveThumb(), this.state = "SELECTED", this.showSelectedMarker(), this.submitFeedback();
1171
1490
  }
1172
1491
  createTargetingOverlay() {
@@ -1189,8 +1508,8 @@ class Re {
1189
1508
  * Shared by the mouse (hover) and touch (drag) targeting paths. */
1190
1509
  updateReticleAt(t, i) {
1191
1510
  if (this.mousePos.x = t, this.mousePos.y = i, this.crosshairH && (this.crosshairH.style.top = `${i}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${i}px`), this.captureLayer && this.shadowHost) {
1192
- const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = K(t, i, o);
1193
- if (n && !M(n)) {
1511
+ const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = Y(t, i, o);
1512
+ if (n && !B(n)) {
1194
1513
  if (this.highlightBox) {
1195
1514
  const s = n.getBoundingClientRect();
1196
1515
  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";
@@ -1213,22 +1532,22 @@ class Re {
1213
1532
  }
1214
1533
  handleTouchEnd(t) {
1215
1534
  const i = t.changedTouches[0], o = this.touchStartPos;
1216
- this.touchStartPos = null, !(!i || !o || Math.hypot(i.clientX - o.x, i.clientY - o.y) > Ae) && (t.preventDefault(), this.selectAt(i.clientX, i.clientY));
1535
+ this.touchStartPos = null, !(!i || !o || Math.hypot(i.clientX - o.x, i.clientY - o.y) > ii) && (t.preventDefault(), this.selectAt(i.clientX, i.clientY));
1217
1536
  }
1218
1537
  /** Select the element under (x, y) and tear down targeting.
1219
1538
  * Shared by the mouse (click) and touch (touchend) targeting paths. */
1220
1539
  selectAt(t, i) {
1221
- const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = K(t, i, o);
1222
- if (!n || M(n))
1540
+ const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = Y(t, i, o);
1541
+ if (!n || B(n))
1223
1542
  return;
1224
- const s = j(n, 8);
1543
+ const s = Q(n, 8);
1225
1544
  this.selectedBounds = {
1226
1545
  ...s,
1227
1546
  clickX: t,
1228
1547
  clickY: i,
1229
1548
  visible: !0
1230
1549
  };
1231
- const { selector: a, text: d } = D(n);
1550
+ const { selector: a, text: d } = R(n);
1232
1551
  this.feedbackData.elementSelector = a, this.feedbackData.elementText = d, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.state = "SELECTED", this.clearActiveThumb(), this.showSelectedMarker(), this.submitFeedback();
1233
1552
  }
1234
1553
  /** Remove the targeting overlay and every mouse/touch/keyboard listener the
@@ -1249,9 +1568,40 @@ class Re {
1249
1568
  hideSelectedMarker() {
1250
1569
  this.marker && (this.marker.remove(), this.marker = null);
1251
1570
  }
1571
+ /** Whether to capture the screenshot with the DOM/canvas method (html2canvas)
1572
+ * instead of the permission-based Screen Capture API. Explicit "dom" wins;
1573
+ * otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
1574
+ shouldCaptureViaDom() {
1575
+ return this.config.screenshotMethod === "dom" || oi();
1576
+ }
1577
+ /**
1578
+ * Open the full-screen annotation editor over the captured screenshot,
1579
+ * reusing the overlay shadow host and the shared dialog a11y helpers.
1580
+ * Resolves with the composited WebP data URL, or null when the user skips
1581
+ * (caller keeps the original). Pointer events on the overlay host are
1582
+ * enabled while the editor is open and restored on close.
1583
+ */
1584
+ async openAnnotationEditor(t) {
1585
+ const i = this.ensureOverlayHost(), o = this.overlayShadowHost, n = o.style.pointerEvents;
1586
+ o.style.pointerEvents = "auto";
1587
+ try {
1588
+ return await Qe({
1589
+ dataUrl: t,
1590
+ root: i,
1591
+ quality: this.config.screenshotOptions.quality,
1592
+ color: this.config.colors.marker,
1593
+ applyVars: (s) => this.applyVars(s),
1594
+ announce: (s, a) => this.announceMsg(s, a),
1595
+ openDialog: (s, a) => this.openDialogA11y(s, a),
1596
+ closeDialog: () => this.closeDialogA11y()
1597
+ });
1598
+ } finally {
1599
+ o.style.pointerEvents = n;
1600
+ }
1601
+ }
1252
1602
  async submitFeedback() {
1253
1603
  let t = null;
1254
- this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await Ce(this.config.screenshotOptions) : t = await we(this.config.screenshotOptions), t && this.announceMsg("Screenshot captured"));
1604
+ this.config.captureScreenshot && (t = this.shouldCaptureViaDom() ? await Oe(this.config.screenshotOptions) : await Re(this.config.screenshotOptions), t && this.announceMsg("Screenshot captured")), t && this.config.annotate && (t = await this.openAnnotationEditor(t) ?? t);
1255
1605
  const i = this.feedbackData.elementSelector ? {
1256
1606
  x: this.selectedBounds.x,
1257
1607
  y: this.selectedBounds.y,
@@ -1315,7 +1665,7 @@ class Re {
1315
1665
  const o = this.questIdFor(t);
1316
1666
  if (!o) return !1;
1317
1667
  try {
1318
- return this.activeQuest?.destroy(), this.activeQuest = await Ie({
1668
+ return this.activeQuest?.destroy(), this.activeQuest = await ei({
1319
1669
  questId: o,
1320
1670
  base: this.config.quests.base,
1321
1671
  apiKey: this.config.quests.apiKey || void 0,
@@ -1351,7 +1701,7 @@ class Re {
1351
1701
  `, this.applyVars(i), t.appendChild(i), this.modalContainer = i, this.setupModalInteractions();
1352
1702
  }
1353
1703
  showPositionedModal() {
1354
- const t = this.ensureOverlayHost(), { modal: i, arrow: o } = oe(
1704
+ const t = this.ensureOverlayHost(), { modal: i, arrow: o } = be(
1355
1705
  this.selectedBounds,
1356
1706
  window.innerWidth,
1357
1707
  window.innerHeight,
@@ -1370,7 +1720,7 @@ class Re {
1370
1720
  s.className = "qaid-modal-box", s.innerHTML = this.getModalContent(), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
1371
1721
  }
1372
1722
  getModalContent() {
1373
- const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon || I, o = this.config.negativeIcon || A;
1723
+ const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon || D, o = this.config.negativeIcon || M;
1374
1724
  return `
1375
1725
  <div class="qaid-modal-header">
1376
1726
  <button type="button" class="${this.config.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${this.config.buttonClass} ${t ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${t ? "qaid-type-up" : "qaid-type-down"}`}" title="Click to switch" aria-pressed="${t}" aria-label="${t ? "Feedback type: positive" : "Feedback type: negative"}">
@@ -1403,14 +1753,14 @@ class Re {
1403
1753
  o && o.addEventListener("click", () => {
1404
1754
  const n = this.feedbackData.feedbackType === "up" ? "down" : "up";
1405
1755
  this.feedbackData.feedbackType = n, this.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"));
1406
- const s = this.config.positiveIcon || I, a = this.config.negativeIcon || A;
1756
+ const s = this.config.positiveIcon || D, a = this.config.negativeIcon || M;
1407
1757
  o.innerHTML = n === "up" ? s : a;
1408
1758
  const d = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
1409
1759
  o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", d), this.announceMsg(d), this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
1410
1760
  method: "PATCH",
1411
1761
  headers: { "Content-Type": "application/json" },
1412
1762
  body: JSON.stringify({ feedbackType: n })
1413
- }).catch((l) => console.error("Failed to update feedback type:", l));
1763
+ }).catch((c) => console.error("Failed to update feedback type:", c));
1414
1764
  });
1415
1765
  }
1416
1766
  async submitMessage(t) {
@@ -1439,7 +1789,7 @@ class Re {
1439
1789
  async startRecording() {
1440
1790
  if (!(this.isRecording || this.state !== "IDLE"))
1441
1791
  try {
1442
- this.networkCapture = de(), this.videoRecorder = ve({
1792
+ this.networkCapture = qe(), this.videoRecorder = De({
1443
1793
  maxDuration: this.config.videoOptions.maxDuration
1444
1794
  }), this.videoRecorder.onTick((t) => {
1445
1795
  this.updateRecordingTimer(t);
@@ -1496,17 +1846,17 @@ class Re {
1496
1846
  a.placeholder = "Optional: Describe the issue you recorded...", a.setAttribute("aria-label", "Describe the issue you recorded");
1497
1847
  const d = document.createElement("div");
1498
1848
  d.className = "qaid-video-preview-actions";
1499
- const l = document.createElement("button");
1500
- l.type = "button", l.className = "qaid-video-btn qaid-video-btn-cancel", l.textContent = "Cancel", l.addEventListener("click", () => this.cancelRecordingPreview());
1849
+ const c = document.createElement("button");
1850
+ c.type = "button", c.className = "qaid-video-btn qaid-video-btn-cancel", c.textContent = "Cancel", c.addEventListener("click", () => this.cancelRecordingPreview());
1501
1851
  const r = document.createElement("button");
1502
1852
  r.type = "button", r.className = "qaid-video-btn qaid-video-btn-rerecord", r.textContent = "Re-record", r.addEventListener("click", () => {
1503
1853
  this.cancelRecordingPreview(), this.startRecording();
1504
1854
  });
1505
- const c = document.createElement("button");
1506
- c.type = "button", c.className = "qaid-video-btn qaid-video-btn-send", c.textContent = "Send", c.addEventListener("click", () => {
1855
+ const l = document.createElement("button");
1856
+ l.type = "button", l.className = "qaid-video-btn qaid-video-btn-send", l.textContent = "Send", l.addEventListener("click", () => {
1507
1857
  const p = a.value.trim() || null;
1508
- this.submitVideoFeedback(p, c);
1509
- }), d.appendChild(l), d.appendChild(r), d.appendChild(c), o.appendChild(n), o.appendChild(s), o.appendChild(a), o.appendChild(d), this.videoPreview.appendChild(o), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), this.openDialogA11y(o, { labelledbyId: n.id }), document.addEventListener("keydown", this.boundKeyDown);
1858
+ this.submitVideoFeedback(p, l);
1859
+ }), d.appendChild(c), d.appendChild(r), d.appendChild(l), o.appendChild(n), o.appendChild(s), o.appendChild(a), o.appendChild(d), this.videoPreview.appendChild(o), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), this.openDialogA11y(o, { labelledbyId: n.id }), document.addEventListener("keydown", this.boundKeyDown);
1510
1860
  }
1511
1861
  cancelRecordingPreview() {
1512
1862
  this.removeVideoPreview(), this.cleanupRecording();
@@ -1555,13 +1905,13 @@ class Re {
1555
1905
  * Destroy the embed and clean up all resources
1556
1906
  */
1557
1907
  destroy() {
1558
- this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.keyboardController?.stop(), this.keyboardController = null, this.clearActiveThumb(), this.closeDialogA11y(), this.cleanupRecording(), this.removeVideoPreview(), 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.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.removeEventListener("touchstart", this.boundTouchStart), document.removeEventListener("touchend", this.boundTouchEnd), 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.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null, Lt();
1908
+ this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.keyboardController?.stop(), this.keyboardController = null, this.clearActiveThumb(), this.closeDialogA11y(), this.cleanupRecording(), this.removeVideoPreview(), 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.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.removeEventListener("touchstart", this.boundTouchStart), document.removeEventListener("touchend", this.boundTouchEnd), 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.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null, Ut();
1559
1909
  }
1560
1910
  }
1561
- function et(e) {
1911
+ function at(e) {
1562
1912
  return document.querySelector(e)?.textContent?.trim() ?? "";
1563
1913
  }
1564
- function He() {
1914
+ function ri() {
1565
1915
  const e = document.querySelector(
1566
1916
  'script[type="application/json"][data-feedback-config]'
1567
1917
  );
@@ -1570,87 +1920,94 @@ function He() {
1570
1920
  if (!t) return null;
1571
1921
  try {
1572
1922
  const i = JSON.parse(t);
1573
- return i.cssSelector && !i.css && (i.css = et(i.cssSelector), delete i.cssSelector), i;
1923
+ return i.cssSelector && !i.css && (i.css = at(i.cssSelector), delete i.cssSelector), i;
1574
1924
  } catch {
1575
1925
  return null;
1576
1926
  }
1577
1927
  }
1578
- function Be(e) {
1928
+ function di(e) {
1579
1929
  const t = e.getAttribute("data-endpoint");
1580
1930
  if (!t) return null;
1581
- const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), a = e.getAttribute("data-marker-color"), d = e.getAttribute("data-container"), l = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), c = e.getAttribute("data-incognito"), p = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), m = e.getAttribute("data-offset-y"), b = e.getAttribute("data-modal-width"), v = e.getAttribute("data-backdrop-opacity"), y = e.getAttribute("data-font-family"), f = e.getAttribute("data-font-size"), h = e.getAttribute("data-tooltip"), w = e.getAttribute("data-modal-title"), g = e.getAttribute("data-modal-subtitle"), C = e.getAttribute("data-placeholder"), B = e.getAttribute("data-submit-button"), P = e.getAttribute("data-skip-button"), it = e.getAttribute("data-positive-icon"), ot = e.getAttribute("data-negative-icon"), nt = e.getAttribute("data-api-key"), st = e.getAttribute("data-capture-screenshot"), E = e.getAttribute("data-screenshot-quality"), T = e.getAttribute("data-screenshot-max-width"), L = e.getAttribute("data-screenshot-max-height"), at = e.getAttribute("data-capture-video"), rt = e.getAttribute("data-hide-thumbs"), dt = e.getAttribute("data-hide-dismiss"), z = e.getAttribute("data-video-max-duration"), ct = e.getAttribute("data-screenshot-method"), lt = e.getAttribute("data-direction"), O = e.getAttribute("data-css-selector"), $ = e.getAttribute("data-quest-base"), ht = e.getAttribute("data-quest-up"), ut = e.getAttribute("data-quest-down"), pt = e.getAttribute("data-quest-video"), mt = e.getAttribute("data-quest-api-key"), ft = e.getAttribute("data-quest-module-url");
1931
+ const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), a = e.getAttribute("data-marker-color"), d = e.getAttribute("data-container"), c = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), l = e.getAttribute("data-incognito"), p = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), f = e.getAttribute("data-offset-y"), b = e.getAttribute("data-modal-width"), v = e.getAttribute("data-backdrop-opacity"), y = e.getAttribute("data-font-family"), m = e.getAttribute("data-font-size"), h = e.getAttribute("data-tooltip"), w = e.getAttribute("data-modal-title"), g = e.getAttribute("data-modal-subtitle"), S = e.getAttribute("data-placeholder"), $ = e.getAttribute("data-submit-button"), N = e.getAttribute("data-skip-button"), rt = e.getAttribute("data-positive-icon"), dt = e.getAttribute("data-negative-icon"), lt = e.getAttribute("data-api-key"), ct = e.getAttribute("data-capture-screenshot"), ht = e.getAttribute("data-annotate"), L = e.getAttribute("data-screenshot-quality"), I = e.getAttribute("data-screenshot-max-width"), A = e.getAttribute("data-screenshot-max-height"), ut = e.getAttribute("data-capture-video"), pt = e.getAttribute("data-hide-thumbs"), ft = e.getAttribute("data-hide-dismiss"), U = e.getAttribute("data-video-max-duration"), mt = e.getAttribute("data-screenshot-method"), bt = e.getAttribute("data-direction"), F = e.getAttribute("data-css-selector"), V = e.getAttribute("data-quest-base"), gt = e.getAttribute("data-quest-up"), vt = e.getAttribute("data-quest-down"), yt = e.getAttribute("data-quest-video"), wt = e.getAttribute("data-quest-api-key"), qt = e.getAttribute("data-quest-module-url");
1582
1932
  return {
1583
1933
  endpoint: t,
1584
- css: O ? et(O) : void 0,
1585
- apiKey: nt ?? void 0,
1586
- captureScreenshot: st === "true" ? !0 : void 0,
1587
- screenshotOptions: E || T || L ? {
1588
- quality: E ? parseFloat(E) : void 0,
1589
- maxWidth: T ? parseInt(T, 10) : void 0,
1590
- maxHeight: L ? parseInt(L, 10) : void 0
1934
+ css: F ? at(F) : void 0,
1935
+ apiKey: lt ?? void 0,
1936
+ captureScreenshot: ct === "true" ? !0 : void 0,
1937
+ // Annotation is on by default; only an explicit "false" disables it.
1938
+ annotate: ht === "false" ? !1 : void 0,
1939
+ screenshotOptions: L || I || A ? {
1940
+ quality: L ? parseFloat(L) : void 0,
1941
+ maxWidth: I ? parseInt(I, 10) : void 0,
1942
+ maxHeight: A ? parseInt(A, 10) : void 0
1591
1943
  } : void 0,
1592
1944
  container: d ?? void 0,
1593
- buttonClass: l ?? void 0,
1594
- direction: lt ?? void 0,
1945
+ buttonClass: c ?? void 0,
1946
+ direction: bt ?? void 0,
1595
1947
  position: i ?? void 0,
1596
1948
  zIndex: o ? parseInt(o, 10) : void 0,
1597
1949
  skipTargeting: r === "true" ? !0 : void 0,
1598
- incognito: c === "true" ? !0 : void 0,
1950
+ incognito: l === "true" ? !0 : void 0,
1599
1951
  buttonSize: p ?? void 0,
1600
- offset: u || m ? {
1952
+ offset: u || f ? {
1601
1953
  x: u ? parseInt(u, 10) : void 0,
1602
- y: m ? parseInt(m, 10) : void 0
1954
+ y: f ? parseInt(f, 10) : void 0
1603
1955
  } : void 0,
1604
1956
  modalWidth: b ? parseInt(b, 10) : void 0,
1605
1957
  backdropOpacity: v ? parseFloat(v) : void 0,
1606
1958
  fontFamily: y ?? void 0,
1607
- fontSize: f ? parseInt(f, 10) : void 0,
1959
+ fontSize: m ? parseInt(m, 10) : void 0,
1608
1960
  colors: {
1609
1961
  positive: n ?? void 0,
1610
1962
  negative: s ?? void 0,
1611
1963
  marker: a ?? void 0
1612
1964
  },
1613
- text: h || w || g || C || B || P ? {
1965
+ text: h || w || g || S || $ || N ? {
1614
1966
  tooltip: h ?? void 0,
1615
1967
  modalTitle: w ?? void 0,
1616
1968
  modalSubtitle: g ?? void 0,
1617
- placeholder: C ?? void 0,
1618
- submitButton: B ?? void 0,
1619
- skipButton: P ?? void 0
1969
+ placeholder: S ?? void 0,
1970
+ submitButton: $ ?? void 0,
1971
+ skipButton: N ?? void 0
1620
1972
  } : void 0,
1621
- positiveIcon: it ?? void 0,
1622
- negativeIcon: ot ?? void 0,
1623
- screenshotMethod: ct ?? void 0,
1624
- captureVideo: at === "true" ? !0 : void 0,
1625
- hideThumbs: rt === "true" ? !0 : void 0,
1626
- hideDismiss: dt === "true" ? !0 : void 0,
1627
- videoOptions: z ? {
1628
- maxDuration: parseInt(z, 10)
1973
+ positiveIcon: rt ?? void 0,
1974
+ negativeIcon: dt ?? void 0,
1975
+ screenshotMethod: mt ?? void 0,
1976
+ captureVideo: ut === "true" ? !0 : void 0,
1977
+ hideThumbs: pt === "true" ? !0 : void 0,
1978
+ hideDismiss: ft === "true" ? !0 : void 0,
1979
+ videoOptions: U ? {
1980
+ maxDuration: parseInt(U, 10)
1629
1981
  } : void 0,
1630
- quests: $ ? {
1631
- base: $,
1632
- up: ht ?? void 0,
1633
- down: ut ?? void 0,
1634
- video: pt ?? void 0,
1635
- apiKey: mt ?? void 0,
1636
- moduleUrl: ft ?? void 0
1982
+ quests: V ? {
1983
+ base: V,
1984
+ up: gt ?? void 0,
1985
+ down: vt ?? void 0,
1986
+ video: yt ?? void 0,
1987
+ apiKey: wt ?? void 0,
1988
+ moduleUrl: qt ?? void 0
1637
1989
  } : void 0
1638
1990
  };
1639
1991
  }
1640
1992
  if (typeof document < "u") {
1641
1993
  const e = () => {
1642
- const t = document.currentScript, i = He(), o = t ? Be(t) : null, n = i ?? o;
1643
- n?.endpoint && new Re(n);
1994
+ const t = document.currentScript, i = ri(), o = t ? di(t) : null, n = i ?? o;
1995
+ n?.endpoint && new ai(n);
1644
1996
  };
1645
1997
  document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e();
1646
1998
  }
1647
1999
  export {
1648
- Re as QaidFeedback,
1649
- Ce as captureDomScreenshot,
1650
- de as captureNetworkErrors,
1651
- ve as createVideoRecorder,
1652
- ge as getSupportedMimeType,
1653
- Pe as isDomScreenshotSupported,
1654
- be as isVideoRecordingSupported
2000
+ Xe as AnnotationEditor,
2001
+ ai as QaidFeedback,
2002
+ Oe as captureDomScreenshot,
2003
+ qe as captureNetworkErrors,
2004
+ je as compositeAnnotations,
2005
+ De as createVideoRecorder,
2006
+ O as drawShape,
2007
+ Ae as getSupportedMimeType,
2008
+ li as isDomScreenshotSupported,
2009
+ Ie as isVideoRecordingSupported,
2010
+ Qe as openAnnotationEditor,
2011
+ P as rectFromPoints
1655
2012
  };
1656
2013
  //# sourceMappingURL=qaid.js.map