@qaiddev/thumbs-embed 1.0.14 → 1.0.16
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/README.md +3 -0
- package/dist/embed.d.ts +6 -0
- package/dist/modal-positioning.d.ts +27 -0
- package/dist/network-capture.d.ts +8 -0
- package/dist/qaid.js +232 -233
- package/dist/qaid.js.map +1 -1
- package/dist/qaid.umd.cjs +5 -5
- package/dist/qaid.umd.cjs.map +1 -1
- package/package.json +4 -2
package/dist/qaid.js
CHANGED
|
@@ -4,7 +4,7 @@ const E = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none"
|
|
|
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
5
|
</svg>`, it = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
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>`, ot = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{transition:transform .3s ease-in-out}.qaid-buttons.qaid-dismissed.qaid-bottom-right,.qaid-buttons.qaid-dismissed.qaid-top-right{transform:translate(calc(100% + 2rem))}.qaid-buttons.qaid-dismissed.qaid-bottom-left,.qaid-buttons.qaid-dismissed.qaid-top-left{transform:translate(calc(-100% - 2rem))}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}", nt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
7
|
+
</svg>`, ot = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-incognito.qaid-force-hidden{opacity:0}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}", nt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
8
8
|
let w = 0;
|
|
9
9
|
const st = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", at = {
|
|
10
10
|
small: 36,
|
|
@@ -16,7 +16,7 @@ const st = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-siz
|
|
|
16
16
|
large: 32
|
|
17
17
|
};
|
|
18
18
|
function dt(e, t, i) {
|
|
19
|
-
const [o, n, s] = [e, t, i].map((
|
|
19
|
+
const [o, n, s] = [e, t, i].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
|
|
20
20
|
return 0.2126 * o + 0.7152 * n + 0.0722 * s;
|
|
21
21
|
}
|
|
22
22
|
function ct(e) {
|
|
@@ -46,28 +46,28 @@ function ht(e = {}) {
|
|
|
46
46
|
markerColor: o = "#6366f1",
|
|
47
47
|
buttonSize: n = "medium",
|
|
48
48
|
modalWidth: s = 400,
|
|
49
|
-
backdropOpacity:
|
|
50
|
-
fontFamily:
|
|
51
|
-
fontSize:
|
|
52
|
-
} = e,
|
|
49
|
+
backdropOpacity: a = 0.3,
|
|
50
|
+
fontFamily: c = "system-ui, -apple-system, sans-serif",
|
|
51
|
+
fontSize: l = 16
|
|
52
|
+
} = e, r = at[n], d = rt[n], h = lt(o);
|
|
53
53
|
return {
|
|
54
54
|
"--qaid-positive": t,
|
|
55
55
|
"--qaid-negative": i,
|
|
56
56
|
"--qaid-marker": o,
|
|
57
57
|
"--qaid-marker-text": h,
|
|
58
|
-
"--qaid-btn-size": `${
|
|
59
|
-
"--qaid-icon-size": `${
|
|
58
|
+
"--qaid-btn-size": `${r}px`,
|
|
59
|
+
"--qaid-icon-size": `${d}px`,
|
|
60
60
|
"--qaid-modal-width": `${s}px`,
|
|
61
|
-
"--qaid-backdrop-opacity": String(
|
|
62
|
-
"--qaid-font-family":
|
|
63
|
-
"--qaid-font-size": `${
|
|
61
|
+
"--qaid-backdrop-opacity": String(a),
|
|
62
|
+
"--qaid-font-family": c,
|
|
63
|
+
"--qaid-font-size": `${l}px`
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
function ut(e, t) {
|
|
67
67
|
for (const [i, o] of Object.entries(t))
|
|
68
68
|
e.style.setProperty(i, o);
|
|
69
69
|
}
|
|
70
|
-
function
|
|
70
|
+
function z() {
|
|
71
71
|
return ot + st;
|
|
72
72
|
}
|
|
73
73
|
function pt() {
|
|
@@ -76,10 +76,7 @@ function pt() {
|
|
|
76
76
|
e.id = "qaid-styles", e.textContent = nt, document.head.appendChild(e);
|
|
77
77
|
}
|
|
78
78
|
function mt() {
|
|
79
|
-
|
|
80
|
-
const e = document.getElementById("qaid-styles");
|
|
81
|
-
e && e.remove();
|
|
82
|
-
}
|
|
79
|
+
w <= 0 || (w--, w === 0 && document.getElementById("qaid-styles").remove());
|
|
83
80
|
}
|
|
84
81
|
const ft = ["data-comp", "data-qa", "data-testid", "data-id"];
|
|
85
82
|
function U(e, t = document.body) {
|
|
@@ -94,11 +91,11 @@ function U(e, t = document.body) {
|
|
|
94
91
|
}
|
|
95
92
|
return null;
|
|
96
93
|
}
|
|
97
|
-
function
|
|
94
|
+
function gt(e, t = 100) {
|
|
98
95
|
const i = e.textContent?.trim().slice(0, t) || "";
|
|
99
96
|
return i.length === t ? i + "..." : i;
|
|
100
97
|
}
|
|
101
|
-
function
|
|
98
|
+
function bt(e) {
|
|
102
99
|
let t = 1, i = e.previousElementSibling;
|
|
103
100
|
for (; i; )
|
|
104
101
|
t++, i = i.previousElementSibling;
|
|
@@ -108,7 +105,7 @@ function vt(e) {
|
|
|
108
105
|
const t = [];
|
|
109
106
|
let i = e;
|
|
110
107
|
for (; i && i !== document.body && i !== document.documentElement; ) {
|
|
111
|
-
const o = i.tagName.toLowerCase(), n =
|
|
108
|
+
const o = i.tagName.toLowerCase(), n = bt(i);
|
|
112
109
|
t.unshift(`${o}:nth-child(${n})`), i = i.parentElement;
|
|
113
110
|
}
|
|
114
111
|
return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
|
|
@@ -120,20 +117,20 @@ function wt(e) {
|
|
|
120
117
|
const t = U(e);
|
|
121
118
|
return t ? `[${t}]` : e.id ? `#${yt(e.id)}` : vt(e);
|
|
122
119
|
}
|
|
123
|
-
function
|
|
124
|
-
const t =
|
|
120
|
+
function xt(e) {
|
|
121
|
+
const t = gt(e), i = U(e);
|
|
125
122
|
return { selector: wt(e), text: t, dataAttr: i };
|
|
126
123
|
}
|
|
127
|
-
const
|
|
124
|
+
const X = {
|
|
128
125
|
width: 400,
|
|
129
126
|
height: 280,
|
|
130
127
|
arrowHeight: 12,
|
|
131
128
|
gap: 8,
|
|
132
129
|
viewportPadding: 16
|
|
133
130
|
};
|
|
134
|
-
function
|
|
135
|
-
const s = e.y,
|
|
136
|
-
if (
|
|
131
|
+
function qt(e, t, i, o, n) {
|
|
132
|
+
const s = e.y, a = t - (e.y + e.height);
|
|
133
|
+
if (a >= i + o)
|
|
137
134
|
return {
|
|
138
135
|
top: e.y + e.height + o,
|
|
139
136
|
position: "below"
|
|
@@ -143,29 +140,29 @@ function xt(e, t, i, o, n) {
|
|
|
143
140
|
top: e.y - i - o,
|
|
144
141
|
position: "above"
|
|
145
142
|
};
|
|
146
|
-
const
|
|
147
|
-
let
|
|
148
|
-
return
|
|
143
|
+
const c = a > s ? "below" : "above";
|
|
144
|
+
let l;
|
|
145
|
+
return c === "below" ? l = Math.min(
|
|
149
146
|
e.y + e.height + o,
|
|
150
147
|
t - i - n
|
|
151
|
-
) :
|
|
148
|
+
) : l = Math.max(n, e.y - i - o), { top: l, position: c };
|
|
152
149
|
}
|
|
153
150
|
function kt(e, t, i, o) {
|
|
154
151
|
let s = e.x + e.width / 2 - i / 2;
|
|
155
152
|
return s = Math.max(o, Math.min(s, t - i - o)), s;
|
|
156
153
|
}
|
|
157
154
|
function Ct(e, t, i, o = 24, n = 24) {
|
|
158
|
-
const
|
|
159
|
-
return Math.max(o, Math.min(
|
|
155
|
+
const a = e.clickX - t - n / 2;
|
|
156
|
+
return Math.max(o, Math.min(a, i - o - n / 2));
|
|
160
157
|
}
|
|
161
|
-
function St(e, t, i, o =
|
|
162
|
-
const n = o.height + o.arrowHeight, s =
|
|
158
|
+
function St(e, t, i, o = X) {
|
|
159
|
+
const n = o.height + o.arrowHeight, s = qt(
|
|
163
160
|
e,
|
|
164
161
|
i,
|
|
165
162
|
n,
|
|
166
163
|
o.gap,
|
|
167
164
|
o.viewportPadding
|
|
168
|
-
),
|
|
165
|
+
), a = kt(
|
|
169
166
|
e,
|
|
170
167
|
t,
|
|
171
168
|
o.width,
|
|
@@ -173,11 +170,18 @@ function St(e, t, i, o = W) {
|
|
|
173
170
|
);
|
|
174
171
|
return {
|
|
175
172
|
top: s.top,
|
|
176
|
-
left:
|
|
173
|
+
left: a,
|
|
177
174
|
position: s.position
|
|
178
175
|
};
|
|
179
176
|
}
|
|
180
|
-
function Et(e, t, i, o =
|
|
177
|
+
function Et(e, t, i, o = {}) {
|
|
178
|
+
const n = o.gap ?? 8;
|
|
179
|
+
let s = e.bottom + n;
|
|
180
|
+
s + t.height > i.height - n && (s = e.top - t.height - n);
|
|
181
|
+
let a = e.left;
|
|
182
|
+
return a < n ? a = n : a + t.width > i.width - n && (a = i.width - t.width - n), s < n ? s = n : s + t.height > i.height - n && (s = i.height - t.height - n), { top: s, left: a };
|
|
183
|
+
}
|
|
184
|
+
function Tt(e, t, i, o = X) {
|
|
181
185
|
const n = St(e, t, i, o), s = Ct(
|
|
182
186
|
e,
|
|
183
187
|
n.left,
|
|
@@ -188,22 +192,22 @@ function Et(e, t, i, o = W) {
|
|
|
188
192
|
arrow: { left: s }
|
|
189
193
|
};
|
|
190
194
|
}
|
|
191
|
-
const
|
|
192
|
-
function
|
|
193
|
-
const t = [], i = console.error, o = console.warn, n = console.log, s = (
|
|
194
|
-
const
|
|
195
|
-
message:
|
|
195
|
+
const It = 20;
|
|
196
|
+
function Lt(e) {
|
|
197
|
+
const t = [], i = console.error, o = console.warn, n = console.log, s = (a, c) => {
|
|
198
|
+
const l = {
|
|
199
|
+
message: c.map((r) => String(r)).join(" "),
|
|
196
200
|
timestamp: Date.now(),
|
|
197
|
-
level:
|
|
201
|
+
level: a
|
|
198
202
|
};
|
|
199
|
-
t.length >=
|
|
203
|
+
t.length >= It && t.shift(), t.push(l), e && e(l);
|
|
200
204
|
};
|
|
201
|
-
return console.error = function(...
|
|
202
|
-
s("error",
|
|
203
|
-
}, console.warn = function(...
|
|
204
|
-
s("warn",
|
|
205
|
-
}, console.log = function(...
|
|
206
|
-
s("log",
|
|
205
|
+
return console.error = function(...a) {
|
|
206
|
+
s("error", a), i.apply(console, a);
|
|
207
|
+
}, console.warn = function(...a) {
|
|
208
|
+
s("warn", a), o.apply(console, a);
|
|
209
|
+
}, console.log = function(...a) {
|
|
210
|
+
s("log", a), n.apply(console, a);
|
|
207
211
|
}, {
|
|
208
212
|
errors: t,
|
|
209
213
|
restore: () => {
|
|
@@ -211,57 +215,56 @@ function It(e) {
|
|
|
211
215
|
}
|
|
212
216
|
};
|
|
213
217
|
}
|
|
214
|
-
const
|
|
215
|
-
function
|
|
216
|
-
if (e == null) return;
|
|
218
|
+
const Dt = 20, P = 4096;
|
|
219
|
+
function q(e) {
|
|
217
220
|
const t = typeof e == "string" ? e : JSON.stringify(e);
|
|
218
|
-
return t.length >
|
|
221
|
+
return t.length > P ? t.slice(0, P) + "…[truncated]" : t;
|
|
219
222
|
}
|
|
220
223
|
function O(e, t) {
|
|
221
|
-
e.length >=
|
|
224
|
+
e.length >= Dt && e.shift(), e.push(t);
|
|
222
225
|
}
|
|
223
|
-
async function
|
|
226
|
+
async function Ht(e) {
|
|
224
227
|
try {
|
|
225
228
|
const t = await e.clone().text();
|
|
226
|
-
return
|
|
229
|
+
return q(t);
|
|
227
230
|
} catch {
|
|
228
231
|
return;
|
|
229
232
|
}
|
|
230
233
|
}
|
|
231
|
-
function
|
|
234
|
+
function Mt() {
|
|
232
235
|
const e = [], t = window.fetch;
|
|
233
236
|
window.fetch = async function(n, s) {
|
|
234
|
-
const
|
|
235
|
-
let
|
|
236
|
-
s?.body && (
|
|
237
|
-
const
|
|
238
|
-
if (
|
|
239
|
-
const
|
|
237
|
+
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, c = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
|
|
238
|
+
let l;
|
|
239
|
+
s?.body && (l = q(s.body));
|
|
240
|
+
const r = await t.apply(window, [n, s]);
|
|
241
|
+
if (r.status >= 400) {
|
|
242
|
+
const d = await Ht(r);
|
|
240
243
|
O(e, {
|
|
241
|
-
url:
|
|
242
|
-
method:
|
|
243
|
-
status:
|
|
244
|
-
statusText:
|
|
245
|
-
requestBody:
|
|
246
|
-
responseBody:
|
|
244
|
+
url: a,
|
|
245
|
+
method: c.toUpperCase(),
|
|
246
|
+
status: r.status,
|
|
247
|
+
statusText: r.statusText,
|
|
248
|
+
requestBody: l,
|
|
249
|
+
responseBody: d,
|
|
247
250
|
timestamp: Date.now()
|
|
248
251
|
});
|
|
249
252
|
}
|
|
250
|
-
return
|
|
253
|
+
return r;
|
|
251
254
|
};
|
|
252
255
|
const i = XMLHttpRequest.prototype.open, o = XMLHttpRequest.prototype.send;
|
|
253
|
-
return XMLHttpRequest.prototype.open = function(n, s, ...
|
|
254
|
-
return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), i.apply(this, [n, s, ...
|
|
256
|
+
return XMLHttpRequest.prototype.open = function(n, s, ...a) {
|
|
257
|
+
return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), i.apply(this, [n, s, ...a]);
|
|
255
258
|
}, XMLHttpRequest.prototype.send = function(n) {
|
|
256
|
-
const s = this,
|
|
259
|
+
const s = this, a = n ? q(n) : void 0;
|
|
257
260
|
return s.addEventListener("load", function() {
|
|
258
261
|
s.status >= 400 && O(e, {
|
|
259
262
|
url: s._qaid_url,
|
|
260
263
|
method: s._qaid_method.toUpperCase(),
|
|
261
264
|
status: s.status,
|
|
262
265
|
statusText: s.statusText,
|
|
263
|
-
requestBody:
|
|
264
|
-
responseBody:
|
|
266
|
+
requestBody: a,
|
|
267
|
+
responseBody: q(s.responseText),
|
|
265
268
|
timestamp: Date.now()
|
|
266
269
|
});
|
|
267
270
|
}), o.apply(this, [n]);
|
|
@@ -272,10 +275,10 @@ function Ht() {
|
|
|
272
275
|
}
|
|
273
276
|
};
|
|
274
277
|
}
|
|
275
|
-
function
|
|
278
|
+
function Bt() {
|
|
276
279
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
277
280
|
}
|
|
278
|
-
function
|
|
281
|
+
function Rt() {
|
|
279
282
|
if (typeof MediaRecorder > "u") return "";
|
|
280
283
|
const e = [
|
|
281
284
|
"video/webm;codecs=vp9",
|
|
@@ -288,11 +291,11 @@ function Bt() {
|
|
|
288
291
|
return t;
|
|
289
292
|
return "";
|
|
290
293
|
}
|
|
291
|
-
function
|
|
294
|
+
function zt(e = {}) {
|
|
292
295
|
const t = e.maxDuration ?? 15, i = e.videoBitsPerSecond ?? 8e5;
|
|
293
|
-
let o = null, n = null, s = [],
|
|
294
|
-
function
|
|
295
|
-
|
|
296
|
+
let o = null, n = null, s = [], a = null, c = null, l = null, r = 0, d = null, h = null, u = !1, p = null;
|
|
297
|
+
function b() {
|
|
298
|
+
l !== null && (clearInterval(l), l = null), p !== null && (clearTimeout(p), p = null), o && (o.getTracks().forEach((m) => m.stop()), o = null), n = null, s = [], a = null, c = null, d = null, h = null;
|
|
296
299
|
}
|
|
297
300
|
function f() {
|
|
298
301
|
u || (u = !0, n && n.state !== "inactive" && n.stop());
|
|
@@ -300,7 +303,7 @@ function Rt(e = {}) {
|
|
|
300
303
|
return {
|
|
301
304
|
async start() {
|
|
302
305
|
u = !1, s = [];
|
|
303
|
-
const m =
|
|
306
|
+
const m = Rt();
|
|
304
307
|
if (!m)
|
|
305
308
|
throw new Error("No supported video MIME type found");
|
|
306
309
|
o = await navigator.mediaDevices.getDisplayMedia({
|
|
@@ -317,49 +320,49 @@ function Rt(e = {}) {
|
|
|
317
320
|
}), n = new MediaRecorder(o, {
|
|
318
321
|
mimeType: m,
|
|
319
322
|
videoBitsPerSecond: i
|
|
320
|
-
}), n.ondataavailable = (
|
|
321
|
-
|
|
323
|
+
}), n.ondataavailable = (g) => {
|
|
324
|
+
g.data.size > 0 && s.push(g.data);
|
|
322
325
|
}, n.onstop = () => {
|
|
323
|
-
const
|
|
324
|
-
|
|
326
|
+
const g = new Blob(s, { type: m });
|
|
327
|
+
d && d(g), c && c(g), o && o.getTracks().forEach((x) => x.stop());
|
|
325
328
|
}, n.onerror = () => {
|
|
326
329
|
h && h(new Error("MediaRecorder error"));
|
|
327
|
-
}, n.start(1e3),
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
+
}, n.start(1e3), r = Date.now(), l = setInterval(() => {
|
|
331
|
+
const g = Math.floor((Date.now() - r) / 1e3);
|
|
332
|
+
a && a(g);
|
|
330
333
|
}, 1e3), p = setTimeout(() => {
|
|
331
334
|
f();
|
|
332
335
|
}, t * 1e3);
|
|
333
336
|
},
|
|
334
337
|
stop() {
|
|
335
338
|
return new Promise((m, v) => {
|
|
336
|
-
|
|
339
|
+
d = m, h = v, f();
|
|
337
340
|
});
|
|
338
341
|
},
|
|
339
342
|
onTick(m) {
|
|
340
|
-
|
|
343
|
+
a = m;
|
|
341
344
|
},
|
|
342
345
|
onStop(m) {
|
|
343
|
-
|
|
346
|
+
c = m;
|
|
344
347
|
},
|
|
345
348
|
destroy() {
|
|
346
|
-
f(),
|
|
349
|
+
f(), b();
|
|
347
350
|
}
|
|
348
351
|
};
|
|
349
352
|
}
|
|
350
|
-
function
|
|
353
|
+
function Pt(e = 640) {
|
|
351
354
|
return typeof window < "u" && window.innerWidth < e;
|
|
352
355
|
}
|
|
353
|
-
function
|
|
356
|
+
function A(e, t, i) {
|
|
354
357
|
const o = i.map((s) => s.style.visibility);
|
|
355
358
|
i.forEach((s) => s.style.visibility = "hidden");
|
|
356
359
|
const n = document.elementFromPoint(e, t);
|
|
357
|
-
return i.forEach((s,
|
|
360
|
+
return i.forEach((s, a) => s.style.visibility = o[a]), n;
|
|
358
361
|
}
|
|
359
|
-
function
|
|
362
|
+
function $(e) {
|
|
360
363
|
return e ? e.hasAttribute("data-qaid-embed") || e.hasAttribute("data-qaid-embed-overlay") ? !0 : !!e.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
|
|
361
364
|
}
|
|
362
|
-
function
|
|
365
|
+
function Ot(e, t = 0) {
|
|
363
366
|
const i = e.getBoundingClientRect();
|
|
364
367
|
return {
|
|
365
368
|
x: i.left - t,
|
|
@@ -378,26 +381,26 @@ async function At(e = {}) {
|
|
|
378
381
|
video: {
|
|
379
382
|
displaySurface: "browser"
|
|
380
383
|
}
|
|
381
|
-
}), s = n.getVideoTracks()[0],
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
384
|
+
}), s = n.getVideoTracks()[0], a = s.getSettings(), c = document.createElement("video");
|
|
385
|
+
c.srcObject = n, c.muted = !0, await new Promise((f) => {
|
|
386
|
+
c.onloadedmetadata = () => {
|
|
387
|
+
c.play(), f();
|
|
385
388
|
};
|
|
386
389
|
}), await new Promise((f) => {
|
|
387
390
|
const m = () => {
|
|
388
|
-
|
|
391
|
+
c.readyState >= 2 ? f() : requestAnimationFrame(m);
|
|
389
392
|
};
|
|
390
393
|
m();
|
|
391
394
|
}), await new Promise((f) => setTimeout(f, 100));
|
|
392
|
-
const
|
|
395
|
+
const l = a.width || c.videoWidth, r = a.height || c.videoHeight, d = Math.min(i / l, o / r, 1), h = Math.round(l * d), u = Math.round(r * d), p = document.createElement("canvas");
|
|
393
396
|
p.width = h, p.height = u;
|
|
394
|
-
const
|
|
395
|
-
return
|
|
397
|
+
const b = p.getContext("2d");
|
|
398
|
+
return b ? (b.drawImage(c, 0, 0, h, u), s.stop(), p.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
396
399
|
} catch (n) {
|
|
397
400
|
return console.warn("Screenshot capture failed:", n), null;
|
|
398
401
|
}
|
|
399
402
|
}
|
|
400
|
-
const
|
|
403
|
+
const N = "https://qaid.dev/lib/html2canvas.min.js", $t = 1e4, Nt = 50;
|
|
401
404
|
let y = null;
|
|
402
405
|
function Kt() {
|
|
403
406
|
if (typeof document > "u" || typeof window > "u")
|
|
@@ -405,32 +408,32 @@ function Kt() {
|
|
|
405
408
|
const e = document.createElement("canvas");
|
|
406
409
|
return typeof e.getContext == "function" && !!e.getContext("2d");
|
|
407
410
|
}
|
|
408
|
-
function
|
|
411
|
+
function Vt() {
|
|
409
412
|
return window.html2canvas ? Promise.resolve(!0) : y || (y = new Promise((e) => {
|
|
410
413
|
if (!document.querySelector(
|
|
411
|
-
`script[src="${
|
|
414
|
+
`script[src="${N}"]`
|
|
412
415
|
)) {
|
|
413
416
|
const n = document.createElement("script");
|
|
414
|
-
n.src =
|
|
417
|
+
n.src = N, n.async = !0, document.head.appendChild(n);
|
|
415
418
|
}
|
|
416
419
|
const i = Date.now(), o = () => {
|
|
417
420
|
if (window.html2canvas) {
|
|
418
421
|
e(!0);
|
|
419
422
|
return;
|
|
420
423
|
}
|
|
421
|
-
if (Date.now() - i >
|
|
424
|
+
if (Date.now() - i > $t) {
|
|
422
425
|
y = null, e(!1);
|
|
423
426
|
return;
|
|
424
427
|
}
|
|
425
|
-
setTimeout(o,
|
|
428
|
+
setTimeout(o, Nt);
|
|
426
429
|
};
|
|
427
430
|
o();
|
|
428
431
|
}), y);
|
|
429
432
|
}
|
|
430
|
-
async function
|
|
433
|
+
async function _t(e = {}) {
|
|
431
434
|
const { quality: t = 0.8, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
432
435
|
try {
|
|
433
|
-
if (!await
|
|
436
|
+
if (!await Vt() || !window.html2canvas)
|
|
434
437
|
return console.warn("html2canvas failed to load"), null;
|
|
435
438
|
const s = await window.html2canvas(document.body, {
|
|
436
439
|
useCORS: !0,
|
|
@@ -442,45 +445,45 @@ async function Vt(e = {}) {
|
|
|
442
445
|
height: document.documentElement.clientHeight,
|
|
443
446
|
x: window.scrollX,
|
|
444
447
|
y: window.scrollY,
|
|
445
|
-
ignoreElements: (
|
|
446
|
-
}),
|
|
447
|
-
if (
|
|
448
|
-
const
|
|
449
|
-
h.width =
|
|
448
|
+
ignoreElements: (r) => r instanceof HTMLElement ? r.classList.contains("qaid-buttons") || r.classList.contains("qaid-targeting-overlay") || r.classList.contains("qaid-modal-container") || r.classList.contains("qaid-bottom-sheet") || r.classList.contains("qaid-backdrop") || r.classList.contains("qaid-selected-marker") || r.classList.contains("qaid-tooltip-text") || r.classList.contains("qaid-recording-indicator") || r.classList.contains("qaid-video-preview") || r.className?.toString().startsWith?.("qaid-") : !1
|
|
449
|
+
}), a = s.width, c = s.height, l = Math.min(i / a, o / c, 1);
|
|
450
|
+
if (l < 1) {
|
|
451
|
+
const r = Math.round(a * l), d = Math.round(c * l), h = document.createElement("canvas");
|
|
452
|
+
h.width = r, h.height = d;
|
|
450
453
|
const u = h.getContext("2d");
|
|
451
|
-
return u ? (u.drawImage(s, 0, 0,
|
|
454
|
+
return u ? (u.drawImage(s, 0, 0, r, d), h.toDataURL("image/webp", t)) : null;
|
|
452
455
|
}
|
|
453
456
|
return s.toDataURL("image/webp", t);
|
|
454
457
|
} catch (n) {
|
|
455
458
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
456
459
|
}
|
|
457
460
|
}
|
|
458
|
-
const
|
|
459
|
-
function
|
|
460
|
-
return e ? `${
|
|
461
|
+
const V = "qaid_visitor_id", _ = "qaid_hide_feedback";
|
|
462
|
+
function I(e) {
|
|
463
|
+
return e ? `${_}_${e}` : _;
|
|
461
464
|
}
|
|
462
|
-
function
|
|
465
|
+
function Ft(e) {
|
|
463
466
|
try {
|
|
464
|
-
return localStorage.getItem(
|
|
467
|
+
return localStorage.getItem(I(e)) === "1";
|
|
465
468
|
} catch {
|
|
466
469
|
return !1;
|
|
467
470
|
}
|
|
468
471
|
}
|
|
469
|
-
function
|
|
472
|
+
function F(e, t = !0) {
|
|
470
473
|
try {
|
|
471
|
-
t ? localStorage.setItem(
|
|
474
|
+
t ? localStorage.setItem(I(e), "1") : localStorage.removeItem(I(e));
|
|
472
475
|
} catch {
|
|
473
476
|
}
|
|
474
477
|
}
|
|
475
|
-
function
|
|
478
|
+
function Ut() {
|
|
476
479
|
try {
|
|
477
|
-
let e = localStorage.getItem(
|
|
478
|
-
return e || (e = crypto.randomUUID(), localStorage.setItem(
|
|
480
|
+
let e = localStorage.getItem(V);
|
|
481
|
+
return e || (e = crypto.randomUUID(), localStorage.setItem(V, e)), e;
|
|
479
482
|
} catch {
|
|
480
483
|
return crypto.randomUUID();
|
|
481
484
|
}
|
|
482
485
|
}
|
|
483
|
-
class
|
|
486
|
+
class Xt {
|
|
484
487
|
config;
|
|
485
488
|
state = "IDLE";
|
|
486
489
|
feedbackData = {
|
|
@@ -594,7 +597,7 @@ class Ut {
|
|
|
594
597
|
maxDuration: t.videoOptions?.maxDuration ?? 15
|
|
595
598
|
},
|
|
596
599
|
recordIcon: t.recordIcon ?? ""
|
|
597
|
-
}, 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 =
|
|
600
|
+
}, 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 = Ut(), this.init();
|
|
598
601
|
}
|
|
599
602
|
applyVars(t) {
|
|
600
603
|
ut(t, this.cssVars);
|
|
@@ -609,7 +612,7 @@ class Ut {
|
|
|
609
612
|
backdropOpacity: this.config.backdropOpacity,
|
|
610
613
|
fontFamily: this.config.fontFamily,
|
|
611
614
|
fontSize: this.config.fontSize
|
|
612
|
-
}), !this.config.hideDismiss &&
|
|
615
|
+
}), !this.config.hideDismiss && Ft(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = Lt((t) => {
|
|
613
616
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
614
617
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom();
|
|
615
618
|
}
|
|
@@ -632,7 +635,7 @@ class Ut {
|
|
|
632
635
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
633
636
|
}
|
|
634
637
|
checkMobile() {
|
|
635
|
-
this.isMobile =
|
|
638
|
+
this.isMobile = Pt();
|
|
636
639
|
}
|
|
637
640
|
handleResize() {
|
|
638
641
|
this.checkMobile();
|
|
@@ -642,41 +645,39 @@ class Ut {
|
|
|
642
645
|
let t = null;
|
|
643
646
|
this.config.container && (t = document.querySelector(this.config.container)), t ? (t.appendChild(this.shadowHost), this.isUserProvidedContainer = !0, this.config.hideDismiss = !0) : (this.shadowHost.style.position = "fixed", this.shadowHost.style.display = "block", this.shadowHost.style.inset = "0", this.shadowHost.style.pointerEvents = "none", this.shadowHost.style.zIndex = String(this.config.zIndex), document.body.appendChild(this.shadowHost)), this.shadowRoot = this.shadowHost.attachShadow({ mode: "open" });
|
|
644
647
|
const i = document.createElement("style");
|
|
645
|
-
if (i.textContent =
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
+
if (i.textContent = z(), this.shadowRoot.appendChild(i), this.config.css) {
|
|
649
|
+
const r = document.createElement("style");
|
|
650
|
+
r.textContent = this.config.css, this.shadowRoot.appendChild(r);
|
|
648
651
|
}
|
|
649
652
|
const o = this.config.direction === "vertical" ? "qaid-vertical" : "";
|
|
650
653
|
if (this.isUserProvidedContainer)
|
|
651
654
|
this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-${this.config.position} ${o}`.trim(), this.config.incognito && this.buttonsContainer.classList.add("qaid-incognito");
|
|
652
655
|
else {
|
|
653
656
|
this.buttonsContainer = document.createElement("div"), this.buttonsContainer.className = `qaid-buttons qaid-auto-container qaid-${this.config.position} ${o}${this.config.incognito ? " qaid-incognito" : ""}`.trim(), this.buttonsContainer.style.pointerEvents = "auto";
|
|
654
|
-
const { x:
|
|
655
|
-
this.config.position.includes("right") ? this.buttonsContainer.style.right = `${
|
|
657
|
+
const { x: r, y: d } = this.config.offset;
|
|
658
|
+
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 = `${d}px` : this.buttonsContainer.style.top = `${d}px`;
|
|
656
659
|
}
|
|
657
660
|
this.applyVars(this.buttonsContainer), this.shadowRoot.appendChild(this.buttonsContainer);
|
|
658
|
-
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn",
|
|
659
|
-
if (
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
const
|
|
663
|
-
|
|
661
|
+
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", c = this.config.text.tooltip || "Feedback for us?", l = document.createElement("div");
|
|
662
|
+
if (l.className = "qaid-tooltip-text", l.textContent = c, this.applyVars(l), this.shadowRoot.appendChild(l), this.tooltipElement = l, !this.config.hideThumbs) {
|
|
663
|
+
const r = document.createElement("div");
|
|
664
|
+
r.className = "qaid-tooltip-wrapper";
|
|
665
|
+
const d = document.createElement("button");
|
|
666
|
+
d.type = "button", d.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", d.innerHTML = this.config.positiveIcon || E, d.addEventListener("click", (p) => this.handleThumbClick("up", p.currentTarget, p)), d.addEventListener("mouseenter", () => this.showTooltip(d)), d.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(d);
|
|
664
667
|
const h = document.createElement("div");
|
|
665
668
|
h.className = "qaid-tooltip-wrapper";
|
|
666
669
|
const u = document.createElement("button");
|
|
667
|
-
u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.innerHTML = this.config.negativeIcon || T, u.addEventListener("click", (p) => this.handleThumbClick("down", p.currentTarget, p)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(u), this.buttonsContainer.appendChild(
|
|
670
|
+
u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.innerHTML = this.config.negativeIcon || T, u.addEventListener("click", (p) => this.handleThumbClick("down", p.currentTarget, p)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(u), this.buttonsContainer.appendChild(r), this.buttonsContainer.appendChild(h);
|
|
668
671
|
}
|
|
669
|
-
if (this.config.captureVideo &&
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
const
|
|
673
|
-
|
|
672
|
+
if (this.config.captureVideo && Bt()) {
|
|
673
|
+
const r = document.createElement("div");
|
|
674
|
+
r.className = "qaid-tooltip-wrapper";
|
|
675
|
+
const d = document.createElement("button");
|
|
676
|
+
d.type = "button", d.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", d.innerHTML = this.config.recordIcon || it, d.addEventListener("click", () => this.startRecording()), d.addEventListener("mouseenter", () => this.showTooltip(d)), d.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(d), this.buttonsContainer.appendChild(r);
|
|
674
677
|
}
|
|
675
|
-
this.config.hideDismiss || (this.dismissBtn = document.createElement("button"), this.dismissBtn.type = "button", this.dismissBtn.className = "qaid-dismiss-btn", this.dismissBtn.setAttribute("aria-label", "Hide Feedback"), this.dismissBtn.title = "Hide Feedback", this.dismissBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', this.dismissBtn.addEventListener("click", (
|
|
676
|
-
|
|
677
|
-
}), this.buttonsContainer.insertBefore(this.dismissBtn, this.buttonsContainer.firstChild), this._startDismissed &&
|
|
678
|
-
this.buttonsContainer && (this.buttonsContainer.style.transition = "");
|
|
679
|
-
})));
|
|
678
|
+
this.config.hideDismiss || (this.dismissBtn = document.createElement("button"), this.dismissBtn.type = "button", this.dismissBtn.className = "qaid-dismiss-btn", this.dismissBtn.setAttribute("aria-label", "Hide Feedback"), this.dismissBtn.title = "Hide Feedback", this.dismissBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', this.dismissBtn.addEventListener("click", (r) => {
|
|
679
|
+
r.stopPropagation(), this.handleDismiss();
|
|
680
|
+
}), this.buttonsContainer.insertBefore(this.dismissBtn, this.buttonsContainer.firstChild), this._startDismissed && this.buttonsContainer.classList.add("qaid-incognito"));
|
|
680
681
|
}
|
|
681
682
|
/**
|
|
682
683
|
* Lazily create a separate overlay shadow host on document.body.
|
|
@@ -688,7 +689,7 @@ class Ut {
|
|
|
688
689
|
if (this.overlayShadowRoot) return this.overlayShadowRoot;
|
|
689
690
|
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" });
|
|
690
691
|
const t = document.createElement("style");
|
|
691
|
-
if (t.textContent =
|
|
692
|
+
if (t.textContent = z(), this.overlayShadowRoot.appendChild(t), this.config.css) {
|
|
692
693
|
const i = document.createElement("style");
|
|
693
694
|
i.textContent = this.config.css, this.overlayShadowRoot.appendChild(i);
|
|
694
695
|
}
|
|
@@ -696,21 +697,26 @@ class Ut {
|
|
|
696
697
|
}
|
|
697
698
|
tooltipElement = null;
|
|
698
699
|
showTooltip(t) {
|
|
699
|
-
|
|
700
|
-
const i = this.tooltipElement, o = 8;
|
|
700
|
+
const i = this.tooltipElement;
|
|
701
701
|
i.style.visibility = "hidden", i.classList.add("qaid-tooltip-visible");
|
|
702
|
-
const
|
|
703
|
-
|
|
704
|
-
|
|
702
|
+
const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } = Et(
|
|
703
|
+
o,
|
|
704
|
+
n,
|
|
705
|
+
{ width: window.innerWidth, height: window.innerHeight }
|
|
706
|
+
);
|
|
707
|
+
i.style.top = `${s}px`, i.style.left = `${a}px`, i.style.visibility = "visible";
|
|
705
708
|
}
|
|
706
709
|
hideTooltip() {
|
|
707
|
-
this.tooltipElement
|
|
710
|
+
this.tooltipElement.classList.remove("qaid-tooltip-visible");
|
|
708
711
|
}
|
|
709
712
|
handleDismiss() {
|
|
710
|
-
|
|
713
|
+
const t = this.buttonsContainer;
|
|
714
|
+
t.classList.add("qaid-incognito"), t.classList.add("qaid-force-hidden"), t.addEventListener("mouseleave", () => {
|
|
715
|
+
t.classList.remove("qaid-force-hidden");
|
|
716
|
+
}, { once: !0 }), F(this.config.apiKey, !0);
|
|
711
717
|
}
|
|
712
718
|
handleThumbClick(t, i, o) {
|
|
713
|
-
this.buttonsContainer?.classList.contains("qaid-
|
|
719
|
+
this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), this.buttonsContainer.classList.remove("qaid-force-hidden"), F(this.config.apiKey, !1)), this.config.skipTargeting ? this.submitDirectFeedback(t, i) : this.startTargeting(t, o);
|
|
714
720
|
}
|
|
715
721
|
submitDirectFeedback(t, i) {
|
|
716
722
|
this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null;
|
|
@@ -743,12 +749,12 @@ class Ut {
|
|
|
743
749
|
}
|
|
744
750
|
handleMouseMove(t) {
|
|
745
751
|
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) {
|
|
746
|
-
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o =
|
|
752
|
+
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o = A(
|
|
747
753
|
t.clientX,
|
|
748
754
|
t.clientY,
|
|
749
755
|
i
|
|
750
756
|
);
|
|
751
|
-
if (o &&
|
|
757
|
+
if (o && !$(o)) {
|
|
752
758
|
if (this.highlightBox) {
|
|
753
759
|
const n = o.getBoundingClientRect();
|
|
754
760
|
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";
|
|
@@ -758,24 +764,23 @@ class Ut {
|
|
|
758
764
|
}
|
|
759
765
|
}
|
|
760
766
|
handleClick(t) {
|
|
761
|
-
if (this.state !== "TARGETING" || !this.shadowHost) return;
|
|
762
767
|
t.preventDefault(), t.stopPropagation();
|
|
763
|
-
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o =
|
|
768
|
+
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o = A(
|
|
764
769
|
t.clientX,
|
|
765
770
|
t.clientY,
|
|
766
771
|
i
|
|
767
772
|
);
|
|
768
|
-
if (!o ||
|
|
773
|
+
if (!o || $(o))
|
|
769
774
|
return;
|
|
770
|
-
const n =
|
|
775
|
+
const n = Ot(o, 8);
|
|
771
776
|
this.selectedBounds = {
|
|
772
777
|
...n,
|
|
773
778
|
clickX: t.clientX,
|
|
774
779
|
clickY: t.clientY,
|
|
775
780
|
visible: !0
|
|
776
781
|
};
|
|
777
|
-
const { selector: s, text:
|
|
778
|
-
this.feedbackData.elementSelector = s, this.feedbackData.elementText =
|
|
782
|
+
const { selector: s, text: a } = xt(o);
|
|
783
|
+
this.feedbackData.elementSelector = s, this.feedbackData.elementText = a, 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();
|
|
779
784
|
}
|
|
780
785
|
cancelTargeting() {
|
|
781
786
|
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;
|
|
@@ -784,7 +789,6 @@ class Ut {
|
|
|
784
789
|
this.overlayContainer && (this.overlayContainer.remove(), this.overlayContainer = null), this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null;
|
|
785
790
|
}
|
|
786
791
|
showSelectedMarker() {
|
|
787
|
-
if (!this.selectedBounds.visible) return;
|
|
788
792
|
const t = this.ensureOverlayHost();
|
|
789
793
|
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);
|
|
790
794
|
}
|
|
@@ -792,9 +796,8 @@ class Ut {
|
|
|
792
796
|
this.marker && (this.marker.remove(), this.marker = null);
|
|
793
797
|
}
|
|
794
798
|
async submitFeedback() {
|
|
795
|
-
if (!this.feedbackData.feedbackType) return;
|
|
796
799
|
let t = null;
|
|
797
|
-
this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await
|
|
800
|
+
this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await _t(this.config.screenshotOptions) : t = await At(this.config.screenshotOptions));
|
|
798
801
|
const i = this.feedbackData.elementSelector ? {
|
|
799
802
|
x: this.selectedBounds.x,
|
|
800
803
|
y: this.selectedBounds.y,
|
|
@@ -848,7 +851,7 @@ class Ut {
|
|
|
848
851
|
`, this.applyVars(i), t.appendChild(i), this.modalContainer = i, this.setupModalInteractions();
|
|
849
852
|
}
|
|
850
853
|
showPositionedModal() {
|
|
851
|
-
const t = this.ensureOverlayHost(), { modal: i, arrow: o } =
|
|
854
|
+
const t = this.ensureOverlayHost(), { modal: i, arrow: o } = Tt(
|
|
852
855
|
this.selectedBounds,
|
|
853
856
|
window.innerWidth,
|
|
854
857
|
window.innerHeight,
|
|
@@ -885,7 +888,6 @@ class Ut {
|
|
|
885
888
|
`;
|
|
886
889
|
}
|
|
887
890
|
setupModalInteractions() {
|
|
888
|
-
if (!this.modalContainer) return;
|
|
889
891
|
const t = this.modalContainer.querySelector(".qaid-textarea"), i = this.modalContainer.querySelector(".qaid-btn-submit");
|
|
890
892
|
t && (setTimeout(() => t.focus(), 100), t.addEventListener("input", () => {
|
|
891
893
|
i && (i.textContent = t.value.trim() ? this.config.text.submitButton : this.config.text.skipButton);
|
|
@@ -897,12 +899,12 @@ class Ut {
|
|
|
897
899
|
o && o.addEventListener("click", () => {
|
|
898
900
|
const n = this.feedbackData.feedbackType === "up" ? "down" : "up";
|
|
899
901
|
this.feedbackData.feedbackType = n, this.config.buttonClass ? (o.classList.toggle("qaid-btn-up", n === "up"), o.classList.toggle("qaid-btn-down", n === "down")) : (o.classList.toggle("qaid-type-up", n === "up"), o.classList.toggle("qaid-type-down", n === "down"));
|
|
900
|
-
const s = this.config.positiveIcon || E,
|
|
901
|
-
o.innerHTML = n === "up" ? s :
|
|
902
|
+
const s = this.config.positiveIcon || E, a = this.config.negativeIcon || T;
|
|
903
|
+
o.innerHTML = n === "up" ? s : a, this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
|
|
902
904
|
method: "PATCH",
|
|
903
905
|
headers: { "Content-Type": "application/json" },
|
|
904
906
|
body: JSON.stringify({ feedbackType: n })
|
|
905
|
-
}).catch((
|
|
907
|
+
}).catch((c) => console.error("Failed to update feedback type:", c));
|
|
906
908
|
});
|
|
907
909
|
}
|
|
908
910
|
async submitMessage(t) {
|
|
@@ -931,7 +933,7 @@ class Ut {
|
|
|
931
933
|
async startRecording() {
|
|
932
934
|
if (!(this.isRecording || this.state !== "IDLE"))
|
|
933
935
|
try {
|
|
934
|
-
this.networkCapture =
|
|
936
|
+
this.networkCapture = Mt(), this.videoRecorder = zt({
|
|
935
937
|
maxDuration: this.config.videoOptions.maxDuration
|
|
936
938
|
}), this.videoRecorder.onTick((t) => {
|
|
937
939
|
this.updateRecordingTimer(t);
|
|
@@ -943,14 +945,12 @@ class Ut {
|
|
|
943
945
|
}
|
|
944
946
|
}
|
|
945
947
|
async stopRecording() {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
this.recordedBlob = null;
|
|
951
|
-
}
|
|
952
|
-
this.isRecording = !1, this.removeRecordingIndicator(), document.removeEventListener("keydown", this.boundKeyDown), this.recordedBlob && this.recordedBlob.size > 0 ? this.showRecordingPreview() : this.cleanupRecording();
|
|
948
|
+
try {
|
|
949
|
+
this.recordedBlob = await this.videoRecorder.stop();
|
|
950
|
+
} catch {
|
|
951
|
+
this.recordedBlob = null;
|
|
953
952
|
}
|
|
953
|
+
this.isRecording = !1, this.removeRecordingIndicator(), document.removeEventListener("keydown", this.boundKeyDown), this.recordedBlob && this.recordedBlob.size > 0 ? this.showRecordingPreview() : this.cleanupRecording();
|
|
954
954
|
}
|
|
955
955
|
showRecordingIndicator() {
|
|
956
956
|
const t = this.ensureOverlayHost();
|
|
@@ -978,7 +978,6 @@ class Ut {
|
|
|
978
978
|
this.recordingIndicator && (this.recordingIndicator.remove(), this.recordingIndicator = null);
|
|
979
979
|
}
|
|
980
980
|
showRecordingPreview() {
|
|
981
|
-
if (!this.recordedBlob) return;
|
|
982
981
|
const t = this.ensureOverlayHost(), i = URL.createObjectURL(this.recordedBlob);
|
|
983
982
|
this.videoPreview = document.createElement("div"), this.videoPreview.className = "qaid-video-preview", this.videoPreview.style.zIndex = String(this.config.zIndex + 100);
|
|
984
983
|
const o = document.createElement("div");
|
|
@@ -987,21 +986,21 @@ class Ut {
|
|
|
987
986
|
n.textContent = "Review your recording";
|
|
988
987
|
const s = document.createElement("video");
|
|
989
988
|
s.src = i, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
const
|
|
993
|
-
|
|
994
|
-
const
|
|
995
|
-
|
|
996
|
-
const
|
|
997
|
-
|
|
989
|
+
const a = document.createElement("textarea");
|
|
990
|
+
a.placeholder = "Optional: Describe the issue you recorded...";
|
|
991
|
+
const c = document.createElement("div");
|
|
992
|
+
c.className = "qaid-video-preview-actions";
|
|
993
|
+
const l = document.createElement("button");
|
|
994
|
+
l.type = "button", l.className = "qaid-video-btn qaid-video-btn-cancel", l.textContent = "Cancel", l.addEventListener("click", () => this.cancelRecordingPreview());
|
|
995
|
+
const r = document.createElement("button");
|
|
996
|
+
r.type = "button", r.className = "qaid-video-btn qaid-video-btn-rerecord", r.textContent = "Re-record", r.addEventListener("click", () => {
|
|
998
997
|
this.cancelRecordingPreview(), this.startRecording();
|
|
999
998
|
});
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1002
|
-
const h =
|
|
1003
|
-
this.submitVideoFeedback(h,
|
|
1004
|
-
}),
|
|
999
|
+
const d = document.createElement("button");
|
|
1000
|
+
d.type = "button", d.className = "qaid-video-btn qaid-video-btn-send", d.textContent = "Send", d.addEventListener("click", () => {
|
|
1001
|
+
const h = a.value.trim() || null;
|
|
1002
|
+
this.submitVideoFeedback(h, d);
|
|
1003
|
+
}), c.appendChild(l), c.appendChild(r), c.appendChild(d), o.appendChild(n), o.appendChild(s), o.appendChild(a), o.appendChild(c), this.videoPreview.appendChild(o), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), document.addEventListener("keydown", this.boundKeyDown);
|
|
1005
1004
|
}
|
|
1006
1005
|
cancelRecordingPreview() {
|
|
1007
1006
|
this.removeVideoPreview(), this.cleanupRecording();
|
|
@@ -1045,7 +1044,7 @@ class Ut {
|
|
|
1045
1044
|
this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.cleanupRecording(), this.removeVideoPreview(), this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null, mt();
|
|
1046
1045
|
}
|
|
1047
1046
|
}
|
|
1048
|
-
function
|
|
1047
|
+
function W(e) {
|
|
1049
1048
|
return document.querySelector(e)?.textContent?.trim() ?? "";
|
|
1050
1049
|
}
|
|
1051
1050
|
function Wt() {
|
|
@@ -1057,18 +1056,18 @@ function Wt() {
|
|
|
1057
1056
|
if (!t) return null;
|
|
1058
1057
|
try {
|
|
1059
1058
|
const i = JSON.parse(t);
|
|
1060
|
-
return i.cssSelector && !i.css && (i.css =
|
|
1059
|
+
return i.cssSelector && !i.css && (i.css = W(i.cssSelector), delete i.cssSelector), i;
|
|
1061
1060
|
} catch {
|
|
1062
1061
|
return null;
|
|
1063
1062
|
}
|
|
1064
1063
|
}
|
|
1065
|
-
function
|
|
1064
|
+
function jt(e) {
|
|
1066
1065
|
const t = e.getAttribute("data-endpoint");
|
|
1067
1066
|
if (!t) return null;
|
|
1068
|
-
const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"),
|
|
1067
|
+
const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), a = e.getAttribute("data-marker-color"), c = e.getAttribute("data-container"), l = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), d = e.getAttribute("data-incognito"), h = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), p = e.getAttribute("data-offset-y"), b = e.getAttribute("data-modal-width"), f = e.getAttribute("data-backdrop-opacity"), m = e.getAttribute("data-font-family"), v = e.getAttribute("data-font-size"), g = e.getAttribute("data-tooltip"), x = e.getAttribute("data-modal-title"), L = e.getAttribute("data-modal-subtitle"), D = e.getAttribute("data-placeholder"), H = e.getAttribute("data-submit-button"), M = e.getAttribute("data-skip-button"), j = e.getAttribute("data-positive-icon"), K = e.getAttribute("data-negative-icon"), Y = e.getAttribute("data-api-key"), J = e.getAttribute("data-capture-screenshot"), k = e.getAttribute("data-screenshot-quality"), C = e.getAttribute("data-screenshot-max-width"), S = e.getAttribute("data-screenshot-max-height"), G = e.getAttribute("data-capture-video"), Z = e.getAttribute("data-hide-thumbs"), Q = e.getAttribute("data-hide-dismiss"), B = e.getAttribute("data-video-max-duration"), tt = e.getAttribute("data-screenshot-method"), et = e.getAttribute("data-direction"), R = e.getAttribute("data-css-selector");
|
|
1069
1068
|
return {
|
|
1070
1069
|
endpoint: t,
|
|
1071
|
-
css:
|
|
1070
|
+
css: R ? W(R) : void 0,
|
|
1072
1071
|
apiKey: Y ?? void 0,
|
|
1073
1072
|
captureScreenshot: J === "true" ? !0 : void 0,
|
|
1074
1073
|
screenshotOptions: k || C || S ? {
|
|
@@ -1076,60 +1075,60 @@ function Xt(e) {
|
|
|
1076
1075
|
maxWidth: C ? parseInt(C, 10) : void 0,
|
|
1077
1076
|
maxHeight: S ? parseInt(S, 10) : void 0
|
|
1078
1077
|
} : void 0,
|
|
1079
|
-
container:
|
|
1080
|
-
buttonClass:
|
|
1078
|
+
container: c ?? void 0,
|
|
1079
|
+
buttonClass: l ?? void 0,
|
|
1081
1080
|
direction: et ?? void 0,
|
|
1082
1081
|
position: i ?? void 0,
|
|
1083
1082
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1084
|
-
skipTargeting:
|
|
1085
|
-
incognito:
|
|
1083
|
+
skipTargeting: r === "true" ? !0 : void 0,
|
|
1084
|
+
incognito: d === "true" ? !0 : void 0,
|
|
1086
1085
|
buttonSize: h ?? void 0,
|
|
1087
1086
|
offset: u || p ? {
|
|
1088
1087
|
x: u ? parseInt(u, 10) : void 0,
|
|
1089
1088
|
y: p ? parseInt(p, 10) : void 0
|
|
1090
1089
|
} : void 0,
|
|
1091
|
-
modalWidth:
|
|
1090
|
+
modalWidth: b ? parseInt(b, 10) : void 0,
|
|
1092
1091
|
backdropOpacity: f ? parseFloat(f) : void 0,
|
|
1093
1092
|
fontFamily: m ?? void 0,
|
|
1094
1093
|
fontSize: v ? parseInt(v, 10) : void 0,
|
|
1095
1094
|
colors: {
|
|
1096
1095
|
positive: n ?? void 0,
|
|
1097
1096
|
negative: s ?? void 0,
|
|
1098
|
-
marker:
|
|
1097
|
+
marker: a ?? void 0
|
|
1099
1098
|
},
|
|
1100
|
-
text:
|
|
1101
|
-
tooltip:
|
|
1102
|
-
modalTitle:
|
|
1103
|
-
modalSubtitle:
|
|
1104
|
-
placeholder:
|
|
1105
|
-
submitButton:
|
|
1106
|
-
skipButton:
|
|
1099
|
+
text: g || x || L || D || H || M ? {
|
|
1100
|
+
tooltip: g ?? void 0,
|
|
1101
|
+
modalTitle: x ?? void 0,
|
|
1102
|
+
modalSubtitle: L ?? void 0,
|
|
1103
|
+
placeholder: D ?? void 0,
|
|
1104
|
+
submitButton: H ?? void 0,
|
|
1105
|
+
skipButton: M ?? void 0
|
|
1107
1106
|
} : void 0,
|
|
1108
|
-
positiveIcon:
|
|
1109
|
-
negativeIcon:
|
|
1107
|
+
positiveIcon: j ?? void 0,
|
|
1108
|
+
negativeIcon: K ?? void 0,
|
|
1110
1109
|
screenshotMethod: tt ?? void 0,
|
|
1111
1110
|
captureVideo: G === "true" ? !0 : void 0,
|
|
1112
1111
|
hideThumbs: Z === "true" ? !0 : void 0,
|
|
1113
1112
|
hideDismiss: Q === "true" ? !0 : void 0,
|
|
1114
|
-
videoOptions:
|
|
1115
|
-
maxDuration: parseInt(
|
|
1113
|
+
videoOptions: B ? {
|
|
1114
|
+
maxDuration: parseInt(B, 10)
|
|
1116
1115
|
} : void 0
|
|
1117
1116
|
};
|
|
1118
1117
|
}
|
|
1119
1118
|
if (typeof document < "u") {
|
|
1120
1119
|
const e = () => {
|
|
1121
|
-
const t = document.currentScript, i = Wt(), o = t ?
|
|
1122
|
-
n?.endpoint && new
|
|
1120
|
+
const t = document.currentScript, i = Wt(), o = t ? jt(t) : null, n = i ?? o;
|
|
1121
|
+
n?.endpoint && new Xt(n);
|
|
1123
1122
|
};
|
|
1124
1123
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e();
|
|
1125
1124
|
}
|
|
1126
1125
|
export {
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1126
|
+
Xt as QaidFeedback,
|
|
1127
|
+
_t as captureDomScreenshot,
|
|
1128
|
+
Mt as captureNetworkErrors,
|
|
1129
|
+
zt as createVideoRecorder,
|
|
1130
|
+
Rt as getSupportedMimeType,
|
|
1132
1131
|
Kt as isDomScreenshotSupported,
|
|
1133
|
-
|
|
1132
|
+
Bt as isVideoRecordingSupported
|
|
1134
1133
|
};
|
|
1135
1134
|
//# sourceMappingURL=qaid.js.map
|