@qaiddev/thumbs-embed 1.2.0 → 1.2.2
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/embed.d.ts +18 -0
- package/dist/qaid.js +355 -251
- package/dist/qaid.js.map +1 -1
- package/dist/qaid.umd.cjs +6 -6
- package/dist/qaid.umd.cjs.map +1 -1
- package/dist/video-orientation.d.ts +48 -0
- package/package.json +1 -1
package/dist/qaid.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const
|
|
1
|
+
const I = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
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>`, A = `<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
5
|
</svg>`, bt = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
6
6
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z"/>
|
|
7
|
-
</svg>`, gt = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0;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)}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}", vt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
8
|
-
let
|
|
7
|
+
</svg>`, gt = "button{cursor:pointer}.qaid-buttons{display:flex;gap:.5rem}.qaid-buttons.qaid-vertical{flex-direction:column}.qaid-buttons.qaid-auto-container{position:fixed;z-index:50}.qaid-buttons.qaid-auto-container.qaid-bottom-right{bottom:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-bottom-left{bottom:1rem;left:1rem}.qaid-buttons.qaid-auto-container.qaid-top-right{top:1rem;right:1rem}.qaid-buttons.qaid-auto-container.qaid-top-left{top:1rem;left:1rem}.qaid-buttons.qaid-incognito{opacity:0;transition:opacity .2s ease-in-out}.qaid-buttons.qaid-incognito:hover{opacity:1}.qaid-buttons.qaid-dismissed{display:none!important}.qaid-dismiss-btn{width:20px;height:20px;padding:0;border:none;border-radius:50%;background:#0006;color:#fff;display:flex;align-items:center;justify-content:center;align-self:center;opacity:0;transition:opacity .15s,background .15s;cursor:pointer;pointer-events:auto;-webkit-appearance:none;appearance:none}.qaid-dismiss-btn:hover{background:#0009}.qaid-buttons:hover .qaid-dismiss-btn{opacity:1}button.qaid-btn-structural{display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-appearance:none;appearance:none}.qaid-icon{width:24px;height:24px}.qaid-btn-structural:not(:has(svg)),.qaid-btn:not(:has(svg)){font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-emoji-icon{font-size:var(--qaid-icon-size, 24px);line-height:1}.qaid-buttons,.qaid-buttons *,.qaid-modal-container,.qaid-modal-container *{cursor:pointer!important}.qaid-tooltip-wrapper{position:relative}.qaid-tooltip-text{position:fixed;padding:.5rem .75rem;background:#1f2937;color:#fff;font-size:1rem;font-weight:600;border-radius:.5rem;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .15s;z-index:99999}.qaid-tooltip-text.qaid-tooltip-visible{opacity:1}.qaid-targeting-overlay{position:fixed;inset:0;z-index:40;pointer-events:none}.qaid-capture-layer{position:fixed;inset:0;pointer-events:none;z-index:9999}@keyframes qaid-slideDown{0%{transform:translateY(-100%)}to{transform:translateY(0)}}.qaid-vignette{position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.3) 70%,rgba(0,0,0,.6) 100%);z-index:41}.qaid-crosshair-h,.qaid-crosshair-v{position:fixed;pointer-events:none;z-index:42}.qaid-crosshair-h{left:0;right:0;height:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-crosshair-v{top:0;bottom:0;width:1px;background:color-mix(in srgb,var(--qaid-negative) 60%,transparent)}.qaid-type-up .qaid-crosshair-h,.qaid-type-up .qaid-crosshair-v{background:color-mix(in srgb,var(--qaid-positive) 60%,transparent)}.qaid-highlight-box{position:fixed;top:0;left:0;pointer-events:none;z-index:41;display:none;border:3px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:2px;background:color-mix(in srgb,var(--qaid-negative) 8%,transparent);will-change:transform,width,height}.qaid-type-up .qaid-highlight-box{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent);background:color-mix(in srgb,var(--qaid-positive) 8%,transparent)}.qaid-scope{position:fixed;width:80px;height:80px;pointer-events:none;z-index:43;transform:translate(-50%,-50%)}.qaid-scope-ring{position:absolute;inset:10px;border:2px solid color-mix(in srgb,var(--qaid-negative) 80%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring{border-color:color-mix(in srgb,var(--qaid-positive) 80%,transparent)}.qaid-scope-ring-inner{position:absolute;inset:20px;border:1px solid color-mix(in srgb,var(--qaid-negative) 50%,transparent);border-radius:50%}.qaid-type-up .qaid-scope-ring-inner{border-color:color-mix(in srgb,var(--qaid-positive) 50%,transparent)}.qaid-scope-dot{position:absolute;top:50%;left:50%;width:4px;height:4px;background:var(--qaid-negative);border-radius:50%;transform:translate(-50%,-50%)}.qaid-type-up .qaid-scope-dot{background:var(--qaid-positive)}.qaid-selected-marker{position:fixed;border:3px solid var(--qaid-marker, #6366f1);border-radius:50%;pointer-events:none;z-index:44;animation:qaid-markerPulse 1.5s ease-in-out infinite}@keyframes qaid-markerPulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.05)}}.qaid-backdrop{position:fixed;inset:0;z-index:45;background:#0000004d}.qaid-modal-container{position:fixed;z-index:50;display:flex;flex-direction:column;align-items:flex-start;max-height:calc(100vh - 32px);font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-modal-container.qaid-above{flex-direction:column-reverse}.qaid-modal-arrow{width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;position:relative;align-self:flex-start}.qaid-modal-container.qaid-below .qaid-modal-arrow{border-bottom:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-container.qaid-above .qaid-modal-arrow{border-top:12px solid light-dark(#ffffff,#1f2937)}.qaid-modal-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5));width:var(--qaid-modal-width, 400px);max-width:calc(100vw - 32px);max-height:calc(100vh - 60px);overflow-y:auto}.qaid-modal-header{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}button.qaid-type-toggle{border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;flex-shrink:0;-webkit-appearance:none;appearance:none}button.qaid-type-toggle:hover{transform:scale(1.1)}button.qaid-type-toggle:not(.qaid-type-toggle-custom){width:2.5rem;height:2.5rem;border-radius:50%}button.qaid-type-toggle:not(.qaid-type-toggle-custom) svg{width:1.25rem;height:1.25rem}button.qaid-type-toggle.qaid-type-up{background:var(--qaid-positive);color:#fff}button.qaid-type-toggle.qaid-type-down{background:var(--qaid-negative);color:#fff}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-textarea:focus-visible,button.qaid-btn-submit:focus-visible,.qaid-video-preview-box textarea:focus-visible{outline:2px solid var(--qaid-marker, #6366f1);outline-offset:2px}.qaid-buttons.qaid-incognito:focus-within{opacity:1}.qaid-buttons:focus-within .qaid-dismiss-btn,.qaid-dismiss-btn:focus-visible{opacity:1}.qaid-dismiss-btn{min-width:24px;min-height:24px}button.qaid-recording-stop{min-height:24px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}@media(forced-colors:active){button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible,.qaid-textarea:focus,button.qaid-btn-submit:focus,.qaid-video-preview-box textarea:focus{outline:2px solid CanvasText;outline-offset:2px}.qaid-selected-marker,.qaid-highlight-box{border-color:Highlight}}", vt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
8
|
+
let k = 0;
|
|
9
9
|
const yt = "button.qaid-btn{width:var(--qaid-btn-size);height:var(--qaid-btn-size);border-radius:50%;border:none;background:#f3f4f6;color:#374151;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);transition:background-color .2s,color .2s,transform .2s;-webkit-appearance:none;appearance:none;--qaid-hover-up-bg:var(--qaid-positive);--qaid-hover-up-color:#fff;--qaid-hover-down-bg:var(--qaid-negative);--qaid-hover-down-color:#fff}button.qaid-btn:hover{transform:scale(1.05)}button.qaid-btn-up:hover{background:var(--qaid-hover-up-bg);color:var(--qaid-hover-up-color)}button.qaid-btn-down:hover{background:var(--qaid-hover-down-bg);color:var(--qaid-hover-down-color)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", wt = {
|
|
10
10
|
small: 36,
|
|
11
11
|
medium: 48,
|
|
@@ -39,7 +39,7 @@ function Ct(e) {
|
|
|
39
39
|
const t = kt(e);
|
|
40
40
|
return t && qt(t.r, t.g, t.b) > 0.4 ? "black" : "white";
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function St(e = {}) {
|
|
43
43
|
const {
|
|
44
44
|
positiveColor: t = "rgb(0, 200, 83)",
|
|
45
45
|
negativeColor: i = "rgb(255, 0, 0)",
|
|
@@ -47,23 +47,23 @@ function Et(e = {}) {
|
|
|
47
47
|
buttonSize: n = "medium",
|
|
48
48
|
modalWidth: s = 400,
|
|
49
49
|
backdropOpacity: a = 0.3,
|
|
50
|
-
fontFamily:
|
|
51
|
-
fontSize:
|
|
52
|
-
} = e, r = wt[n],
|
|
50
|
+
fontFamily: d = "system-ui, -apple-system, sans-serif",
|
|
51
|
+
fontSize: l = 16
|
|
52
|
+
} = e, r = wt[n], c = xt[n], p = Ct(o);
|
|
53
53
|
return {
|
|
54
54
|
"--qaid-positive": t,
|
|
55
55
|
"--qaid-negative": i,
|
|
56
56
|
"--qaid-marker": o,
|
|
57
57
|
"--qaid-marker-text": p,
|
|
58
58
|
"--qaid-btn-size": `${r}px`,
|
|
59
|
-
"--qaid-icon-size": `${
|
|
59
|
+
"--qaid-icon-size": `${c}px`,
|
|
60
60
|
"--qaid-modal-width": `${s}px`,
|
|
61
61
|
"--qaid-backdrop-opacity": String(a),
|
|
62
|
-
"--qaid-font-family":
|
|
63
|
-
"--qaid-font-size": `${
|
|
62
|
+
"--qaid-font-family": d,
|
|
63
|
+
"--qaid-font-size": `${l}px`
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function Et(e, t) {
|
|
67
67
|
for (const [i, o] of Object.entries(t))
|
|
68
68
|
e.style.setProperty(i, o);
|
|
69
69
|
}
|
|
@@ -71,12 +71,12 @@ function N() {
|
|
|
71
71
|
return gt + yt;
|
|
72
72
|
}
|
|
73
73
|
function Tt() {
|
|
74
|
-
if (
|
|
74
|
+
if (k++, k > 1) return;
|
|
75
75
|
const e = document.createElement("style");
|
|
76
76
|
e.id = "qaid-styles", e.textContent = vt, document.head.appendChild(e);
|
|
77
77
|
}
|
|
78
78
|
function Lt() {
|
|
79
|
-
|
|
79
|
+
k <= 0 || (k--, k === 0 && document.getElementById("qaid-styles").remove());
|
|
80
80
|
}
|
|
81
81
|
const G = ["data-comp", "data-qa", "data-testid", "data-id"];
|
|
82
82
|
function J(e, t = document.body) {
|
|
@@ -117,7 +117,7 @@ function Rt(e) {
|
|
|
117
117
|
const t = J(e);
|
|
118
118
|
return t ? `[${t}]` : e.id ? `#${Mt(e.id)}` : Dt(e);
|
|
119
119
|
}
|
|
120
|
-
function
|
|
120
|
+
function D(e) {
|
|
121
121
|
const t = It(e), i = J(e);
|
|
122
122
|
return { selector: Rt(e), text: t, dataAttr: i };
|
|
123
123
|
}
|
|
@@ -142,7 +142,7 @@ const Ht = [
|
|
|
142
142
|
"label",
|
|
143
143
|
...G.map((e) => `[${e}]`)
|
|
144
144
|
].join(","), Bt = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
|
|
145
|
-
function
|
|
145
|
+
function Pt(e) {
|
|
146
146
|
if (e.hasAttribute("hidden") || e.getAttribute("aria-hidden") === "true") return !1;
|
|
147
147
|
const t = e.ownerDocument?.defaultView;
|
|
148
148
|
if (t && typeof t.getComputedStyle == "function") {
|
|
@@ -151,67 +151,67 @@ function zt(e) {
|
|
|
151
151
|
}
|
|
152
152
|
return !0;
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
const t = e.root ?? document.body, i = e.selector ?? Ht, o = e.isExcluded ?? (() => !1), n = e.isVisible ??
|
|
154
|
+
function zt(e = {}) {
|
|
155
|
+
const t = e.root ?? document.body, i = e.selector ?? Ht, o = e.isExcluded ?? (() => !1), n = e.isVisible ?? Pt;
|
|
156
156
|
return Array.from(t.querySelectorAll(i)).filter(
|
|
157
157
|
(s) => !o(s) && n(s)
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
|
-
function
|
|
161
|
-
const t = e.candidates ??
|
|
160
|
+
function Ot(e) {
|
|
161
|
+
const t = e.candidates ?? zt({
|
|
162
162
|
root: e.root,
|
|
163
163
|
selector: e.selector,
|
|
164
164
|
isExcluded: e.isExcluded,
|
|
165
165
|
isVisible: e.isVisible
|
|
166
166
|
}), i = e.moveFocus ?? !0, o = e.eventTarget ?? document, n = /* @__PURE__ */ new Set();
|
|
167
167
|
let s = -1, a = !1;
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
const h = t.indexOf(
|
|
168
|
+
const d = e.initial !== void 0 ? e.initial : typeof document < "u" ? document.activeElement : null;
|
|
169
|
+
if (d) {
|
|
170
|
+
const h = t.indexOf(d);
|
|
171
171
|
h >= 0 && (s = h);
|
|
172
172
|
}
|
|
173
173
|
s < 0 && t.length > 0 && (s = 0);
|
|
174
|
-
function
|
|
174
|
+
function l(h) {
|
|
175
175
|
if (!i) return;
|
|
176
|
-
const
|
|
177
|
-
if (typeof
|
|
176
|
+
const w = h;
|
|
177
|
+
if (typeof w.focus == "function") {
|
|
178
178
|
h.getAttribute("tabindex") === null && !Bt.test(h.tagName) && (h.setAttribute("tabindex", "-1"), n.add(h));
|
|
179
179
|
try {
|
|
180
|
-
|
|
180
|
+
w.focus();
|
|
181
181
|
} catch {
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
function r() {
|
|
186
186
|
const h = t[s];
|
|
187
|
-
h && (
|
|
187
|
+
h && (l(h), e.onHighlight?.(h, s));
|
|
188
188
|
}
|
|
189
|
-
function
|
|
189
|
+
function c(h) {
|
|
190
190
|
if (a || t.length === 0) return;
|
|
191
|
-
const
|
|
192
|
-
s = (h %
|
|
191
|
+
const w = t.length;
|
|
192
|
+
s = (h % w + w) % w, r();
|
|
193
193
|
}
|
|
194
194
|
function p() {
|
|
195
|
-
|
|
195
|
+
c(s + 1);
|
|
196
196
|
}
|
|
197
197
|
function u() {
|
|
198
|
-
|
|
198
|
+
c(s - 1);
|
|
199
199
|
}
|
|
200
200
|
function m() {
|
|
201
201
|
return t[s] ?? null;
|
|
202
202
|
}
|
|
203
|
-
function g() {
|
|
204
|
-
a || (a = !0, o.removeEventListener("keydown", v, !0), n.forEach((h) => h.removeAttribute("tabindex")), n.clear());
|
|
205
|
-
}
|
|
206
203
|
function b() {
|
|
204
|
+
a || (a = !0, o.removeEventListener("keydown", f, !0), n.forEach((h) => h.removeAttribute("tabindex")), n.clear());
|
|
205
|
+
}
|
|
206
|
+
function v() {
|
|
207
207
|
if (a) return;
|
|
208
208
|
const h = m();
|
|
209
|
-
|
|
209
|
+
b(), h && e.onSelect(h);
|
|
210
210
|
}
|
|
211
|
-
function
|
|
212
|
-
a || (
|
|
211
|
+
function y() {
|
|
212
|
+
a || (b(), e.onCancel?.());
|
|
213
213
|
}
|
|
214
|
-
function
|
|
214
|
+
function f(h) {
|
|
215
215
|
if (!a)
|
|
216
216
|
switch (h.key) {
|
|
217
217
|
case "Tab":
|
|
@@ -228,28 +228,28 @@ function $t(e) {
|
|
|
228
228
|
case "Enter":
|
|
229
229
|
case " ":
|
|
230
230
|
case "Spacebar":
|
|
231
|
-
h.preventDefault(), h.stopPropagation(),
|
|
231
|
+
h.preventDefault(), h.stopPropagation(), v();
|
|
232
232
|
break;
|
|
233
233
|
case "Escape":
|
|
234
234
|
case "Esc":
|
|
235
|
-
h.preventDefault(), h.stopPropagation(),
|
|
235
|
+
h.preventDefault(), h.stopPropagation(), y();
|
|
236
236
|
break;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
-
return o.addEventListener("keydown",
|
|
239
|
+
return o.addEventListener("keydown", f, !0), s >= 0 && r(), {
|
|
240
240
|
candidates: t,
|
|
241
241
|
getIndex: () => s,
|
|
242
242
|
getCurrent: m,
|
|
243
243
|
next: p,
|
|
244
244
|
prev: u,
|
|
245
|
-
moveTo:
|
|
246
|
-
select:
|
|
247
|
-
cancel:
|
|
248
|
-
handleKey:
|
|
249
|
-
stop:
|
|
245
|
+
moveTo: c,
|
|
246
|
+
select: v,
|
|
247
|
+
cancel: y,
|
|
248
|
+
handleKey: f,
|
|
249
|
+
stop: b
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
-
const V = "data-qaid-a11y-live",
|
|
252
|
+
const V = "data-qaid-a11y-live", $t = "position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;", Nt = [
|
|
253
253
|
"a[href]",
|
|
254
254
|
"button",
|
|
255
255
|
"input",
|
|
@@ -266,7 +266,7 @@ function Ft(e, t) {
|
|
|
266
266
|
);
|
|
267
267
|
if (o) return o;
|
|
268
268
|
const s = Vt(e).createElement("div");
|
|
269
|
-
return s.setAttribute(V, i), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText =
|
|
269
|
+
return s.setAttribute(V, i), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = $t, e.appendChild(s), s;
|
|
270
270
|
}
|
|
271
271
|
function Ut(e, t, i = {}) {
|
|
272
272
|
const o = Ft(e, !!i.assertive);
|
|
@@ -297,7 +297,7 @@ function Z(e) {
|
|
|
297
297
|
t = t.shadowRoot.activeElement;
|
|
298
298
|
return t instanceof HTMLElement ? t : null;
|
|
299
299
|
}
|
|
300
|
-
function
|
|
300
|
+
function jt(e) {
|
|
301
301
|
const t = e.ownerDocument || document;
|
|
302
302
|
let i = !1;
|
|
303
303
|
const o = (s) => {
|
|
@@ -307,8 +307,8 @@ function Xt(e) {
|
|
|
307
307
|
s.preventDefault(), e.focus();
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
|
-
const
|
|
311
|
-
s.shiftKey ? (!
|
|
310
|
+
const d = a[0], l = a[a.length - 1], r = Z(t), c = r ? a.indexOf(r) !== -1 : !1;
|
|
311
|
+
s.shiftKey ? (!c || r === d) && (s.preventDefault(), l.focus()) : (!c || r === l) && (s.preventDefault(), d.focus());
|
|
312
312
|
};
|
|
313
313
|
e.addEventListener("keydown", o);
|
|
314
314
|
const n = F(e);
|
|
@@ -318,7 +318,7 @@ function Xt(e) {
|
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
|
-
function
|
|
321
|
+
function Xt() {
|
|
322
322
|
return Z(document);
|
|
323
323
|
}
|
|
324
324
|
function Wt(e) {
|
|
@@ -352,8 +352,8 @@ function Gt(e) {
|
|
|
352
352
|
const o = Qt(e, i), n = [];
|
|
353
353
|
return Array.from(i.children).forEach((s) => {
|
|
354
354
|
if (!(s instanceof HTMLElement) || o && s === o) return;
|
|
355
|
-
const a = s.inert === !0,
|
|
356
|
-
a &&
|
|
355
|
+
const a = s.inert === !0, d = s.getAttribute("aria-hidden");
|
|
356
|
+
a && d === "true" || (s.inert = !0, s.setAttribute("aria-hidden", "true"), n.push({ el: s, prevInert: a, prevAriaHidden: d }));
|
|
357
357
|
}), function() {
|
|
358
358
|
for (; n.length; ) {
|
|
359
359
|
const a = n.pop();
|
|
@@ -380,12 +380,12 @@ function Jt(e, t, i, o, n) {
|
|
|
380
380
|
top: e.y - i - o,
|
|
381
381
|
position: "above"
|
|
382
382
|
};
|
|
383
|
-
const
|
|
384
|
-
let
|
|
385
|
-
return
|
|
383
|
+
const d = a > s ? "below" : "above";
|
|
384
|
+
let l;
|
|
385
|
+
return d === "below" ? l = Math.min(
|
|
386
386
|
e.y + e.height + o,
|
|
387
387
|
t - i - n
|
|
388
|
-
) :
|
|
388
|
+
) : l = Math.max(n, e.y - i - o), { top: l, position: d };
|
|
389
389
|
}
|
|
390
390
|
function Zt(e, t, i, o) {
|
|
391
391
|
let s = e.x + e.width / 2 - i / 2;
|
|
@@ -434,13 +434,13 @@ function oe(e, t, i, o = tt) {
|
|
|
434
434
|
}
|
|
435
435
|
const ne = 20;
|
|
436
436
|
function se(e) {
|
|
437
|
-
const t = [], i = console.error, o = console.warn, n = console.log, s = (a,
|
|
438
|
-
const
|
|
439
|
-
message:
|
|
437
|
+
const t = [], i = console.error, o = console.warn, n = console.log, s = (a, d) => {
|
|
438
|
+
const l = {
|
|
439
|
+
message: d.map((r) => String(r)).join(" "),
|
|
440
440
|
timestamp: Date.now(),
|
|
441
441
|
level: a
|
|
442
442
|
};
|
|
443
|
-
t.length >= ne && t.shift(), t.push(
|
|
443
|
+
t.length >= ne && t.shift(), t.push(l), e && e(l);
|
|
444
444
|
};
|
|
445
445
|
return console.error = function(...a) {
|
|
446
446
|
s("error", a), i.apply(console, a);
|
|
@@ -456,7 +456,7 @@ function se(e) {
|
|
|
456
456
|
};
|
|
457
457
|
}
|
|
458
458
|
const ae = 20, U = 4096;
|
|
459
|
-
function
|
|
459
|
+
function S(e) {
|
|
460
460
|
const t = typeof e == "string" ? e : JSON.stringify(e);
|
|
461
461
|
return t.length > U ? t.slice(0, U) + "…[truncated]" : t;
|
|
462
462
|
}
|
|
@@ -466,7 +466,7 @@ function _(e, t) {
|
|
|
466
466
|
async function re(e) {
|
|
467
467
|
try {
|
|
468
468
|
const t = await e.clone().text();
|
|
469
|
-
return
|
|
469
|
+
return S(t);
|
|
470
470
|
} catch {
|
|
471
471
|
return;
|
|
472
472
|
}
|
|
@@ -474,19 +474,19 @@ async function re(e) {
|
|
|
474
474
|
function de() {
|
|
475
475
|
const e = [], t = window.fetch;
|
|
476
476
|
window.fetch = async function(n, s) {
|
|
477
|
-
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url,
|
|
478
|
-
let
|
|
479
|
-
s?.body && (
|
|
477
|
+
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, d = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
|
|
478
|
+
let l;
|
|
479
|
+
s?.body && (l = S(s.body));
|
|
480
480
|
const r = await t.apply(window, [n, s]);
|
|
481
481
|
if (r.status >= 400) {
|
|
482
|
-
const
|
|
482
|
+
const c = await re(r);
|
|
483
483
|
_(e, {
|
|
484
484
|
url: a,
|
|
485
|
-
method:
|
|
485
|
+
method: d.toUpperCase(),
|
|
486
486
|
status: r.status,
|
|
487
487
|
statusText: r.statusText,
|
|
488
|
-
requestBody:
|
|
489
|
-
responseBody:
|
|
488
|
+
requestBody: l,
|
|
489
|
+
responseBody: c,
|
|
490
490
|
timestamp: Date.now()
|
|
491
491
|
});
|
|
492
492
|
}
|
|
@@ -496,7 +496,7 @@ function de() {
|
|
|
496
496
|
return XMLHttpRequest.prototype.open = function(n, s, ...a) {
|
|
497
497
|
return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), i.apply(this, [n, s, ...a]);
|
|
498
498
|
}, XMLHttpRequest.prototype.send = function(n) {
|
|
499
|
-
const s = this, a = n ?
|
|
499
|
+
const s = this, a = n ? S(n) : void 0;
|
|
500
500
|
return s.addEventListener("load", function() {
|
|
501
501
|
s.status >= 400 && _(e, {
|
|
502
502
|
url: s._qaid_url,
|
|
@@ -504,7 +504,7 @@ function de() {
|
|
|
504
504
|
status: s.status,
|
|
505
505
|
statusText: s.statusText,
|
|
506
506
|
requestBody: a,
|
|
507
|
-
responseBody:
|
|
507
|
+
responseBody: S(s.responseText),
|
|
508
508
|
timestamp: Date.now()
|
|
509
509
|
});
|
|
510
510
|
}), o.apply(this, [n]);
|
|
@@ -515,10 +515,73 @@ function de() {
|
|
|
515
515
|
}
|
|
516
516
|
};
|
|
517
517
|
}
|
|
518
|
-
function
|
|
518
|
+
function ce() {
|
|
519
|
+
const e = navigator.userAgent || "";
|
|
520
|
+
return /iP(hone|ad|od)/.test(e) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
|
|
521
|
+
navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
|
|
522
|
+
}
|
|
523
|
+
function le(e, t, i, o, n) {
|
|
524
|
+
const s = e >= t, a = i >= o;
|
|
525
|
+
return s === a ? { width: e, height: t, rotate: 0 } : { width: t, height: e, rotate: n === 270 ? -90 : 90 };
|
|
526
|
+
}
|
|
527
|
+
function he(e, t, i) {
|
|
528
|
+
if (i.rotate === 0) {
|
|
529
|
+
e.drawImage(t, 0, 0, i.width, i.height);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
e.save(), i.rotate === 90 ? (e.translate(i.width, 0), e.rotate(Math.PI / 2)) : (e.translate(0, i.height), e.rotate(-Math.PI / 2)), e.drawImage(t, 0, 0, i.height, i.width), e.restore();
|
|
533
|
+
}
|
|
534
|
+
function ue() {
|
|
535
|
+
const e = typeof screen < "u" ? screen.orientation : void 0;
|
|
536
|
+
return e && typeof e.angle == "number" ? e.angle : 0;
|
|
537
|
+
}
|
|
538
|
+
function pe(e) {
|
|
539
|
+
return new Promise((t) => {
|
|
540
|
+
if (e.videoWidth > 0) {
|
|
541
|
+
t();
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
e.addEventListener("loadedmetadata", () => t(), { once: !0 });
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
async function me(e) {
|
|
548
|
+
try {
|
|
549
|
+
await e.play();
|
|
550
|
+
} catch {
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async function fe(e, t = 15) {
|
|
554
|
+
const i = document.createElement("canvas");
|
|
555
|
+
if (typeof i.captureStream != "function") return null;
|
|
556
|
+
const o = i.getContext("2d");
|
|
557
|
+
if (!o) return null;
|
|
558
|
+
const n = document.createElement("video");
|
|
559
|
+
n.muted = !0, n.playsInline = !0, n.srcObject = e, await pe(n);
|
|
560
|
+
const s = le(
|
|
561
|
+
n.videoWidth,
|
|
562
|
+
n.videoHeight,
|
|
563
|
+
window.innerWidth,
|
|
564
|
+
window.innerHeight,
|
|
565
|
+
ue()
|
|
566
|
+
);
|
|
567
|
+
i.width = s.width, i.height = s.height, await me(n);
|
|
568
|
+
let a = 0;
|
|
569
|
+
const d = () => {
|
|
570
|
+
he(o, n, s), a = requestAnimationFrame(d);
|
|
571
|
+
};
|
|
572
|
+
d();
|
|
573
|
+
const l = i.captureStream(t);
|
|
574
|
+
return {
|
|
575
|
+
stream: l,
|
|
576
|
+
stop: () => {
|
|
577
|
+
a && cancelAnimationFrame(a), a = 0, l.getTracks().forEach((r) => r.stop()), n.pause(), n.srcObject = null;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
function be() {
|
|
519
582
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
520
583
|
}
|
|
521
|
-
function
|
|
584
|
+
function ge() {
|
|
522
585
|
if (typeof MediaRecorder > "u") return "";
|
|
523
586
|
const e = [
|
|
524
587
|
"video/webm;codecs=vp9",
|
|
@@ -531,19 +594,19 @@ function ce() {
|
|
|
531
594
|
return t;
|
|
532
595
|
return "";
|
|
533
596
|
}
|
|
534
|
-
function
|
|
597
|
+
function ve(e = {}) {
|
|
535
598
|
const t = e.maxDuration ?? 15, i = e.videoBitsPerSecond ?? 8e5;
|
|
536
|
-
let o = null, n = null, s = [],
|
|
537
|
-
function
|
|
538
|
-
|
|
599
|
+
let o = null, n = null, s = null, a = [], d = null, l = null, r = null, c = 0, p = null, u = null, m = !1, b = null;
|
|
600
|
+
function v() {
|
|
601
|
+
r !== null && (clearInterval(r), r = null), b !== null && (clearTimeout(b), b = null), n && (n.stop(), n = null), o && (o.getTracks().forEach((f) => f.stop()), o = null), s = null, a = [], d = null, l = null, p = null, u = null;
|
|
539
602
|
}
|
|
540
|
-
function
|
|
541
|
-
|
|
603
|
+
function y() {
|
|
604
|
+
m || (m = !0, s && s.state !== "inactive" && s.stop());
|
|
542
605
|
}
|
|
543
606
|
return {
|
|
544
607
|
async start() {
|
|
545
|
-
|
|
546
|
-
const f =
|
|
608
|
+
m = !1, a = [];
|
|
609
|
+
const f = ge();
|
|
547
610
|
if (!f)
|
|
548
611
|
throw new Error("No supported video MIME type found");
|
|
549
612
|
o = await navigator.mediaDevices.getDisplayMedia({
|
|
@@ -554,43 +617,49 @@ function he(e = {}) {
|
|
|
554
617
|
// @ts-expect-error preferCurrentTab is not in the TS types yet
|
|
555
618
|
preferCurrentTab: !0
|
|
556
619
|
});
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
})
|
|
620
|
+
const h = o.getVideoTracks()[0];
|
|
621
|
+
h && h.addEventListener("ended", () => {
|
|
622
|
+
y();
|
|
623
|
+
});
|
|
624
|
+
let w = o;
|
|
625
|
+
if (ce()) {
|
|
626
|
+
const g = await fe(o);
|
|
627
|
+
g && (n = g, w = g.stream);
|
|
628
|
+
}
|
|
629
|
+
s = new MediaRecorder(w, {
|
|
561
630
|
mimeType: f,
|
|
562
631
|
videoBitsPerSecond: i
|
|
563
|
-
}),
|
|
564
|
-
|
|
565
|
-
},
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
},
|
|
569
|
-
|
|
570
|
-
},
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
}, 1e3),
|
|
574
|
-
|
|
632
|
+
}), s.ondataavailable = (g) => {
|
|
633
|
+
g.data.size > 0 && a.push(g.data);
|
|
634
|
+
}, s.onstop = () => {
|
|
635
|
+
const g = new Blob(a, { type: f });
|
|
636
|
+
p && p(g), l && l(g), n && (n.stop(), n = null), o && o.getTracks().forEach((C) => C.stop());
|
|
637
|
+
}, s.onerror = () => {
|
|
638
|
+
u && u(new Error("MediaRecorder error"));
|
|
639
|
+
}, s.start(1e3), c = Date.now(), r = setInterval(() => {
|
|
640
|
+
const g = Math.floor((Date.now() - c) / 1e3);
|
|
641
|
+
d && d(g);
|
|
642
|
+
}, 1e3), b = setTimeout(() => {
|
|
643
|
+
y();
|
|
575
644
|
}, t * 1e3);
|
|
576
645
|
},
|
|
577
646
|
stop() {
|
|
578
|
-
return new Promise((f,
|
|
579
|
-
|
|
647
|
+
return new Promise((f, h) => {
|
|
648
|
+
p = f, u = h, y();
|
|
580
649
|
});
|
|
581
650
|
},
|
|
582
651
|
onTick(f) {
|
|
583
|
-
|
|
652
|
+
d = f;
|
|
584
653
|
},
|
|
585
654
|
onStop(f) {
|
|
586
655
|
l = f;
|
|
587
656
|
},
|
|
588
657
|
destroy() {
|
|
589
|
-
|
|
658
|
+
y(), v();
|
|
590
659
|
}
|
|
591
660
|
};
|
|
592
661
|
}
|
|
593
|
-
function
|
|
662
|
+
function ye(e = 640) {
|
|
594
663
|
return typeof window < "u" && window.innerWidth < e;
|
|
595
664
|
}
|
|
596
665
|
function K(e, t, i) {
|
|
@@ -599,10 +668,10 @@ function K(e, t, i) {
|
|
|
599
668
|
const n = document.elementFromPoint(e, t);
|
|
600
669
|
return i.forEach((s, a) => s.style.visibility = o[a]), n;
|
|
601
670
|
}
|
|
602
|
-
function
|
|
671
|
+
function M(e) {
|
|
603
672
|
return e ? e.hasAttribute("data-qaid-embed") || e.hasAttribute("data-qaid-embed-overlay") ? !0 : !!e.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
|
|
604
673
|
}
|
|
605
|
-
function
|
|
674
|
+
function j(e, t = 0) {
|
|
606
675
|
const i = e.getBoundingClientRect();
|
|
607
676
|
return {
|
|
608
677
|
x: i.left - t,
|
|
@@ -611,7 +680,7 @@ function X(e, t = 0) {
|
|
|
611
680
|
height: i.height + t * 2
|
|
612
681
|
};
|
|
613
682
|
}
|
|
614
|
-
async function
|
|
683
|
+
async function we(e = {}) {
|
|
615
684
|
const { quality: t = 1, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
616
685
|
try {
|
|
617
686
|
if (!navigator.mediaDevices?.getDisplayMedia)
|
|
@@ -621,59 +690,59 @@ async function pe(e = {}) {
|
|
|
621
690
|
video: {
|
|
622
691
|
displaySurface: "browser"
|
|
623
692
|
}
|
|
624
|
-
}), s = n.getVideoTracks()[0], a = s.getSettings(),
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
693
|
+
}), s = n.getVideoTracks()[0], a = s.getSettings(), d = document.createElement("video");
|
|
694
|
+
d.srcObject = n, d.muted = !0, await new Promise((v) => {
|
|
695
|
+
d.onloadedmetadata = () => {
|
|
696
|
+
d.play(), v();
|
|
628
697
|
};
|
|
629
|
-
}), await new Promise((
|
|
630
|
-
const
|
|
631
|
-
|
|
698
|
+
}), await new Promise((v) => {
|
|
699
|
+
const y = () => {
|
|
700
|
+
d.readyState >= 2 ? v() : requestAnimationFrame(y);
|
|
632
701
|
};
|
|
633
|
-
|
|
634
|
-
}), await new Promise((
|
|
635
|
-
const
|
|
702
|
+
y();
|
|
703
|
+
}), await new Promise((v) => setTimeout(v, 100));
|
|
704
|
+
const l = a.width || d.videoWidth, r = a.height || d.videoHeight, c = Math.min(i / l, o / r, 1), p = Math.round(l * c), u = Math.round(r * c), m = document.createElement("canvas");
|
|
636
705
|
m.width = p, m.height = u;
|
|
637
|
-
const
|
|
638
|
-
return
|
|
706
|
+
const b = m.getContext("2d");
|
|
707
|
+
return b ? (b.drawImage(d, 0, 0, p, u), s.stop(), m.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
639
708
|
} catch (n) {
|
|
640
709
|
return console.warn("Screenshot capture failed:", n), null;
|
|
641
710
|
}
|
|
642
711
|
}
|
|
643
|
-
const
|
|
644
|
-
let
|
|
645
|
-
function
|
|
712
|
+
const X = "https://qaid.dev/lib/html2canvas.min.js", xe = 1e4, qe = 50;
|
|
713
|
+
let x = null;
|
|
714
|
+
function ze() {
|
|
646
715
|
if (typeof document > "u" || typeof window > "u")
|
|
647
716
|
return !1;
|
|
648
717
|
const e = document.createElement("canvas");
|
|
649
718
|
return typeof e.getContext == "function" && !!e.getContext("2d");
|
|
650
719
|
}
|
|
651
|
-
function
|
|
652
|
-
return window.html2canvas ? Promise.resolve(!0) :
|
|
720
|
+
function ke() {
|
|
721
|
+
return window.html2canvas ? Promise.resolve(!0) : x || (x = new Promise((e) => {
|
|
653
722
|
if (!document.querySelector(
|
|
654
|
-
`script[src="${
|
|
723
|
+
`script[src="${X}"]`
|
|
655
724
|
)) {
|
|
656
725
|
const n = document.createElement("script");
|
|
657
|
-
n.src =
|
|
726
|
+
n.src = X, n.async = !0, document.head.appendChild(n);
|
|
658
727
|
}
|
|
659
728
|
const i = Date.now(), o = () => {
|
|
660
729
|
if (window.html2canvas) {
|
|
661
730
|
e(!0);
|
|
662
731
|
return;
|
|
663
732
|
}
|
|
664
|
-
if (Date.now() - i >
|
|
665
|
-
|
|
733
|
+
if (Date.now() - i > xe) {
|
|
734
|
+
x = null, e(!1);
|
|
666
735
|
return;
|
|
667
736
|
}
|
|
668
|
-
setTimeout(o,
|
|
737
|
+
setTimeout(o, qe);
|
|
669
738
|
};
|
|
670
739
|
o();
|
|
671
|
-
}),
|
|
740
|
+
}), x);
|
|
672
741
|
}
|
|
673
|
-
async function
|
|
742
|
+
async function Ce(e = {}) {
|
|
674
743
|
const { quality: t = 0.8, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
675
744
|
try {
|
|
676
|
-
if (!await
|
|
745
|
+
if (!await ke() || !window.html2canvas)
|
|
677
746
|
return console.warn("html2canvas failed to load"), null;
|
|
678
747
|
const s = await window.html2canvas(document.body, {
|
|
679
748
|
useCORS: !0,
|
|
@@ -686,19 +755,19 @@ async function ge(e = {}) {
|
|
|
686
755
|
x: window.scrollX,
|
|
687
756
|
y: window.scrollY,
|
|
688
757
|
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
|
|
689
|
-
}), a = s.width,
|
|
690
|
-
if (
|
|
691
|
-
const r = Math.round(a *
|
|
692
|
-
p.width = r, p.height =
|
|
758
|
+
}), a = s.width, d = s.height, l = Math.min(i / a, o / d, 1);
|
|
759
|
+
if (l < 1) {
|
|
760
|
+
const r = Math.round(a * l), c = Math.round(d * l), p = document.createElement("canvas");
|
|
761
|
+
p.width = r, p.height = c;
|
|
693
762
|
const u = p.getContext("2d");
|
|
694
|
-
return u ? (u.drawImage(s, 0, 0, r,
|
|
763
|
+
return u ? (u.drawImage(s, 0, 0, r, c), p.toDataURL("image/webp", t)) : null;
|
|
695
764
|
}
|
|
696
765
|
return s.toDataURL("image/webp", t);
|
|
697
766
|
} catch (n) {
|
|
698
767
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
699
768
|
}
|
|
700
769
|
}
|
|
701
|
-
const
|
|
770
|
+
const Se = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Ee = (e) => (
|
|
702
771
|
// The URL is a runtime value, not a static specifier — keep Vite from
|
|
703
772
|
// trying to analyze/bundle it.
|
|
704
773
|
import(
|
|
@@ -706,19 +775,19 @@ const ve = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", ye =
|
|
|
706
775
|
e
|
|
707
776
|
)
|
|
708
777
|
);
|
|
709
|
-
let
|
|
710
|
-
function
|
|
711
|
-
return
|
|
778
|
+
let Te = Ee, q = null, R = null;
|
|
779
|
+
function Le(e) {
|
|
780
|
+
return q && R === e || (R = e, q = Promise.resolve(Te(e)).then((t) => {
|
|
712
781
|
const i = t;
|
|
713
782
|
if (!i || typeof i.QaidQuests != "function")
|
|
714
783
|
throw new Error("quests module has no QaidQuests export");
|
|
715
784
|
return i;
|
|
716
785
|
}).catch((t) => {
|
|
717
|
-
throw
|
|
718
|
-
})),
|
|
786
|
+
throw q = null, R = null, t;
|
|
787
|
+
})), q;
|
|
719
788
|
}
|
|
720
|
-
async function
|
|
721
|
-
const t = await
|
|
789
|
+
async function Ie(e) {
|
|
790
|
+
const t = await Le(e.moduleUrl), i = e.base.replace(/\/+$/, ""), o = e.feedbackId != null ? { feedbackId: e.feedbackId } : void 0;
|
|
722
791
|
return new t.QaidQuests({
|
|
723
792
|
endpoint: `${i}/responses`,
|
|
724
793
|
configUrl: `${i}/${encodeURIComponent(e.questId)}/definition`,
|
|
@@ -727,24 +796,27 @@ async function qe(e) {
|
|
|
727
796
|
onClose: e.onClose
|
|
728
797
|
});
|
|
729
798
|
}
|
|
730
|
-
const W = "qaid_visitor_id", Y = "qaid_hide_feedback";
|
|
731
|
-
function
|
|
799
|
+
const W = "qaid_visitor_id", Y = "qaid_hide_feedback", Ae = 12;
|
|
800
|
+
function De() {
|
|
801
|
+
return typeof window.matchMedia == "function" && window.matchMedia("(pointer: coarse)").matches;
|
|
802
|
+
}
|
|
803
|
+
function H(e) {
|
|
732
804
|
return e ? `${Y}_${e}` : Y;
|
|
733
805
|
}
|
|
734
|
-
function
|
|
806
|
+
function Me(e) {
|
|
735
807
|
try {
|
|
736
|
-
return localStorage.getItem(
|
|
808
|
+
return localStorage.getItem(H(e)) === "1";
|
|
737
809
|
} catch {
|
|
738
810
|
return !1;
|
|
739
811
|
}
|
|
740
812
|
}
|
|
741
813
|
function Q(e, t = !0) {
|
|
742
814
|
try {
|
|
743
|
-
t ? localStorage.setItem(
|
|
815
|
+
t ? localStorage.setItem(H(e), "1") : localStorage.removeItem(H(e));
|
|
744
816
|
} catch {
|
|
745
817
|
}
|
|
746
818
|
}
|
|
747
|
-
function
|
|
819
|
+
function Re() {
|
|
748
820
|
try {
|
|
749
821
|
let e = localStorage.getItem(W);
|
|
750
822
|
return e || (e = crypto.randomUUID(), localStorage.setItem(W, e)), e;
|
|
@@ -752,7 +824,7 @@ function Ce() {
|
|
|
752
824
|
return crypto.randomUUID();
|
|
753
825
|
}
|
|
754
826
|
}
|
|
755
|
-
class
|
|
827
|
+
class He {
|
|
756
828
|
config;
|
|
757
829
|
state = "IDLE";
|
|
758
830
|
feedbackData = {
|
|
@@ -823,6 +895,13 @@ class Ee {
|
|
|
823
895
|
boundKeyDown;
|
|
824
896
|
boundMouseMove;
|
|
825
897
|
boundClick;
|
|
898
|
+
// Touch equivalents for targeting. iOS/iPadOS does not synthesise `click`
|
|
899
|
+
// (or `mousemove`) for taps on non-interactive page elements, so targeting
|
|
900
|
+
// must be driven by touch events there.
|
|
901
|
+
boundTouchStart;
|
|
902
|
+
boundTouchEnd;
|
|
903
|
+
// Where the current targeting touch began, to tell a tap from a scroll.
|
|
904
|
+
touchStartPos = null;
|
|
826
905
|
boundResize;
|
|
827
906
|
// Start with buttons slid off-screen (localStorage dismiss, no animation)
|
|
828
907
|
_startDismissed = !1;
|
|
@@ -891,12 +970,12 @@ class Ee {
|
|
|
891
970
|
video: t.quests?.video ?? "",
|
|
892
971
|
// Quest service reuses the feedback API key unless overridden.
|
|
893
972
|
apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
|
|
894
|
-
moduleUrl: t.quests?.moduleUrl ??
|
|
973
|
+
moduleUrl: t.quests?.moduleUrl ?? Se
|
|
895
974
|
}
|
|
896
|
-
}, 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 =
|
|
975
|
+
}, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundMouseMove = this.handleMouseMove.bind(this), this.boundClick = this.handleClick.bind(this), this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = Re(), this.init();
|
|
897
976
|
}
|
|
898
977
|
applyVars(t) {
|
|
899
|
-
|
|
978
|
+
Et(t, this.cssVars);
|
|
900
979
|
}
|
|
901
980
|
/**
|
|
902
981
|
* Announce a message via the shared visually-hidden live regions.
|
|
@@ -914,7 +993,7 @@ class Ee {
|
|
|
914
993
|
* background. Paired with closeDialogA11y() on every close path.
|
|
915
994
|
*/
|
|
916
995
|
openDialogA11y(t, i) {
|
|
917
|
-
this.dialogTrigger =
|
|
996
|
+
this.dialogTrigger = Xt(), Yt(t, i), this.dialogTrap = jt(t), this.dialogRestoreInert = Gt(t);
|
|
918
997
|
}
|
|
919
998
|
closeDialogA11y() {
|
|
920
999
|
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), Wt(this.dialogTrigger), this.dialogTrigger = null;
|
|
@@ -923,7 +1002,7 @@ class Ee {
|
|
|
923
1002
|
this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
|
|
924
1003
|
}
|
|
925
1004
|
init() {
|
|
926
|
-
Tt(), this.cssVars =
|
|
1005
|
+
Tt(), this.cssVars = St({
|
|
927
1006
|
positiveColor: this.config.colors.positive,
|
|
928
1007
|
negativeColor: this.config.colors.negative,
|
|
929
1008
|
markerColor: this.config.colors.marker,
|
|
@@ -932,7 +1011,7 @@ class Ee {
|
|
|
932
1011
|
backdropOpacity: this.config.backdropOpacity,
|
|
933
1012
|
fontFamily: this.config.fontFamily,
|
|
934
1013
|
fontSize: this.config.fontSize
|
|
935
|
-
}), !this.config.hideDismiss &&
|
|
1014
|
+
}), !this.config.hideDismiss && Me(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = se((t) => {
|
|
936
1015
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
937
1016
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom();
|
|
938
1017
|
}
|
|
@@ -955,7 +1034,7 @@ class Ee {
|
|
|
955
1034
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
956
1035
|
}
|
|
957
1036
|
checkMobile() {
|
|
958
|
-
this.isMobile =
|
|
1037
|
+
this.isMobile = ye();
|
|
959
1038
|
}
|
|
960
1039
|
handleResize() {
|
|
961
1040
|
this.checkMobile();
|
|
@@ -974,8 +1053,8 @@ class Ee {
|
|
|
974
1053
|
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");
|
|
975
1054
|
else {
|
|
976
1055
|
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";
|
|
977
|
-
const { x: r, y:
|
|
978
|
-
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 = `${
|
|
1056
|
+
const { x: r, y: c } = this.config.offset;
|
|
1057
|
+
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`;
|
|
979
1058
|
}
|
|
980
1059
|
this.applyVars(this.buttonsContainer), this.shadowRoot.appendChild(this.buttonsContainer), this.buttonsContainer.addEventListener("keydown", (r) => {
|
|
981
1060
|
(r.key === "Enter" || r.key === " " || r.key === "Spacebar") && (this.keyboardActivation = !0);
|
|
@@ -984,22 +1063,22 @@ class Ee {
|
|
|
984
1063
|
}), this.buttonsContainer.addEventListener("pointerdown", () => {
|
|
985
1064
|
this.keyboardActivation = !1;
|
|
986
1065
|
});
|
|
987
|
-
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn",
|
|
988
|
-
if (
|
|
1066
|
+
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", d = this.config.text.tooltip || "Feedback for us?", l = document.createElement("div");
|
|
1067
|
+
if (l.className = "qaid-tooltip-text", l.textContent = d, this.applyVars(l), this.shadowRoot.appendChild(l), this.tooltipElement = l, !this.config.hideThumbs) {
|
|
989
1068
|
const r = document.createElement("div");
|
|
990
1069
|
r.className = "qaid-tooltip-wrapper";
|
|
991
|
-
const
|
|
992
|
-
|
|
1070
|
+
const c = document.createElement("button");
|
|
1071
|
+
c.type = "button", c.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", c.setAttribute("aria-label", this.config.text.positiveLabel), c.innerHTML = this.config.positiveIcon || I, c.addEventListener("click", (m) => this.handleThumbClick("up", m.currentTarget, m)), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c);
|
|
993
1072
|
const p = document.createElement("div");
|
|
994
1073
|
p.className = "qaid-tooltip-wrapper";
|
|
995
1074
|
const u = document.createElement("button");
|
|
996
|
-
u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.setAttribute("aria-label", this.config.text.negativeLabel), u.innerHTML = this.config.negativeIcon ||
|
|
1075
|
+
u.type = "button", u.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", u.setAttribute("aria-label", this.config.text.negativeLabel), u.innerHTML = this.config.negativeIcon || A, u.addEventListener("click", (m) => this.handleThumbClick("down", m.currentTarget, m)), u.addEventListener("mouseenter", () => this.showTooltip(u)), u.addEventListener("mouseleave", () => this.hideTooltip()), p.appendChild(u), this.buttonsContainer.appendChild(r), this.buttonsContainer.appendChild(p);
|
|
997
1076
|
}
|
|
998
|
-
if (this.config.captureVideo &&
|
|
1077
|
+
if (this.config.captureVideo && be()) {
|
|
999
1078
|
const r = document.createElement("div");
|
|
1000
1079
|
r.className = "qaid-tooltip-wrapper";
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1080
|
+
const c = document.createElement("button");
|
|
1081
|
+
c.type = "button", c.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", c.setAttribute("aria-label", this.config.text.recordLabel), c.innerHTML = this.config.recordIcon || bt, c.addEventListener("click", () => this.startRecording()), c.addEventListener("mouseenter", () => this.showTooltip(c)), c.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(c), this.buttonsContainer.appendChild(r);
|
|
1003
1082
|
}
|
|
1004
1083
|
this.config.hideDismiss || (this.dismissBtn = document.createElement("button"), this.dismissBtn.type = "button", this.dismissBtn.className = "qaid-dismiss-btn", this.dismissBtn.setAttribute("aria-label", this.config.text.dismissLabel), this.dismissBtn.title = this.config.text.dismissLabel, this.dismissBtn.innerHTML = '<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2l8 8M10 2l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', this.dismissBtn.addEventListener("click", (r) => {
|
|
1005
1084
|
r.stopPropagation(), this.handleDismiss();
|
|
@@ -1061,7 +1140,7 @@ class Ee {
|
|
|
1061
1140
|
}, this.submitFeedback();
|
|
1062
1141
|
}
|
|
1063
1142
|
startTargeting(t, i) {
|
|
1064
|
-
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, this.mousePos.x = i.clientX, this.mousePos.y = i.clientY, document.body.classList.add("qaid-targeting"), t === "up" ? document.body.classList.add("qaid-type-up") : document.body.classList.remove("qaid-type-up"), document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), document.addEventListener("keydown", this.boundKeyDown), document.addEventListener("mousemove", this.boundMouseMove), document.addEventListener("click", this.boundClick, !0);
|
|
1143
|
+
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, this.mousePos.x = i.clientX, this.mousePos.y = i.clientY, document.body.classList.add("qaid-targeting"), t === "up" ? document.body.classList.add("qaid-type-up") : document.body.classList.remove("qaid-type-up"), document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), document.addEventListener("keydown", this.boundKeyDown), document.addEventListener("mousemove", this.boundMouseMove), document.addEventListener("click", this.boundClick, !0), document.addEventListener("touchstart", this.boundTouchStart, { passive: !0 }), document.addEventListener("touchend", this.boundTouchEnd, { passive: !1 });
|
|
1065
1144
|
}
|
|
1066
1145
|
/**
|
|
1067
1146
|
* Keyboard-driven targeting. Mirrors startTargeting minus the mouse
|
|
@@ -1070,12 +1149,12 @@ class Ee {
|
|
|
1070
1149
|
* The KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
|
|
1071
1150
|
*/
|
|
1072
1151
|
startKeyboardTargetingFlow(t) {
|
|
1073
|
-
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController =
|
|
1074
|
-
isExcluded: (i) =>
|
|
1152
|
+
this.state = "TARGETING", this.feedbackData.feedbackType = t, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.cssVars["--qaid-negative"]), this.createTargetingOverlay(), this.crosshairH && (this.crosshairH.style.display = "none"), this.crosshairV && (this.crosshairV.style.display = "none"), this.scope && (this.scope.style.display = "none"), this.keyboardController = Ot({
|
|
1153
|
+
isExcluded: (i) => M(i),
|
|
1075
1154
|
onHighlight: (i) => {
|
|
1076
1155
|
const o = i.getBoundingClientRect(), n = this.highlightBox;
|
|
1077
1156
|
n && (n.style.transform = `translate(${o.left}px, ${o.top}px)`, n.style.width = `${o.width}px`, n.style.height = `${o.height}px`, n.style.display = "block");
|
|
1078
|
-
const { text: s } =
|
|
1157
|
+
const { text: s } = D(i);
|
|
1079
1158
|
this.announceMsg(`Targeting ${s || i.tagName.toLowerCase()}`);
|
|
1080
1159
|
},
|
|
1081
1160
|
onSelect: (i) => this.selectKeyboardTarget(i),
|
|
@@ -1083,14 +1162,14 @@ class Ee {
|
|
|
1083
1162
|
});
|
|
1084
1163
|
}
|
|
1085
1164
|
selectKeyboardTarget(t) {
|
|
1086
|
-
const i =
|
|
1165
|
+
const i = j(t, 8);
|
|
1087
1166
|
this.selectedBounds = {
|
|
1088
1167
|
...i,
|
|
1089
1168
|
clickX: i.x + i.width / 2,
|
|
1090
1169
|
clickY: i.y + i.height / 2,
|
|
1091
1170
|
visible: !0
|
|
1092
1171
|
};
|
|
1093
|
-
const { selector: o, text: n } =
|
|
1172
|
+
const { selector: o, text: n } = D(t);
|
|
1094
1173
|
this.feedbackData.elementSelector = o, this.feedbackData.elementText = n, this.removeTargetingOverlay(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.keyboardController = null, this.clearActiveThumb(), this.state = "SELECTED", this.showSelectedMarker(), this.submitFeedback();
|
|
1095
1174
|
}
|
|
1096
1175
|
createTargetingOverlay() {
|
|
@@ -1107,42 +1186,61 @@ class Ee {
|
|
|
1107
1186
|
t.key === "Escape" && (this.isRecording ? this.stopRecording() : this.videoPreview ? this.cancelRecordingPreview() : this.state === "TARGETING" ? this.cancelTargeting() : this.state === "MODAL_OPEN" && this.closeModal());
|
|
1108
1187
|
}
|
|
1109
1188
|
handleMouseMove(t) {
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1189
|
+
this.updateReticleAt(t.clientX, t.clientY);
|
|
1190
|
+
}
|
|
1191
|
+
/** Move the crosshair/scope reticle and highlight the element under (x, y).
|
|
1192
|
+
* Shared by the mouse (hover) and touch (drag) targeting paths. */
|
|
1193
|
+
updateReticleAt(t, i) {
|
|
1194
|
+
if (this.mousePos.x = t, this.mousePos.y = i, this.crosshairH && (this.crosshairH.style.top = `${i}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${i}px`), this.captureLayer && this.shadowHost) {
|
|
1195
|
+
const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = K(t, i, o);
|
|
1196
|
+
if (n && !M(n)) {
|
|
1117
1197
|
if (this.highlightBox) {
|
|
1118
|
-
const
|
|
1119
|
-
this.highlightBox.style.transform = `translate(${
|
|
1198
|
+
const s = n.getBoundingClientRect();
|
|
1199
|
+
this.highlightBox.style.transform = `translate(${s.left}px, ${s.top}px)`, this.highlightBox.style.width = `${s.width}px`, this.highlightBox.style.height = `${s.height}px`, this.highlightBox.style.display = "block";
|
|
1120
1200
|
}
|
|
1121
1201
|
} else
|
|
1122
1202
|
this.highlightBox && (this.highlightBox.style.display = "none");
|
|
1123
1203
|
}
|
|
1124
1204
|
}
|
|
1125
1205
|
handleClick(t) {
|
|
1126
|
-
t.preventDefault(), t.stopPropagation();
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1206
|
+
t.preventDefault(), t.stopPropagation(), this.selectAt(t.clientX, t.clientY);
|
|
1207
|
+
}
|
|
1208
|
+
// ---- Touch targeting (iOS/iPadOS) ----
|
|
1209
|
+
// iOS/iPadOS taps on non-interactive elements don't fire click, so touch
|
|
1210
|
+
// drives targeting here. Scrolling stays enabled (the page may need to scroll
|
|
1211
|
+
// to bring the target into view); a low-movement touch is treated as a tap
|
|
1212
|
+
// that selects, distinguishing it from a scroll/drag.
|
|
1213
|
+
handleTouchStart(t) {
|
|
1214
|
+
const i = t.touches[0];
|
|
1215
|
+
i && (this.touchStartPos = { x: i.clientX, y: i.clientY }, this.updateReticleAt(i.clientX, i.clientY));
|
|
1216
|
+
}
|
|
1217
|
+
handleTouchEnd(t) {
|
|
1218
|
+
const i = t.changedTouches[0], o = this.touchStartPos;
|
|
1219
|
+
this.touchStartPos = null, !(!i || !o || Math.hypot(i.clientX - o.x, i.clientY - o.y) > Ae) && (t.preventDefault(), this.selectAt(i.clientX, i.clientY));
|
|
1220
|
+
}
|
|
1221
|
+
/** Select the element under (x, y) and tear down targeting.
|
|
1222
|
+
* Shared by the mouse (click) and touch (touchend) targeting paths. */
|
|
1223
|
+
selectAt(t, i) {
|
|
1224
|
+
const o = [this.shadowHost, this.overlayShadowHost].filter(Boolean), n = K(t, i, o);
|
|
1225
|
+
if (!n || M(n))
|
|
1133
1226
|
return;
|
|
1134
|
-
const
|
|
1227
|
+
const s = j(n, 8);
|
|
1135
1228
|
this.selectedBounds = {
|
|
1136
|
-
...
|
|
1137
|
-
clickX: t
|
|
1138
|
-
clickY:
|
|
1229
|
+
...s,
|
|
1230
|
+
clickX: t,
|
|
1231
|
+
clickY: i,
|
|
1139
1232
|
visible: !0
|
|
1140
1233
|
};
|
|
1141
|
-
const { selector:
|
|
1142
|
-
this.feedbackData.elementSelector =
|
|
1234
|
+
const { selector: a, text: d } = D(n);
|
|
1235
|
+
this.feedbackData.elementSelector = a, this.feedbackData.elementText = d, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.state = "SELECTED", this.clearActiveThumb(), this.showSelectedMarker(), this.submitFeedback();
|
|
1236
|
+
}
|
|
1237
|
+
/** Remove the targeting overlay and every mouse/touch/keyboard listener the
|
|
1238
|
+
* pointer-targeting flow attaches to the document. */
|
|
1239
|
+
stopTargetingListeners() {
|
|
1240
|
+
this.removeTargetingOverlay(), this.touchStartPos = null, document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.removeEventListener("touchstart", this.boundTouchStart), document.removeEventListener("touchend", this.boundTouchEnd), document.removeEventListener("keydown", this.boundKeyDown);
|
|
1143
1241
|
}
|
|
1144
1242
|
cancelTargeting() {
|
|
1145
|
-
this.keyboardController?.stop(), this.keyboardController = null, this.
|
|
1243
|
+
this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.clearActiveThumb(), this.state = "IDLE", this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
|
|
1146
1244
|
}
|
|
1147
1245
|
removeTargetingOverlay() {
|
|
1148
1246
|
this.overlayContainer && (this.overlayContainer.remove(), this.overlayContainer = null), this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null;
|
|
@@ -1154,9 +1252,15 @@ class Ee {
|
|
|
1154
1252
|
hideSelectedMarker() {
|
|
1155
1253
|
this.marker && (this.marker.remove(), this.marker = null);
|
|
1156
1254
|
}
|
|
1255
|
+
/** Whether to capture the screenshot with the DOM/canvas method (html2canvas)
|
|
1256
|
+
* instead of the permission-based Screen Capture API. Explicit "dom" wins;
|
|
1257
|
+
* otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
|
|
1258
|
+
shouldCaptureViaDom() {
|
|
1259
|
+
return this.config.screenshotMethod === "dom" || De();
|
|
1260
|
+
}
|
|
1157
1261
|
async submitFeedback() {
|
|
1158
1262
|
let t = null;
|
|
1159
|
-
this.config.captureScreenshot && (this.
|
|
1263
|
+
this.config.captureScreenshot && (t = this.shouldCaptureViaDom() ? await Ce(this.config.screenshotOptions) : await we(this.config.screenshotOptions), t && this.announceMsg("Screenshot captured"));
|
|
1160
1264
|
const i = this.feedbackData.elementSelector ? {
|
|
1161
1265
|
x: this.selectedBounds.x,
|
|
1162
1266
|
y: this.selectedBounds.y,
|
|
@@ -1220,7 +1324,7 @@ class Ee {
|
|
|
1220
1324
|
const o = this.questIdFor(t);
|
|
1221
1325
|
if (!o) return !1;
|
|
1222
1326
|
try {
|
|
1223
|
-
return this.activeQuest?.destroy(), this.activeQuest = await
|
|
1327
|
+
return this.activeQuest?.destroy(), this.activeQuest = await Ie({
|
|
1224
1328
|
questId: o,
|
|
1225
1329
|
base: this.config.quests.base,
|
|
1226
1330
|
apiKey: this.config.quests.apiKey || void 0,
|
|
@@ -1275,7 +1379,7 @@ class Ee {
|
|
|
1275
1379
|
s.className = "qaid-modal-box", s.innerHTML = this.getModalContent(), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
|
|
1276
1380
|
}
|
|
1277
1381
|
getModalContent() {
|
|
1278
|
-
const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon ||
|
|
1382
|
+
const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon || I, o = this.config.negativeIcon || A;
|
|
1279
1383
|
return `
|
|
1280
1384
|
<div class="qaid-modal-header">
|
|
1281
1385
|
<button type="button" class="${this.config.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${this.config.buttonClass} ${t ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${t ? "qaid-type-up" : "qaid-type-down"}`}" title="Click to switch" aria-pressed="${t}" aria-label="${t ? "Feedback type: positive" : "Feedback type: negative"}">
|
|
@@ -1308,14 +1412,14 @@ class Ee {
|
|
|
1308
1412
|
o && o.addEventListener("click", () => {
|
|
1309
1413
|
const n = this.feedbackData.feedbackType === "up" ? "down" : "up";
|
|
1310
1414
|
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"));
|
|
1311
|
-
const s = this.config.positiveIcon ||
|
|
1415
|
+
const s = this.config.positiveIcon || I, a = this.config.negativeIcon || A;
|
|
1312
1416
|
o.innerHTML = n === "up" ? s : a;
|
|
1313
|
-
const
|
|
1314
|
-
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label",
|
|
1417
|
+
const d = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
|
|
1418
|
+
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", d), this.announceMsg(d), this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
|
|
1315
1419
|
method: "PATCH",
|
|
1316
1420
|
headers: { "Content-Type": "application/json" },
|
|
1317
1421
|
body: JSON.stringify({ feedbackType: n })
|
|
1318
|
-
}).catch((
|
|
1422
|
+
}).catch((l) => console.error("Failed to update feedback type:", l));
|
|
1319
1423
|
});
|
|
1320
1424
|
}
|
|
1321
1425
|
async submitMessage(t) {
|
|
@@ -1344,7 +1448,7 @@ class Ee {
|
|
|
1344
1448
|
async startRecording() {
|
|
1345
1449
|
if (!(this.isRecording || this.state !== "IDLE"))
|
|
1346
1450
|
try {
|
|
1347
|
-
this.networkCapture = de(), this.videoRecorder =
|
|
1451
|
+
this.networkCapture = de(), this.videoRecorder = ve({
|
|
1348
1452
|
maxDuration: this.config.videoOptions.maxDuration
|
|
1349
1453
|
}), this.videoRecorder.onTick((t) => {
|
|
1350
1454
|
this.updateRecordingTimer(t);
|
|
@@ -1399,19 +1503,19 @@ class Ee {
|
|
|
1399
1503
|
s.src = i, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
1400
1504
|
const a = document.createElement("textarea");
|
|
1401
1505
|
a.placeholder = "Optional: Describe the issue you recorded...", a.setAttribute("aria-label", "Describe the issue you recorded");
|
|
1402
|
-
const
|
|
1403
|
-
|
|
1404
|
-
const
|
|
1405
|
-
|
|
1506
|
+
const d = document.createElement("div");
|
|
1507
|
+
d.className = "qaid-video-preview-actions";
|
|
1508
|
+
const l = document.createElement("button");
|
|
1509
|
+
l.type = "button", l.className = "qaid-video-btn qaid-video-btn-cancel", l.textContent = "Cancel", l.addEventListener("click", () => this.cancelRecordingPreview());
|
|
1406
1510
|
const r = document.createElement("button");
|
|
1407
1511
|
r.type = "button", r.className = "qaid-video-btn qaid-video-btn-rerecord", r.textContent = "Re-record", r.addEventListener("click", () => {
|
|
1408
1512
|
this.cancelRecordingPreview(), this.startRecording();
|
|
1409
1513
|
});
|
|
1410
|
-
const
|
|
1411
|
-
|
|
1514
|
+
const c = document.createElement("button");
|
|
1515
|
+
c.type = "button", c.className = "qaid-video-btn qaid-video-btn-send", c.textContent = "Send", c.addEventListener("click", () => {
|
|
1412
1516
|
const p = a.value.trim() || null;
|
|
1413
|
-
this.submitVideoFeedback(p,
|
|
1414
|
-
}),
|
|
1517
|
+
this.submitVideoFeedback(p, c);
|
|
1518
|
+
}), d.appendChild(l), d.appendChild(r), d.appendChild(c), o.appendChild(n), o.appendChild(s), o.appendChild(a), o.appendChild(d), this.videoPreview.appendChild(o), this.applyVars(this.videoPreview), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto"), t.appendChild(this.videoPreview), this.openDialogA11y(o, { labelledbyId: n.id }), document.addEventListener("keydown", this.boundKeyDown);
|
|
1415
1519
|
}
|
|
1416
1520
|
cancelRecordingPreview() {
|
|
1417
1521
|
this.removeVideoPreview(), this.cleanupRecording();
|
|
@@ -1460,13 +1564,13 @@ class Ee {
|
|
|
1460
1564
|
* Destroy the embed and clean up all resources
|
|
1461
1565
|
*/
|
|
1462
1566
|
destroy() {
|
|
1463
|
-
this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.keyboardController?.stop(), this.keyboardController = null, this.clearActiveThumb(), this.closeDialogA11y(), this.cleanupRecording(), this.removeVideoPreview(), this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null, Lt();
|
|
1567
|
+
this.destroyed = !0, this.domObserver && (this.domObserver.disconnect(), this.domObserver = null), this.boundBeforeSwap && (document.removeEventListener("astro:before-swap", this.boundBeforeSwap), this.boundBeforeSwap = null), this.keyboardController?.stop(), this.keyboardController = null, this.clearActiveThumb(), this.closeDialogA11y(), this.cleanupRecording(), this.removeVideoPreview(), this.activeQuest?.destroy(), this.activeQuest = null, this.consoleCapture && (this.consoleCapture.restore(), this.consoleCapture = null), window.removeEventListener("resize", this.boundResize), document.removeEventListener("keydown", this.boundKeyDown), document.removeEventListener("mousemove", this.boundMouseMove), document.removeEventListener("click", this.boundClick, !0), document.removeEventListener("touchstart", this.boundTouchStart), document.removeEventListener("touchend", this.boundTouchEnd), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.shadowHost && (this.shadowHost.remove(), this.shadowHost = null, this.shadowRoot = null), this.overlayShadowHost && (this.overlayShadowHost.remove(), this.overlayShadowHost = null, this.overlayShadowRoot = null), this.buttonsContainer = null, this.overlayContainer = null, this.captureLayer = null, this.crosshairH = null, this.crosshairV = null, this.scope = null, this.marker = null, this.modalContainer = null, this.backdrop = null, this.dismissBtn = null, this.tooltipElement = null, Lt();
|
|
1464
1568
|
}
|
|
1465
1569
|
}
|
|
1466
1570
|
function et(e) {
|
|
1467
1571
|
return document.querySelector(e)?.textContent?.trim() ?? "";
|
|
1468
1572
|
}
|
|
1469
|
-
function
|
|
1573
|
+
function Be() {
|
|
1470
1574
|
const e = document.querySelector(
|
|
1471
1575
|
'script[type="application/json"][data-feedback-config]'
|
|
1472
1576
|
);
|
|
@@ -1480,60 +1584,60 @@ function Se() {
|
|
|
1480
1584
|
return null;
|
|
1481
1585
|
}
|
|
1482
1586
|
}
|
|
1483
|
-
function
|
|
1587
|
+
function Pe(e) {
|
|
1484
1588
|
const t = e.getAttribute("data-endpoint");
|
|
1485
1589
|
if (!t) return null;
|
|
1486
|
-
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"),
|
|
1590
|
+
const i = e.getAttribute("data-position"), o = e.getAttribute("data-zindex"), n = e.getAttribute("data-positive-color"), s = e.getAttribute("data-negative-color"), a = e.getAttribute("data-marker-color"), d = e.getAttribute("data-container"), l = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), c = e.getAttribute("data-incognito"), p = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), m = e.getAttribute("data-offset-y"), b = e.getAttribute("data-modal-width"), v = e.getAttribute("data-backdrop-opacity"), y = e.getAttribute("data-font-family"), f = e.getAttribute("data-font-size"), h = e.getAttribute("data-tooltip"), w = e.getAttribute("data-modal-title"), g = e.getAttribute("data-modal-subtitle"), C = e.getAttribute("data-placeholder"), B = e.getAttribute("data-submit-button"), P = e.getAttribute("data-skip-button"), it = e.getAttribute("data-positive-icon"), ot = e.getAttribute("data-negative-icon"), nt = e.getAttribute("data-api-key"), st = e.getAttribute("data-capture-screenshot"), E = e.getAttribute("data-screenshot-quality"), T = e.getAttribute("data-screenshot-max-width"), L = e.getAttribute("data-screenshot-max-height"), at = e.getAttribute("data-capture-video"), rt = e.getAttribute("data-hide-thumbs"), dt = e.getAttribute("data-hide-dismiss"), z = e.getAttribute("data-video-max-duration"), ct = e.getAttribute("data-screenshot-method"), lt = e.getAttribute("data-direction"), O = e.getAttribute("data-css-selector"), $ = e.getAttribute("data-quest-base"), ht = e.getAttribute("data-quest-up"), ut = e.getAttribute("data-quest-down"), pt = e.getAttribute("data-quest-video"), mt = e.getAttribute("data-quest-api-key"), ft = e.getAttribute("data-quest-module-url");
|
|
1487
1591
|
return {
|
|
1488
1592
|
endpoint: t,
|
|
1489
|
-
css:
|
|
1593
|
+
css: O ? et(O) : void 0,
|
|
1490
1594
|
apiKey: nt ?? void 0,
|
|
1491
1595
|
captureScreenshot: st === "true" ? !0 : void 0,
|
|
1492
|
-
screenshotOptions:
|
|
1493
|
-
quality:
|
|
1494
|
-
maxWidth:
|
|
1495
|
-
maxHeight:
|
|
1596
|
+
screenshotOptions: E || T || L ? {
|
|
1597
|
+
quality: E ? parseFloat(E) : void 0,
|
|
1598
|
+
maxWidth: T ? parseInt(T, 10) : void 0,
|
|
1599
|
+
maxHeight: L ? parseInt(L, 10) : void 0
|
|
1496
1600
|
} : void 0,
|
|
1497
|
-
container:
|
|
1498
|
-
buttonClass:
|
|
1499
|
-
direction:
|
|
1601
|
+
container: d ?? void 0,
|
|
1602
|
+
buttonClass: l ?? void 0,
|
|
1603
|
+
direction: lt ?? void 0,
|
|
1500
1604
|
position: i ?? void 0,
|
|
1501
1605
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1502
1606
|
skipTargeting: r === "true" ? !0 : void 0,
|
|
1503
|
-
incognito:
|
|
1607
|
+
incognito: c === "true" ? !0 : void 0,
|
|
1504
1608
|
buttonSize: p ?? void 0,
|
|
1505
1609
|
offset: u || m ? {
|
|
1506
1610
|
x: u ? parseInt(u, 10) : void 0,
|
|
1507
1611
|
y: m ? parseInt(m, 10) : void 0
|
|
1508
1612
|
} : void 0,
|
|
1509
|
-
modalWidth:
|
|
1510
|
-
backdropOpacity:
|
|
1511
|
-
fontFamily:
|
|
1512
|
-
fontSize:
|
|
1613
|
+
modalWidth: b ? parseInt(b, 10) : void 0,
|
|
1614
|
+
backdropOpacity: v ? parseFloat(v) : void 0,
|
|
1615
|
+
fontFamily: y ?? void 0,
|
|
1616
|
+
fontSize: f ? parseInt(f, 10) : void 0,
|
|
1513
1617
|
colors: {
|
|
1514
1618
|
positive: n ?? void 0,
|
|
1515
1619
|
negative: s ?? void 0,
|
|
1516
1620
|
marker: a ?? void 0
|
|
1517
1621
|
},
|
|
1518
|
-
text: h ||
|
|
1622
|
+
text: h || w || g || C || B || P ? {
|
|
1519
1623
|
tooltip: h ?? void 0,
|
|
1520
|
-
modalTitle:
|
|
1521
|
-
modalSubtitle:
|
|
1522
|
-
placeholder:
|
|
1624
|
+
modalTitle: w ?? void 0,
|
|
1625
|
+
modalSubtitle: g ?? void 0,
|
|
1626
|
+
placeholder: C ?? void 0,
|
|
1523
1627
|
submitButton: B ?? void 0,
|
|
1524
|
-
skipButton:
|
|
1628
|
+
skipButton: P ?? void 0
|
|
1525
1629
|
} : void 0,
|
|
1526
1630
|
positiveIcon: it ?? void 0,
|
|
1527
1631
|
negativeIcon: ot ?? void 0,
|
|
1528
|
-
screenshotMethod:
|
|
1632
|
+
screenshotMethod: ct ?? void 0,
|
|
1529
1633
|
captureVideo: at === "true" ? !0 : void 0,
|
|
1530
1634
|
hideThumbs: rt === "true" ? !0 : void 0,
|
|
1531
1635
|
hideDismiss: dt === "true" ? !0 : void 0,
|
|
1532
|
-
videoOptions:
|
|
1533
|
-
maxDuration: parseInt(
|
|
1636
|
+
videoOptions: z ? {
|
|
1637
|
+
maxDuration: parseInt(z, 10)
|
|
1534
1638
|
} : void 0,
|
|
1535
|
-
quests:
|
|
1536
|
-
base:
|
|
1639
|
+
quests: $ ? {
|
|
1640
|
+
base: $,
|
|
1537
1641
|
up: ht ?? void 0,
|
|
1538
1642
|
down: ut ?? void 0,
|
|
1539
1643
|
video: pt ?? void 0,
|
|
@@ -1544,18 +1648,18 @@ function Te(e) {
|
|
|
1544
1648
|
}
|
|
1545
1649
|
if (typeof document < "u") {
|
|
1546
1650
|
const e = () => {
|
|
1547
|
-
const t = document.currentScript, i =
|
|
1548
|
-
n?.endpoint && new
|
|
1651
|
+
const t = document.currentScript, i = Be(), o = t ? Pe(t) : null, n = i ?? o;
|
|
1652
|
+
n?.endpoint && new He(n);
|
|
1549
1653
|
};
|
|
1550
1654
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e();
|
|
1551
1655
|
}
|
|
1552
1656
|
export {
|
|
1553
|
-
|
|
1554
|
-
|
|
1657
|
+
He as QaidFeedback,
|
|
1658
|
+
Ce as captureDomScreenshot,
|
|
1555
1659
|
de as captureNetworkErrors,
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1660
|
+
ve as createVideoRecorder,
|
|
1661
|
+
ge as getSupportedMimeType,
|
|
1662
|
+
ze as isDomScreenshotSupported,
|
|
1663
|
+
be as isVideoRecordingSupported
|
|
1560
1664
|
};
|
|
1561
1665
|
//# sourceMappingURL=qaid.js.map
|