@qaiddev/thumbs-embed 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/qaid.js +140 -139
- package/dist/qaid.js.map +1 -1
- package/dist/qaid.umd.cjs +7 -7
- package/dist/qaid.umd.cjs.map +1 -1
- package/package.json +2 -2
package/dist/qaid.umd.cjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(g,b){typeof exports=="object"&&typeof module<"u"?b(exports):typeof define=="function"&&define.amd?define(["exports"],b):(g=typeof globalThis<"u"?globalThis:g||self,b(g.Qaid={}))})(this,function(g){"use strict";var Xt=Object.defineProperty;var _t=(g,b,q)=>b in g?Xt(g,b,{enumerable:!0,configurable:!0,writable:!0,value:q}):g[b]=q;var h=(g,b,q)=>_t(g,typeof b!="symbol"?b+"":b,q);const b=`<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
2
2
|
<path stroke-linecap="round" stroke-linejoin="round" d="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5"/>
|
|
3
|
-
</svg>`,
|
|
3
|
+
</svg>`,q=`<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
4
4
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.737 3h4.018a2 2 0 01.485.06l3.76.94m-7 10v5a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5-10h2a2 2 0 012 2v6a2 2 0 01-2 2h-2.5"/>
|
|
5
|
-
</svg>`,
|
|
5
|
+
</svg>`,Q=`<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
6
6
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z"/>
|
|
7
|
-
</svg>`,tt=".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;cursor:crosshair;pointer-events:auto;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-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)}",et="body.qaid-targeting,body.qaid-targeting *{cursor:none!important}.qaid-highlight{outline:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent)!important;outline-offset:2px!important;box-shadow:inset 0 0 0 9999px color-mix(in srgb,var(--qaid-negative) 8%,transparent)!important;transition:outline .1s ease!important}body.qaid-targeting.qaid-type-up .qaid-highlight{outline-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)!important;box-shadow:inset 0 0 0 9999px color-mix(in srgb,var(--qaid-positive) 8%,transparent)!important}";let k=0;const it="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)}",ot={small:36,medium:48,large:64},nt={small:18,medium:24,large:32};function at(i,t,o){const[e,n,a]=[i,t,o].map(s=>(s=s/255,s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4)));return .2126*e+.7152*n+.0722*a}function st(i){if(i.startsWith("#")){const o=i.slice(1),e=o.length===3?o.split("").map(a=>a+a).join(""):o,n=parseInt(e,16);return{r:n>>16&255,g:n>>8&255,b:n&255}}const t=i.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);return t?{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}:null}function rt(i){const t=st(i);return t&&at(t.r,t.g,t.b)>.4?"black":"white"}function dt(i={}){const{positiveColor:t="rgb(0, 200, 83)",negativeColor:o="rgb(255, 0, 0)",markerColor:e="#6366f1",buttonSize:n="medium",modalWidth:a=400,backdropOpacity:s=.3,fontFamily:l="system-ui, -apple-system, sans-serif",fontSize:d=16}=i,r=ot[n],c=nt[n],u=rt(e);return{"--qaid-positive":t,"--qaid-negative":o,"--qaid-marker":e,"--qaid-marker-text":u,"--qaid-btn-size":`${r}px`,"--qaid-icon-size":`${c}px`,"--qaid-modal-width":`${a}px`,"--qaid-backdrop-opacity":String(s),"--qaid-font-family":l,"--qaid-font-size":`${d}px`}}function ct(i,t){for(const[o,e]of Object.entries(t))i.style.setProperty(o,e)}function R(){return tt+it}function lt(){if(k++,k>1)return;const i=document.createElement("style");i.id="qaid-styles",i.textContent=et,document.head.appendChild(i)}function ht(){if(!(k<=0)&&(k--,k===0)){const i=document.getElementById("qaid-styles");i&&i.remove()}}const ut=["data-comp","data-qa","data-testid","data-id"];function D(i,t=document.body){let o=i;for(;o&&o!==t;){for(const e of ut){const n=o.getAttribute(e);if(n)return`${e}="${n}"`}o=o.parentElement}return null}function pt(i,t=100){var e;const o=((e=i.textContent)==null?void 0:e.trim().slice(0,t))||"";return o.length===t?o+"...":o}function mt(i){let t=1,o=i.previousElementSibling;for(;o;)t++,o=o.previousElementSibling;return t}function ft(i){const t=[];let o=i;for(;o&&o!==document.body&&o!==document.documentElement;){const e=o.tagName.toLowerCase(),n=mt(o);t.unshift(`${e}:nth-child(${n})`),o=o.parentElement}return t.length>0?`body > ${t.join(" > ")}`:"body"}function gt(i){return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function bt(i){const t=D(i);return t?`[${t}]`:i.id?`#${gt(i.id)}`:ft(i)}function vt(i){const t=pt(i),o=D(i);return{selector:bt(i),text:t,dataAttr:o}}const M={width:400,height:280,arrowHeight:12,gap:8,viewportPadding:16};function yt(i,t,o,e,n){const a=i.y,s=t-(i.y+i.height);if(s>=o+e)return{top:i.y+i.height+e,position:"below"};if(a>=o+e)return{top:i.y-o-e,position:"above"};const l=s>a?"below":"above";let d;return l==="below"?d=Math.min(i.y+i.height+e,t-o-n):d=Math.max(n,i.y-o-e),{top:d,position:l}}function wt(i,t,o,e){let a=i.x+i.width/2-o/2;return a=Math.max(e,Math.min(a,t-o-e)),a}function qt(i,t,o,e=24,n=24){const s=i.clickX-t-n/2;return Math.max(e,Math.min(s,o-e-n/2))}function xt(i,t,o,e=M){const n=e.height+e.arrowHeight,a=yt(i,o,n,e.gap,e.viewportPadding),s=wt(i,t,e.width,e.viewportPadding);return{top:a.top,left:s,position:a.position}}function kt(i,t,o,e=M){const n=xt(i,t,o,e),a=qt(i,n.left,e.width);return{modal:n,arrow:{left:a}}}const Ct=20;function St(i){const t=[],o=console.error,e=console.warn,n=console.log,a=(s,l)=>{const d={message:l.map(r=>String(r)).join(" "),timestamp:Date.now(),level:s};t.length>=Ct&&t.shift(),t.push(d),i&&i(d)};return console.error=function(...s){a("error",s),o.apply(console,s)},console.warn=function(...s){a("warn",s),e.apply(console,s)},console.log=function(...s){a("log",s),n.apply(console,s)},{errors:t,restore:()=>{console.error=o,console.warn=e,console.log=n}}}const Et=20,z=4096;function S(i){if(i==null)return;const t=typeof i=="string"?i:JSON.stringify(i);return t.length>z?t.slice(0,z)+"…[truncated]":t}function B(i,t){i.length>=Et&&i.shift(),i.push(t)}async function Tt(i){try{const t=await i.clone().text();return S(t)}catch{return}}function A(){const i=[],t=window.fetch;window.fetch=async function(n,a){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");let d;a!=null&&a.body&&(d=S(a.body));const r=await t.apply(window,[n,a]);if(r.status>=400){const c=await Tt(r);B(i,{url:s,method:l.toUpperCase(),status:r.status,statusText:r.statusText,requestBody:d,responseBody:c,timestamp:Date.now()})}return r};const o=XMLHttpRequest.prototype.open,e=XMLHttpRequest.prototype.send;return XMLHttpRequest.prototype.open=function(n,a,...s){return this._qaid_method=n,this._qaid_url=typeof a=="string"?a:a.toString(),o.apply(this,[n,a,...s])},XMLHttpRequest.prototype.send=function(n){const a=this,s=n?S(n):void 0;return a.addEventListener("load",function(){a.status>=400&&B(i,{url:a._qaid_url,method:a._qaid_method.toUpperCase(),status:a.status,statusText:a.statusText,requestBody:s,responseBody:S(a.responseText),timestamp:Date.now()})}),e.apply(this,[n])},{errors:i,restore:()=>{window.fetch=t,XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=e}}}function O(){return typeof navigator<"u"&&!!navigator.mediaDevices&&typeof navigator.mediaDevices.getDisplayMedia=="function"&&typeof MediaRecorder<"u"}function P(){if(typeof MediaRecorder>"u")return"";const i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"];for(const t of i)if(MediaRecorder.isTypeSupported(t))return t;return""}function $(i={}){const t=i.maxDuration??15,o=i.videoBitsPerSecond??8e5;let e=null,n=null,a=[],s=null,l=null,d=null,r=0,c=null,u=null,p=!1,g=null;function y(){d!==null&&(clearInterval(d),d=null),g!==null&&(clearTimeout(g),g=null),e&&(e.getTracks().forEach(m=>m.stop()),e=null),n=null,a=[],s=null,l=null,c=null,u=null}function v(){p||(p=!0,n&&n.state!=="inactive"&&n.stop())}return{async start(){p=!1,a=[];const m=P();if(!m)throw new Error("No supported video MIME type found");e=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1,preferCurrentTab:!0});const w=e.getVideoTracks()[0];w&&w.addEventListener("ended",()=>{v()}),n=new MediaRecorder(e,{mimeType:m,videoBitsPerSecond:o}),n.ondataavailable=q=>{q.data.size>0&&a.push(q.data)},n.onstop=()=>{const q=new Blob(a,{type:m});c&&c(q),l&&l(q),e&&e.getTracks().forEach(E=>E.stop())},n.onerror=()=>{u&&u(new Error("MediaRecorder error"))},n.start(1e3),r=Date.now(),d=setInterval(()=>{const q=Math.floor((Date.now()-r)/1e3);s&&s(q)},1e3),g=setTimeout(()=>{v()},t*1e3)},stop(){return new Promise((m,w)=>{c=m,u=w,v()})},onTick(m){s=m},onStop(m){l=m},destroy(){v(),y()}}}function It(i=640){return typeof window<"u"&&window.innerWidth<i}function N(i,t,o){const e=o.map(a=>a.style.visibility);o.forEach(a=>a.style.visibility="hidden");const n=document.elementFromPoint(i,t);return o.forEach((a,s)=>a.style.visibility=e[s]),n}function V(i){return i?i.hasAttribute("data-qaid-embed")||i.hasAttribute("data-qaid-embed-overlay")?!0:!!i.closest("[data-qaid-embed], [data-qaid-embed-overlay]"):!1}function Lt(i,t=0){const o=i.getBoundingClientRect();return{x:o.left-t,y:o.top-t,width:o.width+t*2,height:o.height+t*2}}function T(i){document.querySelectorAll(`.${i}`).forEach(t=>{t.classList.remove(i)})}async function Ht(i={}){var n;const{quality:t=1,maxWidth:o=1280,maxHeight:e=800}=i;try{if(!((n=navigator.mediaDevices)!=null&&n.getDisplayMedia))return console.warn("Screen Capture API not available"),null;const a=await navigator.mediaDevices.getDisplayMedia({preferCurrentTab:!0,video:{displaySurface:"browser"}}),s=a.getVideoTracks()[0],l=s.getSettings(),d=document.createElement("video");d.srcObject=a,d.muted=!0,await new Promise(m=>{d.onloadedmetadata=()=>{d.play(),m()}}),await new Promise(m=>{const w=()=>{d.readyState>=2?m():requestAnimationFrame(w)};w()}),await new Promise(m=>setTimeout(m,100));const r=l.width||d.videoWidth,c=l.height||d.videoHeight,u=Math.min(o/r,e/c,1),p=Math.round(r*u),g=Math.round(c*u),y=document.createElement("canvas");y.width=p,y.height=g;const v=y.getContext("2d");return v?(v.drawImage(d,0,0,p,g),s.stop(),y.toDataURL("image/webp",t)):(s.stop(),null)}catch(a){return console.warn("Screenshot capture failed:",a),null}}const F="https://qaid.dev/lib/html2canvas.min.js",Rt=1e4,Dt=50;let C=null;function Mt(){if(typeof document>"u"||typeof window>"u")return!1;const i=document.createElement("canvas");return typeof i.getContext=="function"&&!!i.getContext("2d")}function zt(){return window.html2canvas?Promise.resolve(!0):C||(C=new Promise(i=>{if(!document.querySelector(`script[src="${F}"]`)){const n=document.createElement("script");n.src=F,n.async=!0,document.head.appendChild(n)}const o=Date.now(),e=()=>{if(window.html2canvas){i(!0);return}if(Date.now()-o>Rt){C=null,i(!1);return}setTimeout(e,Dt)};e()}),C)}async function U(i={}){const{quality:t=.8,maxWidth:o=1280,maxHeight:e=800}=i;try{if(!await zt()||!window.html2canvas)return console.warn("html2canvas failed to load"),null;const a=await window.html2canvas(document.body,{useCORS:!0,allowTaint:!1,logging:!1,windowWidth:document.documentElement.clientWidth,windowHeight:document.documentElement.clientHeight,width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,x:window.scrollX,y:window.scrollY,ignoreElements:r=>{var c,u,p;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}}),s=a.width,l=a.height,d=Math.min(o/s,e/l,1);if(d<1){const r=Math.round(s*d),c=Math.round(l*d),u=document.createElement("canvas");u.width=r,u.height=c;const p=u.getContext("2d");return p?(p.drawImage(a,0,0,r,c),u.toDataURL("image/webp",t)):null}return a.toDataURL("image/webp",t)}catch(n){return console.warn("DOM screenshot capture failed:",n),null}}const W="qaid_visitor_id";function Bt(){try{let i=localStorage.getItem(W);return i||(i=crypto.randomUUID(),localStorage.setItem(W,i)),i}catch{return crypto.randomUUID()}}class _{constructor(t){h(this,"config");h(this,"state","IDLE");h(this,"feedbackData",{feedbackType:null,elementSelector:null,elementText:null,consoleErrors:[]});h(this,"selectedBounds",{x:0,y:0,width:0,height:0,clickX:0,clickY:0,visible:!1});h(this,"feedbackId",null);h(this,"mousePos",{x:0,y:0});h(this,"lastHighlighted",null);h(this,"isMobile",!1);h(this,"visitorId");h(this,"consoleCapture",null);h(this,"videoRecorder",null);h(this,"networkCapture",null);h(this,"recordedBlob",null);h(this,"recordingIndicator",null);h(this,"videoPreview",null);h(this,"isRecording",!1);h(this,"isSendingVideo",!1);h(this,"shadowHost",null);h(this,"shadowRoot",null);h(this,"overlayShadowHost",null);h(this,"overlayShadowRoot",null);h(this,"buttonsContainer",null);h(this,"isUserProvidedContainer",!1);h(this,"overlayContainer",null);h(this,"captureLayer",null);h(this,"crosshairH",null);h(this,"crosshairV",null);h(this,"scope",null);h(this,"marker",null);h(this,"modalContainer",null);h(this,"backdrop",null);h(this,"cssVars",{});h(this,"boundKeyDown");h(this,"boundMouseMove");h(this,"boundClick");h(this,"boundResize");h(this,"tooltipElement",null);var o,e,n,a,s,l,d,r,c,u,p,g,y,v,m;this.config={endpoint:t.endpoint,apiKey:t.apiKey??"",container:t.container??"",buttonClass:t.buttonClass??"",direction:t.direction??"horizontal",position:t.position??"bottom-right",offset:{x:((o=t.offset)==null?void 0:o.x)??16,y:((e=t.offset)==null?void 0:e.y)??16},zIndex:t.zIndex??50,skipTargeting:t.skipTargeting??!1,colors:{positive:((n=t.colors)==null?void 0:n.positive)??"rgb(0, 200, 83)",negative:((a=t.colors)==null?void 0:a.negative)??"rgb(255, 0, 0)",marker:((s=t.colors)==null?void 0:s.marker)??"#6366f1"},buttonSize:t.buttonSize??"medium",text:{tooltip:((l=t.text)==null?void 0:l.tooltip)??"",modalTitle:((d=t.text)==null?void 0:d.modalTitle)??"Thank you for your feedback!",modalSubtitle:((r=t.text)==null?void 0:r.modalSubtitle)??"Would you like to add a message to help us understand your feedback better?",placeholder:((c=t.text)==null?void 0:c.placeholder)??"Optional: Tell us more about your experience...",submitButton:((u=t.text)==null?void 0:u.submitButton)??"Submit",skipButton:((p=t.text)==null?void 0:p.skipButton)??"Skip"},modalWidth:t.modalWidth??400,backdropOpacity:t.backdropOpacity??.3,fontFamily:t.fontFamily??"system-ui, -apple-system, sans-serif",fontSize:t.fontSize??16,captureScreenshot:t.captureScreenshot??!1,screenshotMethod:t.screenshotMethod??"permission",screenshotOptions:{quality:((g=t.screenshotOptions)==null?void 0:g.quality)??.8,maxWidth:((y=t.screenshotOptions)==null?void 0:y.maxWidth)??1280,maxHeight:((v=t.screenshotOptions)==null?void 0:v.maxHeight)??800},incognito:t.incognito??!1,positiveIcon:t.positiveIcon??"",negativeIcon:t.negativeIcon??"",hideThumbs:t.hideThumbs??!1,css:t.css??"",captureVideo:t.captureVideo??!1,videoOptions:{maxDuration:((m=t.videoOptions)==null?void 0:m.maxDuration)??15},recordIcon:t.recordIcon??""},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=Bt(),this.init()}applyVars(t){ct(t,this.cssVars)}init(){lt(),this.cssVars=dt({positiveColor:this.config.colors.positive,negativeColor:this.config.colors.negative,markerColor:this.config.colors.marker,buttonSize:this.config.buttonSize,modalWidth:this.config.modalWidth,backdropOpacity:this.config.backdropOpacity,fontFamily:this.config.fontFamily,fontSize:this.config.fontSize}),this.checkMobile(),window.addEventListener("resize",this.boundResize),this.createEmbed(),this.consoleCapture=St(t=>{var o;this.feedbackData.consoleErrors=((o=this.consoleCapture)==null?void 0:o.errors)??[]}),this.feedbackData.consoleErrors=this.consoleCapture.errors}checkMobile(){this.isMobile=It()}handleResize(){this.checkMobile()}createEmbed(){this.shadowHost=document.createElement("div"),this.shadowHost.setAttribute("data-qaid-embed",""),this.shadowHost.style.position="static",this.shadowHost.style.display="contents";let t=null;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"});const o=document.createElement("style");if(o.textContent=R(),this.shadowRoot.appendChild(o),this.config.css){const r=document.createElement("style");r.textContent=this.config.css,this.shadowRoot.appendChild(r)}const e=this.config.direction==="vertical"?"qaid-vertical":"";if(this.isUserProvidedContainer)this.buttonsContainer=document.createElement("div"),this.buttonsContainer.className=`qaid-buttons qaid-${this.config.position} ${e}`.trim(),this.config.incognito&&this.buttonsContainer.classList.add("qaid-incognito");else{this.buttonsContainer=document.createElement("div"),this.buttonsContainer.className=`qaid-buttons qaid-auto-container qaid-${this.config.position} ${e}${this.config.incognito?" qaid-incognito":""}`.trim(),this.buttonsContainer.style.pointerEvents="auto";const{x:r,y:c}=this.config.offset;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`}this.applyVars(this.buttonsContainer),this.shadowRoot.appendChild(this.buttonsContainer);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");if(d.className="qaid-tooltip-text",d.textContent=l,this.applyVars(d),this.shadowRoot.appendChild(d),this.tooltipElement=d,!this.config.hideThumbs){const r=document.createElement("div");r.className="qaid-tooltip-wrapper";const c=document.createElement("button");c.type="button",c.className=n?`${a} qaid-btn-up`:"qaid-btn qaid-btn-up",c.innerHTML=this.config.positiveIcon||b,c.addEventListener("click",g=>this.handleThumbClick("up",g.currentTarget)),c.addEventListener("mouseenter",()=>this.showTooltip(c)),c.addEventListener("mouseleave",()=>this.hideTooltip()),r.appendChild(c);const u=document.createElement("div");u.className="qaid-tooltip-wrapper";const p=document.createElement("button");p.type="button",p.className=n?`${a} qaid-btn-down`:"qaid-btn qaid-btn-down",p.innerHTML=this.config.negativeIcon||x,p.addEventListener("click",g=>this.handleThumbClick("down",g.currentTarget)),p.addEventListener("mouseenter",()=>this.showTooltip(p)),p.addEventListener("mouseleave",()=>this.hideTooltip()),u.appendChild(p),this.buttonsContainer.appendChild(r),this.buttonsContainer.appendChild(u)}if(this.config.captureVideo&&O()){const r=document.createElement("div");r.className="qaid-tooltip-wrapper";const c=document.createElement("button");c.type="button",c.className=n?`${a} 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()),r.appendChild(c),this.buttonsContainer.appendChild(r)}}ensureOverlayHost(){if(this.overlayShadowRoot)return this.overlayShadowRoot;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"});const t=document.createElement("style");if(t.textContent=R(),this.overlayShadowRoot.appendChild(t),this.config.css){const o=document.createElement("style");o.textContent=this.config.css,this.overlayShadowRoot.appendChild(o)}return this.overlayShadowRoot}showTooltip(t){if(!this.tooltipElement)return;const o=this.tooltipElement,e=8;o.style.visibility="hidden",o.classList.add("qaid-tooltip-visible");const n=t.getBoundingClientRect(),a=o.getBoundingClientRect(),s=window.innerWidth,l=window.innerHeight;let d,r;d=n.bottom+e,d+a.height>l-e&&(d=n.top-a.height-e),r=n.left,r<e?r=e:r+a.width>s-e&&(r=s-a.width-e),d<e?d=e:d+a.height>l-e&&(d=l-a.height-e),o.style.top=`${d}px`,o.style.left=`${r}px`,o.style.visibility="visible"}hideTooltip(){this.tooltipElement&&this.tooltipElement.classList.remove("qaid-tooltip-visible")}handleThumbClick(t,o){this.config.skipTargeting?this.submitDirectFeedback(t,o):this.startTargeting(t)}submitDirectFeedback(t,o){this.feedbackData.feedbackType=t,this.feedbackData.elementSelector=null,this.feedbackData.elementText=null;const e=o.getBoundingClientRect();this.selectedBounds={x:e.left,y:e.top,width:e.width,height:e.height,clickX:e.left+e.width/2,clickY:e.top+e.height/2,visible:!1},this.submitFeedback()}startTargeting(t){this.state="TARGETING",this.feedbackData.feedbackType=t,this.feedbackData.elementSelector=null,this.feedbackData.elementText=null,this.selectedBounds.visible=!1,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(),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="auto"),document.addEventListener("keydown",this.boundKeyDown)}createTargetingOverlay(){const t=this.ensureOverlayHost();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",this.captureLayer.addEventListener("mousemove",this.boundMouseMove),this.captureLayer.addEventListener("click",this.boundClick);const o=document.createElement("div");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=`
|
|
7
|
+
</svg>`,Z="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)}",tt="body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";let k=0;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={small:36,medium:48,large:64},ot={small:18,medium:24,large:32};function nt(i,t,o){const[e,n,a]=[i,t,o].map(s=>(s=s/255,s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4)));return .2126*e+.7152*n+.0722*a}function at(i){if(i.startsWith("#")){const o=i.slice(1),e=o.length===3?o.split("").map(a=>a+a).join(""):o,n=parseInt(e,16);return{r:n>>16&255,g:n>>8&255,b:n&255}}const t=i.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);return t?{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}:null}function st(i){const t=at(i);return t&&nt(t.r,t.g,t.b)>.4?"black":"white"}function rt(i={}){const{positiveColor:t="rgb(0, 200, 83)",negativeColor:o="rgb(255, 0, 0)",markerColor:e="#6366f1",buttonSize:n="medium",modalWidth:a=400,backdropOpacity:s=.3,fontFamily:l="system-ui, -apple-system, sans-serif",fontSize:d=16}=i,r=it[n],c=ot[n],u=st(e);return{"--qaid-positive":t,"--qaid-negative":o,"--qaid-marker":e,"--qaid-marker-text":u,"--qaid-btn-size":`${r}px`,"--qaid-icon-size":`${c}px`,"--qaid-modal-width":`${a}px`,"--qaid-backdrop-opacity":String(s),"--qaid-font-family":l,"--qaid-font-size":`${d}px`}}function dt(i,t){for(const[o,e]of Object.entries(t))i.style.setProperty(o,e)}function R(){return Z+et}function ct(){if(k++,k>1)return;const i=document.createElement("style");i.id="qaid-styles",i.textContent=tt,document.head.appendChild(i)}function lt(){if(!(k<=0)&&(k--,k===0)){const i=document.getElementById("qaid-styles");i&&i.remove()}}const ht=["data-comp","data-qa","data-testid","data-id"];function M(i,t=document.body){let o=i;for(;o&&o!==t;){for(const e of ht){const n=o.getAttribute(e);if(n)return`${e}="${n}"`}o=o.parentElement}return null}function ut(i,t=100){var e;const o=((e=i.textContent)==null?void 0:e.trim().slice(0,t))||"";return o.length===t?o+"...":o}function pt(i){let t=1,o=i.previousElementSibling;for(;o;)t++,o=o.previousElementSibling;return t}function mt(i){const t=[];let o=i;for(;o&&o!==document.body&&o!==document.documentElement;){const e=o.tagName.toLowerCase(),n=pt(o);t.unshift(`${e}:nth-child(${n})`),o=o.parentElement}return t.length>0?`body > ${t.join(" > ")}`:"body"}function ft(i){return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function gt(i){const t=M(i);return t?`[${t}]`:i.id?`#${ft(i.id)}`:mt(i)}function bt(i){const t=ut(i),o=M(i);return{selector:gt(i),text:t,dataAttr:o}}const D={width:400,height:280,arrowHeight:12,gap:8,viewportPadding:16};function vt(i,t,o,e,n){const a=i.y,s=t-(i.y+i.height);if(s>=o+e)return{top:i.y+i.height+e,position:"below"};if(a>=o+e)return{top:i.y-o-e,position:"above"};const l=s>a?"below":"above";let d;return l==="below"?d=Math.min(i.y+i.height+e,t-o-n):d=Math.max(n,i.y-o-e),{top:d,position:l}}function yt(i,t,o,e){let a=i.x+i.width/2-o/2;return a=Math.max(e,Math.min(a,t-o-e)),a}function wt(i,t,o,e=24,n=24){const s=i.clickX-t-n/2;return Math.max(e,Math.min(s,o-e-n/2))}function xt(i,t,o,e=D){const n=e.height+e.arrowHeight,a=vt(i,o,n,e.gap,e.viewportPadding),s=yt(i,t,e.width,e.viewportPadding);return{top:a.top,left:s,position:a.position}}function qt(i,t,o,e=D){const n=xt(i,t,o,e),a=wt(i,n.left,e.width);return{modal:n,arrow:{left:a}}}const kt=20;function Ct(i){const t=[],o=console.error,e=console.warn,n=console.log,a=(s,l)=>{const d={message:l.map(r=>String(r)).join(" "),timestamp:Date.now(),level:s};t.length>=kt&&t.shift(),t.push(d),i&&i(d)};return console.error=function(...s){a("error",s),o.apply(console,s)},console.warn=function(...s){a("warn",s),e.apply(console,s)},console.log=function(...s){a("log",s),n.apply(console,s)},{errors:t,restore:()=>{console.error=o,console.warn=e,console.log=n}}}const St=20,z=4096;function S(i){if(i==null)return;const t=typeof i=="string"?i:JSON.stringify(i);return t.length>z?t.slice(0,z)+"…[truncated]":t}function H(i,t){i.length>=St&&i.shift(),i.push(t)}async function Et(i){try{const t=await i.clone().text();return S(t)}catch{return}}function B(){const i=[],t=window.fetch;window.fetch=async function(n,a){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");let d;a!=null&&a.body&&(d=S(a.body));const r=await t.apply(window,[n,a]);if(r.status>=400){const c=await Et(r);H(i,{url:s,method:l.toUpperCase(),status:r.status,statusText:r.statusText,requestBody:d,responseBody:c,timestamp:Date.now()})}return r};const o=XMLHttpRequest.prototype.open,e=XMLHttpRequest.prototype.send;return XMLHttpRequest.prototype.open=function(n,a,...s){return this._qaid_method=n,this._qaid_url=typeof a=="string"?a:a.toString(),o.apply(this,[n,a,...s])},XMLHttpRequest.prototype.send=function(n){const a=this,s=n?S(n):void 0;return a.addEventListener("load",function(){a.status>=400&&H(i,{url:a._qaid_url,method:a._qaid_method.toUpperCase(),status:a.status,statusText:a.statusText,requestBody:s,responseBody:S(a.responseText),timestamp:Date.now()})}),e.apply(this,[n])},{errors:i,restore:()=>{window.fetch=t,XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=e}}}function P(){return typeof navigator<"u"&&!!navigator.mediaDevices&&typeof navigator.mediaDevices.getDisplayMedia=="function"&&typeof MediaRecorder<"u"}function A(){if(typeof MediaRecorder>"u")return"";const i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"];for(const t of i)if(MediaRecorder.isTypeSupported(t))return t;return""}function O(i={}){const t=i.maxDuration??15,o=i.videoBitsPerSecond??8e5;let e=null,n=null,a=[],s=null,l=null,d=null,r=0,c=null,u=null,p=!1,f=null;function y(){d!==null&&(clearInterval(d),d=null),f!==null&&(clearTimeout(f),f=null),e&&(e.getTracks().forEach(m=>m.stop()),e=null),n=null,a=[],s=null,l=null,c=null,u=null}function v(){p||(p=!0,n&&n.state!=="inactive"&&n.stop())}return{async start(){p=!1,a=[];const m=A();if(!m)throw new Error("No supported video MIME type found");e=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1,preferCurrentTab:!0});const w=e.getVideoTracks()[0];w&&w.addEventListener("ended",()=>{v()}),n=new MediaRecorder(e,{mimeType:m,videoBitsPerSecond:o}),n.ondataavailable=x=>{x.data.size>0&&a.push(x.data)},n.onstop=()=>{const x=new Blob(a,{type:m});c&&c(x),l&&l(x),e&&e.getTracks().forEach(E=>E.stop())},n.onerror=()=>{u&&u(new Error("MediaRecorder error"))},n.start(1e3),r=Date.now(),d=setInterval(()=>{const x=Math.floor((Date.now()-r)/1e3);s&&s(x)},1e3),f=setTimeout(()=>{v()},t*1e3)},stop(){return new Promise((m,w)=>{c=m,u=w,v()})},onTick(m){s=m},onStop(m){l=m},destroy(){v(),y()}}}function Tt(i=640){return typeof window<"u"&&window.innerWidth<i}function $(i,t,o){const e=o.map(a=>a.style.visibility);o.forEach(a=>a.style.visibility="hidden");const n=document.elementFromPoint(i,t);return o.forEach((a,s)=>a.style.visibility=e[s]),n}function N(i){return i?i.hasAttribute("data-qaid-embed")||i.hasAttribute("data-qaid-embed-overlay")?!0:!!i.closest("[data-qaid-embed], [data-qaid-embed-overlay]"):!1}function It(i,t=0){const o=i.getBoundingClientRect();return{x:o.left-t,y:o.top-t,width:o.width+t*2,height:o.height+t*2}}async function Lt(i={}){var n;const{quality:t=1,maxWidth:o=1280,maxHeight:e=800}=i;try{if(!((n=navigator.mediaDevices)!=null&&n.getDisplayMedia))return console.warn("Screen Capture API not available"),null;const a=await navigator.mediaDevices.getDisplayMedia({preferCurrentTab:!0,video:{displaySurface:"browser"}}),s=a.getVideoTracks()[0],l=s.getSettings(),d=document.createElement("video");d.srcObject=a,d.muted=!0,await new Promise(m=>{d.onloadedmetadata=()=>{d.play(),m()}}),await new Promise(m=>{const w=()=>{d.readyState>=2?m():requestAnimationFrame(w)};w()}),await new Promise(m=>setTimeout(m,100));const r=l.width||d.videoWidth,c=l.height||d.videoHeight,u=Math.min(o/r,e/c,1),p=Math.round(r*u),f=Math.round(c*u),y=document.createElement("canvas");y.width=p,y.height=f;const v=y.getContext("2d");return v?(v.drawImage(d,0,0,p,f),s.stop(),y.toDataURL("image/webp",t)):(s.stop(),null)}catch(a){return console.warn("Screenshot capture failed:",a),null}}const V="https://qaid.dev/lib/html2canvas.min.js",Rt=1e4,Mt=50;let C=null;function Dt(){if(typeof document>"u"||typeof window>"u")return!1;const i=document.createElement("canvas");return typeof i.getContext=="function"&&!!i.getContext("2d")}function zt(){return window.html2canvas?Promise.resolve(!0):C||(C=new Promise(i=>{if(!document.querySelector(`script[src="${V}"]`)){const n=document.createElement("script");n.src=V,n.async=!0,document.head.appendChild(n)}const o=Date.now(),e=()=>{if(window.html2canvas){i(!0);return}if(Date.now()-o>Rt){C=null,i(!1);return}setTimeout(e,Mt)};e()}),C)}async function F(i={}){const{quality:t=.8,maxWidth:o=1280,maxHeight:e=800}=i;try{if(!await zt()||!window.html2canvas)return console.warn("html2canvas failed to load"),null;const a=await window.html2canvas(document.body,{useCORS:!0,allowTaint:!1,logging:!1,windowWidth:document.documentElement.clientWidth,windowHeight:document.documentElement.clientHeight,width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,x:window.scrollX,y:window.scrollY,ignoreElements:r=>{var c,u,p;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}}),s=a.width,l=a.height,d=Math.min(o/s,e/l,1);if(d<1){const r=Math.round(s*d),c=Math.round(l*d),u=document.createElement("canvas");u.width=r,u.height=c;const p=u.getContext("2d");return p?(p.drawImage(a,0,0,r,c),u.toDataURL("image/webp",t)):null}return a.toDataURL("image/webp",t)}catch(n){return console.warn("DOM screenshot capture failed:",n),null}}const U="qaid_visitor_id";function Ht(){try{let i=localStorage.getItem(U);return i||(i=crypto.randomUUID(),localStorage.setItem(U,i)),i}catch{return crypto.randomUUID()}}class W{constructor(t){h(this,"config");h(this,"state","IDLE");h(this,"feedbackData",{feedbackType:null,elementSelector:null,elementText:null,consoleErrors:[]});h(this,"selectedBounds",{x:0,y:0,width:0,height:0,clickX:0,clickY:0,visible:!1});h(this,"feedbackId",null);h(this,"mousePos",{x:0,y:0});h(this,"isMobile",!1);h(this,"visitorId");h(this,"consoleCapture",null);h(this,"videoRecorder",null);h(this,"networkCapture",null);h(this,"recordedBlob",null);h(this,"recordingIndicator",null);h(this,"videoPreview",null);h(this,"isRecording",!1);h(this,"isSendingVideo",!1);h(this,"shadowHost",null);h(this,"shadowRoot",null);h(this,"overlayShadowHost",null);h(this,"overlayShadowRoot",null);h(this,"buttonsContainer",null);h(this,"isUserProvidedContainer",!1);h(this,"overlayContainer",null);h(this,"captureLayer",null);h(this,"crosshairH",null);h(this,"crosshairV",null);h(this,"scope",null);h(this,"highlightBox",null);h(this,"marker",null);h(this,"modalContainer",null);h(this,"backdrop",null);h(this,"cssVars",{});h(this,"boundKeyDown");h(this,"boundMouseMove");h(this,"boundClick");h(this,"boundResize");h(this,"tooltipElement",null);var o,e,n,a,s,l,d,r,c,u,p,f,y,v,m;this.config={endpoint:t.endpoint,apiKey:t.apiKey??"",container:t.container??"",buttonClass:t.buttonClass??"",direction:t.direction??"horizontal",position:t.position??"bottom-right",offset:{x:((o=t.offset)==null?void 0:o.x)??16,y:((e=t.offset)==null?void 0:e.y)??16},zIndex:t.zIndex??50,skipTargeting:t.skipTargeting??!1,colors:{positive:((n=t.colors)==null?void 0:n.positive)??"rgb(0, 200, 83)",negative:((a=t.colors)==null?void 0:a.negative)??"rgb(255, 0, 0)",marker:((s=t.colors)==null?void 0:s.marker)??"#6366f1"},buttonSize:t.buttonSize??"medium",text:{tooltip:((l=t.text)==null?void 0:l.tooltip)??"",modalTitle:((d=t.text)==null?void 0:d.modalTitle)??"Thank you for your feedback!",modalSubtitle:((r=t.text)==null?void 0:r.modalSubtitle)??"Would you like to add a message to help us understand your feedback better?",placeholder:((c=t.text)==null?void 0:c.placeholder)??"Optional: Tell us more about your experience...",submitButton:((u=t.text)==null?void 0:u.submitButton)??"Submit",skipButton:((p=t.text)==null?void 0:p.skipButton)??"Skip"},modalWidth:t.modalWidth??400,backdropOpacity:t.backdropOpacity??.3,fontFamily:t.fontFamily??"system-ui, -apple-system, sans-serif",fontSize:t.fontSize??16,captureScreenshot:t.captureScreenshot??!1,screenshotMethod:t.screenshotMethod??"permission",screenshotOptions:{quality:((f=t.screenshotOptions)==null?void 0:f.quality)??.8,maxWidth:((y=t.screenshotOptions)==null?void 0:y.maxWidth)??1280,maxHeight:((v=t.screenshotOptions)==null?void 0:v.maxHeight)??800},incognito:t.incognito??!1,positiveIcon:t.positiveIcon??"",negativeIcon:t.negativeIcon??"",hideThumbs:t.hideThumbs??!1,css:t.css??"",captureVideo:t.captureVideo??!1,videoOptions:{maxDuration:((m=t.videoOptions)==null?void 0:m.maxDuration)??15},recordIcon:t.recordIcon??""},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=Ht(),this.init()}applyVars(t){dt(t,this.cssVars)}init(){ct(),this.cssVars=rt({positiveColor:this.config.colors.positive,negativeColor:this.config.colors.negative,markerColor:this.config.colors.marker,buttonSize:this.config.buttonSize,modalWidth:this.config.modalWidth,backdropOpacity:this.config.backdropOpacity,fontFamily:this.config.fontFamily,fontSize:this.config.fontSize}),this.checkMobile(),window.addEventListener("resize",this.boundResize),this.createEmbed(),this.consoleCapture=Ct(t=>{var o;this.feedbackData.consoleErrors=((o=this.consoleCapture)==null?void 0:o.errors)??[]}),this.feedbackData.consoleErrors=this.consoleCapture.errors}checkMobile(){this.isMobile=Tt()}handleResize(){this.checkMobile()}createEmbed(){this.shadowHost=document.createElement("div"),this.shadowHost.setAttribute("data-qaid-embed",""),this.shadowHost.style.position="static",this.shadowHost.style.display="contents";let t=null;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"});const o=document.createElement("style");if(o.textContent=R(),this.shadowRoot.appendChild(o),this.config.css){const r=document.createElement("style");r.textContent=this.config.css,this.shadowRoot.appendChild(r)}const e=this.config.direction==="vertical"?"qaid-vertical":"";if(this.isUserProvidedContainer)this.buttonsContainer=document.createElement("div"),this.buttonsContainer.className=`qaid-buttons qaid-${this.config.position} ${e}`.trim(),this.config.incognito&&this.buttonsContainer.classList.add("qaid-incognito");else{this.buttonsContainer=document.createElement("div"),this.buttonsContainer.className=`qaid-buttons qaid-auto-container qaid-${this.config.position} ${e}${this.config.incognito?" qaid-incognito":""}`.trim(),this.buttonsContainer.style.pointerEvents="auto";const{x:r,y:c}=this.config.offset;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`}this.applyVars(this.buttonsContainer),this.shadowRoot.appendChild(this.buttonsContainer);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");if(d.className="qaid-tooltip-text",d.textContent=l,this.applyVars(d),this.shadowRoot.appendChild(d),this.tooltipElement=d,!this.config.hideThumbs){const r=document.createElement("div");r.className="qaid-tooltip-wrapper";const c=document.createElement("button");c.type="button",c.className=n?`${a} qaid-btn-up`:"qaid-btn qaid-btn-up",c.innerHTML=this.config.positiveIcon||b,c.addEventListener("click",f=>this.handleThumbClick("up",f.currentTarget,f)),c.addEventListener("mouseenter",()=>this.showTooltip(c)),c.addEventListener("mouseleave",()=>this.hideTooltip()),r.appendChild(c);const u=document.createElement("div");u.className="qaid-tooltip-wrapper";const p=document.createElement("button");p.type="button",p.className=n?`${a} qaid-btn-down`:"qaid-btn qaid-btn-down",p.innerHTML=this.config.negativeIcon||q,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)}if(this.config.captureVideo&&P()){const r=document.createElement("div");r.className="qaid-tooltip-wrapper";const c=document.createElement("button");c.type="button",c.className=n?`${a} qaid-btn-record`:"qaid-btn qaid-btn-record",c.innerHTML=this.config.recordIcon||Q,c.addEventListener("click",()=>this.startRecording()),c.addEventListener("mouseenter",()=>this.showTooltip(c)),c.addEventListener("mouseleave",()=>this.hideTooltip()),r.appendChild(c),this.buttonsContainer.appendChild(r)}}ensureOverlayHost(){if(this.overlayShadowRoot)return this.overlayShadowRoot;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"});const t=document.createElement("style");if(t.textContent=R(),this.overlayShadowRoot.appendChild(t),this.config.css){const o=document.createElement("style");o.textContent=this.config.css,this.overlayShadowRoot.appendChild(o)}return this.overlayShadowRoot}showTooltip(t){if(!this.tooltipElement)return;const o=this.tooltipElement,e=8;o.style.visibility="hidden",o.classList.add("qaid-tooltip-visible");const n=t.getBoundingClientRect(),a=o.getBoundingClientRect(),s=window.innerWidth,l=window.innerHeight;let d,r;d=n.bottom+e,d+a.height>l-e&&(d=n.top-a.height-e),r=n.left,r<e?r=e:r+a.width>s-e&&(r=s-a.width-e),d<e?d=e:d+a.height>l-e&&(d=l-a.height-e),o.style.top=`${d}px`,o.style.left=`${r}px`,o.style.visibility="visible"}hideTooltip(){this.tooltipElement&&this.tooltipElement.classList.remove("qaid-tooltip-visible")}handleThumbClick(t,o,e){this.config.skipTargeting?this.submitDirectFeedback(t,o):this.startTargeting(t,e)}submitDirectFeedback(t,o){this.feedbackData.feedbackType=t,this.feedbackData.elementSelector=null,this.feedbackData.elementText=null;const e=o.getBoundingClientRect();this.selectedBounds={x:e.left,y:e.top,width:e.width,height:e.height,clickX:e.left+e.width/2,clickY:e.top+e.height/2,visible:!1},this.submitFeedback()}startTargeting(t,o){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)}createTargetingOverlay(){const t=this.ensureOverlayHost();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";const o=document.createElement("div");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=`
|
|
8
8
|
<div class="qaid-scope-ring"></div>
|
|
9
9
|
<div class="qaid-scope-ring-inner"></div>
|
|
10
10
|
<div class="qaid-scope-dot"></div>
|
|
11
|
-
`,this.overlayContainer.appendChild(this.captureLayer),this.overlayContainer.appendChild(o),this.overlayContainer.appendChild(this.crosshairH),this.overlayContainer.appendChild(this.crosshairV),this.overlayContainer.appendChild(this.scope),this.applyVars(this.overlayContainer),t.appendChild(this.overlayContainer)}handleKeyDown(t){t.key==="Escape"&&(this.isRecording?this.stopRecording():this.videoPreview?this.cancelRecordingPreview():this.state==="TARGETING"?this.cancelTargeting():this.state==="MODAL_OPEN"&&this.closeModal())}handleMouseMove(t){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){const o=[this.shadowHost,this.overlayShadowHost].filter(Boolean),e
|
|
11
|
+
`,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)}handleKeyDown(t){t.key==="Escape"&&(this.isRecording?this.stopRecording():this.videoPreview?this.cancelRecordingPreview():this.state==="TARGETING"?this.cancelTargeting():this.state==="MODAL_OPEN"&&this.closeModal())}handleMouseMove(t){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){const o=[this.shadowHost,this.overlayShadowHost].filter(Boolean),e=$(t.clientX,t.clientY,o);if(e&&!N(e)){if(this.highlightBox){const n=e.getBoundingClientRect();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"}}else this.highlightBox&&(this.highlightBox.style.display="none")}}handleClick(t){if(this.state!=="TARGETING"||!this.shadowHost)return;t.preventDefault(),t.stopPropagation();const o=[this.shadowHost,this.overlayShadowHost].filter(Boolean),e=$(t.clientX,t.clientY,o);if(!e||N(e))return;const n=It(e,8);this.selectedBounds={...n,clickX:t.clientX,clickY:t.clientY,visible:!0};const{selector:a,text:s}=bt(e);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()}cancelTargeting(){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}removeTargetingOverlay(){this.overlayContainer&&(this.overlayContainer.remove(),this.overlayContainer=null),this.captureLayer=null,this.crosshairH=null,this.crosshairV=null,this.scope=null}showSelectedMarker(){if(!this.selectedBounds.visible)return;const t=this.ensureOverlayHost();this.marker=document.createElement("div"),this.marker.className="qaid-selected-marker",this.marker.style.left=`${this.selectedBounds.x}px`,this.marker.style.top=`${this.selectedBounds.y}px`,this.marker.style.width=`${this.selectedBounds.width}px`,this.marker.style.height=`${this.selectedBounds.height}px`,this.marker.style.zIndex=String(this.config.zIndex+1),this.applyVars(this.marker),t.appendChild(this.marker)}hideSelectedMarker(){this.marker&&(this.marker.remove(),this.marker=null)}async submitFeedback(){if(!this.feedbackData.feedbackType)return;let t=null;this.config.captureScreenshot&&(this.config.screenshotMethod==="dom"?t=await F(this.config.screenshotOptions):t=await Lt(this.config.screenshotOptions));const o=this.feedbackData.elementSelector?{x:this.selectedBounds.x,y:this.selectedBounds.y,width:this.selectedBounds.width,height:this.selectedBounds.height}:null,e={feedbackType:this.feedbackData.feedbackType,pageUrl:window.location.href,apiKey:this.config.apiKey||void 0,elementSelector:this.feedbackData.elementSelector,elementText:this.feedbackData.elementText,consoleErrors:[...this.feedbackData.consoleErrors],screenWidth:window.innerWidth,screenHeight:window.innerHeight,clickX:this.selectedBounds.clickX,clickY:this.selectedBounds.clickY,scrollX:window.scrollX,scrollY:window.scrollY,screenshot:t,visitorId:this.visitorId,elementBounds:o,userAgent:navigator.userAgent};try{const n=await fetch(this.config.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(n.ok){const a=await n.json();this.feedbackId=a.id}}catch(n){console.error("Failed to submit feedback:",n)}this.state="MODAL_OPEN",this.showModal(),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="auto")}showModal(){const t=this.ensureOverlayHost();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)}showBottomSheet(){const t=this.ensureOverlayHost(),o=document.createElement("div");o.className="qaid-bottom-sheet",o.style.zIndex=String(this.config.zIndex+3),o.innerHTML=`
|
|
12
12
|
<div class="qaid-bottom-sheet-content">
|
|
13
13
|
<div class="qaid-bottom-sheet-handle"></div>
|
|
14
14
|
${this.getModalContent()}
|
|
15
15
|
</div>
|
|
16
|
-
`,this.applyVars(o),t.appendChild(o),this.modalContainer=o,this.setupModalInteractions()}showPositionedModal(){const t=this.ensureOverlayHost(),{modal:o,arrow:e}=
|
|
16
|
+
`,this.applyVars(o),t.appendChild(o),this.modalContainer=o,this.setupModalInteractions()}showPositionedModal(){const t=this.ensureOverlayHost(),{modal:o,arrow:e}=qt(this.selectedBounds,window.innerWidth,window.innerHeight,{width:this.config.modalWidth,height:280,arrowHeight:12,gap:8,viewportPadding:16});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);const n=document.createElement("div");n.className="qaid-modal-arrow",n.style.left=`${e.left}px`;const a=document.createElement("div");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()}getModalContent(){const t=this.feedbackData.feedbackType==="up",o=this.config.positiveIcon||b,e=this.config.negativeIcon||q;return`
|
|
17
17
|
<div class="qaid-modal-header">
|
|
18
18
|
<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">
|
|
19
19
|
${t?o:e}
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
<div class="qaid-btn-row">
|
|
28
28
|
<button type="button" class="qaid-btn-submit">${this.config.text.skipButton}</button>
|
|
29
29
|
</div>
|
|
30
|
-
`}setupModalInteractions(){if(!this.modalContainer)return;const t=this.modalContainer.querySelector(".qaid-textarea"),o=this.modalContainer.querySelector(".qaid-btn-submit");t&&(setTimeout(()=>t.focus(),100),t.addEventListener("input",()=>{o&&(o.textContent=t.value.trim()?this.config.text.submitButton:this.config.text.skipButton)})),o&&o.addEventListener("click",()=>{const n=(t==null?void 0:t.value.trim())||null;this.submitMessage(n)});const e=this.modalContainer.querySelector(".qaid-type-toggle");e&&e.addEventListener("click",()=>{const n=this.feedbackData.feedbackType==="up"?"down":"up";this.feedbackData.feedbackType=n,this.config.buttonClass?(e.classList.toggle("qaid-btn-up",n==="up"),e.classList.toggle("qaid-btn-down",n==="down")):(e.classList.toggle("qaid-type-up",n==="up"),e.classList.toggle("qaid-type-down",n==="down"));const a=this.config.positiveIcon||b,s=this.config.negativeIcon||x;e.innerHTML=n==="up"?a:s,this.feedbackId&&fetch(`${this.config.endpoint}/${this.feedbackId}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({feedbackType:n})}).catch(l=>console.error("Failed to update feedback type:",l))})}async submitMessage(t){if(this.feedbackId){try{await fetch(`${this.config.endpoint}/${this.feedbackId}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:t})})}catch(o){console.error("Failed to submit feedback message:",o)}this.feedbackId=null}this.closeModal()}closeModal(){this.state==="MODAL_OPEN"&&this.feedbackId&&fetch(`${this.config.endpoint}/${this.feedbackId}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:null})}).catch(t=>console.error("Failed to finalize feedback:",t)),this.modalContainer&&(this.modalContainer.remove(),this.modalContainer=null),this.backdrop&&(this.backdrop.remove(),this.backdrop=null),document.removeEventListener("keydown",this.boundKeyDown),this.hideSelectedMarker(),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="none"),this.state="IDLE",this.feedbackId=null,this.feedbackData.feedbackType=null,this.feedbackData.elementSelector=null,this.feedbackData.elementText=null,this.selectedBounds.visible=!1}async startRecording(){if(!(this.isRecording||this.state!=="IDLE"))try{this.networkCapture=A(),this.videoRecorder=$({maxDuration:this.config.videoOptions.maxDuration}),this.videoRecorder.onTick(t=>{this.updateRecordingTimer(t)}),this.videoRecorder.onStop(t=>{this.isRecording&&(this.recordedBlob=t,this.isRecording=!1,this.removeRecordingIndicator(),document.removeEventListener("keydown",this.boundKeyDown),this.setButtonsDisabled(!1),t&&t.size>0?this.showRecordingPreview():this.cleanupRecording())}),await this.videoRecorder.start(),this.isRecording=!0,this.setButtonsDisabled(!0),this.showRecordingIndicator(),document.addEventListener("keydown",this.boundKeyDown)}catch{this.cleanupRecording()}}async stopRecording(){if(!(!this.isRecording||!this.videoRecorder)){try{this.recordedBlob=await this.videoRecorder.stop()}catch{this.recordedBlob=null}this.isRecording=!1,this.removeRecordingIndicator(),document.removeEventListener("keydown",this.boundKeyDown),this.recordedBlob&&this.recordedBlob.size>0?this.showRecordingPreview():this.cleanupRecording()}}showRecordingIndicator(){const t=this.ensureOverlayHost();this.recordingIndicator=document.createElement("div"),this.recordingIndicator.className="qaid-recording-indicator",this.recordingIndicator.style.zIndex=String(this.config.zIndex+100);const o=document.createElement("div");o.className="qaid-recording-dot";const e=document.createElement("span");e.className="qaid-recording-time",e.textContent=this.formatTime(this.config.videoOptions.maxDuration);const n=document.createElement("button");n.type="button",n.className="qaid-recording-stop",n.textContent="Stop",n.addEventListener("click",()=>this.stopRecording()),this.recordingIndicator.appendChild(o),this.recordingIndicator.appendChild(e),this.recordingIndicator.appendChild(n),this.applyVars(this.recordingIndicator),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="auto"),t.appendChild(this.recordingIndicator)}updateRecordingTimer(t){if(!this.recordingIndicator)return;const o=this.recordingIndicator.querySelector(".qaid-recording-time");if(o){const e=Math.max(0,this.config.videoOptions.maxDuration-t);o.textContent=this.formatTime(e)}}formatTime(t){const o=Math.floor(t/60),e=t%60;return`${o}:${e.toString().padStart(2,"0")}`}removeRecordingIndicator(){this.recordingIndicator&&(this.recordingIndicator.remove(),this.recordingIndicator=null)}showRecordingPreview(){if(!this.recordedBlob)return;const t=this.ensureOverlayHost(),o=URL.createObjectURL(this.recordedBlob);this.videoPreview=document.createElement("div"),this.videoPreview.className="qaid-video-preview",this.videoPreview.style.zIndex=String(this.config.zIndex+100);const e=document.createElement("div");e.className="qaid-video-preview-box";const n=document.createElement("h3");n.textContent="Review your recording";const a=document.createElement("video");a.src=o,a.controls=!0,a.autoplay=!0,a.muted=!0;const s=document.createElement("textarea");s.placeholder="Optional: Describe the issue you recorded...";const l=document.createElement("div");l.className="qaid-video-preview-actions";const d=document.createElement("button");d.type="button",d.className="qaid-video-btn qaid-video-btn-cancel",d.textContent="Cancel",d.addEventListener("click",()=>this.cancelRecordingPreview());const r=document.createElement("button");r.type="button",r.className="qaid-video-btn qaid-video-btn-rerecord",r.textContent="Re-record",r.addEventListener("click",()=>{this.cancelRecordingPreview(),this.startRecording()});const c=document.createElement("button");c.type="button",c.className="qaid-video-btn qaid-video-btn-send",c.textContent="Send",c.addEventListener("click",()=>{const u=s.value.trim()||null;this.submitVideoFeedback(u,c)}),l.appendChild(d),l.appendChild(r),l.appendChild(c),e.appendChild(n),e.appendChild(a),e.appendChild(s),e.appendChild(l),this.videoPreview.appendChild(e),this.applyVars(this.videoPreview),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="auto"),t.appendChild(this.videoPreview),document.addEventListener("keydown",this.boundKeyDown)}cancelRecordingPreview(){this.removeVideoPreview(),this.cleanupRecording()}removeVideoPreview(){if(this.videoPreview){const t=this.videoPreview.querySelector("video");t!=null&&t.src&&URL.revokeObjectURL(t.src),this.videoPreview.remove(),this.videoPreview=null}document.removeEventListener("keydown",this.boundKeyDown)}async submitVideoFeedback(t,o){if(!this.recordedBlob||this.isSendingVideo)return;this.isSendingVideo=!0,o.disabled=!0,o.textContent="Sending...";const e=new FormData;e.append("video",this.recordedBlob,`recording.${this.recordedBlob.type.includes("mp4")?"mp4":"webm"}`),e.append("pageUrl",window.location.href),e.append("visitorId",this.visitorId),this.config.apiKey&&e.append("apiKey",this.config.apiKey),t&&e.append("message",t),this.consoleCapture&&e.append("consoleErrors",JSON.stringify(this.consoleCapture.errors)),this.networkCapture&&e.append("networkErrors",JSON.stringify(this.networkCapture.errors));try{const n=await fetch(`${this.config.endpoint}/video`,{method:"POST",body:e});n.ok||console.error("Failed to submit video feedback:",await n.text())}catch(n){console.error("Failed to submit video feedback:",n)}this.isSendingVideo=!1,this.removeVideoPreview(),this.cleanupRecording()}cleanupRecording(){this.isRecording=!1,this.removeRecordingIndicator(),this.videoRecorder&&(this.videoRecorder.destroy(),this.videoRecorder=null),this.networkCapture&&(this.networkCapture.restore(),this.networkCapture=null),this.recordedBlob&&(this.recordedBlob=null),this.setButtonsDisabled(!1),this.overlayShadowHost&&this.state==="IDLE"&&(this.overlayShadowHost.style.pointerEvents="none")}setButtonsDisabled(t){if(!this.buttonsContainer)return;this.buttonsContainer.querySelectorAll("button.qaid-btn, button.qaid-btn-structural").forEach(e=>{t?e.classList.contains("qaid-btn-record")||(e.disabled=!0,e.style.opacity="0.5"):(e.disabled=!1,e.style.opacity="")})}destroy(){this.cleanupRecording(),this.removeVideoPreview(),this.consoleCapture&&(this.consoleCapture.restore(),this.consoleCapture=null),window.removeEventListener("resize",this.boundResize),document.removeEventListener("keydown",this.boundKeyDown),T("qaid-highlight"),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,ht()}}function X(i){var o;const t=document.querySelector(i);return((o=t==null?void 0:t.textContent)==null?void 0:o.trim())??""}function At(){var o;const i=document.querySelector('script[type="application/json"][data-feedback-config]');if(!i)return null;const t=(o=i.textContent)==null?void 0:o.trim();if(!t)return null;try{const e=JSON.parse(t);return e.cssSelector&&!e.css&&(e.css=X(e.cssSelector),delete e.cssSelector),e}catch{return null}}function Ot(i){const t=i.getAttribute("data-endpoint");if(!t)return null;const o=i.getAttribute("data-position"),e=i.getAttribute("data-zindex"),n=i.getAttribute("data-positive-color"),a=i.getAttribute("data-negative-color"),s=i.getAttribute("data-marker-color"),l=i.getAttribute("data-container"),d=i.getAttribute("data-button-class"),r=i.getAttribute("data-skip-targeting"),c=i.getAttribute("data-incognito"),u=i.getAttribute("data-button-size"),p=i.getAttribute("data-offset-x"),g=i.getAttribute("data-offset-y"),y=i.getAttribute("data-modal-width"),v=i.getAttribute("data-backdrop-opacity"),m=i.getAttribute("data-font-family"),w=i.getAttribute("data-font-size"),q=i.getAttribute("data-tooltip"),E=i.getAttribute("data-modal-title"),j=i.getAttribute("data-modal-subtitle"),K=i.getAttribute("data-placeholder"),Y=i.getAttribute("data-submit-button"),J=i.getAttribute("data-skip-button"),Pt=i.getAttribute("data-positive-icon"),$t=i.getAttribute("data-negative-icon"),Nt=i.getAttribute("data-api-key"),Vt=i.getAttribute("data-capture-screenshot"),I=i.getAttribute("data-screenshot-quality"),L=i.getAttribute("data-screenshot-max-width"),H=i.getAttribute("data-screenshot-max-height"),Ft=i.getAttribute("data-capture-video"),Ut=i.getAttribute("data-hide-thumbs"),G=i.getAttribute("data-video-max-duration"),Wt=i.getAttribute("data-screenshot-method"),_t=i.getAttribute("data-direction"),Q=i.getAttribute("data-css-selector");return{endpoint:t,css:Q?X(Q):void 0,apiKey:Nt??void 0,captureScreenshot:Vt==="true"?!0:void 0,screenshotOptions:I||L||H?{quality:I?parseFloat(I):void 0,maxWidth:L?parseInt(L,10):void 0,maxHeight:H?parseInt(H,10):void 0}:void 0,container:l??void 0,buttonClass:d??void 0,direction:_t??void 0,position:o??void 0,zIndex:e?parseInt(e,10):void 0,skipTargeting:r==="true"?!0:void 0,incognito:c==="true"?!0:void 0,buttonSize:u??void 0,offset:p||g?{x:p?parseInt(p,10):void 0,y:g?parseInt(g,10):void 0}:void 0,modalWidth:y?parseInt(y,10):void 0,backdropOpacity:v?parseFloat(v):void 0,fontFamily:m??void 0,fontSize:w?parseInt(w,10):void 0,colors:{positive:n??void 0,negative:a??void 0,marker:s??void 0},text:q||E||j||K||Y||J?{tooltip:q??void 0,modalTitle:E??void 0,modalSubtitle:j??void 0,placeholder:K??void 0,submitButton:Y??void 0,skipButton:J??void 0}:void 0,positiveIcon:Pt??void 0,negativeIcon:$t??void 0,screenshotMethod:Wt??void 0,captureVideo:Ft==="true"?!0:void 0,hideThumbs:Ut==="true"?!0:void 0,videoOptions:G?{maxDuration:parseInt(G,10)}:void 0}}if(typeof document<"u"){const i=()=>{const t=document.currentScript,o=At(),e=t?Ot(t):null,n=o??e;n!=null&&n.endpoint&&new _(n)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",i):i()}f.QaidFeedback=_,f.captureDomScreenshot=U,f.captureNetworkErrors=A,f.createVideoRecorder=$,f.getSupportedMimeType=P,f.isDomScreenshotSupported=Mt,f.isVideoRecordingSupported=O,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
|
|
30
|
+
`}setupModalInteractions(){if(!this.modalContainer)return;const t=this.modalContainer.querySelector(".qaid-textarea"),o=this.modalContainer.querySelector(".qaid-btn-submit");t&&(setTimeout(()=>t.focus(),100),t.addEventListener("input",()=>{o&&(o.textContent=t.value.trim()?this.config.text.submitButton:this.config.text.skipButton)})),o&&o.addEventListener("click",()=>{const n=(t==null?void 0:t.value.trim())||null;this.submitMessage(n)});const e=this.modalContainer.querySelector(".qaid-type-toggle");e&&e.addEventListener("click",()=>{const n=this.feedbackData.feedbackType==="up"?"down":"up";this.feedbackData.feedbackType=n,this.config.buttonClass?(e.classList.toggle("qaid-btn-up",n==="up"),e.classList.toggle("qaid-btn-down",n==="down")):(e.classList.toggle("qaid-type-up",n==="up"),e.classList.toggle("qaid-type-down",n==="down"));const a=this.config.positiveIcon||b,s=this.config.negativeIcon||q;e.innerHTML=n==="up"?a:s,this.feedbackId&&fetch(`${this.config.endpoint}/${this.feedbackId}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({feedbackType:n})}).catch(l=>console.error("Failed to update feedback type:",l))})}async submitMessage(t){if(this.feedbackId){try{await fetch(`${this.config.endpoint}/${this.feedbackId}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:t})})}catch(o){console.error("Failed to submit feedback message:",o)}this.feedbackId=null}this.closeModal()}closeModal(){this.state==="MODAL_OPEN"&&this.feedbackId&&fetch(`${this.config.endpoint}/${this.feedbackId}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:null})}).catch(t=>console.error("Failed to finalize feedback:",t)),this.modalContainer&&(this.modalContainer.remove(),this.modalContainer=null),this.backdrop&&(this.backdrop.remove(),this.backdrop=null),document.removeEventListener("keydown",this.boundKeyDown),this.hideSelectedMarker(),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="none"),this.state="IDLE",this.feedbackId=null,this.feedbackData.feedbackType=null,this.feedbackData.elementSelector=null,this.feedbackData.elementText=null,this.selectedBounds.visible=!1}async startRecording(){if(!(this.isRecording||this.state!=="IDLE"))try{this.networkCapture=B(),this.videoRecorder=O({maxDuration:this.config.videoOptions.maxDuration}),this.videoRecorder.onTick(t=>{this.updateRecordingTimer(t)}),this.videoRecorder.onStop(t=>{this.isRecording&&(this.recordedBlob=t,this.isRecording=!1,this.removeRecordingIndicator(),document.removeEventListener("keydown",this.boundKeyDown),this.setButtonsDisabled(!1),t&&t.size>0?this.showRecordingPreview():this.cleanupRecording())}),await this.videoRecorder.start(),this.isRecording=!0,this.setButtonsDisabled(!0),this.showRecordingIndicator(),document.addEventListener("keydown",this.boundKeyDown)}catch{this.cleanupRecording()}}async stopRecording(){if(!(!this.isRecording||!this.videoRecorder)){try{this.recordedBlob=await this.videoRecorder.stop()}catch{this.recordedBlob=null}this.isRecording=!1,this.removeRecordingIndicator(),document.removeEventListener("keydown",this.boundKeyDown),this.recordedBlob&&this.recordedBlob.size>0?this.showRecordingPreview():this.cleanupRecording()}}showRecordingIndicator(){const t=this.ensureOverlayHost();this.recordingIndicator=document.createElement("div"),this.recordingIndicator.className="qaid-recording-indicator",this.recordingIndicator.style.zIndex=String(this.config.zIndex+100);const o=document.createElement("div");o.className="qaid-recording-dot";const e=document.createElement("span");e.className="qaid-recording-time",e.textContent=this.formatTime(this.config.videoOptions.maxDuration);const n=document.createElement("button");n.type="button",n.className="qaid-recording-stop",n.textContent="Stop",n.addEventListener("click",()=>this.stopRecording()),this.recordingIndicator.appendChild(o),this.recordingIndicator.appendChild(e),this.recordingIndicator.appendChild(n),this.applyVars(this.recordingIndicator),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="auto"),t.appendChild(this.recordingIndicator)}updateRecordingTimer(t){if(!this.recordingIndicator)return;const o=this.recordingIndicator.querySelector(".qaid-recording-time");if(o){const e=Math.max(0,this.config.videoOptions.maxDuration-t);o.textContent=this.formatTime(e)}}formatTime(t){const o=Math.floor(t/60),e=t%60;return`${o}:${e.toString().padStart(2,"0")}`}removeRecordingIndicator(){this.recordingIndicator&&(this.recordingIndicator.remove(),this.recordingIndicator=null)}showRecordingPreview(){if(!this.recordedBlob)return;const t=this.ensureOverlayHost(),o=URL.createObjectURL(this.recordedBlob);this.videoPreview=document.createElement("div"),this.videoPreview.className="qaid-video-preview",this.videoPreview.style.zIndex=String(this.config.zIndex+100);const e=document.createElement("div");e.className="qaid-video-preview-box";const n=document.createElement("h3");n.textContent="Review your recording";const a=document.createElement("video");a.src=o,a.controls=!0,a.autoplay=!0,a.muted=!0;const s=document.createElement("textarea");s.placeholder="Optional: Describe the issue you recorded...";const l=document.createElement("div");l.className="qaid-video-preview-actions";const d=document.createElement("button");d.type="button",d.className="qaid-video-btn qaid-video-btn-cancel",d.textContent="Cancel",d.addEventListener("click",()=>this.cancelRecordingPreview());const r=document.createElement("button");r.type="button",r.className="qaid-video-btn qaid-video-btn-rerecord",r.textContent="Re-record",r.addEventListener("click",()=>{this.cancelRecordingPreview(),this.startRecording()});const c=document.createElement("button");c.type="button",c.className="qaid-video-btn qaid-video-btn-send",c.textContent="Send",c.addEventListener("click",()=>{const u=s.value.trim()||null;this.submitVideoFeedback(u,c)}),l.appendChild(d),l.appendChild(r),l.appendChild(c),e.appendChild(n),e.appendChild(a),e.appendChild(s),e.appendChild(l),this.videoPreview.appendChild(e),this.applyVars(this.videoPreview),this.overlayShadowHost&&(this.overlayShadowHost.style.pointerEvents="auto"),t.appendChild(this.videoPreview),document.addEventListener("keydown",this.boundKeyDown)}cancelRecordingPreview(){this.removeVideoPreview(),this.cleanupRecording()}removeVideoPreview(){if(this.videoPreview){const t=this.videoPreview.querySelector("video");t!=null&&t.src&&URL.revokeObjectURL(t.src),this.videoPreview.remove(),this.videoPreview=null}document.removeEventListener("keydown",this.boundKeyDown)}async submitVideoFeedback(t,o){if(!this.recordedBlob||this.isSendingVideo)return;this.isSendingVideo=!0,o.disabled=!0,o.textContent="Sending...";const e=new FormData;e.append("video",this.recordedBlob,`recording.${this.recordedBlob.type.includes("mp4")?"mp4":"webm"}`),e.append("pageUrl",window.location.href),e.append("visitorId",this.visitorId),this.config.apiKey&&e.append("apiKey",this.config.apiKey),t&&e.append("message",t),this.consoleCapture&&e.append("consoleErrors",JSON.stringify(this.consoleCapture.errors)),this.networkCapture&&e.append("networkErrors",JSON.stringify(this.networkCapture.errors));try{const n=await fetch(`${this.config.endpoint}/video`,{method:"POST",body:e});n.ok||console.error("Failed to submit video feedback:",await n.text())}catch(n){console.error("Failed to submit video feedback:",n)}this.isSendingVideo=!1,this.removeVideoPreview(),this.cleanupRecording()}cleanupRecording(){this.isRecording=!1,this.removeRecordingIndicator(),this.videoRecorder&&(this.videoRecorder.destroy(),this.videoRecorder=null),this.networkCapture&&(this.networkCapture.restore(),this.networkCapture=null),this.recordedBlob&&(this.recordedBlob=null),this.setButtonsDisabled(!1),this.overlayShadowHost&&this.state==="IDLE"&&(this.overlayShadowHost.style.pointerEvents="none")}setButtonsDisabled(t){if(!this.buttonsContainer)return;this.buttonsContainer.querySelectorAll("button.qaid-btn, button.qaid-btn-structural").forEach(e=>{t?e.classList.contains("qaid-btn-record")||(e.disabled=!0,e.style.opacity="0.5"):(e.disabled=!1,e.style.opacity="")})}destroy(){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()}}function X(i){var o;const t=document.querySelector(i);return((o=t==null?void 0:t.textContent)==null?void 0:o.trim())??""}function Bt(){var o;const i=document.querySelector('script[type="application/json"][data-feedback-config]');if(!i)return null;const t=(o=i.textContent)==null?void 0:o.trim();if(!t)return null;try{const e=JSON.parse(t);return e.cssSelector&&!e.css&&(e.css=X(e.cssSelector),delete e.cssSelector),e}catch{return null}}function Pt(i){const t=i.getAttribute("data-endpoint");if(!t)return null;const o=i.getAttribute("data-position"),e=i.getAttribute("data-zindex"),n=i.getAttribute("data-positive-color"),a=i.getAttribute("data-negative-color"),s=i.getAttribute("data-marker-color"),l=i.getAttribute("data-container"),d=i.getAttribute("data-button-class"),r=i.getAttribute("data-skip-targeting"),c=i.getAttribute("data-incognito"),u=i.getAttribute("data-button-size"),p=i.getAttribute("data-offset-x"),f=i.getAttribute("data-offset-y"),y=i.getAttribute("data-modal-width"),v=i.getAttribute("data-backdrop-opacity"),m=i.getAttribute("data-font-family"),w=i.getAttribute("data-font-size"),x=i.getAttribute("data-tooltip"),E=i.getAttribute("data-modal-title"),_=i.getAttribute("data-modal-subtitle"),j=i.getAttribute("data-placeholder"),K=i.getAttribute("data-submit-button"),Y=i.getAttribute("data-skip-button"),At=i.getAttribute("data-positive-icon"),Ot=i.getAttribute("data-negative-icon"),$t=i.getAttribute("data-api-key"),Nt=i.getAttribute("data-capture-screenshot"),T=i.getAttribute("data-screenshot-quality"),I=i.getAttribute("data-screenshot-max-width"),L=i.getAttribute("data-screenshot-max-height"),Vt=i.getAttribute("data-capture-video"),Ft=i.getAttribute("data-hide-thumbs"),J=i.getAttribute("data-video-max-duration"),Ut=i.getAttribute("data-screenshot-method"),Wt=i.getAttribute("data-direction"),G=i.getAttribute("data-css-selector");return{endpoint:t,css:G?X(G):void 0,apiKey:$t??void 0,captureScreenshot:Nt==="true"?!0:void 0,screenshotOptions:T||I||L?{quality:T?parseFloat(T):void 0,maxWidth:I?parseInt(I,10):void 0,maxHeight:L?parseInt(L,10):void 0}:void 0,container:l??void 0,buttonClass:d??void 0,direction:Wt??void 0,position:o??void 0,zIndex:e?parseInt(e,10):void 0,skipTargeting:r==="true"?!0:void 0,incognito:c==="true"?!0:void 0,buttonSize:u??void 0,offset:p||f?{x:p?parseInt(p,10):void 0,y:f?parseInt(f,10):void 0}:void 0,modalWidth:y?parseInt(y,10):void 0,backdropOpacity:v?parseFloat(v):void 0,fontFamily:m??void 0,fontSize:w?parseInt(w,10):void 0,colors:{positive:n??void 0,negative:a??void 0,marker:s??void 0},text:x||E||_||j||K||Y?{tooltip:x??void 0,modalTitle:E??void 0,modalSubtitle:_??void 0,placeholder:j??void 0,submitButton:K??void 0,skipButton:Y??void 0}:void 0,positiveIcon:At??void 0,negativeIcon:Ot??void 0,screenshotMethod:Ut??void 0,captureVideo:Vt==="true"?!0:void 0,hideThumbs:Ft==="true"?!0:void 0,videoOptions:J?{maxDuration:parseInt(J,10)}:void 0}}if(typeof document<"u"){const i=()=>{const t=document.currentScript,o=Bt(),e=t?Pt(t):null,n=o??e;n!=null&&n.endpoint&&new W(n)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",i):i()}g.QaidFeedback=W,g.captureDomScreenshot=F,g.captureNetworkErrors=B,g.createVideoRecorder=O,g.getSupportedMimeType=A,g.isDomScreenshotSupported=Dt,g.isVideoRecordingSupported=P,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
|
|
31
31
|
//# sourceMappingURL=qaid.umd.cjs.map
|