@qaiddev/thumbs-embed 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/qaid.js CHANGED
@@ -1,30 +1,27 @@
1
- var Q = Object.defineProperty;
2
- var tt = (e, t, o) => t in e ? Q(e, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : e[t] = o;
3
- var h = (e, t, o) => tt(e, typeof t != "symbol" ? t + "" : t, o);
4
- const T = `<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 E = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
5
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"/>
6
- </svg>`, I = `<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>`, T = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
7
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"/>
8
- </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">
5
+ </svg>`, Z = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
9
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"/>
10
- </svg>`, it = "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}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;top:0;right:0;bottom:0;left: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;top:10px;right:10px;bottom:10px;left: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;top:20px;right:20px;bottom:20px;left:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;top:0;right:0;bottom:0;left: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;-moz-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;-moz-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;-moz-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;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:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;-moz-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}", ot = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
11
- let x = 0;
12
- const nt = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", at = {
7
+ </svg>`, Q = "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}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;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:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}", tt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
8
+ let w = 0;
9
+ const et = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", it = {
13
10
  small: 36,
14
11
  medium: 48,
15
12
  large: 64
16
- }, st = {
13
+ }, ot = {
17
14
  small: 18,
18
15
  medium: 24,
19
16
  large: 32
20
17
  };
21
- function rt(e, t, o) {
22
- const [i, n, a] = [e, t, o].map((s) => (s = s / 255, s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4)));
23
- return 0.2126 * i + 0.7152 * n + 0.0722 * a;
18
+ function nt(e, t, i) {
19
+ const [o, n, s] = [e, t, i].map((r) => (r = r / 255, r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4)));
20
+ return 0.2126 * o + 0.7152 * n + 0.0722 * s;
24
21
  }
25
- function dt(e) {
22
+ function st(e) {
26
23
  if (e.startsWith("#")) {
27
- const o = e.slice(1), i = o.length === 3 ? o.split("").map((a) => a + a).join("") : o, n = parseInt(i, 16);
24
+ const i = e.slice(1), o = i.length === 3 ? i.split("").map((s) => s + s).join("") : i, n = parseInt(o, 16);
28
25
  return {
29
26
  r: n >> 16 & 255,
30
27
  g: n >> 8 & 255,
@@ -38,248 +35,247 @@ function dt(e) {
38
35
  b: parseInt(t[3])
39
36
  } : null;
40
37
  }
41
- function ct(e) {
42
- const t = dt(e);
43
- return t && rt(t.r, t.g, t.b) > 0.4 ? "black" : "white";
38
+ function at(e) {
39
+ const t = st(e);
40
+ return t && nt(t.r, t.g, t.b) > 0.4 ? "black" : "white";
44
41
  }
45
- function lt(e = {}) {
42
+ function rt(e = {}) {
46
43
  const {
47
44
  positiveColor: t = "rgb(0, 200, 83)",
48
- negativeColor: o = "rgb(255, 0, 0)",
49
- markerColor: i = "#6366f1",
45
+ negativeColor: i = "rgb(255, 0, 0)",
46
+ markerColor: o = "#6366f1",
50
47
  buttonSize: n = "medium",
51
- modalWidth: a = 400,
52
- backdropOpacity: s = 0.3,
48
+ modalWidth: s = 400,
49
+ backdropOpacity: r = 0.3,
53
50
  fontFamily: l = "system-ui, -apple-system, sans-serif",
54
51
  fontSize: d = 16
55
- } = e, r = at[n], c = st[n], u = ct(i);
52
+ } = e, a = it[n], c = ot[n], h = at(o);
56
53
  return {
57
54
  "--qaid-positive": t,
58
- "--qaid-negative": o,
59
- "--qaid-marker": i,
60
- "--qaid-marker-text": u,
61
- "--qaid-btn-size": `${r}px`,
55
+ "--qaid-negative": i,
56
+ "--qaid-marker": o,
57
+ "--qaid-marker-text": h,
58
+ "--qaid-btn-size": `${a}px`,
62
59
  "--qaid-icon-size": `${c}px`,
63
- "--qaid-modal-width": `${a}px`,
64
- "--qaid-backdrop-opacity": String(s),
60
+ "--qaid-modal-width": `${s}px`,
61
+ "--qaid-backdrop-opacity": String(r),
65
62
  "--qaid-font-family": l,
66
63
  "--qaid-font-size": `${d}px`
67
64
  };
68
65
  }
69
- function ht(e, t) {
70
- for (const [o, i] of Object.entries(t))
71
- e.style.setProperty(o, i);
66
+ function dt(e, t) {
67
+ for (const [i, o] of Object.entries(t))
68
+ e.style.setProperty(i, o);
72
69
  }
73
70
  function B() {
74
- return it + nt;
71
+ return Q + et;
75
72
  }
76
- function ut() {
77
- if (x++, x > 1) return;
73
+ function ct() {
74
+ if (w++, w > 1) return;
78
75
  const e = document.createElement("style");
79
- e.id = "qaid-styles", e.textContent = ot, document.head.appendChild(e);
76
+ e.id = "qaid-styles", e.textContent = tt, document.head.appendChild(e);
80
77
  }
81
- function pt() {
82
- if (!(x <= 0) && (x--, x === 0)) {
78
+ function lt() {
79
+ if (!(w <= 0) && (w--, w === 0)) {
83
80
  const e = document.getElementById("qaid-styles");
84
81
  e && e.remove();
85
82
  }
86
83
  }
87
- const mt = ["data-comp", "data-qa", "data-testid", "data-id"];
88
- function U(e, t = document.body) {
89
- let o = e;
90
- for (; o && o !== t; ) {
91
- for (const i of mt) {
92
- const n = o.getAttribute(i);
84
+ const ht = ["data-comp", "data-qa", "data-testid", "data-id"];
85
+ function V(e, t = document.body) {
86
+ let i = e;
87
+ for (; i && i !== t; ) {
88
+ for (const o of ht) {
89
+ const n = i.getAttribute(o);
93
90
  if (n)
94
- return `${i}="${n}"`;
91
+ return `${o}="${n}"`;
95
92
  }
96
- o = o.parentElement;
93
+ i = i.parentElement;
97
94
  }
98
95
  return null;
99
96
  }
100
- function ft(e, t = 100) {
101
- var i;
102
- const o = ((i = e.textContent) == null ? void 0 : i.trim().slice(0, t)) || "";
103
- return o.length === t ? o + "..." : o;
97
+ function ut(e, t = 100) {
98
+ const i = e.textContent?.trim().slice(0, t) || "";
99
+ return i.length === t ? i + "..." : i;
104
100
  }
105
- function gt(e) {
106
- let t = 1, o = e.previousElementSibling;
107
- for (; o; )
108
- t++, o = o.previousElementSibling;
101
+ function pt(e) {
102
+ let t = 1, i = e.previousElementSibling;
103
+ for (; i; )
104
+ t++, i = i.previousElementSibling;
109
105
  return t;
110
106
  }
111
- function bt(e) {
107
+ function mt(e) {
112
108
  const t = [];
113
- let o = e;
114
- for (; o && o !== document.body && o !== document.documentElement; ) {
115
- const i = o.tagName.toLowerCase(), n = gt(o);
116
- t.unshift(`${i}:nth-child(${n})`), o = o.parentElement;
109
+ let i = e;
110
+ for (; i && i !== document.body && i !== document.documentElement; ) {
111
+ const o = i.tagName.toLowerCase(), n = pt(i);
112
+ t.unshift(`${o}:nth-child(${n})`), i = i.parentElement;
117
113
  }
118
114
  return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
119
115
  }
120
- function vt(e) {
116
+ function ft(e) {
121
117
  return e.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
122
118
  }
123
- function yt(e) {
124
- const t = U(e);
125
- return t ? `[${t}]` : e.id ? `#${vt(e.id)}` : bt(e);
119
+ function bt(e) {
120
+ const t = V(e);
121
+ return t ? `[${t}]` : e.id ? `#${ft(e.id)}` : mt(e);
126
122
  }
127
- function wt(e) {
128
- const t = ft(e), o = U(e);
129
- return { selector: yt(e), text: t, dataAttr: o };
123
+ function gt(e) {
124
+ const t = ut(e), i = V(e);
125
+ return { selector: bt(e), text: t, dataAttr: i };
130
126
  }
131
- const F = {
127
+ const U = {
132
128
  width: 400,
133
129
  height: 280,
134
130
  arrowHeight: 12,
135
131
  gap: 8,
136
132
  viewportPadding: 16
137
133
  };
138
- function xt(e, t, o, i, n) {
139
- const a = e.y, s = t - (e.y + e.height);
140
- if (s >= o + i)
134
+ function vt(e, t, i, o, n) {
135
+ const s = e.y, r = t - (e.y + e.height);
136
+ if (r >= i + o)
141
137
  return {
142
- top: e.y + e.height + i,
138
+ top: e.y + e.height + o,
143
139
  position: "below"
144
140
  };
145
- if (a >= o + i)
141
+ if (s >= i + o)
146
142
  return {
147
- top: e.y - o - i,
143
+ top: e.y - i - o,
148
144
  position: "above"
149
145
  };
150
- const l = s > a ? "below" : "above";
146
+ const l = r > s ? "below" : "above";
151
147
  let d;
152
148
  return l === "below" ? d = Math.min(
153
- e.y + e.height + i,
154
- t - o - n
155
- ) : d = Math.max(n, e.y - o - i), { top: d, position: l };
149
+ e.y + e.height + o,
150
+ t - i - n
151
+ ) : d = Math.max(n, e.y - i - o), { top: d, position: l };
156
152
  }
157
- function qt(e, t, o, i) {
158
- let a = e.x + e.width / 2 - o / 2;
159
- return a = Math.max(i, Math.min(a, t - o - i)), a;
153
+ function yt(e, t, i, o) {
154
+ let s = e.x + e.width / 2 - i / 2;
155
+ return s = Math.max(o, Math.min(s, t - i - o)), s;
160
156
  }
161
- function kt(e, t, o, i = 24, n = 24) {
162
- const s = e.clickX - t - n / 2;
163
- return Math.max(i, Math.min(s, o - i - n / 2));
157
+ function wt(e, t, i, o = 24, n = 24) {
158
+ const r = e.clickX - t - n / 2;
159
+ return Math.max(o, Math.min(r, i - o - n / 2));
164
160
  }
165
- function Ct(e, t, o, i = F) {
166
- const n = i.height + i.arrowHeight, a = xt(
161
+ function xt(e, t, i, o = U) {
162
+ const n = o.height + o.arrowHeight, s = vt(
167
163
  e,
168
- o,
164
+ i,
169
165
  n,
170
- i.gap,
171
- i.viewportPadding
172
- ), s = qt(
166
+ o.gap,
167
+ o.viewportPadding
168
+ ), r = yt(
173
169
  e,
174
170
  t,
175
- i.width,
176
- i.viewportPadding
171
+ o.width,
172
+ o.viewportPadding
177
173
  );
178
174
  return {
179
- top: a.top,
180
- left: s,
181
- position: a.position
175
+ top: s.top,
176
+ left: r,
177
+ position: s.position
182
178
  };
183
179
  }
184
- function St(e, t, o, i = F) {
185
- const n = Ct(e, t, o, i), a = kt(
180
+ function qt(e, t, i, o = U) {
181
+ const n = xt(e, t, i, o), s = wt(
186
182
  e,
187
183
  n.left,
188
- i.width
184
+ o.width
189
185
  );
190
186
  return {
191
187
  modal: n,
192
- arrow: { left: a }
188
+ arrow: { left: s }
193
189
  };
194
190
  }
195
- const Et = 20;
196
- function Tt(e) {
197
- const t = [], o = console.error, i = console.warn, n = console.log, a = (s, l) => {
191
+ const kt = 20;
192
+ function Ct(e) {
193
+ const t = [], i = console.error, o = console.warn, n = console.log, s = (r, l) => {
198
194
  const d = {
199
- message: l.map((r) => String(r)).join(" "),
195
+ message: l.map((a) => String(a)).join(" "),
200
196
  timestamp: Date.now(),
201
- level: s
197
+ level: r
202
198
  };
203
- t.length >= Et && t.shift(), t.push(d), e && e(d);
199
+ t.length >= kt && t.shift(), t.push(d), e && e(d);
204
200
  };
205
- return console.error = function(...s) {
206
- a("error", s), o.apply(console, s);
207
- }, console.warn = function(...s) {
208
- a("warn", s), i.apply(console, s);
209
- }, console.log = function(...s) {
210
- a("log", s), n.apply(console, s);
201
+ return console.error = function(...r) {
202
+ s("error", r), i.apply(console, r);
203
+ }, console.warn = function(...r) {
204
+ s("warn", r), o.apply(console, r);
205
+ }, console.log = function(...r) {
206
+ s("log", r), n.apply(console, r);
211
207
  }, {
212
208
  errors: t,
213
209
  restore: () => {
214
- console.error = o, console.warn = i, console.log = n;
210
+ console.error = i, console.warn = o, console.log = n;
215
211
  }
216
212
  };
217
213
  }
218
- const It = 20, P = 4096;
219
- function k(e) {
214
+ const St = 20, z = 4096;
215
+ function q(e) {
220
216
  if (e == null) return;
221
217
  const t = typeof e == "string" ? e : JSON.stringify(e);
222
- return t.length > P ? t.slice(0, P) + "…[truncated]" : t;
218
+ return t.length > z ? t.slice(0, z) + "…[truncated]" : t;
223
219
  }
224
- function A(e, t) {
225
- e.length >= It && e.shift(), e.push(t);
220
+ function O(e, t) {
221
+ e.length >= St && e.shift(), e.push(t);
226
222
  }
227
- async function Lt(e) {
223
+ async function Et(e) {
228
224
  try {
229
225
  const t = await e.clone().text();
230
- return k(t);
226
+ return q(t);
231
227
  } catch {
232
228
  return;
233
229
  }
234
230
  }
235
- function Rt() {
231
+ function Tt() {
236
232
  const e = [], t = window.fetch;
237
- window.fetch = async function(n, a) {
238
- const s = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, l = (a == null ? void 0 : a.method) ?? (typeof n == "object" && "method" in n ? n.method : "GET");
233
+ window.fetch = async function(n, s) {
234
+ const r = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, l = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
239
235
  let d;
240
- a != null && a.body && (d = k(a.body));
241
- const r = await t.apply(window, [n, a]);
242
- if (r.status >= 400) {
243
- const c = await Lt(r);
244
- A(e, {
245
- url: s,
236
+ s?.body && (d = q(s.body));
237
+ const a = await t.apply(window, [n, s]);
238
+ if (a.status >= 400) {
239
+ const c = await Et(a);
240
+ O(e, {
241
+ url: r,
246
242
  method: l.toUpperCase(),
247
- status: r.status,
248
- statusText: r.statusText,
243
+ status: a.status,
244
+ statusText: a.statusText,
249
245
  requestBody: d,
250
246
  responseBody: c,
251
247
  timestamp: Date.now()
252
248
  });
253
249
  }
254
- return r;
250
+ return a;
255
251
  };
256
- const o = XMLHttpRequest.prototype.open, i = XMLHttpRequest.prototype.send;
257
- return XMLHttpRequest.prototype.open = function(n, a, ...s) {
258
- return this._qaid_method = n, this._qaid_url = typeof a == "string" ? a : a.toString(), o.apply(this, [n, a, ...s]);
252
+ const i = XMLHttpRequest.prototype.open, o = XMLHttpRequest.prototype.send;
253
+ return XMLHttpRequest.prototype.open = function(n, s, ...r) {
254
+ return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), i.apply(this, [n, s, ...r]);
259
255
  }, XMLHttpRequest.prototype.send = function(n) {
260
- const a = this, s = n ? k(n) : void 0;
261
- return a.addEventListener("load", function() {
262
- a.status >= 400 && A(e, {
263
- url: a._qaid_url,
264
- method: a._qaid_method.toUpperCase(),
265
- status: a.status,
266
- statusText: a.statusText,
267
- requestBody: s,
268
- responseBody: k(a.responseText),
256
+ const s = this, r = n ? q(n) : void 0;
257
+ return s.addEventListener("load", function() {
258
+ s.status >= 400 && O(e, {
259
+ url: s._qaid_url,
260
+ method: s._qaid_method.toUpperCase(),
261
+ status: s.status,
262
+ statusText: s.statusText,
263
+ requestBody: r,
264
+ responseBody: q(s.responseText),
269
265
  timestamp: Date.now()
270
266
  });
271
- }), i.apply(this, [n]);
267
+ }), o.apply(this, [n]);
272
268
  }, {
273
269
  errors: e,
274
270
  restore: () => {
275
- window.fetch = t, XMLHttpRequest.prototype.open = o, XMLHttpRequest.prototype.send = i;
271
+ window.fetch = t, XMLHttpRequest.prototype.open = i, XMLHttpRequest.prototype.send = o;
276
272
  }
277
273
  };
278
274
  }
279
- function Mt() {
275
+ function It() {
280
276
  return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
281
277
  }
282
- function Dt() {
278
+ function Lt() {
283
279
  if (typeof MediaRecorder > "u") return "";
284
280
  const e = [
285
281
  "video/webm;codecs=vp9",
@@ -292,22 +288,22 @@ function Dt() {
292
288
  return t;
293
289
  return "";
294
290
  }
295
- function zt(e = {}) {
296
- const t = e.maxDuration ?? 15, o = e.videoBitsPerSecond ?? 8e5;
297
- let i = null, n = null, a = [], s = null, l = null, d = null, r = 0, c = null, u = null, p = !1, f = null;
298
- function b() {
299
- d !== null && (clearInterval(d), d = null), f !== null && (clearTimeout(f), f = null), i && (i.getTracks().forEach((m) => m.stop()), i = null), n = null, a = [], s = null, l = null, c = null, u = null;
300
- }
291
+ function Rt(e = {}) {
292
+ const t = e.maxDuration ?? 15, i = e.videoBitsPerSecond ?? 8e5;
293
+ let o = null, n = null, s = [], r = null, l = null, d = null, a = 0, c = null, h = null, u = !1, p = null;
301
294
  function g() {
302
- p || (p = !0, n && n.state !== "inactive" && n.stop());
295
+ d !== null && (clearInterval(d), d = null), p !== null && (clearTimeout(p), p = null), o && (o.getTracks().forEach((m) => m.stop()), o = null), n = null, s = [], r = null, l = null, c = null, h = null;
296
+ }
297
+ function f() {
298
+ u || (u = !0, n && n.state !== "inactive" && n.stop());
303
299
  }
304
300
  return {
305
301
  async start() {
306
- p = !1, a = [];
307
- const m = Dt();
302
+ u = !1, s = [];
303
+ const m = Lt();
308
304
  if (!m)
309
305
  throw new Error("No supported video MIME type found");
310
- i = await navigator.mediaDevices.getDisplayMedia({
306
+ o = await navigator.mediaDevices.getDisplayMedia({
311
307
  video: {
312
308
  frameRate: 15
313
309
  },
@@ -315,129 +311,128 @@ function zt(e = {}) {
315
311
  // @ts-expect-error preferCurrentTab is not in the TS types yet
316
312
  preferCurrentTab: !0
317
313
  });
318
- const v = i.getVideoTracks()[0];
314
+ const v = o.getVideoTracks()[0];
319
315
  v && v.addEventListener("ended", () => {
320
- g();
321
- }), n = new MediaRecorder(i, {
316
+ f();
317
+ }), n = new MediaRecorder(o, {
322
318
  mimeType: m,
323
- videoBitsPerSecond: o
324
- }), n.ondataavailable = (y) => {
325
- y.data.size > 0 && a.push(y.data);
319
+ videoBitsPerSecond: i
320
+ }), n.ondataavailable = (b) => {
321
+ b.data.size > 0 && s.push(b.data);
326
322
  }, n.onstop = () => {
327
- const y = new Blob(a, { type: m });
328
- c && c(y), l && l(y), i && i.getTracks().forEach((q) => q.stop());
323
+ const b = new Blob(s, { type: m });
324
+ c && c(b), l && l(b), o && o.getTracks().forEach((x) => x.stop());
329
325
  }, n.onerror = () => {
330
- u && u(new Error("MediaRecorder error"));
331
- }, n.start(1e3), r = Date.now(), d = setInterval(() => {
332
- const y = Math.floor((Date.now() - r) / 1e3);
333
- s && s(y);
334
- }, 1e3), f = setTimeout(() => {
335
- g();
326
+ h && h(new Error("MediaRecorder error"));
327
+ }, n.start(1e3), a = Date.now(), d = setInterval(() => {
328
+ const b = Math.floor((Date.now() - a) / 1e3);
329
+ r && r(b);
330
+ }, 1e3), p = setTimeout(() => {
331
+ f();
336
332
  }, t * 1e3);
337
333
  },
338
334
  stop() {
339
335
  return new Promise((m, v) => {
340
- c = m, u = v, g();
336
+ c = m, h = v, f();
341
337
  });
342
338
  },
343
339
  onTick(m) {
344
- s = m;
340
+ r = m;
345
341
  },
346
342
  onStop(m) {
347
343
  l = m;
348
344
  },
349
345
  destroy() {
350
- g(), b();
346
+ f(), g();
351
347
  }
352
348
  };
353
349
  }
354
350
  function Ht(e = 640) {
355
351
  return typeof window < "u" && window.innerWidth < e;
356
352
  }
357
- function O(e, t, o) {
358
- const i = o.map((a) => a.style.visibility);
359
- o.forEach((a) => a.style.visibility = "hidden");
353
+ function P(e, t, i) {
354
+ const o = i.map((s) => s.style.visibility);
355
+ i.forEach((s) => s.style.visibility = "hidden");
360
356
  const n = document.elementFromPoint(e, t);
361
- return o.forEach((a, s) => a.style.visibility = i[s]), n;
357
+ return i.forEach((s, r) => s.style.visibility = o[r]), n;
362
358
  }
363
- function $(e) {
359
+ function A(e) {
364
360
  return e ? e.hasAttribute("data-qaid-embed") || e.hasAttribute("data-qaid-embed-overlay") ? !0 : !!e.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
365
361
  }
366
- function Bt(e, t = 0) {
367
- const o = e.getBoundingClientRect();
362
+ function Mt(e, t = 0) {
363
+ const i = e.getBoundingClientRect();
368
364
  return {
369
- x: o.left - t,
370
- y: o.top - t,
371
- width: o.width + t * 2,
372
- height: o.height + t * 2
365
+ x: i.left - t,
366
+ y: i.top - t,
367
+ width: i.width + t * 2,
368
+ height: i.height + t * 2
373
369
  };
374
370
  }
375
- async function Pt(e = {}) {
376
- var n;
377
- const { quality: t = 1, maxWidth: o = 1280, maxHeight: i = 800 } = e;
371
+ async function Dt(e = {}) {
372
+ const { quality: t = 1, maxWidth: i = 1280, maxHeight: o = 800 } = e;
378
373
  try {
379
- if (!((n = navigator.mediaDevices) != null && n.getDisplayMedia))
374
+ if (!navigator.mediaDevices?.getDisplayMedia)
380
375
  return console.warn("Screen Capture API not available"), null;
381
- const a = await navigator.mediaDevices.getDisplayMedia({
376
+ const n = await navigator.mediaDevices.getDisplayMedia({
382
377
  preferCurrentTab: !0,
383
378
  video: {
384
379
  displaySurface: "browser"
385
380
  }
386
- }), s = a.getVideoTracks()[0], l = s.getSettings(), d = document.createElement("video");
387
- d.srcObject = a, d.muted = !0, await new Promise((m) => {
388
- d.onloadedmetadata = () => {
389
- d.play(), m();
381
+ }), s = n.getVideoTracks()[0], r = s.getSettings(), l = document.createElement("video");
382
+ l.srcObject = n, l.muted = !0, await new Promise((f) => {
383
+ l.onloadedmetadata = () => {
384
+ l.play(), f();
390
385
  };
391
- }), await new Promise((m) => {
392
- const v = () => {
393
- d.readyState >= 2 ? m() : requestAnimationFrame(v);
386
+ }), await new Promise((f) => {
387
+ const m = () => {
388
+ l.readyState >= 2 ? f() : requestAnimationFrame(m);
394
389
  };
395
- v();
396
- }), await new Promise((m) => setTimeout(m, 100));
397
- const r = l.width || d.videoWidth, c = l.height || d.videoHeight, u = Math.min(o / r, i / c, 1), p = Math.round(r * u), f = Math.round(c * u), b = document.createElement("canvas");
398
- b.width = p, b.height = f;
399
- const g = b.getContext("2d");
400
- return g ? (g.drawImage(d, 0, 0, p, f), s.stop(), b.toDataURL("image/webp", t)) : (s.stop(), null);
401
- } catch (a) {
402
- return console.warn("Screenshot capture failed:", a), null;
390
+ m();
391
+ }), await new Promise((f) => setTimeout(f, 100));
392
+ const d = r.width || l.videoWidth, a = r.height || l.videoHeight, c = Math.min(i / d, o / a, 1), h = Math.round(d * c), u = Math.round(a * c), p = document.createElement("canvas");
393
+ p.width = h, p.height = u;
394
+ const g = p.getContext("2d");
395
+ return g ? (g.drawImage(l, 0, 0, h, u), s.stop(), p.toDataURL("image/webp", t)) : (s.stop(), null);
396
+ } catch (n) {
397
+ return console.warn("Screenshot capture failed:", n), null;
403
398
  }
404
399
  }
405
- const N = "https://qaid.dev/lib/html2canvas.min.js", At = 1e4, Ot = 50;
406
- let w = null;
407
- function _t() {
400
+ const $ = "https://qaid.dev/lib/html2canvas.min.js", Bt = 1e4, zt = 50;
401
+ let y = null;
402
+ function Ut() {
408
403
  if (typeof document > "u" || typeof window > "u")
409
404
  return !1;
410
405
  const e = document.createElement("canvas");
411
406
  return typeof e.getContext == "function" && !!e.getContext("2d");
412
407
  }
413
- function $t() {
414
- return window.html2canvas ? Promise.resolve(!0) : w || (w = new Promise((e) => {
408
+ function Ot() {
409
+ return window.html2canvas ? Promise.resolve(!0) : y || (y = new Promise((e) => {
415
410
  if (!document.querySelector(
416
- `script[src="${N}"]`
411
+ `script[src="${$}"]`
417
412
  )) {
418
413
  const n = document.createElement("script");
419
- n.src = N, n.async = !0, document.head.appendChild(n);
414
+ n.src = $, n.async = !0, document.head.appendChild(n);
420
415
  }
421
- const o = Date.now(), i = () => {
416
+ const i = Date.now(), o = () => {
422
417
  if (window.html2canvas) {
423
418
  e(!0);
424
419
  return;
425
420
  }
426
- if (Date.now() - o > At) {
427
- w = null, e(!1);
421
+ if (Date.now() - i > Bt) {
422
+ y = null, e(!1);
428
423
  return;
429
424
  }
430
- setTimeout(i, Ot);
425
+ setTimeout(o, zt);
431
426
  };
432
- i();
433
- }), w);
427
+ o();
428
+ }), y);
434
429
  }
435
- async function Nt(e = {}) {
436
- const { quality: t = 0.8, maxWidth: o = 1280, maxHeight: i = 800 } = e;
430
+ async function Pt(e = {}) {
431
+ const { quality: t = 0.8, maxWidth: i = 1280, maxHeight: o = 800 } = e;
437
432
  try {
438
- if (!await $t() || !window.html2canvas)
433
+ if (!await Ot() || !window.html2canvas)
439
434
  return console.warn("html2canvas failed to load"), null;
440
- const a = await window.html2canvas(document.body, {
435
+ const s = await window.html2canvas(document.body, {
441
436
  useCORS: !0,
442
437
  allowTaint: !1,
443
438
  logging: !1,
@@ -447,91 +442,90 @@ async function Nt(e = {}) {
447
442
  height: document.documentElement.clientHeight,
448
443
  x: window.scrollX,
449
444
  y: window.scrollY,
450
- ignoreElements: (r) => {
451
- var c, u, p;
452
- return r instanceof HTMLElement ? r.classList.contains("qaid-buttons") || r.classList.contains("qaid-targeting-overlay") || r.classList.contains("qaid-modal-container") || r.classList.contains("qaid-bottom-sheet") || r.classList.contains("qaid-backdrop") || r.classList.contains("qaid-selected-marker") || r.classList.contains("qaid-tooltip-text") || r.classList.contains("qaid-recording-indicator") || r.classList.contains("qaid-video-preview") || ((p = (c = r.className) == null ? void 0 : (u = c.toString()).startsWith) == null ? void 0 : p.call(u, "qaid-")) : !1;
453
- }
454
- }), s = a.width, l = a.height, d = Math.min(o / s, i / l, 1);
445
+ ignoreElements: (a) => a instanceof HTMLElement ? a.classList.contains("qaid-buttons") || a.classList.contains("qaid-targeting-overlay") || a.classList.contains("qaid-modal-container") || a.classList.contains("qaid-bottom-sheet") || a.classList.contains("qaid-backdrop") || a.classList.contains("qaid-selected-marker") || a.classList.contains("qaid-tooltip-text") || a.classList.contains("qaid-recording-indicator") || a.classList.contains("qaid-video-preview") || a.className?.toString().startsWith?.("qaid-") : !1
446
+ }), r = s.width, l = s.height, d = Math.min(i / r, o / l, 1);
455
447
  if (d < 1) {
456
- const r = Math.round(s * d), c = Math.round(l * d), u = document.createElement("canvas");
457
- u.width = r, u.height = c;
458
- const p = u.getContext("2d");
459
- return p ? (p.drawImage(a, 0, 0, r, c), u.toDataURL("image/webp", t)) : null;
448
+ const a = Math.round(r * d), c = Math.round(l * d), h = document.createElement("canvas");
449
+ h.width = a, h.height = c;
450
+ const u = h.getContext("2d");
451
+ return u ? (u.drawImage(s, 0, 0, a, c), h.toDataURL("image/webp", t)) : null;
460
452
  }
461
- return a.toDataURL("image/webp", t);
453
+ return s.toDataURL("image/webp", t);
462
454
  } catch (n) {
463
455
  return console.warn("DOM screenshot capture failed:", n), null;
464
456
  }
465
457
  }
466
- const V = "qaid_visitor_id";
467
- function Vt() {
458
+ const N = "qaid_visitor_id";
459
+ function At() {
468
460
  try {
469
- let e = localStorage.getItem(V);
470
- return e || (e = crypto.randomUUID(), localStorage.setItem(V, e)), e;
461
+ let e = localStorage.getItem(N);
462
+ return e || (e = crypto.randomUUID(), localStorage.setItem(N, e)), e;
471
463
  } catch {
472
464
  return crypto.randomUUID();
473
465
  }
474
466
  }
475
- class Ut {
467
+ class $t {
468
+ config;
469
+ state = "IDLE";
470
+ feedbackData = {
471
+ feedbackType: null,
472
+ elementSelector: null,
473
+ elementText: null,
474
+ consoleErrors: []
475
+ };
476
+ selectedBounds = {
477
+ x: 0,
478
+ y: 0,
479
+ width: 0,
480
+ height: 0,
481
+ clickX: 0,
482
+ clickY: 0,
483
+ visible: !1
484
+ };
485
+ feedbackId = null;
486
+ mousePos = { x: 0, y: 0 };
487
+ isMobile = !1;
488
+ visitorId;
489
+ // Console capture
490
+ consoleCapture = null;
491
+ // Video recording
492
+ videoRecorder = null;
493
+ networkCapture = null;
494
+ recordedBlob = null;
495
+ recordingIndicator = null;
496
+ videoPreview = null;
497
+ isRecording = !1;
498
+ isSendingVideo = !1;
499
+ // Shadow DOM
500
+ shadowHost = null;
501
+ shadowRoot = null;
502
+ // Overlay shadow DOM (always on document.body for full-page coverage)
503
+ overlayShadowHost = null;
504
+ overlayShadowRoot = null;
505
+ // DOM elements (inside shadow root)
506
+ buttonsContainer = null;
507
+ isUserProvidedContainer = !1;
508
+ overlayContainer = null;
509
+ captureLayer = null;
510
+ crosshairH = null;
511
+ crosshairV = null;
512
+ scope = null;
513
+ highlightBox = null;
514
+ marker = null;
515
+ modalContainer = null;
516
+ backdrop = null;
517
+ // Per-instance CSS variables
518
+ cssVars = {};
519
+ // Bound event handlers
520
+ boundKeyDown;
521
+ boundMouseMove;
522
+ boundClick;
523
+ boundResize;
524
+ // DOM persistence (survives framework client-side navigation)
525
+ destroyed = !1;
526
+ domObserver = null;
527
+ boundBeforeSwap = null;
476
528
  constructor(t) {
477
- h(this, "config");
478
- h(this, "state", "IDLE");
479
- h(this, "feedbackData", {
480
- feedbackType: null,
481
- elementSelector: null,
482
- elementText: null,
483
- consoleErrors: []
484
- });
485
- h(this, "selectedBounds", {
486
- x: 0,
487
- y: 0,
488
- width: 0,
489
- height: 0,
490
- clickX: 0,
491
- clickY: 0,
492
- visible: !1
493
- });
494
- h(this, "feedbackId", null);
495
- h(this, "mousePos", { x: 0, y: 0 });
496
- h(this, "isMobile", !1);
497
- h(this, "visitorId");
498
- // Console capture
499
- h(this, "consoleCapture", null);
500
- // Video recording
501
- h(this, "videoRecorder", null);
502
- h(this, "networkCapture", null);
503
- h(this, "recordedBlob", null);
504
- h(this, "recordingIndicator", null);
505
- h(this, "videoPreview", null);
506
- h(this, "isRecording", !1);
507
- h(this, "isSendingVideo", !1);
508
- // Shadow DOM
509
- h(this, "shadowHost", null);
510
- h(this, "shadowRoot", null);
511
- // Overlay shadow DOM (always on document.body for full-page coverage)
512
- h(this, "overlayShadowHost", null);
513
- h(this, "overlayShadowRoot", null);
514
- // DOM elements (inside shadow root)
515
- h(this, "buttonsContainer", null);
516
- h(this, "isUserProvidedContainer", !1);
517
- h(this, "overlayContainer", null);
518
- h(this, "captureLayer", null);
519
- h(this, "crosshairH", null);
520
- h(this, "crosshairV", null);
521
- h(this, "scope", null);
522
- h(this, "highlightBox", null);
523
- h(this, "marker", null);
524
- h(this, "modalContainer", null);
525
- h(this, "backdrop", null);
526
- // Per-instance CSS variables
527
- h(this, "cssVars", {});
528
- // Bound event handlers
529
- h(this, "boundKeyDown");
530
- h(this, "boundMouseMove");
531
- h(this, "boundClick");
532
- h(this, "boundResize");
533
- h(this, "tooltipElement", null);
534
- var o, i, n, a, s, l, d, r, c, u, p, f, b, g, m;
535
529
  this.config = {
536
530
  endpoint: t.endpoint,
537
531
  apiKey: t.apiKey ?? "",
@@ -540,24 +534,24 @@ class Ut {
540
534
  direction: t.direction ?? "horizontal",
541
535
  position: t.position ?? "bottom-right",
542
536
  offset: {
543
- x: ((o = t.offset) == null ? void 0 : o.x) ?? 16,
544
- y: ((i = t.offset) == null ? void 0 : i.y) ?? 16
537
+ x: t.offset?.x ?? 16,
538
+ y: t.offset?.y ?? 16
545
539
  },
546
540
  zIndex: t.zIndex ?? 50,
547
541
  skipTargeting: t.skipTargeting ?? !1,
548
542
  colors: {
549
- positive: ((n = t.colors) == null ? void 0 : n.positive) ?? "rgb(0, 200, 83)",
550
- negative: ((a = t.colors) == null ? void 0 : a.negative) ?? "rgb(255, 0, 0)",
551
- marker: ((s = t.colors) == null ? void 0 : s.marker) ?? "#6366f1"
543
+ positive: t.colors?.positive ?? "rgb(0, 200, 83)",
544
+ negative: t.colors?.negative ?? "rgb(255, 0, 0)",
545
+ marker: t.colors?.marker ?? "#6366f1"
552
546
  },
553
547
  buttonSize: t.buttonSize ?? "medium",
554
548
  text: {
555
- tooltip: ((l = t.text) == null ? void 0 : l.tooltip) ?? "",
556
- modalTitle: ((d = t.text) == null ? void 0 : d.modalTitle) ?? "Thank you for your feedback!",
557
- modalSubtitle: ((r = t.text) == null ? void 0 : r.modalSubtitle) ?? "Would you like to add a message to help us understand your feedback better?",
558
- placeholder: ((c = t.text) == null ? void 0 : c.placeholder) ?? "Optional: Tell us more about your experience...",
559
- submitButton: ((u = t.text) == null ? void 0 : u.submitButton) ?? "Submit",
560
- skipButton: ((p = t.text) == null ? void 0 : p.skipButton) ?? "Skip"
549
+ tooltip: t.text?.tooltip ?? "",
550
+ modalTitle: t.text?.modalTitle ?? "Thank you for your feedback!",
551
+ modalSubtitle: t.text?.modalSubtitle ?? "Would you like to add a message to help us understand your feedback better?",
552
+ placeholder: t.text?.placeholder ?? "Optional: Tell us more about your experience...",
553
+ submitButton: t.text?.submitButton ?? "Submit",
554
+ skipButton: t.text?.skipButton ?? "Skip"
561
555
  },
562
556
  modalWidth: t.modalWidth ?? 400,
563
557
  backdropOpacity: t.backdropOpacity ?? 0.3,
@@ -566,9 +560,9 @@ class Ut {
566
560
  captureScreenshot: t.captureScreenshot ?? !1,
567
561
  screenshotMethod: t.screenshotMethod ?? "permission",
568
562
  screenshotOptions: {
569
- quality: ((f = t.screenshotOptions) == null ? void 0 : f.quality) ?? 0.8,
570
- maxWidth: ((b = t.screenshotOptions) == null ? void 0 : b.maxWidth) ?? 1280,
571
- maxHeight: ((g = t.screenshotOptions) == null ? void 0 : g.maxHeight) ?? 800
563
+ quality: t.screenshotOptions?.quality ?? 0.8,
564
+ maxWidth: t.screenshotOptions?.maxWidth ?? 1280,
565
+ maxHeight: t.screenshotOptions?.maxHeight ?? 800
572
566
  },
573
567
  incognito: t.incognito ?? !1,
574
568
  positiveIcon: t.positiveIcon ?? "",
@@ -577,16 +571,16 @@ class Ut {
577
571
  css: t.css ?? "",
578
572
  captureVideo: t.captureVideo ?? !1,
579
573
  videoOptions: {
580
- maxDuration: ((m = t.videoOptions) == null ? void 0 : m.maxDuration) ?? 15
574
+ maxDuration: t.videoOptions?.maxDuration ?? 15
581
575
  },
582
576
  recordIcon: t.recordIcon ?? ""
583
- }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundMouseMove = this.handleMouseMove.bind(this), this.boundClick = this.handleClick.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = Vt(), this.init();
577
+ }, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundMouseMove = this.handleMouseMove.bind(this), this.boundClick = this.handleClick.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = At(), this.init();
584
578
  }
585
579
  applyVars(t) {
586
- ht(t, this.cssVars);
580
+ dt(t, this.cssVars);
587
581
  }
588
582
  init() {
589
- ut(), this.cssVars = lt({
583
+ ct(), this.cssVars = rt({
590
584
  positiveColor: this.config.colors.positive,
591
585
  negativeColor: this.config.colors.negative,
592
586
  markerColor: this.config.colors.marker,
@@ -595,10 +589,27 @@ class Ut {
595
589
  backdropOpacity: this.config.backdropOpacity,
596
590
  fontFamily: this.config.fontFamily,
597
591
  fontSize: this.config.fontSize
598
- }), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = Tt((t) => {
599
- var o;
600
- this.feedbackData.consoleErrors = ((o = this.consoleCapture) == null ? void 0 : o.errors) ?? [];
601
- }), this.feedbackData.consoleErrors = this.consoleCapture.errors;
592
+ }), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = Ct((t) => {
593
+ this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
594
+ }), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom();
595
+ }
596
+ /**
597
+ * Watch for the shadow hosts being removed from the DOM by framework
598
+ * client-side navigation (e.g. Astro View Transitions swapping <body>
599
+ * contents, or any SPA router that replaces DOM subtrees). If the host
600
+ * is disconnected and destroy() wasn't called, re-append it.
601
+ *
602
+ * Also hooks into Astro's `astro:before-swap` when available, which
603
+ * lets us carry elements into the new document before the swap happens
604
+ * (avoids a flash of the widget disappearing and reappearing).
605
+ */
606
+ observeDom() {
607
+ this.boundBeforeSwap = (t) => {
608
+ const i = t.newDocument;
609
+ !i || this.destroyed || (this.shadowHost && i.body.appendChild(this.shadowHost), this.overlayShadowHost && i.body.appendChild(this.overlayShadowHost));
610
+ }, document.addEventListener("astro:before-swap", this.boundBeforeSwap), this.domObserver = new MutationObserver(() => {
611
+ this.destroyed || (this.shadowHost && !this.shadowHost.isConnected && document.body.appendChild(this.shadowHost), this.overlayShadowHost && !this.overlayShadowHost.isConnected && document.body.appendChild(this.overlayShadowHost));
612
+ }), this.domObserver.observe(document.body, { childList: !0 });
602
613
  }
603
614
  checkMobile() {
604
615
  this.isMobile = Ht();
@@ -610,36 +621,36 @@ class Ut {
610
621
  this.shadowHost = document.createElement("div"), this.shadowHost.setAttribute("data-qaid-embed", ""), this.shadowHost.style.position = "static", this.shadowHost.style.display = "contents";
611
622
  let t = null;
612
623
  this.config.container && (t = document.querySelector(this.config.container)), t ? (t.appendChild(this.shadowHost), this.isUserProvidedContainer = !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" });
613
- const o = document.createElement("style");
614
- if (o.textContent = B(), this.shadowRoot.appendChild(o), this.config.css) {
615
- const r = document.createElement("style");
616
- r.textContent = this.config.css, this.shadowRoot.appendChild(r);
624
+ const i = document.createElement("style");
625
+ if (i.textContent = B(), this.shadowRoot.appendChild(i), this.config.css) {
626
+ const a = document.createElement("style");
627
+ a.textContent = this.config.css, this.shadowRoot.appendChild(a);
617
628
  }
618
- const i = this.config.direction === "vertical" ? "qaid-vertical" : "";
629
+ const o = this.config.direction === "vertical" ? "qaid-vertical" : "";
619
630
  if (this.isUserProvidedContainer)
620
- this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-${this.config.position} ${i}`.trim(), this.config.incognito && this.buttonsContainer.classList.add("qaid-incognito");
631
+ this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-${this.config.position} ${o}`.trim(), this.config.incognito && this.buttonsContainer.classList.add("qaid-incognito");
621
632
  else {
622
- this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-auto-container qaid-${this.config.position} ${i}${this.config.incognito ? " qaid-incognito" : ""}`.trim(), this.buttonsContainer.style.pointerEvents = "auto";
623
- const { x: r, y: c } = this.config.offset;
624
- this.config.position.includes("right") ? this.buttonsContainer.style.right = `${r}px` : this.buttonsContainer.style.left = `${r}px`, this.config.position.includes("bottom") ? this.buttonsContainer.style.bottom = `${c}px` : this.buttonsContainer.style.top = `${c}px`;
633
+ this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-auto-container qaid-${this.config.position} ${o}${this.config.incognito ? " qaid-incognito" : ""}`.trim(), this.buttonsContainer.style.pointerEvents = "auto";
634
+ const { x: a, y: c } = this.config.offset;
635
+ this.config.position.includes("right") ? this.buttonsContainer.style.right = `${a}px` : this.buttonsContainer.style.left = `${a}px`, this.config.position.includes("bottom") ? this.buttonsContainer.style.bottom = `${c}px` : this.buttonsContainer.style.top = `${c}px`;
625
636
  }
626
637
  this.applyVars(this.buttonsContainer), this.shadowRoot.appendChild(this.buttonsContainer);
627
- const n = !!this.config.buttonClass, a = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", l = this.config.text.tooltip || "Feedback for us?", d = document.createElement("div");
638
+ const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", l = this.config.text.tooltip || "Feedback for us?", d = document.createElement("div");
628
639
  if (d.className = "qaid-tooltip-text", d.textContent = l, this.applyVars(d), this.shadowRoot.appendChild(d), this.tooltipElement = d, !this.config.hideThumbs) {
629
- const r = document.createElement("div");
630
- r.className = "qaid-tooltip-wrapper";
640
+ const a = document.createElement("div");
641
+ a.className = "qaid-tooltip-wrapper";
631
642
  const c = document.createElement("button");
632
- c.type = "button", c.className = n ? `${a} qaid-btn-up` : "qaid-btn qaid-btn-up", c.innerHTML = this.config.positiveIcon || T, c.addEventListener("click", (f) => this.handleThumbClick("up", f.currentTarget, f)), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c);
633
- const u = document.createElement("div");
634
- u.className = "qaid-tooltip-wrapper";
635
- const p = document.createElement("button");
636
- p.type = "button", p.className = n ? `${a} qaid-btn-down` : "qaid-btn qaid-btn-down", p.innerHTML = this.config.negativeIcon || I, p.addEventListener("click", (f) => this.handleThumbClick("down", f.currentTarget, f)), p.addEventListener("mouseenter", () => this.showTooltip(p)), p.addEventListener("mouseleave", () => this.hideTooltip()), u.appendChild(p), this.buttonsContainer.appendChild(r), this.buttonsContainer.appendChild(u);
643
+ c.type = "button", c.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", c.innerHTML = this.config.positiveIcon || E, c.addEventListener("click", (p) => this.handleThumbClick("up", p.currentTarget, p)), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), a.appendChild(c);
644
+ const h = document.createElement("div");
645
+ h.className = "qaid-tooltip-wrapper";
646
+ const u = document.createElement("button");
647
+ u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.innerHTML = this.config.negativeIcon || T, u.addEventListener("click", (p) => this.handleThumbClick("down", p.currentTarget, p)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(u), this.buttonsContainer.appendChild(a), this.buttonsContainer.appendChild(h);
637
648
  }
638
- if (this.config.captureVideo && Mt()) {
639
- const r = document.createElement("div");
640
- r.className = "qaid-tooltip-wrapper";
649
+ if (this.config.captureVideo && It()) {
650
+ const a = document.createElement("div");
651
+ a.className = "qaid-tooltip-wrapper";
641
652
  const c = document.createElement("button");
642
- c.type = "button", c.className = n ? `${a} qaid-btn-record` : "qaid-btn qaid-btn-record", c.innerHTML = this.config.recordIcon || et, c.addEventListener("click", () => this.startRecording()), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c), this.buttonsContainer.appendChild(r);
653
+ c.type = "button", c.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", c.innerHTML = this.config.recordIcon || Z, c.addEventListener("click", () => this.startRecording()), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), a.appendChild(c), this.buttonsContainer.appendChild(a);
643
654
  }
644
655
  }
645
656
  /**
@@ -653,64 +664,65 @@ class Ut {
653
664
  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" });
654
665
  const t = document.createElement("style");
655
666
  if (t.textContent = B(), this.overlayShadowRoot.appendChild(t), this.config.css) {
656
- const o = document.createElement("style");
657
- o.textContent = this.config.css, this.overlayShadowRoot.appendChild(o);
667
+ const i = document.createElement("style");
668
+ i.textContent = this.config.css, this.overlayShadowRoot.appendChild(i);
658
669
  }
659
670
  return this.overlayShadowRoot;
660
671
  }
672
+ tooltipElement = null;
661
673
  showTooltip(t) {
662
674
  if (!this.tooltipElement) return;
663
- const o = this.tooltipElement, i = 8;
664
- o.style.visibility = "hidden", o.classList.add("qaid-tooltip-visible");
665
- const n = t.getBoundingClientRect(), a = o.getBoundingClientRect(), s = window.innerWidth, l = window.innerHeight;
666
- let d, r;
667
- d = n.bottom + i, d + a.height > l - i && (d = n.top - a.height - i), r = n.left, r < i ? r = i : r + a.width > s - i && (r = s - a.width - i), d < i ? d = i : d + a.height > l - i && (d = l - a.height - i), o.style.top = `${d}px`, o.style.left = `${r}px`, o.style.visibility = "visible";
675
+ const i = this.tooltipElement, o = 8;
676
+ i.style.visibility = "hidden", i.classList.add("qaid-tooltip-visible");
677
+ const n = t.getBoundingClientRect(), s = i.getBoundingClientRect(), r = window.innerWidth, l = window.innerHeight;
678
+ let d, a;
679
+ d = n.bottom + o, d + s.height > l - o && (d = n.top - s.height - o), a = n.left, a < o ? a = o : a + s.width > r - o && (a = r - s.width - o), d < o ? d = o : d + s.height > l - o && (d = l - s.height - o), i.style.top = `${d}px`, i.style.left = `${a}px`, i.style.visibility = "visible";
668
680
  }
669
681
  hideTooltip() {
670
682
  this.tooltipElement && this.tooltipElement.classList.remove("qaid-tooltip-visible");
671
683
  }
672
- handleThumbClick(t, o, i) {
673
- this.config.skipTargeting ? this.submitDirectFeedback(t, o) : this.startTargeting(t, i);
684
+ handleThumbClick(t, i, o) {
685
+ this.config.skipTargeting ? this.submitDirectFeedback(t, i) : this.startTargeting(t, o);
674
686
  }
675
- submitDirectFeedback(t, o) {
687
+ submitDirectFeedback(t, i) {
676
688
  this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null;
677
- const i = o.getBoundingClientRect();
689
+ const o = i.getBoundingClientRect();
678
690
  this.selectedBounds = {
679
- x: i.left,
680
- y: i.top,
681
- width: i.width,
682
- height: i.height,
683
- clickX: i.left + i.width / 2,
684
- clickY: i.top + i.height / 2,
691
+ x: o.left,
692
+ y: o.top,
693
+ width: o.width,
694
+ height: o.height,
695
+ clickX: o.left + o.width / 2,
696
+ clickY: o.top + o.height / 2,
685
697
  visible: !1
686
698
  }, this.submitFeedback();
687
699
  }
688
- startTargeting(t, o) {
689
- this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, this.mousePos.x = o.clientX, this.mousePos.y = o.clientY, document.body.classList.add("qaid-targeting"), t === "up" ? document.body.classList.add("qaid-type-up") : document.body.classList.remove("qaid-type-up"), document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), document.addEventListener("keydown", this.boundKeyDown), document.addEventListener("mousemove", this.boundMouseMove), document.addEventListener("click", this.boundClick, !0);
700
+ startTargeting(t, i) {
701
+ this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, this.mousePos.x = i.clientX, this.mousePos.y = i.clientY, document.body.classList.add("qaid-targeting"), t === "up" ? document.body.classList.add("qaid-type-up") : document.body.classList.remove("qaid-type-up"), document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), document.addEventListener("keydown", this.boundKeyDown), document.addEventListener("mousemove", this.boundMouseMove), document.addEventListener("click", this.boundClick, !0);
690
702
  }
691
703
  createTargetingOverlay() {
692
704
  const t = this.ensureOverlayHost();
693
705
  this.overlayContainer = document.createElement("div"), this.overlayContainer.className = `qaid-targeting-overlay qaid-type-${this.feedbackData.feedbackType}`, this.captureLayer = document.createElement("div"), this.captureLayer.className = "qaid-capture-layer";
694
- const o = document.createElement("div");
695
- o.className = "qaid-vignette", this.crosshairH = document.createElement("div"), this.crosshairH.className = "qaid-crosshair-h", this.crosshairV = document.createElement("div"), this.crosshairV.className = "qaid-crosshair-v", this.scope = document.createElement("div"), this.scope.className = "qaid-scope", this.scope.innerHTML = `
706
+ const i = document.createElement("div");
707
+ i.className = "qaid-vignette", this.crosshairH = document.createElement("div"), this.crosshairH.className = "qaid-crosshair-h", this.crosshairV = document.createElement("div"), this.crosshairV.className = "qaid-crosshair-v", this.scope = document.createElement("div"), this.scope.className = "qaid-scope", this.scope.innerHTML = `
696
708
  <div class="qaid-scope-ring"></div>
697
709
  <div class="qaid-scope-ring-inner"></div>
698
710
  <div class="qaid-scope-dot"></div>
699
- `, this.highlightBox = document.createElement("div"), this.highlightBox.className = "qaid-highlight-box", this.overlayContainer.appendChild(this.captureLayer), this.overlayContainer.appendChild(o), this.overlayContainer.appendChild(this.highlightBox), this.overlayContainer.appendChild(this.crosshairH), this.overlayContainer.appendChild(this.crosshairV), this.overlayContainer.appendChild(this.scope), this.crosshairH.style.top = `${this.mousePos.y}px`, this.crosshairV.style.left = `${this.mousePos.x}px`, this.scope.style.left = `${this.mousePos.x}px`, this.scope.style.top = `${this.mousePos.y}px`, this.applyVars(this.overlayContainer), t.appendChild(this.overlayContainer);
711
+ `, this.highlightBox = document.createElement("div"), this.highlightBox.className = "qaid-highlight-box", this.overlayContainer.appendChild(this.captureLayer), this.overlayContainer.appendChild(i), this.overlayContainer.appendChild(this.highlightBox), this.overlayContainer.appendChild(this.crosshairH), this.overlayContainer.appendChild(this.crosshairV), this.overlayContainer.appendChild(this.scope), this.crosshairH.style.top = `${this.mousePos.y}px`, this.crosshairV.style.left = `${this.mousePos.x}px`, this.scope.style.left = `${this.mousePos.x}px`, this.scope.style.top = `${this.mousePos.y}px`, this.applyVars(this.overlayContainer), t.appendChild(this.overlayContainer);
700
712
  }
701
713
  handleKeyDown(t) {
702
714
  t.key === "Escape" && (this.isRecording ? this.stopRecording() : this.videoPreview ? this.cancelRecordingPreview() : this.state === "TARGETING" ? this.cancelTargeting() : this.state === "MODAL_OPEN" && this.closeModal());
703
715
  }
704
716
  handleMouseMove(t) {
705
717
  if (this.mousePos.x = t.clientX, this.mousePos.y = t.clientY, this.crosshairH && (this.crosshairH.style.top = `${t.clientY}px`), this.crosshairV && (this.crosshairV.style.left = `${t.clientX}px`), this.scope && (this.scope.style.left = `${t.clientX}px`, this.scope.style.top = `${t.clientY}px`), this.captureLayer && this.shadowHost) {
706
- const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), i = O(
718
+ const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o = P(
707
719
  t.clientX,
708
720
  t.clientY,
709
- o
721
+ i
710
722
  );
711
- if (i && !$(i)) {
723
+ if (o && !A(o)) {
712
724
  if (this.highlightBox) {
713
- const n = i.getBoundingClientRect();
725
+ const n = o.getBoundingClientRect();
714
726
  this.highlightBox.style.transform = `translate(${n.left}px, ${n.top}px)`, this.highlightBox.style.width = `${n.width}px`, this.highlightBox.style.height = `${n.height}px`, this.highlightBox.style.display = "block";
715
727
  }
716
728
  } else
@@ -720,22 +732,22 @@ class Ut {
720
732
  handleClick(t) {
721
733
  if (this.state !== "TARGETING" || !this.shadowHost) return;
722
734
  t.preventDefault(), t.stopPropagation();
723
- const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), i = O(
735
+ const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o = P(
724
736
  t.clientX,
725
737
  t.clientY,
726
- o
738
+ i
727
739
  );
728
- if (!i || $(i))
740
+ if (!o || A(o))
729
741
  return;
730
- const n = Bt(i, 8);
742
+ const n = Mt(o, 8);
731
743
  this.selectedBounds = {
732
744
  ...n,
733
745
  clickX: t.clientX,
734
746
  clickY: t.clientY,
735
747
  visible: !0
736
748
  };
737
- const { selector: a, text: s } = wt(i);
738
- this.feedbackData.elementSelector = a, this.feedbackData.elementText = s, this.removeTargetingOverlay(), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), 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.state = "SELECTED", this.showSelectedMarker(), this.submitFeedback();
749
+ const { selector: s, text: r } = gt(o);
750
+ this.feedbackData.elementSelector = s, this.feedbackData.elementText = r, this.removeTargetingOverlay(), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), 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.state = "SELECTED", this.showSelectedMarker(), this.submitFeedback();
739
751
  }
740
752
  cancelTargeting() {
741
753
  this.removeTargetingOverlay(), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), 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.state = "IDLE", this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
@@ -754,13 +766,13 @@ class Ut {
754
766
  async submitFeedback() {
755
767
  if (!this.feedbackData.feedbackType) return;
756
768
  let t = null;
757
- this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await Nt(this.config.screenshotOptions) : t = await Pt(this.config.screenshotOptions));
758
- const o = this.feedbackData.elementSelector ? {
769
+ this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await Pt(this.config.screenshotOptions) : t = await Dt(this.config.screenshotOptions));
770
+ const i = this.feedbackData.elementSelector ? {
759
771
  x: this.selectedBounds.x,
760
772
  y: this.selectedBounds.y,
761
773
  width: this.selectedBounds.width,
762
774
  height: this.selectedBounds.height
763
- } : null, i = {
775
+ } : null, o = {
764
776
  feedbackType: this.feedbackData.feedbackType,
765
777
  pageUrl: window.location.href,
766
778
  apiKey: this.config.apiKey || void 0,
@@ -776,18 +788,18 @@ class Ut {
776
788
  screenshot: t,
777
789
  visitorId: this.visitorId,
778
790
  // Include element bounds and user agent for server-side screenshot fallback
779
- elementBounds: o,
791
+ elementBounds: i,
780
792
  userAgent: navigator.userAgent
781
793
  };
782
794
  try {
783
795
  const n = await fetch(this.config.endpoint, {
784
796
  method: "POST",
785
797
  headers: { "Content-Type": "application/json" },
786
- body: JSON.stringify(i)
798
+ body: JSON.stringify(o)
787
799
  });
788
800
  if (n.ok) {
789
- const a = await n.json();
790
- this.feedbackId = a.id;
801
+ const s = await n.json();
802
+ this.feedbackId = s.id;
791
803
  }
792
804
  } catch (n) {
793
805
  console.error("Failed to submit feedback:", n);
@@ -799,16 +811,16 @@ class Ut {
799
811
  this.backdrop = document.createElement("div"), this.backdrop.className = "qaid-backdrop", this.backdrop.style.zIndex = String(this.config.zIndex + 2), this.backdrop.style.background = `rgba(0, 0, 0, ${this.config.backdropOpacity})`, this.backdrop.addEventListener("click", () => this.closeModal()), this.applyVars(this.backdrop), this.isMobile ? this.showBottomSheet() : this.showPositionedModal(), t.appendChild(this.backdrop), document.addEventListener("keydown", this.boundKeyDown);
800
812
  }
801
813
  showBottomSheet() {
802
- const t = this.ensureOverlayHost(), o = document.createElement("div");
803
- o.className = "qaid-bottom-sheet", o.style.zIndex = String(this.config.zIndex + 3), o.innerHTML = `
814
+ const t = this.ensureOverlayHost(), i = document.createElement("div");
815
+ i.className = "qaid-bottom-sheet", i.style.zIndex = String(this.config.zIndex + 3), i.innerHTML = `
804
816
  <div class="qaid-bottom-sheet-content">
805
817
  <div class="qaid-bottom-sheet-handle"></div>
806
818
  ${this.getModalContent()}
807
819
  </div>
808
- `, this.applyVars(o), t.appendChild(o), this.modalContainer = o, this.setupModalInteractions();
820
+ `, this.applyVars(i), t.appendChild(i), this.modalContainer = i, this.setupModalInteractions();
809
821
  }
810
822
  showPositionedModal() {
811
- const t = this.ensureOverlayHost(), { modal: o, arrow: i } = St(
823
+ const t = this.ensureOverlayHost(), { modal: i, arrow: o } = qt(
812
824
  this.selectedBounds,
813
825
  window.innerWidth,
814
826
  window.innerHeight,
@@ -820,18 +832,18 @@ class Ut {
820
832
  viewportPadding: 16
821
833
  }
822
834
  );
823
- this.modalContainer = document.createElement("div"), this.modalContainer.className = `qaid-modal-container qaid-${o.position}`, this.modalContainer.style.top = `${o.top}px`, this.modalContainer.style.left = `${o.left}px`, this.modalContainer.style.zIndex = String(this.config.zIndex + 3);
835
+ this.modalContainer = document.createElement("div"), this.modalContainer.className = `qaid-modal-container qaid-${i.position}`, this.modalContainer.style.top = `${i.top}px`, this.modalContainer.style.left = `${i.left}px`, this.modalContainer.style.zIndex = String(this.config.zIndex + 3);
824
836
  const n = document.createElement("div");
825
- n.className = "qaid-modal-arrow", n.style.left = `${i.left}px`;
826
- const a = document.createElement("div");
827
- a.className = "qaid-modal-box", a.innerHTML = this.getModalContent(), this.modalContainer.appendChild(n), this.modalContainer.appendChild(a), this.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
837
+ n.className = "qaid-modal-arrow", n.style.left = `${o.left}px`;
838
+ const s = document.createElement("div");
839
+ s.className = "qaid-modal-box", s.innerHTML = this.getModalContent(), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
828
840
  }
829
841
  getModalContent() {
830
- const t = this.feedbackData.feedbackType === "up", o = this.config.positiveIcon || T, i = this.config.negativeIcon || I;
842
+ const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon || E, o = this.config.negativeIcon || T;
831
843
  return `
832
844
  <div class="qaid-modal-header">
833
845
  <button type="button" class="${this.config.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${this.config.buttonClass} ${t ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${t ? "qaid-type-up" : "qaid-type-down"}`}" title="Click to switch">
834
- ${t ? o : i}
846
+ ${t ? i : o}
835
847
  </button>
836
848
  <div class="qaid-modal-header-text">
837
849
  <h3 class="qaid-modal-title">${this.config.text.modalTitle}</h3>
@@ -846,19 +858,19 @@ class Ut {
846
858
  }
847
859
  setupModalInteractions() {
848
860
  if (!this.modalContainer) return;
849
- const t = this.modalContainer.querySelector(".qaid-textarea"), o = this.modalContainer.querySelector(".qaid-btn-submit");
861
+ const t = this.modalContainer.querySelector(".qaid-textarea"), i = this.modalContainer.querySelector(".qaid-btn-submit");
850
862
  t && (setTimeout(() => t.focus(), 100), t.addEventListener("input", () => {
851
- o && (o.textContent = t.value.trim() ? this.config.text.submitButton : this.config.text.skipButton);
852
- })), o && o.addEventListener("click", () => {
853
- const n = (t == null ? void 0 : t.value.trim()) || null;
863
+ i && (i.textContent = t.value.trim() ? this.config.text.submitButton : this.config.text.skipButton);
864
+ })), i && i.addEventListener("click", () => {
865
+ const n = t?.value.trim() || null;
854
866
  this.submitMessage(n);
855
867
  });
856
- const i = this.modalContainer.querySelector(".qaid-type-toggle");
857
- i && i.addEventListener("click", () => {
868
+ const o = this.modalContainer.querySelector(".qaid-type-toggle");
869
+ o && o.addEventListener("click", () => {
858
870
  const n = this.feedbackData.feedbackType === "up" ? "down" : "up";
859
- this.feedbackData.feedbackType = n, this.config.buttonClass ? (i.classList.toggle("qaid-btn-up", n === "up"), i.classList.toggle("qaid-btn-down", n === "down")) : (i.classList.toggle("qaid-type-up", n === "up"), i.classList.toggle("qaid-type-down", n === "down"));
860
- const a = this.config.positiveIcon || T, s = this.config.negativeIcon || I;
861
- i.innerHTML = n === "up" ? a : s, this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
871
+ this.feedbackData.feedbackType = n, this.config.buttonClass ? (o.classList.toggle("qaid-btn-up", n === "up"), o.classList.toggle("qaid-btn-down", n === "down")) : (o.classList.toggle("qaid-type-up", n === "up"), o.classList.toggle("qaid-type-down", n === "down"));
872
+ const s = this.config.positiveIcon || E, r = this.config.negativeIcon || T;
873
+ o.innerHTML = n === "up" ? s : r, this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
862
874
  method: "PATCH",
863
875
  headers: { "Content-Type": "application/json" },
864
876
  body: JSON.stringify({ feedbackType: n })
@@ -873,8 +885,8 @@ class Ut {
873
885
  headers: { "Content-Type": "application/json" },
874
886
  body: JSON.stringify({ message: t })
875
887
  });
876
- } catch (o) {
877
- console.error("Failed to submit feedback message:", o);
888
+ } catch (i) {
889
+ console.error("Failed to submit feedback message:", i);
878
890
  }
879
891
  this.feedbackId = null;
880
892
  }
@@ -891,7 +903,7 @@ class Ut {
891
903
  async startRecording() {
892
904
  if (!(this.isRecording || this.state !== "IDLE"))
893
905
  try {
894
- this.networkCapture = Rt(), this.videoRecorder = zt({
906
+ this.networkCapture = Tt(), this.videoRecorder = Rt({
895
907
  maxDuration: this.config.videoOptions.maxDuration
896
908
  }), this.videoRecorder.onTick((t) => {
897
909
  this.updateRecordingTimer(t);
@@ -915,53 +927,53 @@ class Ut {
915
927
  showRecordingIndicator() {
916
928
  const t = this.ensureOverlayHost();
917
929
  this.recordingIndicator = document.createElement("div"), this.recordingIndicator.className = "qaid-recording-indicator", this.recordingIndicator.style.zIndex = String(this.config.zIndex + 100);
918
- const o = document.createElement("div");
919
- o.className = "qaid-recording-dot";
920
- const i = document.createElement("span");
921
- i.className = "qaid-recording-time", i.textContent = this.formatTime(this.config.videoOptions.maxDuration);
930
+ const i = document.createElement("div");
931
+ i.className = "qaid-recording-dot";
932
+ const o = document.createElement("span");
933
+ o.className = "qaid-recording-time", o.textContent = this.formatTime(this.config.videoOptions.maxDuration);
922
934
  const n = document.createElement("button");
923
- n.type = "button", n.className = "qaid-recording-stop", n.textContent = "Stop", n.addEventListener("click", () => this.stopRecording()), this.recordingIndicator.appendChild(o), this.recordingIndicator.appendChild(i), this.recordingIndicator.appendChild(n), this.applyVars(this.recordingIndicator), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.recordingIndicator);
935
+ n.type = "button", n.className = "qaid-recording-stop", n.textContent = "Stop", n.addEventListener("click", () => this.stopRecording()), this.recordingIndicator.appendChild(i), this.recordingIndicator.appendChild(o), this.recordingIndicator.appendChild(n), this.applyVars(this.recordingIndicator), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.recordingIndicator);
924
936
  }
925
937
  updateRecordingTimer(t) {
926
938
  if (!this.recordingIndicator) return;
927
- const o = this.recordingIndicator.querySelector(".qaid-recording-time");
928
- if (o) {
929
- const i = Math.max(0, this.config.videoOptions.maxDuration - t);
930
- o.textContent = this.formatTime(i);
939
+ const i = this.recordingIndicator.querySelector(".qaid-recording-time");
940
+ if (i) {
941
+ const o = Math.max(0, this.config.videoOptions.maxDuration - t);
942
+ i.textContent = this.formatTime(o);
931
943
  }
932
944
  }
933
945
  formatTime(t) {
934
- const o = Math.floor(t / 60), i = t % 60;
935
- return `${o}:${i.toString().padStart(2, "0")}`;
946
+ const i = Math.floor(t / 60), o = t % 60;
947
+ return `${i}:${o.toString().padStart(2, "0")}`;
936
948
  }
937
949
  removeRecordingIndicator() {
938
950
  this.recordingIndicator && (this.recordingIndicator.remove(), this.recordingIndicator = null);
939
951
  }
940
952
  showRecordingPreview() {
941
953
  if (!this.recordedBlob) return;
942
- const t = this.ensureOverlayHost(), o = URL.createObjectURL(this.recordedBlob);
954
+ const t = this.ensureOverlayHost(), i = URL.createObjectURL(this.recordedBlob);
943
955
  this.videoPreview = document.createElement("div"), this.videoPreview.className = "qaid-video-preview", this.videoPreview.style.zIndex = String(this.config.zIndex + 100);
944
- const i = document.createElement("div");
945
- i.className = "qaid-video-preview-box";
956
+ const o = document.createElement("div");
957
+ o.className = "qaid-video-preview-box";
946
958
  const n = document.createElement("h3");
947
959
  n.textContent = "Review your recording";
948
- const a = document.createElement("video");
949
- a.src = o, a.controls = !0, a.autoplay = !0, a.muted = !0;
950
- const s = document.createElement("textarea");
951
- s.placeholder = "Optional: Describe the issue you recorded...";
960
+ const s = document.createElement("video");
961
+ s.src = i, s.controls = !0, s.autoplay = !0, s.muted = !0;
962
+ const r = document.createElement("textarea");
963
+ r.placeholder = "Optional: Describe the issue you recorded...";
952
964
  const l = document.createElement("div");
953
965
  l.className = "qaid-video-preview-actions";
954
966
  const d = document.createElement("button");
955
967
  d.type = "button", d.className = "qaid-video-btn qaid-video-btn-cancel", d.textContent = "Cancel", d.addEventListener("click", () => this.cancelRecordingPreview());
956
- const r = document.createElement("button");
957
- r.type = "button", r.className = "qaid-video-btn qaid-video-btn-rerecord", r.textContent = "Re-record", r.addEventListener("click", () => {
968
+ const a = document.createElement("button");
969
+ a.type = "button", a.className = "qaid-video-btn qaid-video-btn-rerecord", a.textContent = "Re-record", a.addEventListener("click", () => {
958
970
  this.cancelRecordingPreview(), this.startRecording();
959
971
  });
960
972
  const c = document.createElement("button");
961
973
  c.type = "button", c.className = "qaid-video-btn qaid-video-btn-send", c.textContent = "Send", c.addEventListener("click", () => {
962
- const u = s.value.trim() || null;
963
- this.submitVideoFeedback(u, c);
964
- }), l.appendChild(d), l.appendChild(r), l.appendChild(c), i.appendChild(n), i.appendChild(a), i.appendChild(s), i.appendChild(l), this.videoPreview.appendChild(i), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), document.addEventListener("keydown", this.boundKeyDown);
974
+ const h = r.value.trim() || null;
975
+ this.submitVideoFeedback(h, c);
976
+ }), l.appendChild(d), l.appendChild(a), l.appendChild(c), o.appendChild(n), o.appendChild(s), o.appendChild(r), o.appendChild(l), this.videoPreview.appendChild(o), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), document.addEventListener("keydown", this.boundKeyDown);
965
977
  }
966
978
  cancelRecordingPreview() {
967
979
  this.removeVideoPreview(), this.cleanupRecording();
@@ -969,19 +981,19 @@ class Ut {
969
981
  removeVideoPreview() {
970
982
  if (this.videoPreview) {
971
983
  const t = this.videoPreview.querySelector("video");
972
- t != null && t.src && URL.revokeObjectURL(t.src), this.videoPreview.remove(), this.videoPreview = null;
984
+ t?.src && URL.revokeObjectURL(t.src), this.videoPreview.remove(), this.videoPreview = null;
973
985
  }
974
986
  document.removeEventListener("keydown", this.boundKeyDown);
975
987
  }
976
- async submitVideoFeedback(t, o) {
988
+ async submitVideoFeedback(t, i) {
977
989
  if (!this.recordedBlob || this.isSendingVideo) return;
978
- this.isSendingVideo = !0, o.disabled = !0, o.textContent = "Sending...";
979
- const i = new FormData();
980
- i.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), i.append("pageUrl", window.location.href), i.append("visitorId", this.visitorId), this.config.apiKey && i.append("apiKey", this.config.apiKey), t && i.append("message", t), this.consoleCapture && i.append("consoleErrors", JSON.stringify(this.consoleCapture.errors)), this.networkCapture && i.append("networkErrors", JSON.stringify(this.networkCapture.errors));
990
+ this.isSendingVideo = !0, i.disabled = !0, i.textContent = "Sending...";
991
+ const o = new FormData();
992
+ o.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), o.append("pageUrl", window.location.href), o.append("visitorId", this.visitorId), this.config.apiKey && o.append("apiKey", this.config.apiKey), t && o.append("message", t), this.consoleCapture && o.append("consoleErrors", JSON.stringify(this.consoleCapture.errors)), this.networkCapture && o.append("networkErrors", JSON.stringify(this.networkCapture.errors));
981
993
  try {
982
994
  const n = await fetch(`${this.config.endpoint}/video`, {
983
995
  method: "POST",
984
- body: i
996
+ body: o
985
997
  });
986
998
  n.ok || console.error("Failed to submit video feedback:", await n.text());
987
999
  } catch (n) {
@@ -994,104 +1006,101 @@ class Ut {
994
1006
  }
995
1007
  setButtonsDisabled(t) {
996
1008
  if (!this.buttonsContainer) return;
997
- this.buttonsContainer.querySelectorAll("button.qaid-btn, button.qaid-btn-structural").forEach((i) => {
998
- t ? i.classList.contains("qaid-btn-record") || (i.disabled = !0, i.style.opacity = "0.5") : (i.disabled = !1, i.style.opacity = "");
1009
+ this.buttonsContainer.querySelectorAll("button.qaid-btn, button.qaid-btn-structural").forEach((o) => {
1010
+ t ? o.classList.contains("qaid-btn-record") || (o.disabled = !0, o.style.opacity = "0.5") : (o.disabled = !1, o.style.opacity = "");
999
1011
  });
1000
1012
  }
1001
1013
  /**
1002
1014
  * Destroy the embed and clean up all resources
1003
1015
  */
1004
1016
  destroy() {
1005
- this.cleanupRecording(), this.removeVideoPreview(), this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.tooltipElement = null, pt();
1017
+ this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.cleanupRecording(), this.removeVideoPreview(), this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.tooltipElement = null, lt();
1006
1018
  }
1007
1019
  }
1008
- function W(e) {
1009
- var o;
1010
- const t = document.querySelector(e);
1011
- return ((o = t == null ? void 0 : t.textContent) == null ? void 0 : o.trim()) ?? "";
1020
+ function _(e) {
1021
+ return document.querySelector(e)?.textContent?.trim() ?? "";
1012
1022
  }
1013
- function Ft() {
1014
- var o;
1023
+ function Nt() {
1015
1024
  const e = document.querySelector(
1016
1025
  'script[type="application/json"][data-feedback-config]'
1017
1026
  );
1018
1027
  if (!e) return null;
1019
- const t = (o = e.textContent) == null ? void 0 : o.trim();
1028
+ const t = e.textContent?.trim();
1020
1029
  if (!t) return null;
1021
1030
  try {
1022
1031
  const i = JSON.parse(t);
1023
- return i.cssSelector && !i.css && (i.css = W(i.cssSelector), delete i.cssSelector), i;
1032
+ return i.cssSelector && !i.css && (i.css = _(i.cssSelector), delete i.cssSelector), i;
1024
1033
  } catch {
1025
1034
  return null;
1026
1035
  }
1027
1036
  }
1028
- function Wt(e) {
1037
+ function Vt(e) {
1029
1038
  const t = e.getAttribute("data-endpoint");
1030
1039
  if (!t) return null;
1031
- const o = e.getAttribute("data-position"), i = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), a = e.getAttribute("data-negative-color"), s = e.getAttribute("data-marker-color"), l = e.getAttribute("data-container"), d = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), c = e.getAttribute("data-incognito"), u = e.getAttribute("data-button-size"), p = e.getAttribute("data-offset-x"), f = e.getAttribute("data-offset-y"), b = e.getAttribute("data-modal-width"), g = e.getAttribute("data-backdrop-opacity"), m = e.getAttribute("data-font-family"), v = e.getAttribute("data-font-size"), y = e.getAttribute("data-tooltip"), q = e.getAttribute("data-modal-title"), L = e.getAttribute("data-modal-subtitle"), R = e.getAttribute("data-placeholder"), M = e.getAttribute("data-submit-button"), D = e.getAttribute("data-skip-button"), X = e.getAttribute("data-positive-icon"), _ = e.getAttribute("data-negative-icon"), j = e.getAttribute("data-api-key"), K = e.getAttribute("data-capture-screenshot"), C = e.getAttribute("data-screenshot-quality"), S = e.getAttribute("data-screenshot-max-width"), E = e.getAttribute("data-screenshot-max-height"), Y = e.getAttribute("data-capture-video"), J = e.getAttribute("data-hide-thumbs"), z = e.getAttribute("data-video-max-duration"), G = e.getAttribute("data-screenshot-method"), Z = e.getAttribute("data-direction"), H = e.getAttribute("data-css-selector");
1040
+ const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), r = e.getAttribute("data-marker-color"), l = e.getAttribute("data-container"), d = e.getAttribute("data-button-class"), a = e.getAttribute("data-skip-targeting"), c = e.getAttribute("data-incognito"), h = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), p = e.getAttribute("data-offset-y"), g = e.getAttribute("data-modal-width"), f = e.getAttribute("data-backdrop-opacity"), m = e.getAttribute("data-font-family"), v = e.getAttribute("data-font-size"), b = e.getAttribute("data-tooltip"), x = e.getAttribute("data-modal-title"), I = e.getAttribute("data-modal-subtitle"), L = e.getAttribute("data-placeholder"), R = e.getAttribute("data-submit-button"), H = e.getAttribute("data-skip-button"), F = e.getAttribute("data-positive-icon"), W = e.getAttribute("data-negative-icon"), X = e.getAttribute("data-api-key"), j = e.getAttribute("data-capture-screenshot"), k = e.getAttribute("data-screenshot-quality"), C = e.getAttribute("data-screenshot-max-width"), S = e.getAttribute("data-screenshot-max-height"), K = e.getAttribute("data-capture-video"), Y = e.getAttribute("data-hide-thumbs"), M = e.getAttribute("data-video-max-duration"), J = e.getAttribute("data-screenshot-method"), G = e.getAttribute("data-direction"), D = e.getAttribute("data-css-selector");
1032
1041
  return {
1033
1042
  endpoint: t,
1034
- css: H ? W(H) : void 0,
1035
- apiKey: j ?? void 0,
1036
- captureScreenshot: K === "true" ? !0 : void 0,
1037
- screenshotOptions: C || S || E ? {
1038
- quality: C ? parseFloat(C) : void 0,
1039
- maxWidth: S ? parseInt(S, 10) : void 0,
1040
- maxHeight: E ? parseInt(E, 10) : void 0
1043
+ css: D ? _(D) : void 0,
1044
+ apiKey: X ?? void 0,
1045
+ captureScreenshot: j === "true" ? !0 : void 0,
1046
+ screenshotOptions: k || C || S ? {
1047
+ quality: k ? parseFloat(k) : void 0,
1048
+ maxWidth: C ? parseInt(C, 10) : void 0,
1049
+ maxHeight: S ? parseInt(S, 10) : void 0
1041
1050
  } : void 0,
1042
1051
  container: l ?? void 0,
1043
1052
  buttonClass: d ?? void 0,
1044
- direction: Z ?? void 0,
1045
- position: o ?? void 0,
1046
- zIndex: i ? parseInt(i, 10) : void 0,
1047
- skipTargeting: r === "true" ? !0 : void 0,
1053
+ direction: G ?? void 0,
1054
+ position: i ?? void 0,
1055
+ zIndex: o ? parseInt(o, 10) : void 0,
1056
+ skipTargeting: a === "true" ? !0 : void 0,
1048
1057
  incognito: c === "true" ? !0 : void 0,
1049
- buttonSize: u ?? void 0,
1050
- offset: p || f ? {
1051
- x: p ? parseInt(p, 10) : void 0,
1052
- y: f ? parseInt(f, 10) : void 0
1058
+ buttonSize: h ?? void 0,
1059
+ offset: u || p ? {
1060
+ x: u ? parseInt(u, 10) : void 0,
1061
+ y: p ? parseInt(p, 10) : void 0
1053
1062
  } : void 0,
1054
- modalWidth: b ? parseInt(b, 10) : void 0,
1055
- backdropOpacity: g ? parseFloat(g) : void 0,
1063
+ modalWidth: g ? parseInt(g, 10) : void 0,
1064
+ backdropOpacity: f ? parseFloat(f) : void 0,
1056
1065
  fontFamily: m ?? void 0,
1057
1066
  fontSize: v ? parseInt(v, 10) : void 0,
1058
1067
  colors: {
1059
1068
  positive: n ?? void 0,
1060
- negative: a ?? void 0,
1061
- marker: s ?? void 0
1069
+ negative: s ?? void 0,
1070
+ marker: r ?? void 0
1062
1071
  },
1063
- text: y || q || L || R || M || D ? {
1064
- tooltip: y ?? void 0,
1065
- modalTitle: q ?? void 0,
1066
- modalSubtitle: L ?? void 0,
1067
- placeholder: R ?? void 0,
1068
- submitButton: M ?? void 0,
1069
- skipButton: D ?? void 0
1072
+ text: b || x || I || L || R || H ? {
1073
+ tooltip: b ?? void 0,
1074
+ modalTitle: x ?? void 0,
1075
+ modalSubtitle: I ?? void 0,
1076
+ placeholder: L ?? void 0,
1077
+ submitButton: R ?? void 0,
1078
+ skipButton: H ?? void 0
1070
1079
  } : void 0,
1071
- positiveIcon: X ?? void 0,
1072
- negativeIcon: _ ?? void 0,
1073
- screenshotMethod: G ?? void 0,
1074
- captureVideo: Y === "true" ? !0 : void 0,
1075
- hideThumbs: J === "true" ? !0 : void 0,
1076
- videoOptions: z ? {
1077
- maxDuration: parseInt(z, 10)
1080
+ positiveIcon: F ?? void 0,
1081
+ negativeIcon: W ?? void 0,
1082
+ screenshotMethod: J ?? void 0,
1083
+ captureVideo: K === "true" ? !0 : void 0,
1084
+ hideThumbs: Y === "true" ? !0 : void 0,
1085
+ videoOptions: M ? {
1086
+ maxDuration: parseInt(M, 10)
1078
1087
  } : void 0
1079
1088
  };
1080
1089
  }
1081
1090
  if (typeof document < "u") {
1082
1091
  const e = () => {
1083
- const t = document.currentScript, o = Ft(), i = t ? Wt(t) : null, n = o ?? i;
1084
- n != null && n.endpoint && new Ut(n);
1092
+ const t = document.currentScript, i = Nt(), o = t ? Vt(t) : null, n = i ?? o;
1093
+ n?.endpoint && new $t(n);
1085
1094
  };
1086
1095
  document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e();
1087
1096
  }
1088
1097
  export {
1089
- Ut as QaidFeedback,
1090
- Nt as captureDomScreenshot,
1091
- Rt as captureNetworkErrors,
1092
- zt as createVideoRecorder,
1093
- Dt as getSupportedMimeType,
1094
- _t as isDomScreenshotSupported,
1095
- Mt as isVideoRecordingSupported
1098
+ $t as QaidFeedback,
1099
+ Pt as captureDomScreenshot,
1100
+ Tt as captureNetworkErrors,
1101
+ Rt as createVideoRecorder,
1102
+ Lt as getSupportedMimeType,
1103
+ Ut as isDomScreenshotSupported,
1104
+ It as isVideoRecordingSupported
1096
1105
  };
1097
1106
  //# sourceMappingURL=qaid.js.map