@qaiddev/thumbs-embed 1.9.0 → 1.10.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/index.js CHANGED
@@ -1,43 +1,43 @@
1
- const V = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
1
+ const U = `<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>`, U = `<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>`, j = `<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>`, re = `<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>`, he = `<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>`, St = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
7
+ </svg>`, Et = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
8
8
  <path stroke-linecap="round" stroke-linejoin="round" d="M8 10h8M8 14h5m-9 6l3.5-3.5H18a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v14z"/>
9
- </svg>`, de = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
9
+ </svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
10
10
  <rect x="4" y="6" width="16" height="12" rx="1" stroke-linejoin="round"/>
11
- </svg>`, ce = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
11
+ </svg>`, pe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
12
12
  <path stroke-linecap="round" stroke-linejoin="round" d="M5 19L19 5m0 0h-8m8 0v8"/>
13
- </svg>`, le = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
13
+ </svg>`, fe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
14
14
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 20h9M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/>
15
- </svg>`, he = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
15
+ </svg>`, me = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
16
16
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 3s6 6.4 6 10a6 6 0 01-12 0c0-3.6 6-10 6-10z"/>
17
- </svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
17
+ </svg>`, be = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
18
18
  <path stroke-linecap="round" stroke-linejoin="round" d="M9 14L4 9l5-5M4 9h11a5 5 0 010 10h-4"/>
19
- </svg>`, Et = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
19
+ </svg>`, At = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
20
20
  <path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
21
- </svg>`, pe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
21
+ </svg>`, ge = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
22
22
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v8m0 4h.01"/>
23
- </svg>`, fe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
23
+ </svg>`, ve = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
24
24
  <path stroke-linecap="round" stroke-linejoin="round" d="M6 6l12 12M18 6L6 18"/>
25
- </svg>`, me = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}:where(button.qaid-btn-structural)>svg:where(:not(.qaid-icon):not([width])){width:var(--qaid-icon-size, 24px);height:var(--qaid-icon-size, 24px)}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:var(--qaid-font-size, 16px);font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6365f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875)}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:var(--qaid-font-size, 16px);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:calc(var(--qaid-font-size, 16px) * .75);font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .875);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-error{margin:0 0 .75rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;color:light-dark(#b91c1c,#fca5a5)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .8125);line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .8125);font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6365f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6365f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-error .qaid-confirm-icon{background:var(--qaid-error, #dc2626)}.qaid-confirm-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:600;color:var(--qaid-text, light-dark(#111827, #f9fafb))}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6365f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875);color:var(--qaid-text-muted, light-dark(#6b7280, #9ca3af))}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", be = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
25
+ </svg>`, ye = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}:where(button.qaid-btn-structural)>svg:where(:not(.qaid-icon):not([width])){width:var(--qaid-icon-size, 24px);height:var(--qaid-icon-size, 24px)}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:var(--qaid-font-size, 16px);font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6365f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875)}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:var(--qaid-font-size, 16px);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;pointer-events:auto;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:calc(var(--qaid-font-size, 16px) * .75);font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .875);resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-error{margin:0 0 .75rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;color:light-dark(#b91c1c,#fca5a5)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:calc(var(--qaid-font-size, 16px) * .875);color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .8125);line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .8125);font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6365f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6365f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-error .qaid-confirm-icon{background:var(--qaid-error, #dc2626)}.qaid-confirm-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:600;color:var(--qaid-text, light-dark(#111827, #f9fafb))}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6365f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875);color:var(--qaid-text-muted, light-dark(#6b7280, #9ca3af))}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", we = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
26
26
  let D = 0;
27
- const ge = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn-feedback:hover{background:var(--qaid-marker,#6365f1);color:var(--qaid-marker-text,#fff)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", ve = {
27
+ const ke = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn-feedback:hover{background:var(--qaid-marker,#6365f1);color:var(--qaid-marker-text,#fff)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", xe = {
28
28
  small: 36,
29
29
  medium: 48,
30
30
  large: 64
31
- }, ye = {
31
+ }, qe = {
32
32
  small: 18,
33
33
  medium: 24,
34
34
  large: 32
35
35
  };
36
- function we(i, t, e) {
36
+ function Ce(i, t, e) {
37
37
  const [o, n, s] = [i, t, e].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
38
38
  return 0.2126 * o + 0.7152 * n + 0.0722 * s;
39
39
  }
40
- function ke(i) {
40
+ function Se(i) {
41
41
  if (i.startsWith("#")) {
42
42
  const e = i.slice(1), o = e.length === 3 ? e.split("").map((s) => s + s).join("") : e, n = parseInt(o, 16);
43
43
  return {
@@ -53,11 +53,11 @@ function ke(i) {
53
53
  b: parseInt(t[3])
54
54
  } : null;
55
55
  }
56
- function xe(i) {
57
- const t = ke(i);
58
- return t && we(t.r, t.g, t.b) > 0.4 ? "black" : "white";
56
+ function Te(i) {
57
+ const t = Se(i);
58
+ return t && Ce(t.r, t.g, t.b) > 0.4 ? "black" : "white";
59
59
  }
60
- function qe(i = {}) {
60
+ function Ee(i = {}) {
61
61
  const {
62
62
  positiveColor: t = "rgb(0, 200, 83)",
63
63
  negativeColor: e = "rgb(255, 0, 0)",
@@ -67,7 +67,7 @@ function qe(i = {}) {
67
67
  backdropOpacity: a = 0.3,
68
68
  fontFamily: c = "system-ui, -apple-system, sans-serif",
69
69
  fontSize: l = 16
70
- } = i, d = ve[n], r = ye[n], h = xe(o);
70
+ } = i, d = xe[n], r = qe[n], h = Te(o);
71
71
  return {
72
72
  "--qaid-positive": t,
73
73
  "--qaid-negative": e,
@@ -81,22 +81,22 @@ function qe(i = {}) {
81
81
  "--qaid-font-size": `${l}px`
82
82
  };
83
83
  }
84
- function Ce(i, t) {
84
+ function Ae(i, t) {
85
85
  for (const [e, o] of Object.entries(t))
86
86
  i.style.setProperty(e, o);
87
87
  }
88
- function at() {
89
- return me + ge;
88
+ function dt() {
89
+ return ye + ke;
90
90
  }
91
- function Se() {
91
+ function Le() {
92
92
  if (D++, D > 1) return;
93
93
  const i = document.createElement("style");
94
- i.id = "qaid-styles", i.textContent = be, document.head.appendChild(i);
94
+ i.id = "qaid-styles", i.textContent = we, document.head.appendChild(i);
95
95
  }
96
- function Ee() {
96
+ function Ie() {
97
97
  D <= 0 || (D--, D === 0 && document.getElementById("qaid-styles")?.remove());
98
98
  }
99
- const rt = "data-qaid-a11y-live", Te = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", Ae = [
99
+ const ct = "data-qaid-a11y-live", De = "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;", Me = [
100
100
  "a[href]",
101
101
  "button",
102
102
  "input",
@@ -104,25 +104,25 @@ const rt = "data-qaid-a11y-live", Te = "position:absolute;width:1px;height:1px;m
104
104
  "select",
105
105
  "[tabindex]"
106
106
  ].join(",");
107
- function Ie(i) {
107
+ function Re(i) {
108
108
  return i.ownerDocument || document;
109
109
  }
110
- function Le(i, t) {
110
+ function Pe(i, t) {
111
111
  const e = t ? "assertive" : "polite", o = i.querySelector(
112
- `[${rt}="${e}"]`
112
+ `[${ct}="${e}"]`
113
113
  );
114
114
  if (o) return o;
115
- const s = Ie(i).createElement("div");
116
- return s.setAttribute(rt, e), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = Te, i.appendChild(s), s;
115
+ const s = Re(i).createElement("div");
116
+ return s.setAttribute(ct, e), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = De, i.appendChild(s), s;
117
117
  }
118
- function De(i, t, e = {}) {
119
- const o = Le(i, !!e.assertive);
118
+ function Be(i, t, e = {}) {
119
+ const o = Pe(i, !!e.assertive);
120
120
  o.textContent = "", o.textContent = t;
121
121
  }
122
- function Me(i) {
122
+ function He(i) {
123
123
  return i.hasAttribute("disabled") ? !0 : i.disabled === !0;
124
124
  }
125
- function Re(i) {
125
+ function Oe(i) {
126
126
  let t = i;
127
127
  for (; t; ) {
128
128
  if (t.hasAttribute("hidden")) return !0;
@@ -133,52 +133,52 @@ function Re(i) {
133
133
  }
134
134
  return !1;
135
135
  }
136
- function dt(i) {
136
+ function lt(i) {
137
137
  return Array.from(
138
- i.querySelectorAll(Ae)
139
- ).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") || Me(e) || Re(e)));
138
+ i.querySelectorAll(Me)
139
+ ).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") || He(e) || Oe(e)));
140
140
  }
141
- function Tt(i) {
141
+ function Lt(i) {
142
142
  let t = i.activeElement;
143
143
  for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
144
144
  t = t.shadowRoot.activeElement;
145
145
  return t instanceof HTMLElement ? t : null;
146
146
  }
147
- function Pe(i) {
147
+ function ze(i) {
148
148
  const t = i.ownerDocument || document;
149
149
  let e = !1;
150
150
  const o = (s) => {
151
151
  if (s.key !== "Tab") return;
152
- const a = dt(i);
152
+ const a = lt(i);
153
153
  if (a.length === 0) {
154
154
  s.preventDefault(), i.focus();
155
155
  return;
156
156
  }
157
- const c = a[0], l = a[a.length - 1], d = Tt(t), r = d ? a.indexOf(d) !== -1 : !1;
157
+ const c = a[0], l = a[a.length - 1], d = Lt(t), r = d ? a.indexOf(d) !== -1 : !1;
158
158
  s.shiftKey ? (!r || d === c) && (s.preventDefault(), l.focus()) : (!r || d === l) && (s.preventDefault(), c.focus());
159
159
  };
160
160
  i.addEventListener("keydown", o);
161
- const n = dt(i);
161
+ const n = lt(i);
162
162
  return n.length > 0 ? n[0].focus() : (i.hasAttribute("tabindex") || (i.setAttribute("tabindex", "-1"), e = !0), i.focus()), {
163
163
  release() {
164
164
  i.removeEventListener("keydown", o), e && (i.removeAttribute("tabindex"), e = !1);
165
165
  }
166
166
  };
167
167
  }
168
- function Be() {
169
- return Tt(document);
168
+ function $e() {
169
+ return Lt(document);
170
170
  }
171
- function He(i) {
171
+ function _e(i) {
172
172
  if (!(!i || typeof i.focus != "function"))
173
173
  try {
174
174
  i.focus();
175
175
  } catch {
176
176
  }
177
177
  }
178
- function Oe(i, t = {}) {
178
+ function Fe(i, t = {}) {
179
179
  i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "true"), t.labelledbyId && i.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && i.setAttribute("aria-describedby", t.describedbyId), t.label && i.setAttribute("aria-label", t.label);
180
180
  }
181
- function ze(i, t) {
181
+ function Ne(i, t) {
182
182
  let e = i;
183
183
  for (; e && e !== t; ) {
184
184
  const o = e.parentNode;
@@ -192,11 +192,11 @@ function ze(i, t) {
192
192
  }
193
193
  return null;
194
194
  }
195
- function $e(i) {
195
+ function Ve(i) {
196
196
  const e = (i.ownerDocument || document).body;
197
197
  if (!e) return () => {
198
198
  };
199
- const o = ze(i, e), n = [];
199
+ const o = Ne(i, e), n = [];
200
200
  return Array.from(e.children).forEach((s) => {
201
201
  if (!(s instanceof HTMLElement) || o && s === o) return;
202
202
  const a = s.inert === !0, c = s.getAttribute("aria-hidden");
@@ -208,14 +208,14 @@ function $e(i) {
208
208
  }
209
209
  };
210
210
  }
211
- const At = {
211
+ const It = {
212
212
  width: 400,
213
213
  height: 280,
214
214
  arrowHeight: 12,
215
215
  gap: 8,
216
216
  viewportPadding: 16
217
217
  };
218
- function _e(i, t, e, o, n) {
218
+ function Ue(i, t, e, o, n) {
219
219
  const s = i.y, a = t - (i.y + i.height);
220
220
  if (a >= e + o)
221
221
  return {
@@ -234,22 +234,22 @@ function _e(i, t, e, o, n) {
234
234
  t - e - n
235
235
  ) : l = Math.max(n, i.y - e - o), { top: l, position: c };
236
236
  }
237
- function Ne(i, t, e, o) {
237
+ function je(i, t, e, o) {
238
238
  let s = i.x + i.width / 2 - e / 2;
239
239
  return s = Math.max(o, Math.min(s, t - e - o)), s;
240
240
  }
241
- function Fe(i, t, e, o = 24, n = 24) {
241
+ function Ke(i, t, e, o = 24, n = 24) {
242
242
  const a = i.clickX - t - n / 2;
243
243
  return Math.max(o, Math.min(a, e - o - n / 2));
244
244
  }
245
- function Ve(i, t, e, o = At) {
246
- const n = o.height + o.arrowHeight, s = _e(
245
+ function We(i, t, e, o = It) {
246
+ const n = o.height + o.arrowHeight, s = Ue(
247
247
  i,
248
248
  e,
249
249
  n,
250
250
  o.gap,
251
251
  o.viewportPadding
252
- ), a = Ne(
252
+ ), a = je(
253
253
  i,
254
254
  t,
255
255
  o.width,
@@ -261,15 +261,15 @@ function Ve(i, t, e, o = At) {
261
261
  position: s.position
262
262
  };
263
263
  }
264
- function Ue(i, t, e, o = {}) {
264
+ function Xe(i, t, e, o = {}) {
265
265
  const n = o.gap ?? 8;
266
266
  let s = i.bottom + n;
267
267
  s + t.height > e.height - n && (s = i.top - t.height - n);
268
268
  let a = i.left;
269
269
  return a < n ? a = n : a + t.width > e.width - n && (a = e.width - t.width - n), s < n ? s = n : s + t.height > e.height - n && (s = e.height - t.height - n), { top: s, left: a };
270
270
  }
271
- function je(i, t, e, o = At) {
272
- const n = Ve(i, t, e, o), s = Fe(
271
+ function Ye(i, t, e, o = It) {
272
+ const n = We(i, t, e, o), s = Ke(
273
273
  i,
274
274
  n.left,
275
275
  o.width
@@ -279,15 +279,15 @@ function je(i, t, e, o = At) {
279
279
  arrow: { left: s }
280
280
  };
281
281
  }
282
- const Ke = 20;
283
- function We(i) {
282
+ const Qe = 20;
283
+ function Je(i) {
284
284
  const t = [], e = console.error, o = console.warn, n = console.log, s = (a, c) => {
285
285
  const l = {
286
286
  message: c.map((d) => String(d)).join(" "),
287
287
  timestamp: Date.now(),
288
288
  level: a
289
289
  };
290
- t.length >= Ke && t.shift(), t.push(l), i && i(l);
290
+ t.length >= Qe && t.shift(), t.push(l), i && i(l);
291
291
  };
292
292
  return console.error = function(...a) {
293
293
  s("error", a), e.apply(console, a);
@@ -309,10 +309,10 @@ function q(i, t, e) {
309
309
  n === "className" ? o.className = s : o.setAttribute(n, s);
310
310
  return o;
311
311
  }
312
- function Xe(i = 640) {
312
+ function Ge(i = 640) {
313
313
  return typeof window < "u" && window.innerWidth < i;
314
314
  }
315
- function ct(i, t, e) {
315
+ function ht(i, t, e) {
316
316
  const o = e.map((s) => s.style.visibility);
317
317
  e.forEach((s) => s.style.visibility = "hidden");
318
318
  const n = document.elementFromPoint(i, t);
@@ -321,7 +321,7 @@ function ct(i, t, e) {
321
321
  function R(i) {
322
322
  return i ? i.hasAttribute("data-qaid-embed") || i.hasAttribute("data-qaid-embed-overlay") ? !0 : !!i.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
323
323
  }
324
- function lt(i, t = 0) {
324
+ function ut(i, t = 0) {
325
325
  const e = i.getBoundingClientRect();
326
326
  return {
327
327
  x: e.left - t,
@@ -330,7 +330,7 @@ function lt(i, t = 0) {
330
330
  height: e.height + t * 2
331
331
  };
332
332
  }
333
- const Ye = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Qe = (i) => (
333
+ const Ze = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", ti = (i) => (
334
334
  // The URL is a runtime value, not a static specifier — keep Vite from
335
335
  // trying to analyze/bundle it.
336
336
  import(
@@ -338,28 +338,50 @@ const Ye = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Qe =
338
338
  i
339
339
  )
340
340
  );
341
- let Je = Qe, I = null, N = null;
342
- function Ge(i) {
343
- return I && N === i || (N = i, I = Promise.resolve(Je(i)).then((t) => {
341
+ let ei = ti, L = null, F = null;
342
+ const K = /* @__PURE__ */ new Map(), N = /* @__PURE__ */ new Map();
343
+ function Dt(i, t) {
344
+ return `${i.replace(/\/+$/, "")}/${encodeURIComponent(t)}/definition`;
345
+ }
346
+ function ii(i) {
347
+ if (K.has(i)) return Promise.resolve();
348
+ const t = N.get(i);
349
+ if (t) return t;
350
+ const e = fetch(i, { headers: { Accept: "application/json" } }).then((o) => o.ok ? o.json() : null).then((o) => {
351
+ o && K.set(i, o);
352
+ }).catch(() => {
353
+ }).finally(() => {
354
+ N.delete(i);
355
+ });
356
+ return N.set(i, e), e;
357
+ }
358
+ function Mt(i) {
359
+ return L && F === i || (F = i, L = Promise.resolve(ei(i)).then((t) => {
344
360
  const e = t;
345
361
  if (!e || typeof e.QaidQuests != "function")
346
362
  throw new Error("quests module has no QaidQuests export");
347
363
  return e;
348
364
  }).catch((t) => {
349
- throw I = null, N = null, t;
350
- })), I;
351
- }
352
- async function Ze(i) {
353
- const t = await Ge(i.moduleUrl), e = i.base.replace(/\/+$/, ""), o = i.feedbackId != null ? { feedbackId: i.feedbackId } : void 0;
354
- return new t.QaidQuests({
365
+ throw L = null, F = null, t;
366
+ })), L;
367
+ }
368
+ async function oi(i) {
369
+ const t = await Mt(i.moduleUrl), e = i.base.replace(/\/+$/, ""), o = Dt(e, i.questId), n = (c) => c != null ? { feedbackId: c } : void 0;
370
+ let s;
371
+ const a = i.feedbackId;
372
+ return a instanceof Promise ? s = t.QaidQuests.supports?.asyncMetadata ? a.then(n, () => {
373
+ }) : n(await a.catch(() => null)) : s = n(a ?? null), new t.QaidQuests({
355
374
  endpoint: `${e}/responses`,
356
- configUrl: `${e}/${encodeURIComponent(i.questId)}/definition`,
375
+ configUrl: o,
376
+ // Only a definition already in hand. One still loading is left to the
377
+ // widget, which shows its own loading state instead of nothing.
378
+ questionnaire: K.get(o),
357
379
  apiKey: i.apiKey || void 0,
358
- metadata: o,
380
+ metadata: s,
359
381
  onClose: i.onClose
360
382
  });
361
383
  }
362
- const ht = "qaid_visitor_id", ut = "qaid_hide_feedback", ti = [
384
+ const pt = "qaid_visitor_id", ft = "qaid_hide_feedback", ni = [
363
385
  "#ef4444",
364
386
  "#f59e0b",
365
387
  "#22c55e",
@@ -367,26 +389,26 @@ const ht = "qaid_visitor_id", ut = "qaid_hide_feedback", ti = [
367
389
  "#111827",
368
390
  "#ffffff"
369
391
  ];
370
- function ei() {
392
+ function si() {
371
393
  return typeof window.matchMedia == "function" && window.matchMedia("(pointer: coarse)").matches;
372
394
  }
373
- function j(i) {
374
- return i ? `${ut}_${i}` : ut;
395
+ function W(i) {
396
+ return i ? `${ft}_${i}` : ft;
375
397
  }
376
- function ii(i) {
398
+ function ai(i) {
377
399
  try {
378
- return localStorage.getItem(j(i)) === "1";
400
+ return localStorage.getItem(W(i)) === "1";
379
401
  } catch {
380
402
  return !1;
381
403
  }
382
404
  }
383
- function pt(i, t = !0) {
405
+ function mt(i, t = !0) {
384
406
  try {
385
- t ? localStorage.setItem(j(i), "1") : localStorage.removeItem(j(i));
407
+ t ? localStorage.setItem(W(i), "1") : localStorage.removeItem(W(i));
386
408
  } catch {
387
409
  }
388
410
  }
389
- function ft() {
411
+ function bt() {
390
412
  const i = typeof crypto < "u" ? crypto : void 0;
391
413
  if (i && typeof i.randomUUID == "function") return i.randomUUID();
392
414
  const t = new Uint8Array(16);
@@ -398,15 +420,15 @@ function ft() {
398
420
  const e = Array.from(t, (o) => o.toString(16).padStart(2, "0")).join("");
399
421
  return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
400
422
  }
401
- function oi() {
423
+ function ri() {
402
424
  try {
403
- let i = localStorage.getItem(ht);
404
- return i || (i = ft(), localStorage.setItem(ht, i)), i;
425
+ let i = localStorage.getItem(pt);
426
+ return i || (i = bt(), localStorage.setItem(pt, i)), i;
405
427
  } catch {
406
- return ft();
428
+ return bt();
407
429
  }
408
430
  }
409
- class ni {
431
+ class di {
410
432
  config;
411
433
  state = "IDLE";
412
434
  feedbackData = {
@@ -424,7 +446,13 @@ class ni {
424
446
  clickY: 0,
425
447
  visible: !1
426
448
  };
427
- feedbackId = null;
449
+ /**
450
+ * This feedback's record id, once its POST answers (null if it failed).
451
+ * The message box and a linked quest open without waiting for it; the
452
+ * PATCHes that need the id wait on this instead.
453
+ */
454
+ feedbackIdPromise = Promise.resolve(null);
455
+ questsPrewarmed = !1;
428
456
  // A quest launched from a button (in place of the message box), if any.
429
457
  activeQuest = null;
430
458
  isMobile = !1;
@@ -524,7 +552,7 @@ class ni {
524
552
  captureScreenshot: t.captureScreenshot ?? !1,
525
553
  annotate: t.annotate ?? !0,
526
554
  annotationColor: t.annotationColor ?? t.colors?.marker ?? "#6365f1",
527
- annotationPalette: t.annotationPalette ?? ti,
555
+ annotationPalette: t.annotationPalette ?? ni,
528
556
  screenshotMethod: t.screenshotMethod ?? "permission",
529
557
  screenshotOptions: {
530
558
  quality: t.screenshotOptions?.quality ?? 0.8,
@@ -551,12 +579,12 @@ class ni {
551
579
  video: t.quests?.video ?? "",
552
580
  // Quest service reuses the feedback API key unless overridden.
553
581
  apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
554
- moduleUrl: t.quests?.moduleUrl ?? Ye
582
+ moduleUrl: t.quests?.moduleUrl ?? Ze
555
583
  }
556
- }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = oi(), this.init();
584
+ }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = ri(), this.init();
557
585
  }
558
586
  applyVars(t) {
559
- Ce(t, this.cssVars);
587
+ Ae(t, this.cssVars);
560
588
  }
561
589
  /**
562
590
  * Announce a message via the shared visually-hidden live regions.
@@ -566,7 +594,7 @@ class ni {
566
594
  */
567
595
  announceMsg(t, e = !1) {
568
596
  const o = this.overlayShadowRoot ?? this.shadowRoot;
569
- o && De(o, t, { assertive: e });
597
+ o && Be(o, t, { assertive: e });
570
598
  }
571
599
  /**
572
600
  * Turn a transient surface into an accessible modal dialog: save the
@@ -574,16 +602,16 @@ class ni {
574
602
  * background. Paired with closeDialogA11y() on every close path.
575
603
  */
576
604
  openDialogA11y(t, e) {
577
- this.dialogTrigger = Be(), Oe(t, e), this.dialogTrap = Pe(t), this.dialogRestoreInert = $e(t);
605
+ this.dialogTrigger = $e(), Fe(t, e), this.dialogTrap = ze(t), this.dialogRestoreInert = Ve(t);
578
606
  }
579
607
  closeDialogA11y() {
580
- this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), He(this.dialogTrigger), this.dialogTrigger = null;
608
+ this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), _e(this.dialogTrigger), this.dialogTrigger = null;
581
609
  }
582
610
  clearActiveThumb() {
583
611
  this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
584
612
  }
585
613
  init() {
586
- Se(), this.cssVars = qe({
614
+ Le(), this.cssVars = Ee({
587
615
  positiveColor: this.config.colors.positive,
588
616
  negativeColor: this.config.colors.negative,
589
617
  markerColor: this.config.colors.marker,
@@ -592,10 +620,10 @@ class ni {
592
620
  backdropOpacity: this.config.backdropOpacity,
593
621
  fontFamily: this.config.fontFamily,
594
622
  fontSize: this.config.fontSize
595
- }), !this.config.hideDismiss && ii(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = We((t) => {
623
+ }), !this.config.hideDismiss && ai(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = Je((t) => {
596
624
  this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
597
- }), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom(), (this.config.captureVideo && this.videoSupported() || this.config.captureScreenshot) && this.schedulePrewarm(() => {
598
- this.config.captureVideo && this.videoSupported() && this.prewarmVideo(), this.config.captureScreenshot && this.prewarmScreenshot();
625
+ }), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom(), (this.config.captureVideo && this.videoSupported() || this.config.captureScreenshot || this.linkedQuestIds().length > 0) && this.schedulePrewarm(() => {
626
+ this.config.captureVideo && this.videoSupported() && this.prewarmVideo(), this.config.captureScreenshot && this.prewarmScreenshot(), this.prewarmQuests();
599
627
  });
600
628
  }
601
629
  /**
@@ -605,15 +633,35 @@ class ni {
605
633
  * swallowed — a failed preload just falls back to an on-demand load.
606
634
  */
607
635
  prewarmVideo() {
608
- this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => kt).catch(() => {
609
- }), Promise.resolve().then(() => Bt).catch(() => {
636
+ this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => qt).catch(() => {
637
+ }), Promise.resolve().then(() => $t).catch(() => {
610
638
  }));
611
639
  }
612
640
  prewarmScreenshot() {
613
- this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() => vt) : Promise.resolve().then(() => xt)).catch(() => {
614
- }), this.config.annotate && Promise.resolve().then(() => wt).catch(() => {
641
+ this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() => wt) : Promise.resolve().then(() => Ct)).catch(() => {
642
+ }), this.config.annotate && Promise.resolve().then(() => xt).catch(() => {
615
643
  }));
616
644
  }
645
+ /** Quest ids linked to any button, when quest launching is on. */
646
+ linkedQuestIds() {
647
+ const t = this.config.quests;
648
+ return t.base ? [t.up, t.down, t.video].filter((e) => e) : [];
649
+ }
650
+ /**
651
+ * Load the quests module and fetch every linked quest's definition, so a
652
+ * click opens the quest with no network wait. Both are best-effort: a miss
653
+ * just means the quest loads on click, as it always did.
654
+ */
655
+ prewarmQuests() {
656
+ if (this.questsPrewarmed) return;
657
+ const t = this.linkedQuestIds();
658
+ if (t.length !== 0) {
659
+ this.questsPrewarmed = !0, Mt(this.config.quests.moduleUrl).catch(() => {
660
+ });
661
+ for (const e of t)
662
+ ii(Dt(this.config.quests.base, e));
663
+ }
664
+ }
617
665
  /** Run fn when the main thread is idle; cancelled by destroy(). */
618
666
  schedulePrewarm(t) {
619
667
  const e = window, o = () => {
@@ -640,7 +688,7 @@ class ni {
640
688
  }), this.domObserver.observe(document.body, { childList: !0 });
641
689
  }
642
690
  checkMobile() {
643
- this.isMobile = Xe();
691
+ this.isMobile = Ge();
644
692
  }
645
693
  handleResize() {
646
694
  this.checkMobile();
@@ -650,7 +698,7 @@ class ni {
650
698
  let t = null;
651
699
  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" });
652
700
  const e = document.createElement("style");
653
- if (e.textContent = at(), this.shadowRoot.appendChild(e), this.config.css) {
701
+ if (e.textContent = dt(), this.shadowRoot.appendChild(e), this.config.css) {
654
702
  const d = document.createElement("style");
655
703
  d.textContent = this.config.css, this.shadowRoot.appendChild(d);
656
704
  }
@@ -674,28 +722,28 @@ class ni {
674
722
  const d = document.createElement("div");
675
723
  d.className = "qaid-tooltip-wrapper";
676
724
  const r = document.createElement("button");
677
- r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon || St, r.addEventListener("click", (h) => this.handleThumbClick("neutral", h.currentTarget, h)), r.addEventListener("mouseenter", () => {
725
+ r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon || Et, r.addEventListener("click", (h) => this.handleThumbClick("neutral", h.currentTarget, h)), r.addEventListener("mouseenter", () => {
678
726
  this.prewarmTargeting(), this.showTooltip(r);
679
727
  }), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r), this.buttonsContainer.appendChild(d);
680
728
  } else if (!this.config.hideThumbs) {
681
729
  const d = document.createElement("div");
682
730
  d.className = "qaid-tooltip-wrapper";
683
731
  const r = document.createElement("button");
684
- r.type = "button", r.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", r.setAttribute("aria-label", this.config.text.positiveLabel), r.innerHTML = this.config.positiveIcon || V, r.addEventListener("click", (b) => this.handleThumbClick("up", b.currentTarget, b)), r.addEventListener("mouseenter", () => {
685
- this.prewarmTargeting(), this.showTooltip(r);
732
+ r.type = "button", r.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", r.setAttribute("aria-label", this.config.text.positiveLabel), r.innerHTML = this.config.positiveIcon || U, r.addEventListener("click", (b) => this.handleThumbClick("up", b.currentTarget, b)), r.addEventListener("mouseenter", () => {
733
+ this.prewarmTargeting(), this.prewarmQuests(), this.showTooltip(r);
686
734
  }), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r);
687
735
  const h = document.createElement("div");
688
736
  h.className = "qaid-tooltip-wrapper";
689
737
  const f = document.createElement("button");
690
- f.type = "button", f.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", f.setAttribute("aria-label", this.config.text.negativeLabel), f.innerHTML = this.config.negativeIcon || U, f.addEventListener("click", (b) => this.handleThumbClick("down", b.currentTarget, b)), f.addEventListener("mouseenter", () => {
691
- this.prewarmTargeting(), this.showTooltip(f);
738
+ f.type = "button", f.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", f.setAttribute("aria-label", this.config.text.negativeLabel), f.innerHTML = this.config.negativeIcon || j, f.addEventListener("click", (b) => this.handleThumbClick("down", b.currentTarget, b)), f.addEventListener("mouseenter", () => {
739
+ this.prewarmTargeting(), this.prewarmQuests(), this.showTooltip(f);
692
740
  }), f.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(f), this.buttonsContainer.appendChild(d), this.buttonsContainer.appendChild(h);
693
741
  }
694
742
  if (this.config.captureVideo && this.videoSupported()) {
695
743
  const d = document.createElement("div");
696
744
  d.className = "qaid-tooltip-wrapper";
697
745
  const r = document.createElement("button");
698
- r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon || re, r.addEventListener("click", () => {
746
+ r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon || he, r.addEventListener("click", () => {
699
747
  this.ensureRecording().then(
700
748
  (f) => this.config.videoOptions.redaction ? f.startPicking() : f.startRecording()
701
749
  );
@@ -719,7 +767,7 @@ class ni {
719
767
  if (this.overlayShadowRoot) return this.overlayShadowRoot;
720
768
  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" });
721
769
  const t = document.createElement("style");
722
- if (t.textContent = at(), this.overlayShadowRoot.appendChild(t), this.config.css) {
770
+ if (t.textContent = dt(), this.overlayShadowRoot.appendChild(t), this.config.css) {
723
771
  const e = document.createElement("style");
724
772
  e.textContent = this.config.css, this.overlayShadowRoot.appendChild(e);
725
773
  }
@@ -729,7 +777,7 @@ class ni {
729
777
  showTooltip(t) {
730
778
  const e = this.tooltipElement;
731
779
  e.style.visibility = "hidden", e.classList.add("qaid-tooltip-visible");
732
- const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Ue(
780
+ const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Xe(
733
781
  o,
734
782
  n,
735
783
  { width: window.innerWidth, height: window.innerHeight }
@@ -740,10 +788,10 @@ class ni {
740
788
  this.tooltipElement.classList.remove("qaid-tooltip-visible");
741
789
  }
742
790
  handleDismiss() {
743
- this.buttonsContainer.classList.add("qaid-dismissed"), pt(this.config.apiKey, !0);
791
+ this.buttonsContainer.classList.add("qaid-dismissed"), mt(this.config.apiKey, !0);
744
792
  }
745
793
  handleThumbClick(t, e, o) {
746
- if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), pt(this.config.apiKey, !1)), this.prewarmModal(), this.config.skipTargeting || this.config.feedbackMode === "annotate")
794
+ if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), mt(this.config.apiKey, !1)), this.prewarmModal(), this.config.skipTargeting || this.config.feedbackMode === "annotate")
747
795
  this.submitDirectFeedback(t, e);
748
796
  else {
749
797
  this.activeThumbBtn = e, e.setAttribute("aria-pressed", "true");
@@ -776,7 +824,7 @@ class ni {
776
824
  * instead of the permission-based Screen Capture API. Explicit "dom" wins;
777
825
  * otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
778
826
  shouldCaptureViaDom() {
779
- return this.config.screenshotMethod === "dom" || ei();
827
+ return this.config.screenshotMethod === "dom" || si();
780
828
  }
781
829
  /**
782
830
  * Open the full-screen annotation editor over the captured screenshot,
@@ -789,7 +837,7 @@ class ni {
789
837
  const e = this.ensureOverlayHost(), o = this.overlayShadowHost, n = o.style.pointerEvents;
790
838
  o.style.pointerEvents = "auto";
791
839
  try {
792
- const { openAnnotationEditor: s } = await Promise.resolve().then(() => wt);
840
+ const { openAnnotationEditor: s } = await Promise.resolve().then(() => xt);
793
841
  return await s({
794
842
  dataUrl: t,
795
843
  root: e,
@@ -812,10 +860,10 @@ class ni {
812
860
  if (this.config.captureScreenshot || this.config.feedbackMode === "annotate")
813
861
  try {
814
862
  if (this.shouldCaptureViaDom()) {
815
- const { captureDomScreenshot: a } = await Promise.resolve().then(() => vt);
863
+ const { captureDomScreenshot: a } = await Promise.resolve().then(() => wt);
816
864
  t = await a(this.config.screenshotOptions);
817
865
  } else {
818
- const { captureScreenshot: a } = await Promise.resolve().then(() => xt);
866
+ const { captureScreenshot: a } = await Promise.resolve().then(() => Ct);
819
867
  t = await a(this.config.screenshotOptions);
820
868
  }
821
869
  t && this.announceMsg("Screenshot captured");
@@ -847,21 +895,9 @@ class ni {
847
895
  elementBounds: o,
848
896
  userAgent: navigator.userAgent
849
897
  };
850
- try {
851
- const a = await fetch(this.config.endpoint, {
852
- method: "POST",
853
- headers: { "Content-Type": "application/json" },
854
- body: JSON.stringify(n)
855
- });
856
- if (a.ok) {
857
- const c = await a.json();
858
- this.feedbackId = c.id, this.announceMsg("Feedback sent");
859
- }
860
- } catch (a) {
861
- console.error("Failed to submit feedback:", a), this.announceMsg("Failed to send feedback", !0);
862
- }
898
+ this.feedbackIdPromise = this.postFeedback(n);
863
899
  const s = this.feedbackData.feedbackType;
864
- if (s && s !== "neutral" && await this.tryLaunchQuest(s, this.feedbackId)) {
900
+ if (s && s !== "neutral" && await this.tryLaunchQuest(s, this.feedbackIdPromise)) {
865
901
  this.resetFeedbackUi();
866
902
  return;
867
903
  }
@@ -874,6 +910,23 @@ class ni {
874
910
  console.error("Failed to open the feedback modal:", a), this.announceMsg("Thank you for your feedback!", !0), this.resetFeedbackUi();
875
911
  }
876
912
  }
913
+ /** POST the feedback. Resolves to the new record's id, or null if it failed. */
914
+ async postFeedback(t) {
915
+ try {
916
+ const e = await fetch(this.config.endpoint, {
917
+ method: "POST",
918
+ headers: { "Content-Type": "application/json" },
919
+ body: JSON.stringify(t)
920
+ });
921
+ if (e.ok) {
922
+ const o = await e.json();
923
+ return this.announceMsg("Feedback sent"), o.id;
924
+ }
925
+ } catch (e) {
926
+ console.error("Failed to submit feedback:", e), this.announceMsg("Failed to send feedback", !0);
927
+ }
928
+ return null;
929
+ }
877
930
  /**
878
931
  * Quest id linked to `type`, or "" when quest launching is disabled
879
932
  * (no `base`) or this button has no quest configured.
@@ -893,7 +946,7 @@ class ni {
893
946
  const o = this.questIdFor(t);
894
947
  if (!o) return !1;
895
948
  try {
896
- return this.activeQuest?.destroy(), this.activeQuest = await Ze({
949
+ return this.activeQuest?.destroy(), this.activeQuest = await oi({
897
950
  questId: o,
898
951
  base: this.config.quests.base,
899
952
  apiKey: this.config.quests.apiKey || void 0,
@@ -913,7 +966,7 @@ class ni {
913
966
  * path (which bypasses the modal entirely).
914
967
  */
915
968
  resetFeedbackUi() {
916
- this.targeting?.hideMarker(), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "none"), this.state = "IDLE", this.feedbackId = null, this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
969
+ this.targeting?.hideMarker(), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "none"), this.state = "IDLE", this.feedbackIdPromise = Promise.resolve(null), this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
917
970
  }
918
971
  /**
919
972
  * Lazily load and instantiate the modal controller. The message modal lives
@@ -922,7 +975,7 @@ class ni {
922
975
  */
923
976
  async ensureModal() {
924
977
  if (!this.modal) {
925
- const { ModalController: t } = await Promise.resolve().then(() => qt);
978
+ const { ModalController: t } = await Promise.resolve().then(() => St);
926
979
  this.modal = new t(this.makeModalHost());
927
980
  }
928
981
  return this.modal;
@@ -952,12 +1005,7 @@ class ni {
952
1005
  get selectedBounds() {
953
1006
  return t.selectedBounds;
954
1007
  },
955
- get feedbackId() {
956
- return t.feedbackId;
957
- },
958
- setFeedbackId: (e) => {
959
- t.feedbackId = e;
960
- },
1008
+ whenFeedbackId: () => t.feedbackIdPromise,
961
1009
  ensureOverlayHost: () => t.ensureOverlayHost(),
962
1010
  applyVars: (e) => t.applyVars(e),
963
1011
  announceMsg: (e, o) => t.announceMsg(e, o),
@@ -968,7 +1016,7 @@ class ni {
968
1016
  }
969
1017
  /** Warm the modal chunk while the user is targeting, so it opens instantly. */
970
1018
  prewarmModal() {
971
- this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => qt).catch(() => {
1019
+ this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => St).catch(() => {
972
1020
  }));
973
1021
  }
974
1022
  /**
@@ -978,7 +1026,7 @@ class ni {
978
1026
  */
979
1027
  async ensureTargeting() {
980
1028
  if (!this.targeting) {
981
- const { TargetingController: t } = await Promise.resolve().then(() => Ct);
1029
+ const { TargetingController: t } = await Promise.resolve().then(() => Tt);
982
1030
  this.targeting = new t(this.makeTargetingHost());
983
1031
  }
984
1032
  return this.targeting;
@@ -1023,7 +1071,7 @@ class ni {
1023
1071
  }
1024
1072
  /** Warm the targeting chunk on thumb-button hover, before the click. */
1025
1073
  prewarmTargeting() {
1026
- this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() => Ct).catch(() => {
1074
+ this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() => Tt).catch(() => {
1027
1075
  }));
1028
1076
  }
1029
1077
  // ==================== Video Recording ====================
@@ -1042,7 +1090,7 @@ class ni {
1042
1090
  */
1043
1091
  async ensureRecording() {
1044
1092
  if (!this.recording) {
1045
- const { RecordingController: t } = await Promise.resolve().then(() => kt);
1093
+ const { RecordingController: t } = await Promise.resolve().then(() => qt);
1046
1094
  this.recording = new t(this.makeRecordingHost());
1047
1095
  }
1048
1096
  return this.recording;
@@ -1098,13 +1146,13 @@ class ni {
1098
1146
  const t = window;
1099
1147
  this.prewarmIsTimeout ? clearTimeout(this.prewarmHandle) : t.cancelIdleCallback?.(this.prewarmHandle), this.prewarmHandle = null;
1100
1148
  }
1101
- this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.dismissBtn = null, this.tooltipElement = null, Ee();
1149
+ this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.dismissBtn = null, this.tooltipElement = null, Ie();
1102
1150
  }
1103
1151
  }
1104
- function It(i) {
1152
+ function Rt(i) {
1105
1153
  return document.querySelector(i)?.textContent?.trim() ?? "";
1106
1154
  }
1107
- function si() {
1155
+ function ci() {
1108
1156
  const i = document.querySelector(
1109
1157
  'script[type="application/json"][data-feedback-config]'
1110
1158
  );
@@ -1113,22 +1161,22 @@ function si() {
1113
1161
  if (!t) return null;
1114
1162
  try {
1115
1163
  const e = JSON.parse(t);
1116
- return e.cssSelector && !e.css && (e.css = It(e.cssSelector), delete e.cssSelector), e;
1164
+ return e.cssSelector && !e.css && (e.css = Rt(e.cssSelector), delete e.cssSelector), e;
1117
1165
  } catch {
1118
1166
  return null;
1119
1167
  }
1120
1168
  }
1121
- function Lt(i, t, e) {
1169
+ function Pt(i, t, e) {
1122
1170
  console.warn(`[thumbs-embed] Ignoring ${i}="${t}": expected ${e}.`);
1123
1171
  }
1124
- function ai(i) {
1172
+ function li(i) {
1125
1173
  const t = [];
1126
1174
  let e = 0, o = "";
1127
1175
  for (const n of i)
1128
1176
  n === "(" && e++, n === ")" && (e = Math.max(0, e - 1)), n === "," && e === 0 ? (t.push(o.trim()), o = "") : o += n;
1129
1177
  return t.push(o.trim()), t;
1130
1178
  }
1131
- function ri(i, t) {
1179
+ function hi(i, t) {
1132
1180
  if (t === null) return;
1133
1181
  const e = t.trim();
1134
1182
  let o = null;
@@ -1139,38 +1187,38 @@ function ri(i, t) {
1139
1187
  o = null;
1140
1188
  }
1141
1189
  else
1142
- o = ai(e);
1190
+ o = li(e);
1143
1191
  if (Array.isArray(o) && o.length > 0 && o.every((n) => typeof n == "string" && n.trim() !== ""))
1144
1192
  return o.map((n) => n.trim());
1145
- Lt(i, t, "a JSON array of colours or a comma-separated list");
1193
+ Pt(i, t, "a JSON array of colours or a comma-separated list");
1146
1194
  }
1147
1195
  function M(i, t) {
1148
1196
  if (t !== null) {
1149
1197
  if (t.trim() === "") {
1150
- Lt(i, t, "a non-empty label");
1198
+ Pt(i, t, "a non-empty label");
1151
1199
  return;
1152
1200
  }
1153
1201
  return t;
1154
1202
  }
1155
1203
  }
1156
- function di(i) {
1204
+ function ui(i) {
1157
1205
  const t = i.getAttribute("data-endpoint");
1158
1206
  if (!t) return null;
1159
- const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"), f = i.getAttribute("data-feedback-mode"), b = i.getAttribute("data-incognito"), y = i.getAttribute("data-button-size"), g = i.getAttribute("data-offset-x"), w = i.getAttribute("data-offset-y"), x = i.getAttribute("data-modal-width"), u = i.getAttribute("data-backdrop-opacity"), k = i.getAttribute("data-font-family"), v = i.getAttribute("data-font-size"), C = i.getAttribute("data-tooltip"), A = i.getAttribute("data-modal-title"), S = i.getAttribute("data-confirmation-title"), m = i.getAttribute("data-confirmation-message"), E = i.getAttribute("data-confirmation-close"), K = i.getAttribute("data-error-title"), W = i.getAttribute("data-error-message"), X = i.getAttribute("data-modal-subtitle"), Y = i.getAttribute("data-placeholder"), Q = i.getAttribute("data-submit-button"), J = i.getAttribute("data-skip-button"), Nt = i.getAttribute("data-positive-icon"), Ft = i.getAttribute("data-negative-icon"), Vt = i.getAttribute("data-feedback-icon"), G = i.getAttribute("data-feedback-label"), Ut = i.getAttribute("data-api-key"), jt = i.getAttribute("data-capture-screenshot"), Kt = i.getAttribute("data-annotate"), Wt = i.getAttribute("data-annotation-color"), O = i.getAttribute("data-screenshot-quality"), z = i.getAttribute("data-screenshot-max-width"), $ = i.getAttribute("data-screenshot-max-height"), Xt = i.getAttribute("data-capture-video"), Z = i.getAttribute("data-video-redaction"), Yt = i.getAttribute("data-hide-thumbs"), Qt = i.getAttribute("data-hide-dismiss"), _ = i.getAttribute("data-video-max-duration"), Jt = i.getAttribute("data-screenshot-method"), Gt = i.getAttribute("data-direction"), tt = i.getAttribute("data-css-selector"), Zt = i.getAttribute("data-css"), et = M("data-positive-label", i.getAttribute("data-positive-label")), it = M("data-negative-label", i.getAttribute("data-negative-label")), ot = M("data-record-label", i.getAttribute("data-record-label")), nt = M("data-dismiss-label", i.getAttribute("data-dismiss-label")), te = ri(
1207
+ const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"), f = i.getAttribute("data-feedback-mode"), b = i.getAttribute("data-incognito"), y = i.getAttribute("data-button-size"), g = i.getAttribute("data-offset-x"), w = i.getAttribute("data-offset-y"), x = i.getAttribute("data-modal-width"), u = i.getAttribute("data-backdrop-opacity"), k = i.getAttribute("data-font-family"), v = i.getAttribute("data-font-size"), C = i.getAttribute("data-tooltip"), A = i.getAttribute("data-modal-title"), S = i.getAttribute("data-confirmation-title"), m = i.getAttribute("data-confirmation-message"), T = i.getAttribute("data-confirmation-close"), X = i.getAttribute("data-error-title"), Y = i.getAttribute("data-error-message"), Q = i.getAttribute("data-modal-subtitle"), J = i.getAttribute("data-placeholder"), G = i.getAttribute("data-submit-button"), Z = i.getAttribute("data-skip-button"), jt = i.getAttribute("data-positive-icon"), Kt = i.getAttribute("data-negative-icon"), Wt = i.getAttribute("data-feedback-icon"), tt = i.getAttribute("data-feedback-label"), Xt = i.getAttribute("data-api-key"), Yt = i.getAttribute("data-capture-screenshot"), Qt = i.getAttribute("data-annotate"), Jt = i.getAttribute("data-annotation-color"), O = i.getAttribute("data-screenshot-quality"), z = i.getAttribute("data-screenshot-max-width"), $ = i.getAttribute("data-screenshot-max-height"), Gt = i.getAttribute("data-capture-video"), et = i.getAttribute("data-video-redaction"), Zt = i.getAttribute("data-hide-thumbs"), te = i.getAttribute("data-hide-dismiss"), _ = i.getAttribute("data-video-max-duration"), ee = i.getAttribute("data-screenshot-method"), ie = i.getAttribute("data-direction"), it = i.getAttribute("data-css-selector"), oe = i.getAttribute("data-css"), ot = M("data-positive-label", i.getAttribute("data-positive-label")), nt = M("data-negative-label", i.getAttribute("data-negative-label")), st = M("data-record-label", i.getAttribute("data-record-label")), at = M("data-dismiss-label", i.getAttribute("data-dismiss-label")), ne = hi(
1160
1208
  "data-annotation-palette",
1161
1209
  i.getAttribute("data-annotation-palette")
1162
- ), ee = i.getAttribute("data-record-icon"), st = i.getAttribute("data-quest-base"), ie = i.getAttribute("data-quest-up"), oe = i.getAttribute("data-quest-down"), ne = i.getAttribute("data-quest-video"), se = i.getAttribute("data-quest-api-key"), ae = i.getAttribute("data-quest-module-url");
1210
+ ), se = i.getAttribute("data-record-icon"), rt = i.getAttribute("data-quest-base"), ae = i.getAttribute("data-quest-up"), re = i.getAttribute("data-quest-down"), de = i.getAttribute("data-quest-video"), ce = i.getAttribute("data-quest-api-key"), le = i.getAttribute("data-quest-module-url");
1163
1211
  return {
1164
1212
  endpoint: t,
1165
1213
  // Inline CSS wins over a selector, as `css` wins over `cssSelector` in
1166
1214
  // the JSON block.
1167
- css: Zt || (tt ? It(tt) : void 0),
1168
- apiKey: Ut ?? void 0,
1169
- captureScreenshot: jt === "true" ? !0 : void 0,
1215
+ css: oe || (it ? Rt(it) : void 0),
1216
+ apiKey: Xt ?? void 0,
1217
+ captureScreenshot: Yt === "true" ? !0 : void 0,
1170
1218
  // Annotation is on by default; only an explicit "false" disables it.
1171
- annotate: Kt === "false" ? !1 : void 0,
1172
- annotationColor: Wt ?? void 0,
1173
- annotationPalette: te,
1219
+ annotate: Qt === "false" ? !1 : void 0,
1220
+ annotationColor: Jt ?? void 0,
1221
+ annotationPalette: ne,
1174
1222
  screenshotOptions: O || z || $ ? {
1175
1223
  quality: O ? parseFloat(O) : void 0,
1176
1224
  maxWidth: z ? parseInt(z, 10) : void 0,
@@ -1178,7 +1226,7 @@ function di(i) {
1178
1226
  } : void 0,
1179
1227
  container: c ?? void 0,
1180
1228
  buttonClass: l ?? void 0,
1181
- direction: Gt ?? void 0,
1229
+ direction: ie ?? void 0,
1182
1230
  position: e ?? void 0,
1183
1231
  zIndex: o ? parseInt(o, 10) : void 0,
1184
1232
  skipTargeting: d === "true" ? !0 : void 0,
@@ -1200,63 +1248,63 @@ function di(i) {
1200
1248
  negative: s ?? void 0,
1201
1249
  marker: a ?? void 0
1202
1250
  },
1203
- text: C || A || X || Y || Q || J || G || S || m || E || K || W || et || it || ot || nt ? {
1251
+ text: C || A || Q || J || G || Z || tt || S || m || T || X || Y || ot || nt || st || at ? {
1204
1252
  tooltip: C ?? void 0,
1205
1253
  modalTitle: A ?? void 0,
1206
- modalSubtitle: X ?? void 0,
1207
- placeholder: Y ?? void 0,
1208
- submitButton: Q ?? void 0,
1209
- skipButton: J ?? void 0,
1210
- feedbackLabel: G ?? void 0,
1254
+ modalSubtitle: Q ?? void 0,
1255
+ placeholder: J ?? void 0,
1256
+ submitButton: G ?? void 0,
1257
+ skipButton: Z ?? void 0,
1258
+ feedbackLabel: tt ?? void 0,
1211
1259
  confirmationTitle: S ?? void 0,
1212
1260
  confirmationMessage: m ?? void 0,
1213
- confirmationClose: E ?? void 0,
1214
- errorTitle: K ?? void 0,
1215
- errorMessage: W ?? void 0,
1216
- positiveLabel: et,
1217
- negativeLabel: it,
1218
- recordLabel: ot,
1219
- dismissLabel: nt
1261
+ confirmationClose: T ?? void 0,
1262
+ errorTitle: X ?? void 0,
1263
+ errorMessage: Y ?? void 0,
1264
+ positiveLabel: ot,
1265
+ negativeLabel: nt,
1266
+ recordLabel: st,
1267
+ dismissLabel: at
1220
1268
  } : void 0,
1221
- positiveIcon: Nt ?? void 0,
1222
- recordIcon: ee ?? void 0,
1223
- negativeIcon: Ft ?? void 0,
1224
- feedbackIcon: Vt ?? void 0,
1225
- screenshotMethod: Jt ?? void 0,
1226
- captureVideo: Xt === "true" ? !0 : void 0,
1227
- hideThumbs: Yt === "true" ? !0 : void 0,
1228
- hideDismiss: Qt === "true" ? !0 : void 0,
1229
- videoOptions: _ || Z ? {
1269
+ positiveIcon: jt ?? void 0,
1270
+ recordIcon: se ?? void 0,
1271
+ negativeIcon: Kt ?? void 0,
1272
+ feedbackIcon: Wt ?? void 0,
1273
+ screenshotMethod: ee ?? void 0,
1274
+ captureVideo: Gt === "true" ? !0 : void 0,
1275
+ hideThumbs: Zt === "true" ? !0 : void 0,
1276
+ hideDismiss: te === "true" ? !0 : void 0,
1277
+ videoOptions: _ || et ? {
1230
1278
  maxDuration: _ ? parseInt(_, 10) : void 0,
1231
- redaction: Z === "true" ? !0 : void 0
1279
+ redaction: et === "true" ? !0 : void 0
1232
1280
  } : void 0,
1233
- quests: st ? {
1234
- base: st,
1235
- up: ie ?? void 0,
1236
- down: oe ?? void 0,
1237
- video: ne ?? void 0,
1238
- apiKey: se ?? void 0,
1239
- moduleUrl: ae ?? void 0
1281
+ quests: rt ? {
1282
+ base: rt,
1283
+ up: ae ?? void 0,
1284
+ down: re ?? void 0,
1285
+ video: de ?? void 0,
1286
+ apiKey: ce ?? void 0,
1287
+ moduleUrl: le ?? void 0
1240
1288
  } : void 0
1241
1289
  };
1242
1290
  }
1243
- function ci() {
1291
+ function pi() {
1244
1292
  if (typeof document > "u") return;
1245
1293
  const i = () => {
1246
- const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e = si() ?? (t ? di(t) : null);
1247
- e?.endpoint && new ni(e);
1294
+ const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e = ci() ?? (t ? ui(t) : null);
1295
+ e?.endpoint && new di(e);
1248
1296
  };
1249
1297
  document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", i) : i();
1250
1298
  }
1251
- const li = 20, mt = 4096;
1299
+ const fi = 20, gt = 4096;
1252
1300
  function P(i) {
1253
1301
  const t = typeof i == "string" ? i : JSON.stringify(i);
1254
- return t.length > mt ? t.slice(0, mt) + "…[truncated]" : t;
1302
+ return t.length > gt ? t.slice(0, gt) + "…[truncated]" : t;
1255
1303
  }
1256
- function bt(i, t) {
1257
- i.length >= li && i.shift(), i.push(t);
1304
+ function vt(i, t) {
1305
+ i.length >= fi && i.shift(), i.push(t);
1258
1306
  }
1259
- async function hi(i) {
1307
+ async function mi(i) {
1260
1308
  try {
1261
1309
  const t = await i.clone().text();
1262
1310
  return P(t);
@@ -1264,7 +1312,7 @@ async function hi(i) {
1264
1312
  return;
1265
1313
  }
1266
1314
  }
1267
- function ui() {
1315
+ function bi() {
1268
1316
  const i = [], t = window.fetch;
1269
1317
  window.fetch = async function(n, s) {
1270
1318
  const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, c = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
@@ -1272,8 +1320,8 @@ function ui() {
1272
1320
  s?.body && (l = P(s.body));
1273
1321
  const d = await t.apply(window, [n, s]);
1274
1322
  if (d.status >= 400) {
1275
- const r = await hi(d);
1276
- bt(i, {
1323
+ const r = await mi(d);
1324
+ vt(i, {
1277
1325
  url: a,
1278
1326
  method: c.toUpperCase(),
1279
1327
  status: d.status,
@@ -1291,7 +1339,7 @@ function ui() {
1291
1339
  }, XMLHttpRequest.prototype.send = function(n) {
1292
1340
  const s = this, a = n ? P(n) : void 0;
1293
1341
  return s.addEventListener("load", function() {
1294
- s.status >= 400 && bt(i, {
1342
+ s.status >= 400 && vt(i, {
1295
1343
  url: s._qaid_url,
1296
1344
  method: s._qaid_method.toUpperCase(),
1297
1345
  status: s.status,
@@ -1308,27 +1356,27 @@ function ui() {
1308
1356
  }
1309
1357
  };
1310
1358
  }
1311
- function pi() {
1359
+ function gi() {
1312
1360
  const i = navigator.userAgent || "";
1313
1361
  return /iP(hone|ad|od)/.test(i) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
1314
1362
  navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
1315
1363
  }
1316
- function fi(i, t, e, o, n) {
1364
+ function vi(i, t, e, o, n) {
1317
1365
  const s = i >= t, a = e >= o;
1318
1366
  return s === a ? { width: i, height: t, rotate: 0 } : { width: t, height: i, rotate: n === 270 ? -90 : 90 };
1319
1367
  }
1320
- function mi(i, t, e) {
1368
+ function yi(i, t, e) {
1321
1369
  if (e.rotate === 0) {
1322
1370
  i.drawImage(t, 0, 0, e.width, e.height);
1323
1371
  return;
1324
1372
  }
1325
1373
  i.save(), e.rotate === 90 ? (i.translate(e.width, 0), i.rotate(Math.PI / 2)) : (i.translate(0, e.height), i.rotate(-Math.PI / 2)), i.drawImage(t, 0, 0, e.height, e.width), i.restore();
1326
1374
  }
1327
- function bi() {
1375
+ function wi() {
1328
1376
  const i = typeof screen < "u" ? screen.orientation : void 0;
1329
1377
  return i && typeof i.angle == "number" ? i.angle : 0;
1330
1378
  }
1331
- function Dt(i) {
1379
+ function Bt(i) {
1332
1380
  return new Promise((t) => {
1333
1381
  if (i.videoWidth > 0) {
1334
1382
  t();
@@ -1337,30 +1385,30 @@ function Dt(i) {
1337
1385
  i.addEventListener("loadedmetadata", () => t(), { once: !0 });
1338
1386
  });
1339
1387
  }
1340
- async function Mt(i) {
1388
+ async function Ht(i) {
1341
1389
  try {
1342
1390
  await i.play();
1343
1391
  } catch {
1344
1392
  }
1345
1393
  }
1346
- async function gi(i, t = 15) {
1394
+ async function ki(i, t = 15) {
1347
1395
  const e = document.createElement("canvas");
1348
1396
  if (typeof e.captureStream != "function") return null;
1349
1397
  const o = e.getContext("2d");
1350
1398
  if (!o) return null;
1351
1399
  const n = document.createElement("video");
1352
- n.muted = !0, n.playsInline = !0, n.srcObject = i, await Dt(n);
1353
- const s = fi(
1400
+ n.muted = !0, n.playsInline = !0, n.srcObject = i, await Bt(n);
1401
+ const s = vi(
1354
1402
  n.videoWidth,
1355
1403
  n.videoHeight,
1356
1404
  window.innerWidth,
1357
1405
  window.innerHeight,
1358
- bi()
1406
+ wi()
1359
1407
  );
1360
- e.width = s.width, e.height = s.height, await Mt(n);
1408
+ e.width = s.width, e.height = s.height, await Ht(n);
1361
1409
  let a = 0;
1362
1410
  const c = () => {
1363
- mi(o, n, s), a = requestAnimationFrame(c);
1411
+ yi(o, n, s), a = requestAnimationFrame(c);
1364
1412
  };
1365
1413
  c();
1366
1414
  const l = e.captureStream(t);
@@ -1371,15 +1419,15 @@ async function gi(i, t = 15) {
1371
1419
  }
1372
1420
  };
1373
1421
  }
1374
- function vi(i, t, e, o, n) {
1422
+ function xi(i, t, e, o, n) {
1375
1423
  const s = Math.max(0, Math.min(o, i.left * t)), a = Math.max(0, Math.min(n, i.top * e)), c = Math.max(0, Math.min(o, (i.left + i.width) * t)), l = Math.max(0, Math.min(n, (i.top + i.height) * e)), d = c - s, r = l - a;
1376
1424
  return d <= 0 || r <= 0 ? null : { x: s, y: a, w: d, h: r };
1377
1425
  }
1378
- function yi(i, t, e, o, n, s, a) {
1426
+ function qi(i, t, e, o, n, s, a) {
1379
1427
  i.drawImage(t, 0, 0, o, n);
1380
1428
  const c = o / Math.max(1, window.innerWidth), l = n / Math.max(1, window.innerHeight);
1381
1429
  for (const d of e) {
1382
- const r = vi(
1430
+ const r = xi(
1383
1431
  d.getBoundingClientRect(),
1384
1432
  c,
1385
1433
  l,
@@ -1389,16 +1437,16 @@ function yi(i, t, e, o, n, s, a) {
1389
1437
  r && (i.save(), a ? (i.filter = `blur(${s}px)`, i.drawImage(t, r.x, r.y, r.w, r.h, r.x, r.y, r.w, r.h)) : (i.fillStyle = "#0b0b0b", i.fillRect(r.x, r.y, r.w, r.h)), i.restore());
1390
1438
  }
1391
1439
  }
1392
- async function wi(i, t, e = {}) {
1440
+ async function Ci(i, t, e = {}) {
1393
1441
  const o = e.frameRate ?? 15, n = e.blurRadius ?? 12, s = document.createElement("canvas");
1394
1442
  if (typeof s.captureStream != "function") return null;
1395
1443
  const a = s.getContext("2d");
1396
1444
  if (!a) return null;
1397
1445
  const c = "filter" in a, l = document.createElement("video");
1398
- l.muted = !0, l.playsInline = !0, l.srcObject = i, await Dt(l), s.width = l.videoWidth, s.height = l.videoHeight, await Mt(l);
1446
+ l.muted = !0, l.playsInline = !0, l.srcObject = i, await Bt(l), s.width = l.videoWidth, s.height = l.videoHeight, await Ht(l);
1399
1447
  let d = 0;
1400
1448
  const r = () => {
1401
- yi(
1449
+ qi(
1402
1450
  a,
1403
1451
  l,
1404
1452
  t,
@@ -1417,11 +1465,11 @@ async function wi(i, t, e = {}) {
1417
1465
  }
1418
1466
  };
1419
1467
  }
1420
- const Rt = "This browser cannot blur the areas you picked, so the recording was not started.";
1421
- function ki() {
1468
+ const Ot = "This browser cannot blur the areas you picked, so the recording was not started.";
1469
+ function Si() {
1422
1470
  return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
1423
1471
  }
1424
- function Pt() {
1472
+ function zt() {
1425
1473
  if (typeof MediaRecorder > "u") return "";
1426
1474
  const i = [
1427
1475
  "video/webm;codecs=vp9",
@@ -1434,7 +1482,7 @@ function Pt() {
1434
1482
  return t;
1435
1483
  return "";
1436
1484
  }
1437
- function xi(i = {}) {
1485
+ function Ti(i = {}) {
1438
1486
  const t = i.maxDuration ?? 15, e = i.videoBitsPerSecond ?? 8e5, o = i.redactionElements ?? [], n = i.redactionBlurRadius;
1439
1487
  let s = null, a = null, c = null, l = null, d = [], r = null, h = null, f = null, b = 0, y = null, g = null, w = !1, x = null;
1440
1488
  function u() {
@@ -1446,7 +1494,7 @@ function xi(i = {}) {
1446
1494
  return {
1447
1495
  async start() {
1448
1496
  w = !1, d = [];
1449
- const v = Pt();
1497
+ const v = zt();
1450
1498
  if (!v)
1451
1499
  throw new Error("No supported video MIME type found");
1452
1500
  s = await navigator.mediaDevices.getDisplayMedia({
@@ -1470,16 +1518,16 @@ function xi(i = {}) {
1470
1518
  k();
1471
1519
  });
1472
1520
  let S = s;
1473
- if (pi()) {
1474
- const m = await gi(s);
1521
+ if (gi()) {
1522
+ const m = await ki(s);
1475
1523
  m && (a = m, S = m.stream);
1476
1524
  }
1477
1525
  if (o.length > 0) {
1478
- const m = await wi(S, o, {
1526
+ const m = await Ci(S, o, {
1479
1527
  blurRadius: n
1480
1528
  });
1481
1529
  if (!m)
1482
- throw a && (a.stop(), a = null), s.getTracks().forEach((E) => E.stop()), s = null, new Error(Rt);
1530
+ throw a && (a.stop(), a = null), s.getTracks().forEach((T) => T.stop()), s = null, new Error(Ot);
1483
1531
  c = m, S = m.stream;
1484
1532
  }
1485
1533
  l = new MediaRecorder(S, {
@@ -1489,7 +1537,7 @@ function xi(i = {}) {
1489
1537
  m.data.size > 0 && d.push(m.data);
1490
1538
  }, l.onstop = () => {
1491
1539
  const m = new Blob(d, { type: v });
1492
- y && y(m), h && h(m), a && (a.stop(), a = null), c && (c.stop(), c = null), s && s.getTracks().forEach((E) => E.stop());
1540
+ y && y(m), h && h(m), a && (a.stop(), a = null), c && (c.stop(), c = null), s && s.getTracks().forEach((T) => T.stop());
1493
1541
  }, l.onerror = () => {
1494
1542
  g && g(new Error("MediaRecorder error"));
1495
1543
  }, l.start(1e3), b = Date.now(), f = setInterval(() => {
@@ -1515,46 +1563,46 @@ function xi(i = {}) {
1515
1563
  }
1516
1564
  };
1517
1565
  }
1518
- const Bt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1566
+ const $t = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1519
1567
  __proto__: null,
1520
- REDACTION_UNAVAILABLE: Rt,
1521
- createVideoRecorder: xi,
1522
- getSupportedMimeType: Pt,
1523
- isVideoRecordingSupported: ki
1524
- }, Symbol.toStringTag, { value: "Module" })), gt = "https://qaid.dev/lib/html2canvas.min.js", qi = 1e4, Ci = 50;
1525
- let L = null;
1526
- function Si() {
1568
+ REDACTION_UNAVAILABLE: Ot,
1569
+ createVideoRecorder: Ti,
1570
+ getSupportedMimeType: zt,
1571
+ isVideoRecordingSupported: Si
1572
+ }, Symbol.toStringTag, { value: "Module" })), yt = "https://qaid.dev/lib/html2canvas.min.js", Ei = 1e4, Ai = 50;
1573
+ let I = null;
1574
+ function Li() {
1527
1575
  if (typeof document > "u" || typeof window > "u")
1528
1576
  return !1;
1529
1577
  const i = document.createElement("canvas");
1530
1578
  return typeof i.getContext == "function" && !!i.getContext("2d");
1531
1579
  }
1532
- function Ei() {
1533
- return window.html2canvas ? Promise.resolve(!0) : L || (L = new Promise((i) => {
1580
+ function Ii() {
1581
+ return window.html2canvas ? Promise.resolve(!0) : I || (I = new Promise((i) => {
1534
1582
  if (!document.querySelector(
1535
- `script[src="${gt}"]`
1583
+ `script[src="${yt}"]`
1536
1584
  )) {
1537
1585
  const n = document.createElement("script");
1538
- n.src = gt, n.async = !0, document.head.appendChild(n);
1586
+ n.src = yt, n.async = !0, document.head.appendChild(n);
1539
1587
  }
1540
1588
  const e = Date.now(), o = () => {
1541
1589
  if (window.html2canvas) {
1542
1590
  i(!0);
1543
1591
  return;
1544
1592
  }
1545
- if (Date.now() - e > qi) {
1546
- L = null, i(!1);
1593
+ if (Date.now() - e > Ei) {
1594
+ I = null, i(!1);
1547
1595
  return;
1548
1596
  }
1549
- setTimeout(o, Ci);
1597
+ setTimeout(o, Ai);
1550
1598
  };
1551
1599
  o();
1552
- }), L);
1600
+ }), I);
1553
1601
  }
1554
- async function Ti(i = {}) {
1602
+ async function Di(i = {}) {
1555
1603
  const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
1556
1604
  try {
1557
- if (!await Ei() || !window.html2canvas)
1605
+ if (!await Ii() || !window.html2canvas)
1558
1606
  return console.warn("html2canvas failed to load"), null;
1559
1607
  const s = await window.html2canvas(document.body, {
1560
1608
  useCORS: !0,
@@ -1579,11 +1627,11 @@ async function Ti(i = {}) {
1579
1627
  return console.warn("DOM screenshot capture failed:", n), null;
1580
1628
  }
1581
1629
  }
1582
- const vt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1630
+ const wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1583
1631
  __proto__: null,
1584
- captureDomScreenshot: Ti,
1585
- isDomScreenshotSupported: Si
1586
- }, Symbol.toStringTag, { value: "Module" })), T = 12, Ai = "#ef4444", Ii = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#111827", "#ffffff"], Li = {
1632
+ captureDomScreenshot: Di,
1633
+ isDomScreenshotSupported: Li
1634
+ }, Symbol.toStringTag, { value: "Module" })), E = 12, Mi = "#ef4444", Ri = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#111827", "#ffffff"], Pi = {
1587
1635
  "#ef4444": "red",
1588
1636
  "#f59e0b": "amber",
1589
1637
  "#22c55e": "green",
@@ -1595,10 +1643,10 @@ const vt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1595
1643
  "#6365f1": "indigo",
1596
1644
  "#6366f1": "indigo"
1597
1645
  };
1598
- function yt(i) {
1599
- return Li[i.toLowerCase()] ?? i;
1646
+ function kt(i) {
1647
+ return Pi[i.toLowerCase()] ?? i;
1600
1648
  }
1601
- const Di = 4, Mi = 0.8, Ri = {
1649
+ const Bi = 4, Hi = 0.8, Oi = {
1602
1650
  title: "Annotate screenshot",
1603
1651
  instructions: "Draw on the screenshot to highlight or hide details, then choose Done to attach it or Skip to send the original.",
1604
1652
  rectangle: "Rectangle",
@@ -1618,12 +1666,12 @@ function B(i, t) {
1618
1666
  h: Math.abs(i.y - t.y)
1619
1667
  };
1620
1668
  }
1621
- function Pi(i) {
1669
+ function zi(i) {
1622
1670
  if (i.type === "pen") return i.points.length < 2;
1623
1671
  const t = B(i.points[0], i.points[1]);
1624
1672
  return t.w < 3 && t.h < 3;
1625
1673
  }
1626
- function Bi(i, t, e, o) {
1674
+ function $i(i, t, e, o) {
1627
1675
  i.beginPath(), i.moveTo(t.x, t.y), i.lineTo(e.x, e.y), i.stroke();
1628
1676
  const n = Math.atan2(e.y - t.y, e.x - t.x), s = Math.max(10, o * 3);
1629
1677
  i.beginPath(), i.moveTo(e.x, e.y), i.lineTo(
@@ -1634,7 +1682,7 @@ function Bi(i, t, e, o) {
1634
1682
  e.y - s * Math.sin(n + Math.PI / 6)
1635
1683
  ), i.stroke();
1636
1684
  }
1637
- function Hi(i, t) {
1685
+ function _i(i, t) {
1638
1686
  if (t.length !== 0) {
1639
1687
  i.beginPath(), i.moveTo(t[0].x, t[0].y);
1640
1688
  for (let e = 1; e < t.length; e++)
@@ -1642,15 +1690,15 @@ function Hi(i, t) {
1642
1690
  i.stroke();
1643
1691
  }
1644
1692
  }
1645
- function Oi(i, t, e, o, n) {
1693
+ function Fi(i, t, e, o, n) {
1646
1694
  i.fillStyle = "rgb(15, 23, 42)", i.fillRect(t, e, o, n), i.fillStyle = "rgb(37, 47, 63)";
1647
- for (let s = e; s < e + n; s += T)
1648
- for (let a = t; a < t + o; a += T)
1649
- (Math.floor((a - t) / T) + Math.floor((s - e) / T)) % 2 === 0 && i.fillRect(
1695
+ for (let s = e; s < e + n; s += E)
1696
+ for (let a = t; a < t + o; a += E)
1697
+ (Math.floor((a - t) / E) + Math.floor((s - e) / E)) % 2 === 0 && i.fillRect(
1650
1698
  a,
1651
1699
  s,
1652
- Math.min(T, t + o - a),
1653
- Math.min(T, e + n - s)
1700
+ Math.min(E, t + o - a),
1701
+ Math.min(E, e + n - s)
1654
1702
  );
1655
1703
  }
1656
1704
  function H(i, t) {
@@ -1661,30 +1709,30 @@ function H(i, t) {
1661
1709
  break;
1662
1710
  }
1663
1711
  case "arrow":
1664
- Bi(i, t.points[0], t.points[1], t.strokeWidth);
1712
+ $i(i, t.points[0], t.points[1], t.strokeWidth);
1665
1713
  break;
1666
1714
  case "pen":
1667
- Hi(i, t.points);
1715
+ _i(i, t.points);
1668
1716
  break;
1669
1717
  case "blur": {
1670
1718
  const e = B(t.points[0], t.points[1]);
1671
- Oi(i, e.x, e.y, e.w, e.h);
1719
+ Fi(i, e.x, e.y, e.w, e.h);
1672
1720
  break;
1673
1721
  }
1674
1722
  }
1675
1723
  i.restore();
1676
1724
  }
1677
- function Ht(i) {
1725
+ function _t(i) {
1678
1726
  return new Promise((t, e) => {
1679
1727
  const o = new Image();
1680
1728
  o.onload = () => t(o), o.onerror = () => e(new Error("Failed to load screenshot")), o.src = i;
1681
1729
  });
1682
1730
  }
1683
- async function Ot(i, t, e = {}) {
1684
- const o = e.quality ?? Mi;
1731
+ async function Ft(i, t, e = {}) {
1732
+ const o = e.quality ?? Hi;
1685
1733
  let n;
1686
1734
  try {
1687
- n = await Ht(i);
1735
+ n = await _t(i);
1688
1736
  } catch {
1689
1737
  return i;
1690
1738
  }
@@ -1697,8 +1745,8 @@ async function Ot(i, t, e = {}) {
1697
1745
  H(a, c);
1698
1746
  return s.toDataURL("image/webp", o);
1699
1747
  }
1700
- let zi = 0;
1701
- class zt {
1748
+ let Ni = 0;
1749
+ class Nt {
1702
1750
  shapes = [];
1703
1751
  tool = "rect";
1704
1752
  opts;
@@ -1706,7 +1754,7 @@ class zt {
1706
1754
  color;
1707
1755
  palette;
1708
1756
  strokeWidth;
1709
- uid = `qaid-annotate-${++zi}`;
1757
+ uid = `qaid-annotate-${++Ni}`;
1710
1758
  container;
1711
1759
  canvas;
1712
1760
  ctx = null;
@@ -1720,7 +1768,7 @@ class zt {
1720
1768
  // after the editor is mounted).
1721
1769
  resolveResult;
1722
1770
  constructor(t) {
1723
- this.opts = t, this.labels = { ...Ri, ...t.labels ?? {} }, this.color = t.color ?? Ai, this.palette = (t.palette && t.palette.length ? t.palette : Ii).slice(), this.palette.some((e) => e.toLowerCase() === this.color.toLowerCase()) || this.palette.unshift(this.color), this.strokeWidth = t.strokeWidth ?? Di;
1771
+ this.opts = t, this.labels = { ...Oi, ...t.labels ?? {} }, this.color = t.color ?? Mi, this.palette = (t.palette && t.palette.length ? t.palette : Ri).slice(), this.palette.some((e) => e.toLowerCase() === this.color.toLowerCase()) || this.palette.unshift(this.color), this.strokeWidth = t.strokeWidth ?? Bi;
1724
1772
  }
1725
1773
  /** Mount the editor and resolve when the user commits (Done) or skips. */
1726
1774
  open() {
@@ -1742,7 +1790,7 @@ class zt {
1742
1790
  }
1743
1791
  /** A round colour swatch button for the toolbar's colour group. */
1744
1792
  swatchButton(t) {
1745
- const e = yt(t), o = q("button", {
1793
+ const e = kt(t), o = q("button", {
1746
1794
  type: "button",
1747
1795
  class: "qaid-annotate-swatch",
1748
1796
  "data-qaid-color": t,
@@ -1782,19 +1830,19 @@ class zt {
1782
1830
  "aria-label": this.labels.title
1783
1831
  });
1784
1832
  const a = q("div", { class: "qaid-annotate-tools" });
1785
- a.appendChild(this.toolButton("rect", de, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", ce, this.labels.arrow)), a.appendChild(this.toolButton("pen", le, this.labels.pen)), a.appendChild(this.toolButton("blur", he, this.labels.blur));
1833
+ a.appendChild(this.toolButton("rect", ue, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", pe, this.labels.arrow)), a.appendChild(this.toolButton("pen", fe, this.labels.pen)), a.appendChild(this.toolButton("blur", me, this.labels.blur));
1786
1834
  const c = q("div", {
1787
1835
  class: "qaid-annotate-colors",
1788
1836
  role: "group",
1789
1837
  "aria-label": this.labels.colors
1790
1838
  });
1791
1839
  for (const h of this.palette) c.appendChild(this.swatchButton(h));
1792
- this.undoBtn = this.actionButton("undo", ue, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
1793
- const l = this.actionButton("skip", fe, this.labels.skip, "qaid-annotate-skip"), d = this.actionButton("done", Et, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
1840
+ this.undoBtn = this.actionButton("undo", be, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
1841
+ const l = this.actionButton("skip", ve, this.labels.skip, "qaid-annotate-skip"), d = this.actionButton("done", At, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
1794
1842
  r.appendChild(this.undoBtn), r.appendChild(l), r.appendChild(d), this.toolbar.appendChild(a), this.toolbar.appendChild(c), this.toolbar.appendChild(r), this.container.appendChild(o), this.container.appendChild(n), this.container.appendChild(s), this.container.appendChild(this.toolbar), this.opts.root.appendChild(this.container), this.toolbar.addEventListener("click", this.onToolbarClick), this.canvas.addEventListener("pointerdown", this.onPointerDown), this.container.addEventListener("pointermove", this.onPointerMove), this.container.addEventListener("pointerup", this.onPointerUp), this.container.addEventListener("keydown", this.onKeyDown), this.opts.openDialog?.(this.container, {
1795
1843
  labelledbyId: t,
1796
1844
  describedbyId: e
1797
- }), this.opts.announce?.(this.labels.instructions), Ht(this.opts.dataUrl).then((h) => {
1845
+ }), this.opts.announce?.(this.labels.instructions), _t(this.opts.dataUrl).then((h) => {
1798
1846
  this.img = h, this.canvas.width = h.naturalWidth || h.width || 1, this.canvas.height = h.naturalHeight || h.height || 1, this.redraw();
1799
1847
  }).catch(() => {
1800
1848
  this.img = null, this.redraw();
@@ -1826,7 +1874,7 @@ class zt {
1826
1874
  n.getAttribute("data-qaid-tool") === t ? "true" : "false"
1827
1875
  );
1828
1876
  });
1829
- const o = this.labels[$i[t]];
1877
+ const o = this.labels[Vi[t]];
1830
1878
  this.opts.announce?.(`${o} tool selected`);
1831
1879
  }
1832
1880
  /** Set the active drawing colour; subsequent shapes use it. */
@@ -1836,7 +1884,7 @@ class zt {
1836
1884
  "aria-pressed",
1837
1885
  (o.getAttribute("data-qaid-color") ?? "").toLowerCase() === t.toLowerCase() ? "true" : "false"
1838
1886
  );
1839
- }), this.opts.announce?.(`${yt(t)} colour selected`);
1887
+ }), this.opts.announce?.(`${kt(t)} colour selected`);
1840
1888
  }
1841
1889
  onToolbarClick = (t) => {
1842
1890
  const o = t.target?.closest(
@@ -1875,7 +1923,7 @@ class zt {
1875
1923
  if (!this.drawing || !this.current) return;
1876
1924
  this.drawing = !1;
1877
1925
  const t = this.current;
1878
- if (this.current = null, Pi(t)) {
1926
+ if (this.current = null, zi(t)) {
1879
1927
  this.redraw();
1880
1928
  return;
1881
1929
  }
@@ -1904,7 +1952,7 @@ class zt {
1904
1952
  /** Composite the annotations and resolve with the new WebP data URL. */
1905
1953
  async done() {
1906
1954
  if (this.settled) return;
1907
- const t = await Ot(this.opts.dataUrl, this.shapes, {
1955
+ const t = await Ft(this.opts.dataUrl, this.shapes, {
1908
1956
  quality: this.opts.quality
1909
1957
  });
1910
1958
  this.opts.announce?.("Annotated screenshot attached"), this.settle(t);
@@ -1920,27 +1968,27 @@ class zt {
1920
1968
  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();
1921
1969
  }
1922
1970
  }
1923
- const $i = {
1971
+ const Vi = {
1924
1972
  rect: "rectangle",
1925
1973
  arrow: "arrow",
1926
1974
  pen: "pen",
1927
1975
  blur: "blur"
1928
1976
  };
1929
- function _i(i) {
1930
- return new zt(i).open();
1977
+ function Ui(i) {
1978
+ return new Nt(i).open();
1931
1979
  }
1932
- const wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1980
+ const xt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1933
1981
  __proto__: null,
1934
- AnnotationEditor: zt,
1935
- compositeAnnotations: Ot,
1982
+ AnnotationEditor: Nt,
1983
+ compositeAnnotations: Ft,
1936
1984
  drawShape: H,
1937
- openAnnotationEditor: _i,
1985
+ openAnnotationEditor: Ui,
1938
1986
  rectFromPoints: B
1939
1987
  }, Symbol.toStringTag, { value: "Module" }));
1940
- ci();
1941
- const Ni = document;
1988
+ pi();
1989
+ const ji = document;
1942
1990
  function p(i, t, ...e) {
1943
- const o = Ni.createElement(i);
1991
+ const o = ji.createElement(i);
1944
1992
  if (t) {
1945
1993
  if (t.class && (o.className = t.class), t.style && (o.style.cssText = t.style), t.html != null && (o.innerHTML = t.html), t.text != null && (o.textContent = t.text), t.attrs)
1946
1994
  for (const n in t.attrs) o.setAttribute(n, t.attrs[n]);
@@ -1951,7 +1999,7 @@ function p(i, t, ...e) {
1951
1999
  n != null && n !== !1 && o.append(n);
1952
2000
  return o;
1953
2001
  }
1954
- class Fi {
2002
+ class Ki {
1955
2003
  constructor(t) {
1956
2004
  this.host = t;
1957
2005
  }
@@ -1978,8 +2026,8 @@ class Fi {
1978
2026
  async startRecording(t = []) {
1979
2027
  if (!(this.isRecording || this.host.state !== "IDLE"))
1980
2028
  try {
1981
- this.networkCapture = ui();
1982
- const { createVideoRecorder: e } = await Promise.resolve().then(() => Bt);
2029
+ this.networkCapture = bi();
2030
+ const { createVideoRecorder: e } = await Promise.resolve().then(() => $t);
1983
2031
  this.videoRecorder = e({
1984
2032
  maxDuration: this.host.config.videoOptions.maxDuration,
1985
2033
  redactionElements: t
@@ -2087,7 +2135,7 @@ class Fi {
2087
2135
  attrs: { type: "button" },
2088
2136
  on: { click: () => this.stopRecording() }
2089
2137
  })
2090
- ), this.host.applyVars(this.recordingIndicator), this.host.overlayShadowHost && (this.host.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.recordingIndicator);
2138
+ ), this.host.applyVars(this.recordingIndicator), t.appendChild(this.recordingIndicator);
2091
2139
  }
2092
2140
  updateRecordingTimer(t) {
2093
2141
  if (!this.recordingIndicator) return;
@@ -2206,11 +2254,11 @@ class Fi {
2206
2254
  this.isRecording = !1, this.removeRecordingIndicator(), this.videoRecorder && (this.videoRecorder.destroy(), this.videoRecorder = null), this.networkCapture && (this.networkCapture.restore(), this.networkCapture = null), this.recordedBlob && (this.recordedBlob = null), this.host.setButtonsDisabled(!1), this.host.overlayShadowHost && this.host.state === "IDLE" && (this.host.overlayShadowHost.style.pointerEvents = "none");
2207
2255
  }
2208
2256
  }
2209
- const kt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2257
+ const qt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2210
2258
  __proto__: null,
2211
- RecordingController: Fi
2259
+ RecordingController: Ki
2212
2260
  }, Symbol.toStringTag, { value: "Module" }));
2213
- async function Vi(i = {}) {
2261
+ async function Wi(i = {}) {
2214
2262
  const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
2215
2263
  try {
2216
2264
  if (!navigator.mediaDevices?.getDisplayMedia)
@@ -2239,28 +2287,33 @@ async function Vi(i = {}) {
2239
2287
  return console.warn("Screenshot capture failed:", n), null;
2240
2288
  }
2241
2289
  }
2242
- const xt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2290
+ const Ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2243
2291
  __proto__: null,
2244
- captureScreenshot: Vi
2292
+ captureScreenshot: Wi
2245
2293
  }, Symbol.toStringTag, { value: "Module" }));
2246
- class Ui {
2294
+ class Xi {
2247
2295
  constructor(t) {
2248
2296
  this.host = t;
2249
2297
  }
2250
2298
  host;
2251
2299
  modalContainer = null;
2252
2300
  backdrop = null;
2301
+ /** Set once the message is sent, so closing does not PATCH over it. */
2302
+ finalized = !1;
2253
2303
  open() {
2304
+ this.finalized = !1;
2254
2305
  const t = this.host.ensureOverlayHost();
2255
2306
  this.backdrop = document.createElement("div"), this.backdrop.className = "qaid-backdrop", this.backdrop.style.zIndex = String(this.host.config.zIndex + 2), this.backdrop.style.background = `rgba(0, 0, 0, ${this.host.config.backdropOpacity})`, this.backdrop.addEventListener("click", () => this.close()), this.host.applyVars(this.backdrop), this.host.isMobile ? this.showBottomSheet() : this.showPositionedModal(), t.appendChild(this.backdrop), document.addEventListener("keydown", this.host.boundKeyDown);
2256
2307
  }
2257
2308
  /** Escape / external close. Runs the finalize-PATCH + teardown. */
2258
2309
  close() {
2259
- this.host.state === "MODAL_OPEN" && this.host.feedbackId && fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
2260
- method: "PATCH",
2261
- headers: { "Content-Type": "application/json" },
2262
- body: JSON.stringify({ message: null })
2263
- }).catch((t) => console.error("Failed to finalize feedback:", t)), this.teardown(), this.host.resetFeedbackUi();
2310
+ this.host.state === "MODAL_OPEN" && !this.finalized && (this.finalized = !0, this.host.whenFeedbackId().then((t) => {
2311
+ t && fetch(`${this.host.config.endpoint}/${t}`, {
2312
+ method: "PATCH",
2313
+ headers: { "Content-Type": "application/json" },
2314
+ body: JSON.stringify({ message: null })
2315
+ }).catch((e) => console.error("Failed to finalize feedback:", e));
2316
+ })), this.teardown(), this.host.resetFeedbackUi();
2264
2317
  }
2265
2318
  /** DOM/listener teardown only — no PATCH, no state reset (for embed destroy). */
2266
2319
  destroy() {
@@ -2281,7 +2334,7 @@ class Ui {
2281
2334
  ), this.host.applyVars(e), t.appendChild(e), this.modalContainer = e, this.setupModalInteractions();
2282
2335
  }
2283
2336
  showPositionedModal() {
2284
- const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = je(
2337
+ const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = Ye(
2285
2338
  this.host.selectedBounds,
2286
2339
  window.innerWidth,
2287
2340
  window.innerHeight,
@@ -2308,9 +2361,9 @@ class Ui {
2308
2361
  * markup, because they are documented as SVG/HTML strings.
2309
2362
  */
2310
2363
  buildModalContent() {
2311
- const { config: t, uid: e } = this.host, o = t.text, n = this.host.feedbackData.feedbackType, s = n === "up", a = t.positiveIcon || V, c = t.negativeIcon || U, l = t.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${t.buttonClass} ${s ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${s ? "qaid-type-up" : "qaid-type-down"}`, d = s ? "Feedback type: positive" : "Feedback type: negative", r = n === "neutral" ? p("span", {
2364
+ const { config: t, uid: e } = this.host, o = t.text, n = this.host.feedbackData.feedbackType, s = n === "up", a = t.positiveIcon || U, c = t.negativeIcon || j, l = t.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${t.buttonClass} ${s ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${s ? "qaid-type-up" : "qaid-type-down"}`, d = s ? "Feedback type: positive" : "Feedback type: negative", r = n === "neutral" ? p("span", {
2312
2365
  class: "qaid-type-static",
2313
- html: t.feedbackIcon || St,
2366
+ html: t.feedbackIcon || Et,
2314
2367
  attrs: { "aria-hidden": "true" }
2315
2368
  }) : p("button", {
2316
2369
  class: l,
@@ -2373,31 +2426,33 @@ class Ui {
2373
2426
  o && o.addEventListener("click", () => {
2374
2427
  const n = this.host.feedbackData.feedbackType === "up" ? "down" : "up";
2375
2428
  this.host.feedbackData.feedbackType = n, this.host.config.buttonClass ? (o.classList.toggle("qaid-btn-up", n === "up"), o.classList.toggle("qaid-btn-down", n === "down")) : (o.classList.toggle("qaid-type-up", n === "up"), o.classList.toggle("qaid-type-down", n === "down"));
2376
- const s = this.host.config.positiveIcon || V, a = this.host.config.negativeIcon || U;
2429
+ const s = this.host.config.positiveIcon || U, a = this.host.config.negativeIcon || j;
2377
2430
  o.innerHTML = n === "up" ? s : a;
2378
2431
  const c = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
2379
- o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", c), this.host.announceMsg(c), this.host.feedbackId && fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
2380
- method: "PATCH",
2381
- headers: { "Content-Type": "application/json" },
2382
- body: JSON.stringify({ feedbackType: n })
2383
- }).catch((l) => console.error("Failed to update feedback type:", l));
2432
+ o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", c), this.host.announceMsg(c), this.host.whenFeedbackId().then((l) => {
2433
+ l && fetch(`${this.host.config.endpoint}/${l}`, {
2434
+ method: "PATCH",
2435
+ headers: { "Content-Type": "application/json" },
2436
+ body: JSON.stringify({ feedbackType: n })
2437
+ }).catch((d) => console.error("Failed to update feedback type:", d));
2438
+ });
2384
2439
  });
2385
2440
  }
2386
2441
  async submitMessage(t) {
2387
2442
  let e = null;
2388
- if (this.host.feedbackId) {
2443
+ this.finalized = !0;
2444
+ const o = await this.host.whenFeedbackId();
2445
+ if (o)
2389
2446
  try {
2390
- const o = await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
2447
+ const n = await fetch(`${this.host.config.endpoint}/${o}`, {
2391
2448
  method: "PATCH",
2392
2449
  headers: { "Content-Type": "application/json" },
2393
2450
  body: JSON.stringify({ message: t })
2394
2451
  });
2395
- e = o.ok, o.ok || console.error("Failed to submit feedback message: HTTP", o.status);
2396
- } catch (o) {
2397
- console.error("Failed to submit feedback message:", o), e = !1;
2452
+ e = n.ok, n.ok || console.error("Failed to submit feedback message: HTTP", n.status);
2453
+ } catch (n) {
2454
+ console.error("Failed to submit feedback message:", n), e = !1;
2398
2455
  }
2399
- this.host.setFeedbackId(null);
2400
- }
2401
2456
  if (e === !1) {
2402
2457
  this.showResult(!1);
2403
2458
  return;
@@ -2434,7 +2489,7 @@ class Ui {
2434
2489
  { class: t ? "qaid-confirm" : "qaid-confirm qaid-confirm-error" },
2435
2490
  p("span", {
2436
2491
  class: "qaid-confirm-icon",
2437
- html: t ? Et : pe,
2492
+ html: t ? At : ge,
2438
2493
  attrs: { "aria-hidden": "true" }
2439
2494
  }),
2440
2495
  a,
@@ -2449,14 +2504,14 @@ class Ui {
2449
2504
  ), requestAnimationFrame(() => a.focus()), this.host.announceMsg(`${n} ${s}`, !0);
2450
2505
  }
2451
2506
  }
2452
- const qt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2507
+ const St = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2453
2508
  __proto__: null,
2454
- ModalController: Ui
2455
- }, Symbol.toStringTag, { value: "Module" })), $t = ["data-comp", "data-qa", "data-testid", "data-id"];
2456
- function _t(i, t = document.body) {
2509
+ ModalController: Xi
2510
+ }, Symbol.toStringTag, { value: "Module" })), Vt = ["data-comp", "data-qa", "data-testid", "data-id"];
2511
+ function Ut(i, t = document.body) {
2457
2512
  let e = i;
2458
2513
  for (; e && e !== t; ) {
2459
- for (const o of $t) {
2514
+ for (const o of Vt) {
2460
2515
  const n = e.getAttribute(o);
2461
2516
  if (n)
2462
2517
  return `${o}="${n}"`;
@@ -2465,37 +2520,37 @@ function _t(i, t = document.body) {
2465
2520
  }
2466
2521
  return null;
2467
2522
  }
2468
- function ji(i, t = 100) {
2523
+ function Yi(i, t = 100) {
2469
2524
  const e = i.textContent?.trim().slice(0, t) || "";
2470
2525
  return e.length === t ? e + "..." : e;
2471
2526
  }
2472
- function Ki(i) {
2527
+ function Qi(i) {
2473
2528
  let t = 1, e = i.previousElementSibling;
2474
2529
  for (; e; )
2475
2530
  t++, e = e.previousElementSibling;
2476
2531
  return t;
2477
2532
  }
2478
- function Wi(i) {
2533
+ function Ji(i) {
2479
2534
  const t = [];
2480
2535
  let e = i;
2481
2536
  for (; e && e !== document.body && e !== document.documentElement; ) {
2482
- const o = e.tagName.toLowerCase(), n = Ki(e);
2537
+ const o = e.tagName.toLowerCase(), n = Qi(e);
2483
2538
  t.unshift(`${o}:nth-child(${n})`), e = e.parentElement;
2484
2539
  }
2485
2540
  return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
2486
2541
  }
2487
- function Xi(i) {
2542
+ function Gi(i) {
2488
2543
  return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
2489
2544
  }
2490
- function Yi(i) {
2491
- const t = _t(i);
2492
- return t ? `[${t}]` : i.id ? `#${Xi(i.id)}` : Wi(i);
2545
+ function Zi(i) {
2546
+ const t = Ut(i);
2547
+ return t ? `[${t}]` : i.id ? `#${Gi(i.id)}` : Ji(i);
2493
2548
  }
2494
- function F(i) {
2495
- const t = ji(i), e = _t(i);
2496
- return { selector: Yi(i), text: t, dataAttr: e };
2549
+ function V(i) {
2550
+ const t = Yi(i), e = Ut(i);
2551
+ return { selector: Zi(i), text: t, dataAttr: e };
2497
2552
  }
2498
- const Qi = [
2553
+ const to = [
2499
2554
  "a[href]",
2500
2555
  "button",
2501
2556
  "input:not([type=hidden])",
@@ -2514,9 +2569,9 @@ const Qi = [
2514
2569
  "p",
2515
2570
  "li",
2516
2571
  "label",
2517
- ...$t.map((i) => `[${i}]`)
2518
- ].join(","), Ji = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
2519
- function Gi(i) {
2572
+ ...Vt.map((i) => `[${i}]`)
2573
+ ].join(","), eo = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
2574
+ function io(i) {
2520
2575
  if (i.hasAttribute("hidden") || i.getAttribute("aria-hidden") === "true") return !1;
2521
2576
  const t = i.ownerDocument?.defaultView;
2522
2577
  if (t && typeof t.getComputedStyle == "function") {
@@ -2525,14 +2580,14 @@ function Gi(i) {
2525
2580
  }
2526
2581
  return !0;
2527
2582
  }
2528
- function Zi(i = {}) {
2529
- const t = i.root ?? document.body, e = i.selector ?? Qi, o = i.isExcluded ?? (() => !1), n = i.isVisible ?? Gi;
2583
+ function oo(i = {}) {
2584
+ const t = i.root ?? document.body, e = i.selector ?? to, o = i.isExcluded ?? (() => !1), n = i.isVisible ?? io;
2530
2585
  return Array.from(t.querySelectorAll(e)).filter(
2531
2586
  (s) => !o(s) && n(s)
2532
2587
  );
2533
2588
  }
2534
- function to(i) {
2535
- const t = i.candidates ?? Zi({
2589
+ function no(i) {
2590
+ const t = i.candidates ?? oo({
2536
2591
  root: i.root,
2537
2592
  selector: i.selector,
2538
2593
  isExcluded: i.isExcluded,
@@ -2549,7 +2604,7 @@ function to(i) {
2549
2604
  if (!e) return;
2550
2605
  const k = u;
2551
2606
  if (typeof k.focus == "function") {
2552
- u.getAttribute("tabindex") === null && !Ji.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
2607
+ u.getAttribute("tabindex") === null && !eo.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
2553
2608
  try {
2554
2609
  k.focus();
2555
2610
  } catch {
@@ -2623,8 +2678,8 @@ function to(i) {
2623
2678
  stop: y
2624
2679
  };
2625
2680
  }
2626
- const eo = 12;
2627
- class io {
2681
+ const so = 12;
2682
+ class ao {
2628
2683
  constructor(t) {
2629
2684
  this.host = t;
2630
2685
  }
@@ -2653,12 +2708,12 @@ class io {
2653
2708
  * KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
2654
2709
  */
2655
2710
  startKeyboard(t) {
2656
- this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController = to({
2711
+ this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController = no({
2657
2712
  isExcluded: (e) => R(e),
2658
2713
  onHighlight: (e) => {
2659
2714
  const o = e.getBoundingClientRect(), n = this.highlightBox;
2660
2715
  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");
2661
- const { text: s } = F(e);
2716
+ const { text: s } = V(e);
2662
2717
  this.host.announceMsg(`Targeting ${s || e.tagName.toLowerCase()}`);
2663
2718
  },
2664
2719
  onSelect: (e) => this.selectKeyboardTarget(e),
@@ -2666,13 +2721,13 @@ class io {
2666
2721
  });
2667
2722
  }
2668
2723
  selectKeyboardTarget(t) {
2669
- const e = lt(t, 8);
2724
+ const e = ut(t, 8);
2670
2725
  Object.assign(this.host.selectedBounds, e, {
2671
2726
  clickX: e.x + e.width / 2,
2672
2727
  clickY: e.y + e.height / 2,
2673
2728
  visible: !0
2674
2729
  });
2675
- const { selector: o, text: n } = F(t);
2730
+ const { selector: o, text: n } = V(t);
2676
2731
  this.host.feedbackData.elementSelector = o, this.host.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.host.clearActiveThumb(), this.host.setState("SELECTED"), this.showSelectedMarker(), this.host.submitFeedback();
2677
2732
  }
2678
2733
  createTargetingOverlay() {
@@ -2691,7 +2746,7 @@ class io {
2691
2746
  /** Move the crosshair/scope reticle and highlight the element under (x, y). */
2692
2747
  updateReticleAt(t, e) {
2693
2748
  if (this.mousePos.x = t, this.mousePos.y = e, this.crosshairH && (this.crosshairH.style.top = `${e}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${e}px`), this.captureLayer && this.host.shadowHost) {
2694
- const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ct(t, e, o);
2749
+ const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ht(t, e, o);
2695
2750
  if (n && !R(n)) {
2696
2751
  if (this.highlightBox) {
2697
2752
  const s = n.getBoundingClientRect();
@@ -2710,16 +2765,16 @@ class io {
2710
2765
  }
2711
2766
  handleTouchEnd(t) {
2712
2767
  const e = t.changedTouches[0], o = this.touchStartPos;
2713
- this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) > eo) && (t.preventDefault(), this.selectAt(e.clientX, e.clientY));
2768
+ this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) > so) && (t.preventDefault(), this.selectAt(e.clientX, e.clientY));
2714
2769
  }
2715
2770
  /** Select the element under (x, y) and tear down targeting. */
2716
2771
  selectAt(t, e) {
2717
- const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ct(t, e, o);
2772
+ const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ht(t, e, o);
2718
2773
  if (!n || R(n))
2719
2774
  return;
2720
- const s = lt(n, 8);
2775
+ const s = ut(n, 8);
2721
2776
  Object.assign(this.host.selectedBounds, s, { clickX: t, clickY: e, visible: !0 });
2722
- const { selector: a, text: c } = F(n);
2777
+ const { selector: a, text: c } = V(n);
2723
2778
  this.host.feedbackData.elementSelector = a, this.host.feedbackData.elementText = c, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.host.setState("SELECTED"), this.host.clearActiveThumb(), this.showSelectedMarker(), this.host.submitFeedback();
2724
2779
  }
2725
2780
  stopTargetingListeners() {
@@ -2743,22 +2798,22 @@ class io {
2743
2798
  this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), this.hideMarker();
2744
2799
  }
2745
2800
  }
2746
- const Ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2801
+ const Tt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2747
2802
  __proto__: null,
2748
- TargetingController: io
2803
+ TargetingController: ao
2749
2804
  }, Symbol.toStringTag, { value: "Module" }));
2750
2805
  export {
2751
- zt as AnnotationEditor,
2752
- ni as QaidFeedback,
2753
- Ti as captureDomScreenshot,
2754
- ui as captureNetworkErrors,
2755
- Ot as compositeAnnotations,
2756
- xi as createVideoRecorder,
2806
+ Nt as AnnotationEditor,
2807
+ di as QaidFeedback,
2808
+ Di as captureDomScreenshot,
2809
+ bi as captureNetworkErrors,
2810
+ Ft as compositeAnnotations,
2811
+ Ti as createVideoRecorder,
2757
2812
  H as drawShape,
2758
- Pt as getSupportedMimeType,
2759
- Si as isDomScreenshotSupported,
2760
- ki as isVideoRecordingSupported,
2761
- _i as openAnnotationEditor,
2813
+ zt as getSupportedMimeType,
2814
+ Li as isDomScreenshotSupported,
2815
+ Si as isVideoRecordingSupported,
2816
+ Ui as openAnnotationEditor,
2762
2817
  B as rectFromPoints
2763
2818
  };
2764
2819
  //# sourceMappingURL=index.js.map