@qaiddev/thumbs-embed 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/embed.d.ts +20 -0
- package/dist/index.d.ts +1 -1
- package/dist/qaid.js +361 -259
- package/dist/qaid.js.map +1 -1
- package/dist/qaid.umd.cjs +6 -6
- package/dist/qaid.umd.cjs.map +1 -1
- package/dist/quest-launcher.d.ts +66 -0
- package/dist/types.d.ts +49 -0
- package/package.json +1 -1
package/dist/qaid.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
const
|
|
1
|
+
const T = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
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>`, L = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
4
4
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.737 3h4.018a2 2 0 01.485.06l3.76.94m-7 10v5a2 2 0 002 2h.095c.5 0 .905-.405.905-.905 0-.714.211-1.412.608-2.006L17 13V4m-7 10h2m5-10h2a2 2 0 012 2v6a2 2 0 01-2 2h-2.5"/>
|
|
5
|
-
</svg>`,
|
|
5
|
+
</svg>`, 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>`, ct = "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}}", lt = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
8
|
-
let
|
|
9
|
-
const
|
|
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 q = 0;
|
|
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,
|
|
12
12
|
large: 64
|
|
13
|
-
},
|
|
13
|
+
}, xt = {
|
|
14
14
|
small: 18,
|
|
15
15
|
medium: 24,
|
|
16
16
|
large: 32
|
|
17
17
|
};
|
|
18
|
-
function
|
|
18
|
+
function qt(e, t, i) {
|
|
19
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
|
-
function
|
|
22
|
+
function kt(e) {
|
|
23
23
|
if (e.startsWith("#")) {
|
|
24
24
|
const i = e.slice(1), o = i.length === 3 ? i.split("").map((s) => s + s).join("") : i, n = parseInt(o, 16);
|
|
25
25
|
return {
|
|
@@ -35,11 +35,11 @@ function ft(e) {
|
|
|
35
35
|
b: parseInt(t[3])
|
|
36
36
|
} : null;
|
|
37
37
|
}
|
|
38
|
-
function
|
|
39
|
-
const t =
|
|
40
|
-
return t &&
|
|
38
|
+
function Ct(e) {
|
|
39
|
+
const t = kt(e);
|
|
40
|
+
return t && qt(t.r, t.g, t.b) > 0.4 ? "black" : "white";
|
|
41
41
|
}
|
|
42
|
-
function
|
|
42
|
+
function Et(e = {}) {
|
|
43
43
|
const {
|
|
44
44
|
positiveColor: t = "rgb(0, 200, 83)",
|
|
45
45
|
negativeColor: i = "rgb(255, 0, 0)",
|
|
@@ -47,9 +47,9 @@ function gt(e = {}) {
|
|
|
47
47
|
buttonSize: n = "medium",
|
|
48
48
|
modalWidth: s = 400,
|
|
49
49
|
backdropOpacity: a = 0.3,
|
|
50
|
-
fontFamily:
|
|
51
|
-
fontSize:
|
|
52
|
-
} = e, r =
|
|
50
|
+
fontFamily: l = "system-ui, -apple-system, sans-serif",
|
|
51
|
+
fontSize: c = 16
|
|
52
|
+
} = e, r = wt[n], d = xt[n], p = Ct(o);
|
|
53
53
|
return {
|
|
54
54
|
"--qaid-positive": t,
|
|
55
55
|
"--qaid-negative": i,
|
|
@@ -59,30 +59,30 @@ function gt(e = {}) {
|
|
|
59
59
|
"--qaid-icon-size": `${d}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": l,
|
|
63
|
+
"--qaid-font-size": `${c}px`
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function St(e, t) {
|
|
67
67
|
for (const [i, o] of Object.entries(t))
|
|
68
68
|
e.style.setProperty(i, o);
|
|
69
69
|
}
|
|
70
|
-
function
|
|
71
|
-
return
|
|
70
|
+
function N() {
|
|
71
|
+
return gt + yt;
|
|
72
72
|
}
|
|
73
|
-
function
|
|
74
|
-
if (
|
|
73
|
+
function Tt() {
|
|
74
|
+
if (q++, q > 1) return;
|
|
75
75
|
const e = document.createElement("style");
|
|
76
|
-
e.id = "qaid-styles", e.textContent =
|
|
76
|
+
e.id = "qaid-styles", e.textContent = vt, document.head.appendChild(e);
|
|
77
77
|
}
|
|
78
|
-
function
|
|
79
|
-
|
|
78
|
+
function Lt() {
|
|
79
|
+
q <= 0 || (q--, q === 0 && document.getElementById("qaid-styles").remove());
|
|
80
80
|
}
|
|
81
|
-
const
|
|
82
|
-
function
|
|
81
|
+
const G = ["data-comp", "data-qa", "data-testid", "data-id"];
|
|
82
|
+
function J(e, t = document.body) {
|
|
83
83
|
let i = e;
|
|
84
84
|
for (; i && i !== t; ) {
|
|
85
|
-
for (const o of
|
|
85
|
+
for (const o of G) {
|
|
86
86
|
const n = i.getAttribute(o);
|
|
87
87
|
if (n)
|
|
88
88
|
return `${o}="${n}"`;
|
|
@@ -91,37 +91,37 @@ function Y(e, t = document.body) {
|
|
|
91
91
|
}
|
|
92
92
|
return null;
|
|
93
93
|
}
|
|
94
|
-
function
|
|
94
|
+
function It(e, t = 100) {
|
|
95
95
|
const i = e.textContent?.trim().slice(0, t) || "";
|
|
96
96
|
return i.length === t ? i + "..." : i;
|
|
97
97
|
}
|
|
98
|
-
function
|
|
98
|
+
function At(e) {
|
|
99
99
|
let t = 1, i = e.previousElementSibling;
|
|
100
100
|
for (; i; )
|
|
101
101
|
t++, i = i.previousElementSibling;
|
|
102
102
|
return t;
|
|
103
103
|
}
|
|
104
|
-
function
|
|
104
|
+
function Dt(e) {
|
|
105
105
|
const t = [];
|
|
106
106
|
let i = e;
|
|
107
107
|
for (; i && i !== document.body && i !== document.documentElement; ) {
|
|
108
|
-
const o = i.tagName.toLowerCase(), n =
|
|
108
|
+
const o = i.tagName.toLowerCase(), n = At(i);
|
|
109
109
|
t.unshift(`${o}:nth-child(${n})`), i = i.parentElement;
|
|
110
110
|
}
|
|
111
111
|
return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function Mt(e) {
|
|
114
114
|
return e.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
|
|
115
115
|
}
|
|
116
|
-
function
|
|
117
|
-
const t =
|
|
118
|
-
return t ? `[${t}]` : e.id ? `#${
|
|
116
|
+
function Rt(e) {
|
|
117
|
+
const t = J(e);
|
|
118
|
+
return t ? `[${t}]` : e.id ? `#${Mt(e.id)}` : Dt(e);
|
|
119
119
|
}
|
|
120
|
-
function
|
|
121
|
-
const t =
|
|
122
|
-
return { selector:
|
|
120
|
+
function I(e) {
|
|
121
|
+
const t = It(e), i = J(e);
|
|
122
|
+
return { selector: Rt(e), text: t, dataAttr: i };
|
|
123
123
|
}
|
|
124
|
-
const
|
|
124
|
+
const Ht = [
|
|
125
125
|
"a[href]",
|
|
126
126
|
"button",
|
|
127
127
|
"input:not([type=hidden])",
|
|
@@ -140,9 +140,9 @@ const Et = [
|
|
|
140
140
|
"p",
|
|
141
141
|
"li",
|
|
142
142
|
"label",
|
|
143
|
-
...
|
|
144
|
-
].join(","),
|
|
145
|
-
function
|
|
143
|
+
...G.map((e) => `[${e}]`)
|
|
144
|
+
].join(","), Bt = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
|
|
145
|
+
function zt(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,31 +151,31 @@ function Lt(e) {
|
|
|
151
151
|
}
|
|
152
152
|
return !0;
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
const t = e.root ?? document.body, i = e.selector ??
|
|
154
|
+
function Pt(e = {}) {
|
|
155
|
+
const t = e.root ?? document.body, i = e.selector ?? Ht, o = e.isExcluded ?? (() => !1), n = e.isVisible ?? zt;
|
|
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 $t(e) {
|
|
161
|
+
const t = e.candidates ?? Pt({
|
|
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 l = e.initial !== void 0 ? e.initial : typeof document < "u" ? document.activeElement : null;
|
|
169
|
+
if (l) {
|
|
170
|
+
const h = t.indexOf(l);
|
|
171
171
|
h >= 0 && (s = h);
|
|
172
172
|
}
|
|
173
173
|
s < 0 && t.length > 0 && (s = 0);
|
|
174
|
-
function
|
|
174
|
+
function c(h) {
|
|
175
175
|
if (!i) return;
|
|
176
176
|
const y = h;
|
|
177
177
|
if (typeof y.focus == "function") {
|
|
178
|
-
h.getAttribute("tabindex") === null && !
|
|
178
|
+
h.getAttribute("tabindex") === null && !Bt.test(h.tagName) && (h.setAttribute("tabindex", "-1"), n.add(h));
|
|
179
179
|
try {
|
|
180
180
|
y.focus();
|
|
181
181
|
} catch {
|
|
@@ -184,7 +184,7 @@ function Dt(e) {
|
|
|
184
184
|
}
|
|
185
185
|
function r() {
|
|
186
186
|
const h = t[s];
|
|
187
|
-
h && (
|
|
187
|
+
h && (c(h), e.onHighlight?.(h, s));
|
|
188
188
|
}
|
|
189
189
|
function d(h) {
|
|
190
190
|
if (a || t.length === 0) return;
|
|
@@ -249,7 +249,7 @@ function Dt(e) {
|
|
|
249
249
|
stop: g
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
|
-
const
|
|
252
|
+
const V = "data-qaid-a11y-live", Ot = "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",
|
|
@@ -257,25 +257,25 @@ const O = "data-qaid-a11y-live", At = "position:absolute;width:1px;height:1px;ma
|
|
|
257
257
|
"select",
|
|
258
258
|
"[tabindex]"
|
|
259
259
|
].join(",");
|
|
260
|
-
function
|
|
260
|
+
function Vt(e) {
|
|
261
261
|
return e.ownerDocument || document;
|
|
262
262
|
}
|
|
263
|
-
function
|
|
263
|
+
function Ft(e, t) {
|
|
264
264
|
const i = t ? "assertive" : "polite", o = e.querySelector(
|
|
265
|
-
`[${
|
|
265
|
+
`[${V}="${i}"]`
|
|
266
266
|
);
|
|
267
267
|
if (o) return o;
|
|
268
|
-
const s =
|
|
269
|
-
return s.setAttribute(
|
|
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 = Ot, e.appendChild(s), s;
|
|
270
270
|
}
|
|
271
|
-
function
|
|
272
|
-
const o =
|
|
271
|
+
function Ut(e, t, i = {}) {
|
|
272
|
+
const o = Ft(e, !!i.assertive);
|
|
273
273
|
o.textContent = "", o.textContent = t;
|
|
274
274
|
}
|
|
275
|
-
function
|
|
275
|
+
function _t(e) {
|
|
276
276
|
return e.hasAttribute("disabled") ? !0 : e.disabled === !0;
|
|
277
277
|
}
|
|
278
|
-
function
|
|
278
|
+
function Kt(e) {
|
|
279
279
|
let t = e;
|
|
280
280
|
for (; t; ) {
|
|
281
281
|
if (t.hasAttribute("hidden")) return !0;
|
|
@@ -286,52 +286,52 @@ function Pt(e) {
|
|
|
286
286
|
}
|
|
287
287
|
return !1;
|
|
288
288
|
}
|
|
289
|
-
function
|
|
289
|
+
function F(e) {
|
|
290
290
|
return Array.from(
|
|
291
|
-
e.querySelectorAll(
|
|
292
|
-
).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") ||
|
|
291
|
+
e.querySelectorAll(Nt)
|
|
292
|
+
).filter((i) => !(i.getAttribute("tabindex") === "-1" || i instanceof HTMLInputElement && i.type === "hidden" || i instanceof HTMLAnchorElement && !i.getAttribute("href") || _t(i) || Kt(i)));
|
|
293
293
|
}
|
|
294
|
-
function
|
|
294
|
+
function Z(e) {
|
|
295
295
|
let t = e.activeElement;
|
|
296
296
|
for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
|
|
297
297
|
t = t.shadowRoot.activeElement;
|
|
298
298
|
return t instanceof HTMLElement ? t : null;
|
|
299
299
|
}
|
|
300
|
-
function
|
|
300
|
+
function Xt(e) {
|
|
301
301
|
const t = e.ownerDocument || document;
|
|
302
302
|
let i = !1;
|
|
303
303
|
const o = (s) => {
|
|
304
304
|
if (s.key !== "Tab") return;
|
|
305
|
-
const a =
|
|
305
|
+
const a = F(e);
|
|
306
306
|
if (a.length === 0) {
|
|
307
307
|
s.preventDefault(), e.focus();
|
|
308
308
|
return;
|
|
309
309
|
}
|
|
310
|
-
const
|
|
311
|
-
s.shiftKey ? (!d || r ===
|
|
310
|
+
const l = a[0], c = a[a.length - 1], r = Z(t), d = r ? a.indexOf(r) !== -1 : !1;
|
|
311
|
+
s.shiftKey ? (!d || r === l) && (s.preventDefault(), c.focus()) : (!d || r === c) && (s.preventDefault(), l.focus());
|
|
312
312
|
};
|
|
313
313
|
e.addEventListener("keydown", o);
|
|
314
|
-
const n =
|
|
314
|
+
const n = F(e);
|
|
315
315
|
return n.length > 0 ? n[0].focus() : (e.hasAttribute("tabindex") || (e.setAttribute("tabindex", "-1"), i = !0), e.focus()), {
|
|
316
316
|
release() {
|
|
317
317
|
e.removeEventListener("keydown", o), i && (e.removeAttribute("tabindex"), i = !1);
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
}
|
|
321
|
-
function
|
|
322
|
-
return
|
|
321
|
+
function jt() {
|
|
322
|
+
return Z(document);
|
|
323
323
|
}
|
|
324
|
-
function
|
|
324
|
+
function Wt(e) {
|
|
325
325
|
if (!(!e || typeof e.focus != "function"))
|
|
326
326
|
try {
|
|
327
327
|
e.focus();
|
|
328
328
|
} catch {
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
-
function
|
|
331
|
+
function Yt(e, t = {}) {
|
|
332
332
|
e.setAttribute("role", "dialog"), e.setAttribute("aria-modal", "true"), t.labelledbyId && e.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && e.setAttribute("aria-describedby", t.describedbyId), t.label && e.setAttribute("aria-label", t.label);
|
|
333
333
|
}
|
|
334
|
-
function
|
|
334
|
+
function Qt(e, t) {
|
|
335
335
|
let i = e;
|
|
336
336
|
for (; i && i !== t; ) {
|
|
337
337
|
const o = i.parentNode;
|
|
@@ -345,30 +345,30 @@ function Ft(e, t) {
|
|
|
345
345
|
}
|
|
346
346
|
return null;
|
|
347
347
|
}
|
|
348
|
-
function
|
|
348
|
+
function Gt(e) {
|
|
349
349
|
const i = (e.ownerDocument || document).body;
|
|
350
350
|
if (!i) return () => {
|
|
351
351
|
};
|
|
352
|
-
const o =
|
|
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, l = s.getAttribute("aria-hidden");
|
|
356
|
+
a && l === "true" || (s.inert = !0, s.setAttribute("aria-hidden", "true"), n.push({ el: s, prevInert: a, prevAriaHidden: l }));
|
|
357
357
|
}), function() {
|
|
358
358
|
for (; n.length; ) {
|
|
359
359
|
const a = n.pop();
|
|
360
|
-
a
|
|
360
|
+
a.el.inert = a.prevInert, a.prevAriaHidden === null ? a.el.removeAttribute("aria-hidden") : a.el.setAttribute("aria-hidden", a.prevAriaHidden);
|
|
361
361
|
}
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
|
-
const
|
|
364
|
+
const tt = {
|
|
365
365
|
width: 400,
|
|
366
366
|
height: 280,
|
|
367
367
|
arrowHeight: 12,
|
|
368
368
|
gap: 8,
|
|
369
369
|
viewportPadding: 16
|
|
370
370
|
};
|
|
371
|
-
function
|
|
371
|
+
function Jt(e, t, i, o, n) {
|
|
372
372
|
const s = e.y, a = t - (e.y + e.height);
|
|
373
373
|
if (a >= i + o)
|
|
374
374
|
return {
|
|
@@ -380,29 +380,29 @@ function Ut(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 l = a > s ? "below" : "above";
|
|
384
|
+
let c;
|
|
385
|
+
return l === "below" ? c = Math.min(
|
|
386
386
|
e.y + e.height + o,
|
|
387
387
|
t - i - n
|
|
388
|
-
) :
|
|
388
|
+
) : c = Math.max(n, e.y - i - o), { top: c, position: l };
|
|
389
389
|
}
|
|
390
|
-
function
|
|
390
|
+
function Zt(e, t, i, o) {
|
|
391
391
|
let s = e.x + e.width / 2 - i / 2;
|
|
392
392
|
return s = Math.max(o, Math.min(s, t - i - o)), s;
|
|
393
393
|
}
|
|
394
|
-
function
|
|
394
|
+
function te(e, t, i, o = 24, n = 24) {
|
|
395
395
|
const a = e.clickX - t - n / 2;
|
|
396
396
|
return Math.max(o, Math.min(a, i - o - n / 2));
|
|
397
397
|
}
|
|
398
|
-
function
|
|
399
|
-
const n = o.height + o.arrowHeight, s =
|
|
398
|
+
function ee(e, t, i, o = tt) {
|
|
399
|
+
const n = o.height + o.arrowHeight, s = Jt(
|
|
400
400
|
e,
|
|
401
401
|
i,
|
|
402
402
|
n,
|
|
403
403
|
o.gap,
|
|
404
404
|
o.viewportPadding
|
|
405
|
-
), a =
|
|
405
|
+
), a = Zt(
|
|
406
406
|
e,
|
|
407
407
|
t,
|
|
408
408
|
o.width,
|
|
@@ -414,15 +414,15 @@ function Wt(e, t, i, o = J) {
|
|
|
414
414
|
position: s.position
|
|
415
415
|
};
|
|
416
416
|
}
|
|
417
|
-
function
|
|
417
|
+
function ie(e, t, i, o = {}) {
|
|
418
418
|
const n = o.gap ?? 8;
|
|
419
419
|
let s = e.bottom + n;
|
|
420
420
|
s + t.height > i.height - n && (s = e.top - t.height - n);
|
|
421
421
|
let a = e.left;
|
|
422
422
|
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 };
|
|
423
423
|
}
|
|
424
|
-
function
|
|
425
|
-
const n =
|
|
424
|
+
function oe(e, t, i, o = tt) {
|
|
425
|
+
const n = ee(e, t, i, o), s = te(
|
|
426
426
|
e,
|
|
427
427
|
n.left,
|
|
428
428
|
o.width
|
|
@@ -432,15 +432,15 @@ function Yt(e, t, i, o = J) {
|
|
|
432
432
|
arrow: { left: s }
|
|
433
433
|
};
|
|
434
434
|
}
|
|
435
|
-
const
|
|
436
|
-
function
|
|
437
|
-
const t = [], i = console.error, o = console.warn, n = console.log, s = (a,
|
|
438
|
-
const
|
|
439
|
-
message:
|
|
435
|
+
const ne = 20;
|
|
436
|
+
function se(e) {
|
|
437
|
+
const t = [], i = console.error, o = console.warn, n = console.log, s = (a, l) => {
|
|
438
|
+
const c = {
|
|
439
|
+
message: l.map((r) => String(r)).join(" "),
|
|
440
440
|
timestamp: Date.now(),
|
|
441
441
|
level: a
|
|
442
442
|
};
|
|
443
|
-
t.length >=
|
|
443
|
+
t.length >= ne && t.shift(), t.push(c), e && e(c);
|
|
444
444
|
};
|
|
445
445
|
return console.error = function(...a) {
|
|
446
446
|
s("error", a), i.apply(console, a);
|
|
@@ -455,37 +455,37 @@ function Jt(e) {
|
|
|
455
455
|
}
|
|
456
456
|
};
|
|
457
457
|
}
|
|
458
|
-
const
|
|
459
|
-
function
|
|
458
|
+
const ae = 20, U = 4096;
|
|
459
|
+
function k(e) {
|
|
460
460
|
const t = typeof e == "string" ? e : JSON.stringify(e);
|
|
461
|
-
return t.length >
|
|
461
|
+
return t.length > U ? t.slice(0, U) + "…[truncated]" : t;
|
|
462
462
|
}
|
|
463
|
-
function
|
|
464
|
-
e.length >=
|
|
463
|
+
function _(e, t) {
|
|
464
|
+
e.length >= ae && e.shift(), e.push(t);
|
|
465
465
|
}
|
|
466
|
-
async function
|
|
466
|
+
async function re(e) {
|
|
467
467
|
try {
|
|
468
468
|
const t = await e.clone().text();
|
|
469
|
-
return
|
|
469
|
+
return k(t);
|
|
470
470
|
} catch {
|
|
471
471
|
return;
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
|
-
function
|
|
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, l = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
|
|
478
|
+
let c;
|
|
479
|
+
s?.body && (c = k(s.body));
|
|
480
480
|
const r = await t.apply(window, [n, s]);
|
|
481
481
|
if (r.status >= 400) {
|
|
482
|
-
const d = await
|
|
483
|
-
|
|
482
|
+
const d = await re(r);
|
|
483
|
+
_(e, {
|
|
484
484
|
url: a,
|
|
485
|
-
method:
|
|
485
|
+
method: l.toUpperCase(),
|
|
486
486
|
status: r.status,
|
|
487
487
|
statusText: r.statusText,
|
|
488
|
-
requestBody:
|
|
488
|
+
requestBody: c,
|
|
489
489
|
responseBody: d,
|
|
490
490
|
timestamp: Date.now()
|
|
491
491
|
});
|
|
@@ -496,15 +496,15 @@ function te() {
|
|
|
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 ? k(n) : void 0;
|
|
500
500
|
return s.addEventListener("load", function() {
|
|
501
|
-
s.status >= 400 &&
|
|
501
|
+
s.status >= 400 && _(e, {
|
|
502
502
|
url: s._qaid_url,
|
|
503
503
|
method: s._qaid_method.toUpperCase(),
|
|
504
504
|
status: s.status,
|
|
505
505
|
statusText: s.statusText,
|
|
506
506
|
requestBody: a,
|
|
507
|
-
responseBody:
|
|
507
|
+
responseBody: k(s.responseText),
|
|
508
508
|
timestamp: Date.now()
|
|
509
509
|
});
|
|
510
510
|
}), o.apply(this, [n]);
|
|
@@ -515,10 +515,10 @@ function te() {
|
|
|
515
515
|
}
|
|
516
516
|
};
|
|
517
517
|
}
|
|
518
|
-
function
|
|
518
|
+
function le() {
|
|
519
519
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
520
520
|
}
|
|
521
|
-
function
|
|
521
|
+
function ce() {
|
|
522
522
|
if (typeof MediaRecorder > "u") return "";
|
|
523
523
|
const e = [
|
|
524
524
|
"video/webm;codecs=vp9",
|
|
@@ -531,11 +531,11 @@ function ie() {
|
|
|
531
531
|
return t;
|
|
532
532
|
return "";
|
|
533
533
|
}
|
|
534
|
-
function
|
|
534
|
+
function he(e = {}) {
|
|
535
535
|
const t = e.maxDuration ?? 15, i = e.videoBitsPerSecond ?? 8e5;
|
|
536
|
-
let o = null, n = null, s = [], a = null,
|
|
536
|
+
let o = null, n = null, s = [], a = null, l = null, c = null, r = 0, d = null, p = null, u = !1, m = null;
|
|
537
537
|
function g() {
|
|
538
|
-
|
|
538
|
+
c !== null && (clearInterval(c), c = null), m !== null && (clearTimeout(m), m = null), o && (o.getTracks().forEach((f) => f.stop()), o = null), n = null, s = [], a = null, l = null, d = null, p = null;
|
|
539
539
|
}
|
|
540
540
|
function b() {
|
|
541
541
|
u || (u = !0, n && n.state !== "inactive" && n.stop());
|
|
@@ -543,7 +543,7 @@ function oe(e = {}) {
|
|
|
543
543
|
return {
|
|
544
544
|
async start() {
|
|
545
545
|
u = !1, s = [];
|
|
546
|
-
const f =
|
|
546
|
+
const f = ce();
|
|
547
547
|
if (!f)
|
|
548
548
|
throw new Error("No supported video MIME type found");
|
|
549
549
|
o = await navigator.mediaDevices.getDisplayMedia({
|
|
@@ -564,10 +564,10 @@ function oe(e = {}) {
|
|
|
564
564
|
h.data.size > 0 && s.push(h.data);
|
|
565
565
|
}, n.onstop = () => {
|
|
566
566
|
const h = new Blob(s, { type: f });
|
|
567
|
-
d && d(h),
|
|
567
|
+
d && d(h), l && l(h), o && o.getTracks().forEach((y) => y.stop());
|
|
568
568
|
}, n.onerror = () => {
|
|
569
569
|
p && p(new Error("MediaRecorder error"));
|
|
570
|
-
}, n.start(1e3), r = Date.now(),
|
|
570
|
+
}, n.start(1e3), r = Date.now(), c = setInterval(() => {
|
|
571
571
|
const h = Math.floor((Date.now() - r) / 1e3);
|
|
572
572
|
a && a(h);
|
|
573
573
|
}, 1e3), m = setTimeout(() => {
|
|
@@ -583,26 +583,26 @@ function oe(e = {}) {
|
|
|
583
583
|
a = f;
|
|
584
584
|
},
|
|
585
585
|
onStop(f) {
|
|
586
|
-
|
|
586
|
+
l = f;
|
|
587
587
|
},
|
|
588
588
|
destroy() {
|
|
589
589
|
b(), g();
|
|
590
590
|
}
|
|
591
591
|
};
|
|
592
592
|
}
|
|
593
|
-
function
|
|
593
|
+
function ue(e = 640) {
|
|
594
594
|
return typeof window < "u" && window.innerWidth < e;
|
|
595
595
|
}
|
|
596
|
-
function
|
|
596
|
+
function K(e, t, i) {
|
|
597
597
|
const o = i.map((s) => s.style.visibility);
|
|
598
598
|
i.forEach((s) => s.style.visibility = "hidden");
|
|
599
599
|
const n = document.elementFromPoint(e, t);
|
|
600
600
|
return i.forEach((s, a) => s.style.visibility = o[a]), n;
|
|
601
601
|
}
|
|
602
|
-
function
|
|
602
|
+
function A(e) {
|
|
603
603
|
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
604
|
}
|
|
605
|
-
function
|
|
605
|
+
function X(e, t = 0) {
|
|
606
606
|
const i = e.getBoundingClientRect();
|
|
607
607
|
return {
|
|
608
608
|
x: i.left - t,
|
|
@@ -611,7 +611,7 @@ function _(e, t = 0) {
|
|
|
611
611
|
height: i.height + t * 2
|
|
612
612
|
};
|
|
613
613
|
}
|
|
614
|
-
async function
|
|
614
|
+
async function pe(e = {}) {
|
|
615
615
|
const { quality: t = 1, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
616
616
|
try {
|
|
617
617
|
if (!navigator.mediaDevices?.getDisplayMedia)
|
|
@@ -621,59 +621,59 @@ async function se(e = {}) {
|
|
|
621
621
|
video: {
|
|
622
622
|
displaySurface: "browser"
|
|
623
623
|
}
|
|
624
|
-
}), s = n.getVideoTracks()[0], a = s.getSettings(),
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
624
|
+
}), s = n.getVideoTracks()[0], a = s.getSettings(), l = document.createElement("video");
|
|
625
|
+
l.srcObject = n, l.muted = !0, await new Promise((b) => {
|
|
626
|
+
l.onloadedmetadata = () => {
|
|
627
|
+
l.play(), b();
|
|
628
628
|
};
|
|
629
629
|
}), await new Promise((b) => {
|
|
630
630
|
const f = () => {
|
|
631
|
-
|
|
631
|
+
l.readyState >= 2 ? b() : requestAnimationFrame(f);
|
|
632
632
|
};
|
|
633
633
|
f();
|
|
634
634
|
}), await new Promise((b) => setTimeout(b, 100));
|
|
635
|
-
const
|
|
635
|
+
const c = a.width || l.videoWidth, r = a.height || l.videoHeight, d = Math.min(i / c, o / r, 1), p = Math.round(c * d), u = Math.round(r * d), m = document.createElement("canvas");
|
|
636
636
|
m.width = p, m.height = u;
|
|
637
637
|
const g = m.getContext("2d");
|
|
638
|
-
return g ? (g.drawImage(
|
|
638
|
+
return g ? (g.drawImage(l, 0, 0, p, u), s.stop(), m.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
639
639
|
} catch (n) {
|
|
640
640
|
return console.warn("Screenshot capture failed:", n), null;
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
|
-
const
|
|
643
|
+
const j = "https://qaid.dev/lib/html2canvas.min.js", me = 1e4, fe = 50;
|
|
644
644
|
let w = null;
|
|
645
|
-
function
|
|
645
|
+
function Le() {
|
|
646
646
|
if (typeof document > "u" || typeof window > "u")
|
|
647
647
|
return !1;
|
|
648
648
|
const e = document.createElement("canvas");
|
|
649
649
|
return typeof e.getContext == "function" && !!e.getContext("2d");
|
|
650
650
|
}
|
|
651
|
-
function
|
|
651
|
+
function be() {
|
|
652
652
|
return window.html2canvas ? Promise.resolve(!0) : w || (w = new Promise((e) => {
|
|
653
653
|
if (!document.querySelector(
|
|
654
|
-
`script[src="${
|
|
654
|
+
`script[src="${j}"]`
|
|
655
655
|
)) {
|
|
656
656
|
const n = document.createElement("script");
|
|
657
|
-
n.src =
|
|
657
|
+
n.src = j, n.async = !0, document.head.appendChild(n);
|
|
658
658
|
}
|
|
659
659
|
const i = Date.now(), o = () => {
|
|
660
660
|
if (window.html2canvas) {
|
|
661
661
|
e(!0);
|
|
662
662
|
return;
|
|
663
663
|
}
|
|
664
|
-
if (Date.now() - i >
|
|
664
|
+
if (Date.now() - i > me) {
|
|
665
665
|
w = null, e(!1);
|
|
666
666
|
return;
|
|
667
667
|
}
|
|
668
|
-
setTimeout(o,
|
|
668
|
+
setTimeout(o, fe);
|
|
669
669
|
};
|
|
670
670
|
o();
|
|
671
671
|
}), w);
|
|
672
672
|
}
|
|
673
|
-
async function
|
|
673
|
+
async function ge(e = {}) {
|
|
674
674
|
const { quality: t = 0.8, maxWidth: i = 1280, maxHeight: o = 800 } = e;
|
|
675
675
|
try {
|
|
676
|
-
if (!await
|
|
676
|
+
if (!await be() || !window.html2canvas)
|
|
677
677
|
return console.warn("html2canvas failed to load"), null;
|
|
678
678
|
const s = await window.html2canvas(document.body, {
|
|
679
679
|
useCORS: !0,
|
|
@@ -686,9 +686,9 @@ async function ce(e = {}) {
|
|
|
686
686
|
x: window.scrollX,
|
|
687
687
|
y: window.scrollY,
|
|
688
688
|
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 *
|
|
689
|
+
}), a = s.width, l = s.height, c = Math.min(i / a, o / l, 1);
|
|
690
|
+
if (c < 1) {
|
|
691
|
+
const r = Math.round(a * c), d = Math.round(l * c), p = document.createElement("canvas");
|
|
692
692
|
p.width = r, p.height = d;
|
|
693
693
|
const u = p.getContext("2d");
|
|
694
694
|
return u ? (u.drawImage(s, 0, 0, r, d), p.toDataURL("image/webp", t)) : null;
|
|
@@ -698,32 +698,61 @@ async function ce(e = {}) {
|
|
|
698
698
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
699
699
|
}
|
|
700
700
|
}
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
701
|
+
const ve = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", ye = (e) => (
|
|
702
|
+
// The URL is a runtime value, not a static specifier — keep Vite from
|
|
703
|
+
// trying to analyze/bundle it.
|
|
704
|
+
import(
|
|
705
|
+
/* @vite-ignore */
|
|
706
|
+
e
|
|
707
|
+
)
|
|
708
|
+
);
|
|
709
|
+
let we = ye, x = null, D = null;
|
|
710
|
+
function xe(e) {
|
|
711
|
+
return x && D === e || (D = e, x = Promise.resolve(we(e)).then((t) => {
|
|
712
|
+
const i = t;
|
|
713
|
+
if (!i || typeof i.QaidQuests != "function")
|
|
714
|
+
throw new Error("quests module has no QaidQuests export");
|
|
715
|
+
return i;
|
|
716
|
+
}).catch((t) => {
|
|
717
|
+
throw x = null, D = null, t;
|
|
718
|
+
})), x;
|
|
719
|
+
}
|
|
720
|
+
async function qe(e) {
|
|
721
|
+
const t = await xe(e.moduleUrl), i = e.base.replace(/\/+$/, ""), o = e.feedbackId != null ? { feedbackId: e.feedbackId } : void 0;
|
|
722
|
+
return new t.QaidQuests({
|
|
723
|
+
endpoint: `${i}/responses`,
|
|
724
|
+
configUrl: `${i}/${encodeURIComponent(e.questId)}/definition`,
|
|
725
|
+
apiKey: e.apiKey || void 0,
|
|
726
|
+
metadata: o,
|
|
727
|
+
onClose: e.onClose
|
|
728
|
+
});
|
|
704
729
|
}
|
|
705
|
-
|
|
730
|
+
const W = "qaid_visitor_id", Y = "qaid_hide_feedback";
|
|
731
|
+
function M(e) {
|
|
732
|
+
return e ? `${Y}_${e}` : Y;
|
|
733
|
+
}
|
|
734
|
+
function ke(e) {
|
|
706
735
|
try {
|
|
707
|
-
return localStorage.getItem(
|
|
736
|
+
return localStorage.getItem(M(e)) === "1";
|
|
708
737
|
} catch {
|
|
709
738
|
return !1;
|
|
710
739
|
}
|
|
711
740
|
}
|
|
712
|
-
function
|
|
741
|
+
function Q(e, t = !0) {
|
|
713
742
|
try {
|
|
714
|
-
t ? localStorage.setItem(
|
|
743
|
+
t ? localStorage.setItem(M(e), "1") : localStorage.removeItem(M(e));
|
|
715
744
|
} catch {
|
|
716
745
|
}
|
|
717
746
|
}
|
|
718
|
-
function
|
|
747
|
+
function Ce() {
|
|
719
748
|
try {
|
|
720
|
-
let e = localStorage.getItem(
|
|
721
|
-
return e || (e = crypto.randomUUID(), localStorage.setItem(
|
|
749
|
+
let e = localStorage.getItem(W);
|
|
750
|
+
return e || (e = crypto.randomUUID(), localStorage.setItem(W, e)), e;
|
|
722
751
|
} catch {
|
|
723
752
|
return crypto.randomUUID();
|
|
724
753
|
}
|
|
725
754
|
}
|
|
726
|
-
class
|
|
755
|
+
class Ee {
|
|
727
756
|
config;
|
|
728
757
|
state = "IDLE";
|
|
729
758
|
feedbackData = {
|
|
@@ -742,6 +771,8 @@ class ue {
|
|
|
742
771
|
visible: !1
|
|
743
772
|
};
|
|
744
773
|
feedbackId = null;
|
|
774
|
+
// A quest launched from a button (in place of the message box), if any.
|
|
775
|
+
activeQuest = null;
|
|
745
776
|
mousePos = { x: 0, y: 0 };
|
|
746
777
|
isMobile = !1;
|
|
747
778
|
visitorId;
|
|
@@ -829,7 +860,7 @@ class ue {
|
|
|
829
860
|
positiveLabel: t.text?.positiveLabel ?? "Send positive feedback",
|
|
830
861
|
negativeLabel: t.text?.negativeLabel ?? "Send negative feedback",
|
|
831
862
|
recordLabel: t.text?.recordLabel ?? "Record a screen recording",
|
|
832
|
-
dismissLabel: t.text?.dismissLabel ?? "Hide
|
|
863
|
+
dismissLabel: t.text?.dismissLabel ?? "Hide Feedback"
|
|
833
864
|
},
|
|
834
865
|
modalWidth: t.modalWidth ?? 400,
|
|
835
866
|
backdropOpacity: t.backdropOpacity ?? 0.3,
|
|
@@ -852,11 +883,20 @@ class ue {
|
|
|
852
883
|
videoOptions: {
|
|
853
884
|
maxDuration: t.videoOptions?.maxDuration ?? 15
|
|
854
885
|
},
|
|
855
|
-
recordIcon: t.recordIcon ?? ""
|
|
856
|
-
|
|
886
|
+
recordIcon: t.recordIcon ?? "",
|
|
887
|
+
quests: {
|
|
888
|
+
base: t.quests?.base ?? "",
|
|
889
|
+
up: t.quests?.up ?? "",
|
|
890
|
+
down: t.quests?.down ?? "",
|
|
891
|
+
video: t.quests?.video ?? "",
|
|
892
|
+
// Quest service reuses the feedback API key unless overridden.
|
|
893
|
+
apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
|
|
894
|
+
moduleUrl: t.quests?.moduleUrl ?? ve
|
|
895
|
+
}
|
|
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 = Ce(), this.init();
|
|
857
897
|
}
|
|
858
898
|
applyVars(t) {
|
|
859
|
-
|
|
899
|
+
St(t, this.cssVars);
|
|
860
900
|
}
|
|
861
901
|
/**
|
|
862
902
|
* Announce a message via the shared visually-hidden live regions.
|
|
@@ -866,7 +906,7 @@ class ue {
|
|
|
866
906
|
*/
|
|
867
907
|
announceMsg(t, i = !1) {
|
|
868
908
|
const o = this.overlayShadowRoot ?? this.shadowRoot;
|
|
869
|
-
o &&
|
|
909
|
+
o && Ut(o, t, { assertive: i });
|
|
870
910
|
}
|
|
871
911
|
/**
|
|
872
912
|
* Turn a transient surface into an accessible modal dialog: save the
|
|
@@ -874,16 +914,16 @@ class ue {
|
|
|
874
914
|
* background. Paired with closeDialogA11y() on every close path.
|
|
875
915
|
*/
|
|
876
916
|
openDialogA11y(t, i) {
|
|
877
|
-
this.dialogTrigger =
|
|
917
|
+
this.dialogTrigger = jt(), Yt(t, i), this.dialogTrap = Xt(t), this.dialogRestoreInert = Gt(t);
|
|
878
918
|
}
|
|
879
919
|
closeDialogA11y() {
|
|
880
|
-
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null),
|
|
920
|
+
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), Wt(this.dialogTrigger), this.dialogTrigger = null;
|
|
881
921
|
}
|
|
882
922
|
clearActiveThumb() {
|
|
883
923
|
this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
|
|
884
924
|
}
|
|
885
925
|
init() {
|
|
886
|
-
|
|
926
|
+
Tt(), this.cssVars = Et({
|
|
887
927
|
positiveColor: this.config.colors.positive,
|
|
888
928
|
negativeColor: this.config.colors.negative,
|
|
889
929
|
markerColor: this.config.colors.marker,
|
|
@@ -892,7 +932,7 @@ class ue {
|
|
|
892
932
|
backdropOpacity: this.config.backdropOpacity,
|
|
893
933
|
fontFamily: this.config.fontFamily,
|
|
894
934
|
fontSize: this.config.fontSize
|
|
895
|
-
}), !this.config.hideDismiss &&
|
|
935
|
+
}), !this.config.hideDismiss && ke(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = se((t) => {
|
|
896
936
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
897
937
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom();
|
|
898
938
|
}
|
|
@@ -915,7 +955,7 @@ class ue {
|
|
|
915
955
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
916
956
|
}
|
|
917
957
|
checkMobile() {
|
|
918
|
-
this.isMobile =
|
|
958
|
+
this.isMobile = ue();
|
|
919
959
|
}
|
|
920
960
|
handleResize() {
|
|
921
961
|
this.checkMobile();
|
|
@@ -925,7 +965,7 @@ class ue {
|
|
|
925
965
|
let t = null;
|
|
926
966
|
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" });
|
|
927
967
|
const i = document.createElement("style");
|
|
928
|
-
if (i.textContent =
|
|
968
|
+
if (i.textContent = N(), this.shadowRoot.appendChild(i), this.config.css) {
|
|
929
969
|
const r = document.createElement("style");
|
|
930
970
|
r.textContent = this.config.css, this.shadowRoot.appendChild(r);
|
|
931
971
|
}
|
|
@@ -944,22 +984,22 @@ class ue {
|
|
|
944
984
|
}), this.buttonsContainer.addEventListener("pointerdown", () => {
|
|
945
985
|
this.keyboardActivation = !1;
|
|
946
986
|
});
|
|
947
|
-
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn",
|
|
948
|
-
if (
|
|
987
|
+
const n = !!this.config.buttonClass, s = n ? `qaid-btn-structural ${this.config.buttonClass}` : "qaid-btn", l = this.config.text.tooltip || "Feedback for us?", c = document.createElement("div");
|
|
988
|
+
if (c.className = "qaid-tooltip-text", c.textContent = l, this.applyVars(c), this.shadowRoot.appendChild(c), this.tooltipElement = c, !this.config.hideThumbs) {
|
|
949
989
|
const r = document.createElement("div");
|
|
950
990
|
r.className = "qaid-tooltip-wrapper";
|
|
951
991
|
const d = document.createElement("button");
|
|
952
|
-
d.type = "button", d.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", d.setAttribute("aria-label", this.config.text.positiveLabel), d.innerHTML = this.config.positiveIcon ||
|
|
992
|
+
d.type = "button", d.className = n ? `${s} qaid-btn-up` : "qaid-btn qaid-btn-up", d.setAttribute("aria-label", this.config.text.positiveLabel), d.innerHTML = this.config.positiveIcon || T, d.addEventListener("click", (m) => this.handleThumbClick("up", m.currentTarget, m)), d.addEventListener("mouseenter", () => this.showTooltip(d)), d.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(d);
|
|
953
993
|
const p = document.createElement("div");
|
|
954
994
|
p.className = "qaid-tooltip-wrapper";
|
|
955
995
|
const u = document.createElement("button");
|
|
956
|
-
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 ||
|
|
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 || L, 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);
|
|
957
997
|
}
|
|
958
|
-
if (this.config.captureVideo &&
|
|
998
|
+
if (this.config.captureVideo && le()) {
|
|
959
999
|
const r = document.createElement("div");
|
|
960
1000
|
r.className = "qaid-tooltip-wrapper";
|
|
961
1001
|
const d = document.createElement("button");
|
|
962
|
-
d.type = "button", d.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", d.setAttribute("aria-label", this.config.text.recordLabel), d.innerHTML = this.config.recordIcon ||
|
|
1002
|
+
d.type = "button", d.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", d.setAttribute("aria-label", this.config.text.recordLabel), d.innerHTML = this.config.recordIcon || bt, d.addEventListener("click", () => this.startRecording()), d.addEventListener("mouseenter", () => this.showTooltip(d)), d.addEventListener("mouseleave", () => this.hideTooltip()), r.appendChild(d), this.buttonsContainer.appendChild(r);
|
|
963
1003
|
}
|
|
964
1004
|
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) => {
|
|
965
1005
|
r.stopPropagation(), this.handleDismiss();
|
|
@@ -975,7 +1015,7 @@ class ue {
|
|
|
975
1015
|
if (this.overlayShadowRoot) return this.overlayShadowRoot;
|
|
976
1016
|
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" });
|
|
977
1017
|
const t = document.createElement("style");
|
|
978
|
-
if (t.textContent =
|
|
1018
|
+
if (t.textContent = N(), this.overlayShadowRoot.appendChild(t), this.config.css) {
|
|
979
1019
|
const i = document.createElement("style");
|
|
980
1020
|
i.textContent = this.config.css, this.overlayShadowRoot.appendChild(i);
|
|
981
1021
|
}
|
|
@@ -985,7 +1025,7 @@ class ue {
|
|
|
985
1025
|
showTooltip(t) {
|
|
986
1026
|
const i = this.tooltipElement;
|
|
987
1027
|
i.style.visibility = "hidden", i.classList.add("qaid-tooltip-visible");
|
|
988
|
-
const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } =
|
|
1028
|
+
const o = t.getBoundingClientRect(), n = i.getBoundingClientRect(), { top: s, left: a } = ie(
|
|
989
1029
|
o,
|
|
990
1030
|
n,
|
|
991
1031
|
{ width: window.innerWidth, height: window.innerHeight }
|
|
@@ -996,10 +1036,10 @@ class ue {
|
|
|
996
1036
|
this.tooltipElement.classList.remove("qaid-tooltip-visible");
|
|
997
1037
|
}
|
|
998
1038
|
handleDismiss() {
|
|
999
|
-
this.buttonsContainer.classList.add("qaid-dismissed"),
|
|
1039
|
+
this.buttonsContainer.classList.add("qaid-dismissed"), Q(this.config.apiKey, !0);
|
|
1000
1040
|
}
|
|
1001
1041
|
handleThumbClick(t, i, o) {
|
|
1002
|
-
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"),
|
|
1042
|
+
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), Q(this.config.apiKey, !1)), this.config.skipTargeting)
|
|
1003
1043
|
this.submitDirectFeedback(t, i);
|
|
1004
1044
|
else {
|
|
1005
1045
|
this.activeThumbBtn = i, i.setAttribute("aria-pressed", "true");
|
|
@@ -1030,12 +1070,12 @@ class ue {
|
|
|
1030
1070
|
* The KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
|
|
1031
1071
|
*/
|
|
1032
1072
|
startKeyboardTargetingFlow(t) {
|
|
1033
|
-
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 =
|
|
1034
|
-
isExcluded: (i) =>
|
|
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 = $t({
|
|
1074
|
+
isExcluded: (i) => A(i),
|
|
1035
1075
|
onHighlight: (i) => {
|
|
1036
1076
|
const o = i.getBoundingClientRect(), n = this.highlightBox;
|
|
1037
1077
|
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");
|
|
1038
|
-
const { text: s } =
|
|
1078
|
+
const { text: s } = I(i);
|
|
1039
1079
|
this.announceMsg(`Targeting ${s || i.tagName.toLowerCase()}`);
|
|
1040
1080
|
},
|
|
1041
1081
|
onSelect: (i) => this.selectKeyboardTarget(i),
|
|
@@ -1043,14 +1083,14 @@ class ue {
|
|
|
1043
1083
|
});
|
|
1044
1084
|
}
|
|
1045
1085
|
selectKeyboardTarget(t) {
|
|
1046
|
-
const i =
|
|
1086
|
+
const i = X(t, 8);
|
|
1047
1087
|
this.selectedBounds = {
|
|
1048
1088
|
...i,
|
|
1049
1089
|
clickX: i.x + i.width / 2,
|
|
1050
1090
|
clickY: i.y + i.height / 2,
|
|
1051
1091
|
visible: !0
|
|
1052
1092
|
};
|
|
1053
|
-
const { selector: o, text: n } =
|
|
1093
|
+
const { selector: o, text: n } = I(t);
|
|
1054
1094
|
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();
|
|
1055
1095
|
}
|
|
1056
1096
|
createTargetingOverlay() {
|
|
@@ -1068,12 +1108,12 @@ class ue {
|
|
|
1068
1108
|
}
|
|
1069
1109
|
handleMouseMove(t) {
|
|
1070
1110
|
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) {
|
|
1071
|
-
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o =
|
|
1111
|
+
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o = K(
|
|
1072
1112
|
t.clientX,
|
|
1073
1113
|
t.clientY,
|
|
1074
1114
|
i
|
|
1075
1115
|
);
|
|
1076
|
-
if (o && !
|
|
1116
|
+
if (o && !A(o)) {
|
|
1077
1117
|
if (this.highlightBox) {
|
|
1078
1118
|
const n = o.getBoundingClientRect();
|
|
1079
1119
|
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";
|
|
@@ -1084,21 +1124,21 @@ class ue {
|
|
|
1084
1124
|
}
|
|
1085
1125
|
handleClick(t) {
|
|
1086
1126
|
t.preventDefault(), t.stopPropagation();
|
|
1087
|
-
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o =
|
|
1127
|
+
const i = [this.shadowHost, this.overlayShadowHost].filter(Boolean), o = K(
|
|
1088
1128
|
t.clientX,
|
|
1089
1129
|
t.clientY,
|
|
1090
1130
|
i
|
|
1091
1131
|
);
|
|
1092
|
-
if (!o ||
|
|
1132
|
+
if (!o || A(o))
|
|
1093
1133
|
return;
|
|
1094
|
-
const n =
|
|
1134
|
+
const n = X(o, 8);
|
|
1095
1135
|
this.selectedBounds = {
|
|
1096
1136
|
...n,
|
|
1097
1137
|
clickX: t.clientX,
|
|
1098
1138
|
clickY: t.clientY,
|
|
1099
1139
|
visible: !0
|
|
1100
1140
|
};
|
|
1101
|
-
const { selector: s, text: a } =
|
|
1141
|
+
const { selector: s, text: a } = I(o);
|
|
1102
1142
|
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.clearActiveThumb(), this.showSelectedMarker(), this.submitFeedback();
|
|
1103
1143
|
}
|
|
1104
1144
|
cancelTargeting() {
|
|
@@ -1116,7 +1156,7 @@ class ue {
|
|
|
1116
1156
|
}
|
|
1117
1157
|
async submitFeedback() {
|
|
1118
1158
|
let t = null;
|
|
1119
|
-
this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await
|
|
1159
|
+
this.config.captureScreenshot && (this.config.screenshotMethod === "dom" ? t = await ge(this.config.screenshotOptions) : t = await pe(this.config.screenshotOptions), t && this.announceMsg("Screenshot captured"));
|
|
1120
1160
|
const i = this.feedbackData.elementSelector ? {
|
|
1121
1161
|
x: this.selectedBounds.x,
|
|
1122
1162
|
y: this.selectedBounds.y,
|
|
@@ -1142,20 +1182,66 @@ class ue {
|
|
|
1142
1182
|
userAgent: navigator.userAgent
|
|
1143
1183
|
};
|
|
1144
1184
|
try {
|
|
1145
|
-
const
|
|
1185
|
+
const s = await fetch(this.config.endpoint, {
|
|
1146
1186
|
method: "POST",
|
|
1147
1187
|
headers: { "Content-Type": "application/json" },
|
|
1148
1188
|
body: JSON.stringify(o)
|
|
1149
1189
|
});
|
|
1150
|
-
if (
|
|
1151
|
-
const
|
|
1152
|
-
this.feedbackId =
|
|
1190
|
+
if (s.ok) {
|
|
1191
|
+
const a = await s.json();
|
|
1192
|
+
this.feedbackId = a.id, this.announceMsg("Feedback sent");
|
|
1153
1193
|
}
|
|
1154
|
-
} catch (
|
|
1155
|
-
console.error("Failed to submit feedback:",
|
|
1194
|
+
} catch (s) {
|
|
1195
|
+
console.error("Failed to submit feedback:", s), this.announceMsg("Failed to send feedback", !0);
|
|
1196
|
+
}
|
|
1197
|
+
const n = this.feedbackData.feedbackType;
|
|
1198
|
+
if (n && await this.tryLaunchQuest(n, this.feedbackId)) {
|
|
1199
|
+
this.resetFeedbackUi();
|
|
1200
|
+
return;
|
|
1156
1201
|
}
|
|
1157
1202
|
this.state = "MODAL_OPEN", this.showModal(), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "auto");
|
|
1158
1203
|
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Quest id linked to `type`, or "" when quest launching is disabled
|
|
1206
|
+
* (no `base`) or this button has no quest configured.
|
|
1207
|
+
*/
|
|
1208
|
+
questIdFor(t) {
|
|
1209
|
+
const i = this.config.quests;
|
|
1210
|
+
return i.base && i[t] || "";
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Launch the quest linked to `type`, if any. Resolves `true` when a quest
|
|
1214
|
+
* was configured and the widget launched; `false` when no quest is
|
|
1215
|
+
* configured or the widget failed to load (caller falls back to its
|
|
1216
|
+
* normal UI). The created feedback record id is passed through so the
|
|
1217
|
+
* quest response can be joined back to it server-side.
|
|
1218
|
+
*/
|
|
1219
|
+
async tryLaunchQuest(t, i) {
|
|
1220
|
+
const o = this.questIdFor(t);
|
|
1221
|
+
if (!o) return !1;
|
|
1222
|
+
try {
|
|
1223
|
+
return this.activeQuest?.destroy(), this.activeQuest = await qe({
|
|
1224
|
+
questId: o,
|
|
1225
|
+
base: this.config.quests.base,
|
|
1226
|
+
apiKey: this.config.quests.apiKey || void 0,
|
|
1227
|
+
moduleUrl: this.config.quests.moduleUrl,
|
|
1228
|
+
feedbackId: i,
|
|
1229
|
+
onClose: () => {
|
|
1230
|
+
this.activeQuest = null;
|
|
1231
|
+
}
|
|
1232
|
+
}), !0;
|
|
1233
|
+
} catch (n) {
|
|
1234
|
+
return console.error("Failed to launch quest:", n), this.activeQuest = null, !1;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Reset the thumbs targeting/marker UI back to idle without opening or
|
|
1239
|
+
* closing the message modal. Shared by closeModal() and the quest-launch
|
|
1240
|
+
* path (which bypasses the modal entirely).
|
|
1241
|
+
*/
|
|
1242
|
+
resetFeedbackUi() {
|
|
1243
|
+
this.hideSelectedMarker(), this.overlayShadowHost && (this.overlayShadowHost.style.pointerEvents = "none"), this.state = "IDLE", this.feedbackId = null, this.feedbackData.feedbackType = null, this.feedbackData.elementSelector = null, this.feedbackData.elementText = null, this.selectedBounds.visible = !1;
|
|
1244
|
+
}
|
|
1159
1245
|
showModal() {
|
|
1160
1246
|
const t = this.ensureOverlayHost();
|
|
1161
1247
|
this.backdrop = document.createElement("div"), this.backdrop.className = "qaid-backdrop", this.backdrop.style.zIndex = String(this.config.zIndex + 2), this.backdrop.style.background = `rgba(0, 0, 0, ${this.config.backdropOpacity})`, this.backdrop.addEventListener("click", () => this.closeModal()), this.applyVars(this.backdrop), this.isMobile ? this.showBottomSheet() : this.showPositionedModal(), t.appendChild(this.backdrop), document.addEventListener("keydown", this.boundKeyDown);
|
|
@@ -1170,7 +1256,7 @@ class ue {
|
|
|
1170
1256
|
`, this.applyVars(i), t.appendChild(i), this.modalContainer = i, this.setupModalInteractions();
|
|
1171
1257
|
}
|
|
1172
1258
|
showPositionedModal() {
|
|
1173
|
-
const t = this.ensureOverlayHost(), { modal: i, arrow: o } =
|
|
1259
|
+
const t = this.ensureOverlayHost(), { modal: i, arrow: o } = oe(
|
|
1174
1260
|
this.selectedBounds,
|
|
1175
1261
|
window.innerWidth,
|
|
1176
1262
|
window.innerHeight,
|
|
@@ -1189,7 +1275,7 @@ class ue {
|
|
|
1189
1275
|
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();
|
|
1190
1276
|
}
|
|
1191
1277
|
getModalContent() {
|
|
1192
|
-
const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon ||
|
|
1278
|
+
const t = this.feedbackData.feedbackType === "up", i = this.config.positiveIcon || T, o = this.config.negativeIcon || L;
|
|
1193
1279
|
return `
|
|
1194
1280
|
<div class="qaid-modal-header">
|
|
1195
1281
|
<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"}">
|
|
@@ -1222,14 +1308,14 @@ class ue {
|
|
|
1222
1308
|
o && o.addEventListener("click", () => {
|
|
1223
1309
|
const n = this.feedbackData.feedbackType === "up" ? "down" : "up";
|
|
1224
1310
|
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"));
|
|
1225
|
-
const s = this.config.positiveIcon ||
|
|
1311
|
+
const s = this.config.positiveIcon || T, a = this.config.negativeIcon || L;
|
|
1226
1312
|
o.innerHTML = n === "up" ? s : a;
|
|
1227
|
-
const
|
|
1228
|
-
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label",
|
|
1313
|
+
const l = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
|
|
1314
|
+
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", l), this.announceMsg(l), this.feedbackId && fetch(`${this.config.endpoint}/${this.feedbackId}`, {
|
|
1229
1315
|
method: "PATCH",
|
|
1230
1316
|
headers: { "Content-Type": "application/json" },
|
|
1231
1317
|
body: JSON.stringify({ feedbackType: n })
|
|
1232
|
-
}).catch((
|
|
1318
|
+
}).catch((c) => console.error("Failed to update feedback type:", c));
|
|
1233
1319
|
});
|
|
1234
1320
|
}
|
|
1235
1321
|
async submitMessage(t) {
|
|
@@ -1252,13 +1338,13 @@ class ue {
|
|
|
1252
1338
|
method: "PATCH",
|
|
1253
1339
|
headers: { "Content-Type": "application/json" },
|
|
1254
1340
|
body: JSON.stringify({ message: null })
|
|
1255
|
-
}).catch((t) => console.error("Failed to finalize feedback:", t)), this.closeDialogA11y(), this.modalContainer && (this.modalContainer.remove(), this.modalContainer = null), this.backdrop && (this.backdrop.remove(), this.backdrop = null), document.removeEventListener("keydown", this.boundKeyDown), this.
|
|
1341
|
+
}).catch((t) => console.error("Failed to finalize feedback:", t)), this.closeDialogA11y(), this.modalContainer && (this.modalContainer.remove(), this.modalContainer = null), this.backdrop && (this.backdrop.remove(), this.backdrop = null), document.removeEventListener("keydown", this.boundKeyDown), this.resetFeedbackUi();
|
|
1256
1342
|
}
|
|
1257
1343
|
// ==================== Video Recording ====================
|
|
1258
1344
|
async startRecording() {
|
|
1259
1345
|
if (!(this.isRecording || this.state !== "IDLE"))
|
|
1260
1346
|
try {
|
|
1261
|
-
this.networkCapture =
|
|
1347
|
+
this.networkCapture = de(), this.videoRecorder = he({
|
|
1262
1348
|
maxDuration: this.config.videoOptions.maxDuration
|
|
1263
1349
|
}), this.videoRecorder.onTick((t) => {
|
|
1264
1350
|
this.updateRecordingTimer(t);
|
|
@@ -1313,10 +1399,10 @@ class ue {
|
|
|
1313
1399
|
s.src = i, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
1314
1400
|
const a = document.createElement("textarea");
|
|
1315
1401
|
a.placeholder = "Optional: Describe the issue you recorded...", a.setAttribute("aria-label", "Describe the issue you recorded");
|
|
1316
|
-
const
|
|
1317
|
-
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1402
|
+
const l = document.createElement("div");
|
|
1403
|
+
l.className = "qaid-video-preview-actions";
|
|
1404
|
+
const c = document.createElement("button");
|
|
1405
|
+
c.type = "button", c.className = "qaid-video-btn qaid-video-btn-cancel", c.textContent = "Cancel", c.addEventListener("click", () => this.cancelRecordingPreview());
|
|
1320
1406
|
const r = document.createElement("button");
|
|
1321
1407
|
r.type = "button", r.className = "qaid-video-btn qaid-video-btn-rerecord", r.textContent = "Re-record", r.addEventListener("click", () => {
|
|
1322
1408
|
this.cancelRecordingPreview(), this.startRecording();
|
|
@@ -1325,7 +1411,7 @@ class ue {
|
|
|
1325
1411
|
d.type = "button", d.className = "qaid-video-btn qaid-video-btn-send", d.textContent = "Send", d.addEventListener("click", () => {
|
|
1326
1412
|
const p = a.value.trim() || null;
|
|
1327
1413
|
this.submitVideoFeedback(p, d);
|
|
1328
|
-
}),
|
|
1414
|
+
}), l.appendChild(c), l.appendChild(r), l.appendChild(d), o.appendChild(n), o.appendChild(s), o.appendChild(a), o.appendChild(l), 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);
|
|
1329
1415
|
}
|
|
1330
1416
|
cancelRecordingPreview() {
|
|
1331
1417
|
this.removeVideoPreview(), this.cleanupRecording();
|
|
@@ -1342,16 +1428,24 @@ class ue {
|
|
|
1342
1428
|
this.isSendingVideo = !0, i.disabled = !0, i.textContent = "Sending...";
|
|
1343
1429
|
const o = new FormData();
|
|
1344
1430
|
o.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), o.append("pageUrl", window.location.href), o.append("visitorId", this.visitorId), this.config.apiKey && o.append("apiKey", this.config.apiKey), t && o.append("message", t), this.consoleCapture && o.append("consoleErrors", JSON.stringify(this.consoleCapture.errors)), this.networkCapture && o.append("networkErrors", JSON.stringify(this.networkCapture.errors));
|
|
1431
|
+
let n = null;
|
|
1345
1432
|
try {
|
|
1346
|
-
const
|
|
1433
|
+
const s = await fetch(`${this.config.endpoint}/video`, {
|
|
1347
1434
|
method: "POST",
|
|
1348
1435
|
body: o
|
|
1349
1436
|
});
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1437
|
+
if (s.ok) {
|
|
1438
|
+
this.announceMsg("Recording sent");
|
|
1439
|
+
try {
|
|
1440
|
+
n = (await s.json())?.id ?? null;
|
|
1441
|
+
} catch {
|
|
1442
|
+
}
|
|
1443
|
+
} else
|
|
1444
|
+
console.error("Failed to submit video feedback:", await s.text()), this.announceMsg("Failed to send recording", !0);
|
|
1445
|
+
} catch (s) {
|
|
1446
|
+
console.error("Failed to submit video feedback:", s), this.announceMsg("Failed to send recording", !0);
|
|
1353
1447
|
}
|
|
1354
|
-
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording();
|
|
1448
|
+
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording(), await this.tryLaunchQuest("video", n);
|
|
1355
1449
|
}
|
|
1356
1450
|
cleanupRecording() {
|
|
1357
1451
|
this.isRecording = !1, this.removeRecordingIndicator(), this.videoRecorder && (this.videoRecorder.destroy(), this.videoRecorder = null), this.networkCapture && (this.networkCapture.restore(), this.networkCapture = null), this.recordedBlob && (this.recordedBlob = null), this.setButtonsDisabled(!1), this.overlayShadowHost && this.state === "IDLE" && (this.overlayShadowHost.style.pointerEvents = "none");
|
|
@@ -1366,13 +1460,13 @@ class ue {
|
|
|
1366
1460
|
* Destroy the embed and clean up all resources
|
|
1367
1461
|
*/
|
|
1368
1462
|
destroy() {
|
|
1369
|
-
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.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,
|
|
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();
|
|
1370
1464
|
}
|
|
1371
1465
|
}
|
|
1372
|
-
function
|
|
1466
|
+
function et(e) {
|
|
1373
1467
|
return document.querySelector(e)?.textContent?.trim() ?? "";
|
|
1374
1468
|
}
|
|
1375
|
-
function
|
|
1469
|
+
function Se() {
|
|
1376
1470
|
const e = document.querySelector(
|
|
1377
1471
|
'script[type="application/json"][data-feedback-config]'
|
|
1378
1472
|
);
|
|
@@ -1381,28 +1475,28 @@ function pe() {
|
|
|
1381
1475
|
if (!t) return null;
|
|
1382
1476
|
try {
|
|
1383
1477
|
const i = JSON.parse(t);
|
|
1384
|
-
return i.cssSelector && !i.css && (i.css =
|
|
1478
|
+
return i.cssSelector && !i.css && (i.css = et(i.cssSelector), delete i.cssSelector), i;
|
|
1385
1479
|
} catch {
|
|
1386
1480
|
return null;
|
|
1387
1481
|
}
|
|
1388
1482
|
}
|
|
1389
|
-
function
|
|
1483
|
+
function Te(e) {
|
|
1390
1484
|
const t = e.getAttribute("data-endpoint");
|
|
1391
1485
|
if (!t) return null;
|
|
1392
|
-
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"),
|
|
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"), l = e.getAttribute("data-container"), c = e.getAttribute("data-button-class"), r = e.getAttribute("data-skip-targeting"), d = e.getAttribute("data-incognito"), p = e.getAttribute("data-button-size"), u = e.getAttribute("data-offset-x"), m = e.getAttribute("data-offset-y"), g = e.getAttribute("data-modal-width"), b = e.getAttribute("data-backdrop-opacity"), f = e.getAttribute("data-font-family"), v = e.getAttribute("data-font-size"), h = e.getAttribute("data-tooltip"), y = e.getAttribute("data-modal-title"), R = e.getAttribute("data-modal-subtitle"), H = e.getAttribute("data-placeholder"), B = e.getAttribute("data-submit-button"), z = 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"), C = e.getAttribute("data-screenshot-quality"), E = e.getAttribute("data-screenshot-max-width"), S = e.getAttribute("data-screenshot-max-height"), at = e.getAttribute("data-capture-video"), rt = e.getAttribute("data-hide-thumbs"), dt = e.getAttribute("data-hide-dismiss"), P = e.getAttribute("data-video-max-duration"), lt = e.getAttribute("data-screenshot-method"), ct = e.getAttribute("data-direction"), $ = e.getAttribute("data-css-selector"), O = 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");
|
|
1393
1487
|
return {
|
|
1394
1488
|
endpoint: t,
|
|
1395
|
-
css:
|
|
1396
|
-
apiKey:
|
|
1397
|
-
captureScreenshot:
|
|
1398
|
-
screenshotOptions:
|
|
1399
|
-
quality:
|
|
1400
|
-
maxWidth:
|
|
1489
|
+
css: $ ? et($) : void 0,
|
|
1490
|
+
apiKey: nt ?? void 0,
|
|
1491
|
+
captureScreenshot: st === "true" ? !0 : void 0,
|
|
1492
|
+
screenshotOptions: C || E || S ? {
|
|
1493
|
+
quality: C ? parseFloat(C) : void 0,
|
|
1494
|
+
maxWidth: E ? parseInt(E, 10) : void 0,
|
|
1401
1495
|
maxHeight: S ? parseInt(S, 10) : void 0
|
|
1402
1496
|
} : void 0,
|
|
1403
|
-
container:
|
|
1404
|
-
buttonClass:
|
|
1405
|
-
direction:
|
|
1497
|
+
container: l ?? void 0,
|
|
1498
|
+
buttonClass: c ?? void 0,
|
|
1499
|
+
direction: ct ?? void 0,
|
|
1406
1500
|
position: i ?? void 0,
|
|
1407
1501
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1408
1502
|
skipTargeting: r === "true" ? !0 : void 0,
|
|
@@ -1421,39 +1515,47 @@ function me(e) {
|
|
|
1421
1515
|
negative: s ?? void 0,
|
|
1422
1516
|
marker: a ?? void 0
|
|
1423
1517
|
},
|
|
1424
|
-
text: h || y ||
|
|
1518
|
+
text: h || y || R || H || B || z ? {
|
|
1425
1519
|
tooltip: h ?? void 0,
|
|
1426
1520
|
modalTitle: y ?? void 0,
|
|
1427
|
-
modalSubtitle:
|
|
1428
|
-
placeholder:
|
|
1429
|
-
submitButton:
|
|
1430
|
-
skipButton:
|
|
1521
|
+
modalSubtitle: R ?? void 0,
|
|
1522
|
+
placeholder: H ?? void 0,
|
|
1523
|
+
submitButton: B ?? void 0,
|
|
1524
|
+
skipButton: z ?? void 0
|
|
1525
|
+
} : void 0,
|
|
1526
|
+
positiveIcon: it ?? void 0,
|
|
1527
|
+
negativeIcon: ot ?? void 0,
|
|
1528
|
+
screenshotMethod: lt ?? void 0,
|
|
1529
|
+
captureVideo: at === "true" ? !0 : void 0,
|
|
1530
|
+
hideThumbs: rt === "true" ? !0 : void 0,
|
|
1531
|
+
hideDismiss: dt === "true" ? !0 : void 0,
|
|
1532
|
+
videoOptions: P ? {
|
|
1533
|
+
maxDuration: parseInt(P, 10)
|
|
1431
1534
|
} : void 0,
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
maxDuration: parseInt(B, 10)
|
|
1535
|
+
quests: O ? {
|
|
1536
|
+
base: O,
|
|
1537
|
+
up: ht ?? void 0,
|
|
1538
|
+
down: ut ?? void 0,
|
|
1539
|
+
video: pt ?? void 0,
|
|
1540
|
+
apiKey: mt ?? void 0,
|
|
1541
|
+
moduleUrl: ft ?? void 0
|
|
1440
1542
|
} : void 0
|
|
1441
1543
|
};
|
|
1442
1544
|
}
|
|
1443
1545
|
if (typeof document < "u") {
|
|
1444
1546
|
const e = () => {
|
|
1445
|
-
const t = document.currentScript, i =
|
|
1446
|
-
n?.endpoint && new
|
|
1547
|
+
const t = document.currentScript, i = Se(), o = t ? Te(t) : null, n = i ?? o;
|
|
1548
|
+
n?.endpoint && new Ee(n);
|
|
1447
1549
|
};
|
|
1448
1550
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e();
|
|
1449
1551
|
}
|
|
1450
1552
|
export {
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1553
|
+
Ee as QaidFeedback,
|
|
1554
|
+
ge as captureDomScreenshot,
|
|
1555
|
+
de as captureNetworkErrors,
|
|
1556
|
+
he as createVideoRecorder,
|
|
1557
|
+
ce as getSupportedMimeType,
|
|
1558
|
+
Le as isDomScreenshotSupported,
|
|
1559
|
+
le as isVideoRecordingSupported
|
|
1458
1560
|
};
|
|
1459
1561
|
//# sourceMappingURL=qaid.js.map
|