@qaiddev/thumbs-embed 1.7.0 → 1.9.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 +77 -33
- package/dist/bootstrap.d.ts +4 -2
- package/dist/chunks/{annotate-CMq95aXG.js → annotate-D-o8xCV9.js} +23 -17
- package/dist/chunks/annotate-D-o8xCV9.js.map +1 -0
- package/dist/chunks/dom-DvdtcUS8.js +17 -0
- package/dist/chunks/dom-DvdtcUS8.js.map +1 -0
- package/dist/chunks/{loader-CYM1rxDH.js → loader-XbJ2b8KE.js} +229 -167
- package/dist/chunks/loader-XbJ2b8KE.js.map +1 -0
- package/dist/chunks/modal-XxYobTKE.js +213 -0
- package/dist/chunks/modal-XxYobTKE.js.map +1 -0
- package/dist/chunks/{recording-BVFd_ryf.js → recording-Dx8AX-BC.js} +103 -98
- package/dist/chunks/recording-Dx8AX-BC.js.map +1 -0
- package/dist/chunks/{screenshot-BkOCLuS2.js → screenshot-DYOKg2bS.js} +2 -2
- package/dist/chunks/{screenshot-BkOCLuS2.js.map → screenshot-DYOKg2bS.js.map} +1 -1
- package/dist/chunks/{targeting-1pK6nJI9.js → targeting-Dz6z1BYl.js} +2 -2
- package/dist/chunks/{targeting-1pK6nJI9.js.map → targeting-Dz6z1BYl.js.map} +1 -1
- package/dist/chunks/{video-BOYqf2Im.js → video-Bd_29-rK.js} +76 -71
- package/dist/chunks/video-Bd_29-rK.js.map +1 -0
- package/dist/embed.d.ts +11 -0
- package/dist/icons.d.ts +2 -0
- package/dist/index.js +599 -448
- package/dist/index.js.map +1 -1
- package/dist/loader.js +1 -1
- package/dist/modal.d.ts +14 -4
- package/dist/qaid.umd.cjs +14 -38
- package/dist/qaid.umd.cjs.map +1 -1
- package/dist/recording.d.ts +6 -0
- package/dist/screenshot.d.ts +1 -1
- package/dist/types.d.ts +14 -2
- package/dist/video-capture.d.ts +6 -0
- package/package.json +1 -1
- package/dist/chunks/annotate-CMq95aXG.js.map +0 -1
- package/dist/chunks/loader-CYM1rxDH.js.map +0 -1
- package/dist/chunks/modal-Br5x7m6f.js +0 -150
- package/dist/chunks/modal-Br5x7m6f.js.map +0 -1
- package/dist/chunks/recording-BVFd_ryf.js.map +0 -1
- package/dist/chunks/video-BOYqf2Im.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
const V = `<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>`, U = `<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>`, re = `<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>`,
|
|
7
|
+
</svg>`, St = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
8
8
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8 10h8M8 14h5m-9 6l3.5-3.5H18a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v14z"/>
|
|
9
|
-
</svg>`,
|
|
9
|
+
</svg>`, de = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
10
10
|
<rect x="4" y="6" width="16" height="12" rx="1" stroke-linejoin="round"/>
|
|
11
|
-
</svg>`,
|
|
11
|
+
</svg>`, ce = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
12
12
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 19L19 5m0 0h-8m8 0v8"/>
|
|
13
|
-
</svg>`,
|
|
13
|
+
</svg>`, le = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
14
14
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 20h9M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/>
|
|
15
|
-
</svg>`,
|
|
15
|
+
</svg>`, he = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
16
16
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3s6 6.4 6 10a6 6 0 01-12 0c0-3.6 6-10 6-10z"/>
|
|
17
|
-
</svg>`,
|
|
17
|
+
</svg>`, ue = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
18
18
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 14L4 9l5-5M4 9h11a5 5 0 010 10h-4"/>
|
|
19
|
-
</svg>`,
|
|
19
|
+
</svg>`, Et = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
20
20
|
<path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
|
|
21
|
-
</svg>`,
|
|
21
|
+
</svg>`, pe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
22
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v8m0 4h.01"/>
|
|
23
|
+
</svg>`, fe = `<svg xmlns="http://www.w3.org/2000/svg" class="qaid-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
22
24
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6l12 12M18 6L6 18"/>
|
|
23
|
-
</svg>`, ee = "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-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6366f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:1.125rem;font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:.875rem}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:1rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-btn-row{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-btn-submit{padding:.5rem 1rem;background:var(--qaid-marker);color:var(--qaid-marker-text, white);border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-btn-submit:hover{filter:brightness(.85)}button.qaid-btn-submit:focus{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 30%,transparent)}.qaid-bottom-sheet{position:fixed;bottom:0;left:0;right:0;z-index:50;animation:qaid-slideUpSheet .3s ease-out;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-bottom-sheet-content{background:light-dark(#ffffff,#1f2937);border-radius:1rem 1rem 0 0;padding:1.5rem;padding-bottom:max(1.5rem,env(safe-area-inset-bottom))}.qaid-bottom-sheet-handle{width:36px;height:4px;background:light-dark(rgba(0,0,0,.2),rgba(255,255,255,.2));border-radius:2px;margin:0 auto 1rem}@keyframes qaid-slideUpSheet{0%{transform:translateY(100%)}to{transform:translateY(0)}}button.qaid-btn-record:hover{background:#dc2626;color:#fff}.qaid-recording-indicator{position:fixed;top:12px;left:50%;transform:translate(-50%);display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:light-dark(#1f2937,#374151);color:#fff;border-radius:9999px;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:.875rem;font-weight:500;box-shadow:0 4px 12px #0000004d;z-index:99999;animation:qaid-slideDown .2s ease-out}.qaid-recording-dot{width:10px;height:10px;background:#dc2626;border-radius:50%;animation:qaid-dotPulse 1.5s ease-in-out infinite}@keyframes qaid-dotPulse{0%,to{opacity:1}50%{opacity:.3}}.qaid-recording-time{font-variant-numeric:tabular-nums;min-width:2.5rem;text-align:center}button.qaid-recording-stop{padding:.25rem .75rem;background:#dc2626;color:#fff;border:none;border-radius:9999px;font-size:.75rem;font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:1.125rem;font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:.875rem;resize:vertical;margin-bottom:1rem;box-sizing:border-box;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box textarea:focus{outline:none;border-color:var(--qaid-marker);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker) 20%,transparent)}.qaid-video-preview-actions{display:flex;gap:.5rem;justify-content:flex-end}button.qaid-video-btn{padding:.5rem 1rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:background-color .2s,filter .2s;-webkit-appearance:none;appearance:none}button.qaid-video-btn-cancel{background:light-dark(#f3f4f6,#374151);color:light-dark(#374151,#d1d5db)}button.qaid-video-btn-cancel:hover{background:light-dark(#e5e7eb,#4b5563)}button.qaid-video-btn-rerecord{background:light-dark(#fef3c7,#78350f);color:light-dark(#92400e,#fde68a)}button.qaid-video-btn-rerecord:hover{filter:brightness(.9)}button.qaid-video-btn-send{background:var(--qaid-marker);color:var(--qaid-marker-text, white)}button.qaid-video-btn-send:hover{filter:brightness(.85)}button.qaid-video-btn-send:disabled{opacity:.5;cursor:not-allowed}.qaid-video-sending{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:1rem;font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:.8125rem;line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:.8125rem;font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6366f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6366f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6366f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}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}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-title{margin:0;font-size:1rem;font-weight:600;color:var(--qaid-text, #111827)}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6366f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:.875rem;color:var(--qaid-text-muted, #6b7280)}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", ie = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
24
|
-
let
|
|
25
|
-
const
|
|
25
|
+
</svg>`, me = "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}:where(button.qaid-btn-structural)>svg:where(:not(.qaid-icon):not([width])){width:var(--qaid-icon-size, 24px);height:var(--qaid-icon-size, 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:var(--qaid-font-size, 16px);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, #6365f1);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-type-static{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, white)}.qaid-type-static svg{width:1.25rem;height:1.25rem}.qaid-modal-header-text{flex:1;min-width:0}.qaid-modal-title{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 .25rem;color:light-dark(#1f2937,#f9fafb)}.qaid-modal-subtitle{color:light-dark(#6b7280,#9ca3af);margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875)}.qaid-textarea{width:100%;height:6rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:var(--qaid-font-size, 16px);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:calc(var(--qaid-font-size, 16px) * .875);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:calc(var(--qaid-font-size, 16px) * .875);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:calc(var(--qaid-font-size, 16px) * .75);font-weight:600;cursor:pointer;transition:background-color .2s;-webkit-appearance:none;appearance:none}button.qaid-recording-stop:hover{background:#b91c1c}.qaid-video-preview{position:fixed;inset:0 0 auto;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#0009;z-index:99998;animation:qaid-fadeIn .2s ease-out}@keyframes qaid-fadeIn{0%{opacity:0}to{opacity:1}}.qaid-video-preview-box{color-scheme:inherit;background:light-dark(#ffffff,#1f2937);border-radius:1rem;padding:1.5rem;box-shadow:0 25px 50px -12px #00000080;width:560px;max-width:100%;max-height:100%;overflow-y:auto;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px)}.qaid-video-preview-box h3{font-size:calc(var(--qaid-font-size, 16px) * 1.125);font-weight:700;margin:0 0 1rem;color:light-dark(#1f2937,#f9fafb)}.qaid-video-preview-box video{width:100%;max-height:50vh;max-height:50dvh;object-fit:contain;border-radius:.5rem;background:#000;margin-bottom:1rem}.qaid-video-preview-box textarea{width:100%;height:4rem;padding:.75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .875);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-error{margin:0 0 .75rem;font-size:calc(var(--qaid-font-size, 16px) * .875);font-weight:500;color:light-dark(#b91c1c,#fca5a5)}.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:calc(var(--qaid-font-size, 16px) * .875);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:calc(var(--qaid-font-size, 16px) * .875);color:light-dark(#6b7280,#9ca3af)}.qaid-annotate{position:fixed;inset:0;z-index:2147483000;display:flex;flex-direction:column;gap:.75rem;padding:16px;padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom));box-sizing:border-box;background:#000000d9;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);animation:qaid-fadeIn .2s ease-out}.qaid-annotate-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:700;text-align:center;color:#f9fafb}.qaid-annotate-desc{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .8125);line-height:1.4;text-align:center;color:#f9fafbbf}.qaid-annotate-stage{flex:1 1 auto;min-height:0;display:flex;align-items:center;justify-content:center;overflow:auto}.qaid-annotate-canvas{max-width:100%;max-height:100%;object-fit:contain;background:light-dark(#ffffff,#111827);border-radius:.5rem;box-shadow:0 10px 30px #00000080;touch-action:none;cursor:crosshair}.qaid-annotate-toolbar{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;justify-content:center;padding:.5rem .75rem;background:light-dark(#ffffff,#1f2937);border-radius:.75rem;box-shadow:0 10px 30px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.5))}.qaid-annotate-tools,.qaid-annotate-actions{display:flex;gap:.375rem;align-items:center}button.qaid-annotate-tool,button.qaid-annotate-action{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;min-width:44px;min-height:44px;padding:0 .75rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.5rem;background:light-dark(#f9fafb,#111827);color:light-dark(#1f2937,#f9fafb);font-family:inherit;font-size:calc(var(--qaid-font-size, 16px) * .8125);font-weight:600;cursor:pointer;-webkit-appearance:none;appearance:none;transition:background-color .15s,color .15s,border-color .15s,filter .15s}button.qaid-annotate-tool svg,button.qaid-annotate-action svg{width:20px;height:20px}.qaid-annotate-colors{display:flex;gap:.25rem;align-items:center}button.qaid-annotate-swatch{width:28px;height:28px;min-width:28px;padding:0;border-radius:9999px;border:2px solid light-dark(#d1d5db,#4b5563);background:var(--qaid-swatch, #000);cursor:pointer;-webkit-appearance:none;appearance:none;transition:transform .1s,box-shadow .15s,border-color .15s}button.qaid-annotate-swatch:hover{transform:scale(1.12)}button.qaid-annotate-swatch[aria-pressed=true]{border-color:light-dark(#111827,#f9fafb);box-shadow:0 0 0 2px var(--qaid-swatch)}@media(forced-colors:active){button.qaid-annotate-swatch[aria-pressed=true]{outline:2px solid Highlight;outline-offset:1px}}button.qaid-annotate-tool:hover,button.qaid-annotate-action:hover{background:light-dark(#eef2ff,#312e81)}button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{background:var(--qaid-marker, #6365f1);color:var(--qaid-marker-text, #fff);border-color:var(--qaid-marker, #6365f1)}button.qaid-annotate-done:hover{filter:brightness(.9);background:var(--qaid-marker, #6365f1)}button.qaid-annotate-action:disabled{opacity:.45;cursor:not-allowed}@media(forced-colors:active){button.qaid-annotate-tool[aria-pressed=true],button.qaid-annotate-done{border:2px solid Highlight}.qaid-annotate-canvas{border:1px solid CanvasText}}button:focus-visible,textarea:focus-visible,a:focus-visible,[tabindex]:focus-visible,[role=button]:focus-visible{outline:2px solid var(--qaid-marker, #6365f1);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, #6365f1);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}}.qaid-confirm{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:.5rem 0}.qaid-confirm-icon{display:flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:9999px;color:#fff;background:var(--qaid-success, #22c55e);margin-bottom:.25rem;animation:qaid-confirm-pop .28s cubic-bezier(.34,1.56,.64,1)}.qaid-confirm-icon .qaid-icon{width:24px;height:24px}.qaid-confirm-error .qaid-confirm-icon{background:var(--qaid-error, #dc2626)}.qaid-confirm-title{margin:0;font-size:var(--qaid-font-size, 16px);font-weight:600;color:var(--qaid-text, light-dark(#111827, #f9fafb))}.qaid-confirm-title:focus-visible{outline:2px solid var(--qaid-primary, #6365f1);outline-offset:3px;border-radius:4px}.qaid-confirm-message{margin:0;font-size:calc(var(--qaid-font-size, 16px) * .875);color:var(--qaid-text-muted, light-dark(#6b7280, #9ca3af))}.qaid-confirm .qaid-confirm-close{margin-top:.5rem;min-width:96px}@keyframes qaid-confirm-pop{0%{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.qaid-confirm-icon{animation:none}}", be = "body.qaid-targeting,body.qaid-targeting *{cursor:none!important}";
|
|
26
|
+
let D = 0;
|
|
27
|
+
const ge = "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-feedback:hover{background:var(--qaid-marker,#6365f1);color:var(--qaid-marker-text,#fff)}button.qaid-btn svg{width:var(--qaid-icon-size);height:var(--qaid-icon-size)}", ve = {
|
|
26
28
|
small: 36,
|
|
27
29
|
medium: 48,
|
|
28
30
|
large: 64
|
|
29
|
-
},
|
|
31
|
+
}, ye = {
|
|
30
32
|
small: 18,
|
|
31
33
|
medium: 24,
|
|
32
34
|
large: 32
|
|
33
35
|
};
|
|
34
|
-
function
|
|
36
|
+
function we(i, t, e) {
|
|
35
37
|
const [o, n, s] = [i, t, e].map((a) => (a = a / 255, a <= 0.03928 ? a / 12.92 : Math.pow((a + 0.055) / 1.055, 2.4)));
|
|
36
38
|
return 0.2126 * o + 0.7152 * n + 0.0722 * s;
|
|
37
39
|
}
|
|
38
|
-
function
|
|
40
|
+
function ke(i) {
|
|
39
41
|
if (i.startsWith("#")) {
|
|
40
42
|
const e = i.slice(1), o = e.length === 3 ? e.split("").map((s) => s + s).join("") : e, n = parseInt(o, 16);
|
|
41
43
|
return {
|
|
@@ -51,21 +53,21 @@ function re(i) {
|
|
|
51
53
|
b: parseInt(t[3])
|
|
52
54
|
} : null;
|
|
53
55
|
}
|
|
54
|
-
function
|
|
55
|
-
const t =
|
|
56
|
-
return t &&
|
|
56
|
+
function xe(i) {
|
|
57
|
+
const t = ke(i);
|
|
58
|
+
return t && we(t.r, t.g, t.b) > 0.4 ? "black" : "white";
|
|
57
59
|
}
|
|
58
|
-
function
|
|
60
|
+
function qe(i = {}) {
|
|
59
61
|
const {
|
|
60
62
|
positiveColor: t = "rgb(0, 200, 83)",
|
|
61
63
|
negativeColor: e = "rgb(255, 0, 0)",
|
|
62
|
-
markerColor: o = "#
|
|
64
|
+
markerColor: o = "#6365f1",
|
|
63
65
|
buttonSize: n = "medium",
|
|
64
66
|
modalWidth: s = 400,
|
|
65
67
|
backdropOpacity: a = 0.3,
|
|
66
68
|
fontFamily: c = "system-ui, -apple-system, sans-serif",
|
|
67
69
|
fontSize: l = 16
|
|
68
|
-
} = i, d =
|
|
70
|
+
} = i, d = ve[n], r = ye[n], h = xe(o);
|
|
69
71
|
return {
|
|
70
72
|
"--qaid-positive": t,
|
|
71
73
|
"--qaid-negative": e,
|
|
@@ -79,22 +81,22 @@ function ce(i = {}) {
|
|
|
79
81
|
"--qaid-font-size": `${l}px`
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
|
-
function
|
|
84
|
+
function Ce(i, t) {
|
|
83
85
|
for (const [e, o] of Object.entries(t))
|
|
84
86
|
i.style.setProperty(e, o);
|
|
85
87
|
}
|
|
86
|
-
function
|
|
87
|
-
return
|
|
88
|
+
function at() {
|
|
89
|
+
return me + ge;
|
|
88
90
|
}
|
|
89
|
-
function
|
|
90
|
-
if (
|
|
91
|
+
function Se() {
|
|
92
|
+
if (D++, D > 1) return;
|
|
91
93
|
const i = document.createElement("style");
|
|
92
|
-
i.id = "qaid-styles", i.textContent =
|
|
94
|
+
i.id = "qaid-styles", i.textContent = be, document.head.appendChild(i);
|
|
93
95
|
}
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
+
function Ee() {
|
|
97
|
+
D <= 0 || (D--, D === 0 && document.getElementById("qaid-styles")?.remove());
|
|
96
98
|
}
|
|
97
|
-
const
|
|
99
|
+
const rt = "data-qaid-a11y-live", Te = "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;", Ae = [
|
|
98
100
|
"a[href]",
|
|
99
101
|
"button",
|
|
100
102
|
"input",
|
|
@@ -102,25 +104,25 @@ const tt = "data-qaid-a11y-live", pe = "position:absolute;width:1px;height:1px;m
|
|
|
102
104
|
"select",
|
|
103
105
|
"[tabindex]"
|
|
104
106
|
].join(",");
|
|
105
|
-
function
|
|
107
|
+
function Ie(i) {
|
|
106
108
|
return i.ownerDocument || document;
|
|
107
109
|
}
|
|
108
|
-
function
|
|
110
|
+
function Le(i, t) {
|
|
109
111
|
const e = t ? "assertive" : "polite", o = i.querySelector(
|
|
110
|
-
`[${
|
|
112
|
+
`[${rt}="${e}"]`
|
|
111
113
|
);
|
|
112
114
|
if (o) return o;
|
|
113
|
-
const s =
|
|
114
|
-
return s.setAttribute(
|
|
115
|
+
const s = Ie(i).createElement("div");
|
|
116
|
+
return s.setAttribute(rt, e), s.setAttribute("role", t ? "alert" : "status"), s.setAttribute("aria-live", t ? "assertive" : "polite"), s.setAttribute("aria-atomic", "true"), s.style.cssText = Te, i.appendChild(s), s;
|
|
115
117
|
}
|
|
116
|
-
function
|
|
117
|
-
const o =
|
|
118
|
+
function De(i, t, e = {}) {
|
|
119
|
+
const o = Le(i, !!e.assertive);
|
|
118
120
|
o.textContent = "", o.textContent = t;
|
|
119
121
|
}
|
|
120
|
-
function
|
|
122
|
+
function Me(i) {
|
|
121
123
|
return i.hasAttribute("disabled") ? !0 : i.disabled === !0;
|
|
122
124
|
}
|
|
123
|
-
function
|
|
125
|
+
function Re(i) {
|
|
124
126
|
let t = i;
|
|
125
127
|
for (; t; ) {
|
|
126
128
|
if (t.hasAttribute("hidden")) return !0;
|
|
@@ -131,52 +133,52 @@ function ye(i) {
|
|
|
131
133
|
}
|
|
132
134
|
return !1;
|
|
133
135
|
}
|
|
134
|
-
function
|
|
136
|
+
function dt(i) {
|
|
135
137
|
return Array.from(
|
|
136
|
-
i.querySelectorAll(
|
|
137
|
-
).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") ||
|
|
138
|
+
i.querySelectorAll(Ae)
|
|
139
|
+
).filter((e) => !(e.getAttribute("tabindex") === "-1" || e instanceof HTMLInputElement && e.type === "hidden" || e instanceof HTMLAnchorElement && !e.getAttribute("href") || Me(e) || Re(e)));
|
|
138
140
|
}
|
|
139
|
-
function
|
|
141
|
+
function Tt(i) {
|
|
140
142
|
let t = i.activeElement;
|
|
141
143
|
for (; t && t.shadowRoot && t.shadowRoot.activeElement; )
|
|
142
144
|
t = t.shadowRoot.activeElement;
|
|
143
145
|
return t instanceof HTMLElement ? t : null;
|
|
144
146
|
}
|
|
145
|
-
function
|
|
147
|
+
function Pe(i) {
|
|
146
148
|
const t = i.ownerDocument || document;
|
|
147
149
|
let e = !1;
|
|
148
150
|
const o = (s) => {
|
|
149
151
|
if (s.key !== "Tab") return;
|
|
150
|
-
const a =
|
|
152
|
+
const a = dt(i);
|
|
151
153
|
if (a.length === 0) {
|
|
152
154
|
s.preventDefault(), i.focus();
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
|
-
const c = a[0], l = a[a.length - 1], d =
|
|
157
|
+
const c = a[0], l = a[a.length - 1], d = Tt(t), r = d ? a.indexOf(d) !== -1 : !1;
|
|
156
158
|
s.shiftKey ? (!r || d === c) && (s.preventDefault(), l.focus()) : (!r || d === l) && (s.preventDefault(), c.focus());
|
|
157
159
|
};
|
|
158
160
|
i.addEventListener("keydown", o);
|
|
159
|
-
const n =
|
|
161
|
+
const n = dt(i);
|
|
160
162
|
return n.length > 0 ? n[0].focus() : (i.hasAttribute("tabindex") || (i.setAttribute("tabindex", "-1"), e = !0), i.focus()), {
|
|
161
163
|
release() {
|
|
162
164
|
i.removeEventListener("keydown", o), e && (i.removeAttribute("tabindex"), e = !1);
|
|
163
165
|
}
|
|
164
166
|
};
|
|
165
167
|
}
|
|
166
|
-
function
|
|
167
|
-
return
|
|
168
|
+
function Be() {
|
|
169
|
+
return Tt(document);
|
|
168
170
|
}
|
|
169
|
-
function
|
|
171
|
+
function He(i) {
|
|
170
172
|
if (!(!i || typeof i.focus != "function"))
|
|
171
173
|
try {
|
|
172
174
|
i.focus();
|
|
173
175
|
} catch {
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
|
-
function
|
|
178
|
+
function Oe(i, t = {}) {
|
|
177
179
|
i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "true"), t.labelledbyId && i.setAttribute("aria-labelledby", t.labelledbyId), t.describedbyId && i.setAttribute("aria-describedby", t.describedbyId), t.label && i.setAttribute("aria-label", t.label);
|
|
178
180
|
}
|
|
179
|
-
function
|
|
181
|
+
function ze(i, t) {
|
|
180
182
|
let e = i;
|
|
181
183
|
for (; e && e !== t; ) {
|
|
182
184
|
const o = e.parentNode;
|
|
@@ -190,11 +192,11 @@ function Ce(i, t) {
|
|
|
190
192
|
}
|
|
191
193
|
return null;
|
|
192
194
|
}
|
|
193
|
-
function
|
|
195
|
+
function $e(i) {
|
|
194
196
|
const e = (i.ownerDocument || document).body;
|
|
195
197
|
if (!e) return () => {
|
|
196
198
|
};
|
|
197
|
-
const o =
|
|
199
|
+
const o = ze(i, e), n = [];
|
|
198
200
|
return Array.from(e.children).forEach((s) => {
|
|
199
201
|
if (!(s instanceof HTMLElement) || o && s === o) return;
|
|
200
202
|
const a = s.inert === !0, c = s.getAttribute("aria-hidden");
|
|
@@ -206,14 +208,14 @@ function Se(i) {
|
|
|
206
208
|
}
|
|
207
209
|
};
|
|
208
210
|
}
|
|
209
|
-
const
|
|
211
|
+
const At = {
|
|
210
212
|
width: 400,
|
|
211
213
|
height: 280,
|
|
212
214
|
arrowHeight: 12,
|
|
213
215
|
gap: 8,
|
|
214
216
|
viewportPadding: 16
|
|
215
217
|
};
|
|
216
|
-
function
|
|
218
|
+
function _e(i, t, e, o, n) {
|
|
217
219
|
const s = i.y, a = t - (i.y + i.height);
|
|
218
220
|
if (a >= e + o)
|
|
219
221
|
return {
|
|
@@ -232,22 +234,22 @@ function Ee(i, t, e, o, n) {
|
|
|
232
234
|
t - e - n
|
|
233
235
|
) : l = Math.max(n, i.y - e - o), { top: l, position: c };
|
|
234
236
|
}
|
|
235
|
-
function
|
|
237
|
+
function Ne(i, t, e, o) {
|
|
236
238
|
let s = i.x + i.width / 2 - e / 2;
|
|
237
239
|
return s = Math.max(o, Math.min(s, t - e - o)), s;
|
|
238
240
|
}
|
|
239
|
-
function
|
|
241
|
+
function Fe(i, t, e, o = 24, n = 24) {
|
|
240
242
|
const a = i.clickX - t - n / 2;
|
|
241
243
|
return Math.max(o, Math.min(a, e - o - n / 2));
|
|
242
244
|
}
|
|
243
|
-
function
|
|
244
|
-
const n = o.height + o.arrowHeight, s =
|
|
245
|
+
function Ve(i, t, e, o = At) {
|
|
246
|
+
const n = o.height + o.arrowHeight, s = _e(
|
|
245
247
|
i,
|
|
246
248
|
e,
|
|
247
249
|
n,
|
|
248
250
|
o.gap,
|
|
249
251
|
o.viewportPadding
|
|
250
|
-
), a =
|
|
252
|
+
), a = Ne(
|
|
251
253
|
i,
|
|
252
254
|
t,
|
|
253
255
|
o.width,
|
|
@@ -259,15 +261,15 @@ function Le(i, t, e, o = wt) {
|
|
|
259
261
|
position: s.position
|
|
260
262
|
};
|
|
261
263
|
}
|
|
262
|
-
function
|
|
264
|
+
function Ue(i, t, e, o = {}) {
|
|
263
265
|
const n = o.gap ?? 8;
|
|
264
266
|
let s = i.bottom + n;
|
|
265
267
|
s + t.height > e.height - n && (s = i.top - t.height - n);
|
|
266
268
|
let a = i.left;
|
|
267
269
|
return a < n ? a = n : a + t.width > e.width - n && (a = e.width - t.width - n), s < n ? s = n : s + t.height > e.height - n && (s = e.height - t.height - n), { top: s, left: a };
|
|
268
270
|
}
|
|
269
|
-
function
|
|
270
|
-
const n =
|
|
271
|
+
function je(i, t, e, o = At) {
|
|
272
|
+
const n = Ve(i, t, e, o), s = Fe(
|
|
271
273
|
i,
|
|
272
274
|
n.left,
|
|
273
275
|
o.width
|
|
@@ -277,15 +279,15 @@ function De(i, t, e, o = wt) {
|
|
|
277
279
|
arrow: { left: s }
|
|
278
280
|
};
|
|
279
281
|
}
|
|
280
|
-
const
|
|
281
|
-
function
|
|
282
|
+
const Ke = 20;
|
|
283
|
+
function We(i) {
|
|
282
284
|
const t = [], e = console.error, o = console.warn, n = console.log, s = (a, c) => {
|
|
283
285
|
const l = {
|
|
284
286
|
message: c.map((d) => String(d)).join(" "),
|
|
285
287
|
timestamp: Date.now(),
|
|
286
288
|
level: a
|
|
287
289
|
};
|
|
288
|
-
t.length >=
|
|
290
|
+
t.length >= Ke && t.shift(), t.push(l), i && i(l);
|
|
289
291
|
};
|
|
290
292
|
return console.error = function(...a) {
|
|
291
293
|
s("error", a), e.apply(console, a);
|
|
@@ -307,19 +309,19 @@ function q(i, t, e) {
|
|
|
307
309
|
n === "className" ? o.className = s : o.setAttribute(n, s);
|
|
308
310
|
return o;
|
|
309
311
|
}
|
|
310
|
-
function
|
|
312
|
+
function Xe(i = 640) {
|
|
311
313
|
return typeof window < "u" && window.innerWidth < i;
|
|
312
314
|
}
|
|
313
|
-
function
|
|
315
|
+
function ct(i, t, e) {
|
|
314
316
|
const o = e.map((s) => s.style.visibility);
|
|
315
317
|
e.forEach((s) => s.style.visibility = "hidden");
|
|
316
318
|
const n = document.elementFromPoint(i, t);
|
|
317
319
|
return e.forEach((s, a) => s.style.visibility = o[a]), n;
|
|
318
320
|
}
|
|
319
|
-
function
|
|
321
|
+
function R(i) {
|
|
320
322
|
return i ? i.hasAttribute("data-qaid-embed") || i.hasAttribute("data-qaid-embed-overlay") ? !0 : !!i.closest("[data-qaid-embed], [data-qaid-embed-overlay]") : !1;
|
|
321
323
|
}
|
|
322
|
-
function
|
|
324
|
+
function lt(i, t = 0) {
|
|
323
325
|
const e = i.getBoundingClientRect();
|
|
324
326
|
return {
|
|
325
327
|
x: e.left - t,
|
|
@@ -328,7 +330,7 @@ function ot(i, t = 0) {
|
|
|
328
330
|
height: e.height + t * 2
|
|
329
331
|
};
|
|
330
332
|
}
|
|
331
|
-
const
|
|
333
|
+
const Ye = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", Qe = (i) => (
|
|
332
334
|
// The URL is a runtime value, not a static specifier — keep Vite from
|
|
333
335
|
// trying to analyze/bundle it.
|
|
334
336
|
import(
|
|
@@ -336,19 +338,19 @@ const Be = "https://unpkg.com/@qaiddev/quests-embed@1/dist/qaid-quests.js", He =
|
|
|
336
338
|
i
|
|
337
339
|
)
|
|
338
340
|
);
|
|
339
|
-
let
|
|
340
|
-
function
|
|
341
|
-
return
|
|
341
|
+
let Je = Qe, I = null, N = null;
|
|
342
|
+
function Ge(i) {
|
|
343
|
+
return I && N === i || (N = i, I = Promise.resolve(Je(i)).then((t) => {
|
|
342
344
|
const e = t;
|
|
343
345
|
if (!e || typeof e.QaidQuests != "function")
|
|
344
346
|
throw new Error("quests module has no QaidQuests export");
|
|
345
347
|
return e;
|
|
346
348
|
}).catch((t) => {
|
|
347
|
-
throw
|
|
348
|
-
})),
|
|
349
|
+
throw I = null, N = null, t;
|
|
350
|
+
})), I;
|
|
349
351
|
}
|
|
350
|
-
async function
|
|
351
|
-
const t = await
|
|
352
|
+
async function Ze(i) {
|
|
353
|
+
const t = await Ge(i.moduleUrl), e = i.base.replace(/\/+$/, ""), o = i.feedbackId != null ? { feedbackId: i.feedbackId } : void 0;
|
|
352
354
|
return new t.QaidQuests({
|
|
353
355
|
endpoint: `${e}/responses`,
|
|
354
356
|
configUrl: `${e}/${encodeURIComponent(i.questId)}/definition`,
|
|
@@ -357,7 +359,7 @@ async function ze(i) {
|
|
|
357
359
|
onClose: i.onClose
|
|
358
360
|
});
|
|
359
361
|
}
|
|
360
|
-
const
|
|
362
|
+
const ht = "qaid_visitor_id", ut = "qaid_hide_feedback", ti = [
|
|
361
363
|
"#ef4444",
|
|
362
364
|
"#f59e0b",
|
|
363
365
|
"#22c55e",
|
|
@@ -365,34 +367,46 @@ const nt = "qaid_visitor_id", st = "qaid_hide_feedback", _e = [
|
|
|
365
367
|
"#111827",
|
|
366
368
|
"#ffffff"
|
|
367
369
|
];
|
|
368
|
-
function
|
|
370
|
+
function ei() {
|
|
369
371
|
return typeof window.matchMedia == "function" && window.matchMedia("(pointer: coarse)").matches;
|
|
370
372
|
}
|
|
371
|
-
function
|
|
372
|
-
return i ? `${
|
|
373
|
+
function j(i) {
|
|
374
|
+
return i ? `${ut}_${i}` : ut;
|
|
373
375
|
}
|
|
374
|
-
function
|
|
376
|
+
function ii(i) {
|
|
375
377
|
try {
|
|
376
|
-
return localStorage.getItem(
|
|
378
|
+
return localStorage.getItem(j(i)) === "1";
|
|
377
379
|
} catch {
|
|
378
380
|
return !1;
|
|
379
381
|
}
|
|
380
382
|
}
|
|
381
|
-
function
|
|
383
|
+
function pt(i, t = !0) {
|
|
382
384
|
try {
|
|
383
|
-
t ? localStorage.setItem(
|
|
385
|
+
t ? localStorage.setItem(j(i), "1") : localStorage.removeItem(j(i));
|
|
384
386
|
} catch {
|
|
385
387
|
}
|
|
386
388
|
}
|
|
387
|
-
function
|
|
389
|
+
function ft() {
|
|
390
|
+
const i = typeof crypto < "u" ? crypto : void 0;
|
|
391
|
+
if (i && typeof i.randomUUID == "function") return i.randomUUID();
|
|
392
|
+
const t = new Uint8Array(16);
|
|
393
|
+
if (i && typeof i.getRandomValues == "function")
|
|
394
|
+
i.getRandomValues(t);
|
|
395
|
+
else
|
|
396
|
+
for (let o = 0; o < t.length; o++) t[o] = Math.floor(Math.random() * 256);
|
|
397
|
+
t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
|
|
398
|
+
const e = Array.from(t, (o) => o.toString(16).padStart(2, "0")).join("");
|
|
399
|
+
return `${e.slice(0, 8)}-${e.slice(8, 12)}-${e.slice(12, 16)}-${e.slice(16, 20)}-${e.slice(20)}`;
|
|
400
|
+
}
|
|
401
|
+
function oi() {
|
|
388
402
|
try {
|
|
389
|
-
let i = localStorage.getItem(
|
|
390
|
-
return i || (i =
|
|
403
|
+
let i = localStorage.getItem(ht);
|
|
404
|
+
return i || (i = ft(), localStorage.setItem(ht, i)), i;
|
|
391
405
|
} catch {
|
|
392
|
-
return
|
|
406
|
+
return ft();
|
|
393
407
|
}
|
|
394
408
|
}
|
|
395
|
-
class
|
|
409
|
+
class ni {
|
|
396
410
|
config;
|
|
397
411
|
state = "IDLE";
|
|
398
412
|
feedbackData = {
|
|
@@ -481,7 +495,7 @@ class Ue {
|
|
|
481
495
|
colors: {
|
|
482
496
|
positive: t.colors?.positive ?? "rgb(0, 200, 83)",
|
|
483
497
|
negative: t.colors?.negative ?? "rgb(255, 0, 0)",
|
|
484
|
-
marker: t.colors?.marker ?? "#
|
|
498
|
+
marker: t.colors?.marker ?? "#6365f1"
|
|
485
499
|
},
|
|
486
500
|
buttonSize: t.buttonSize ?? "medium",
|
|
487
501
|
text: {
|
|
@@ -498,7 +512,9 @@ class Ue {
|
|
|
498
512
|
feedbackLabel: t.text?.feedbackLabel ?? "Send feedback",
|
|
499
513
|
confirmationTitle: t.text?.confirmationTitle ?? "Thank you!",
|
|
500
514
|
confirmationMessage: t.text?.confirmationMessage ?? "Your feedback has been received.",
|
|
501
|
-
confirmationClose: t.text?.confirmationClose ?? "Close"
|
|
515
|
+
confirmationClose: t.text?.confirmationClose ?? "Close",
|
|
516
|
+
errorTitle: t.text?.errorTitle ?? "Message not sent",
|
|
517
|
+
errorMessage: t.text?.errorMessage ?? "Something went wrong, so we did not get your message. Please try again later."
|
|
502
518
|
},
|
|
503
519
|
hideConfirmation: t.hideConfirmation ?? !1,
|
|
504
520
|
modalWidth: t.modalWidth ?? 400,
|
|
@@ -507,8 +523,8 @@ class Ue {
|
|
|
507
523
|
fontSize: t.fontSize ?? 16,
|
|
508
524
|
captureScreenshot: t.captureScreenshot ?? !1,
|
|
509
525
|
annotate: t.annotate ?? !0,
|
|
510
|
-
annotationColor: t.annotationColor ?? t.colors?.marker ?? "#
|
|
511
|
-
annotationPalette: t.annotationPalette ??
|
|
526
|
+
annotationColor: t.annotationColor ?? t.colors?.marker ?? "#6365f1",
|
|
527
|
+
annotationPalette: t.annotationPalette ?? ti,
|
|
512
528
|
screenshotMethod: t.screenshotMethod ?? "permission",
|
|
513
529
|
screenshotOptions: {
|
|
514
530
|
quality: t.screenshotOptions?.quality ?? 0.8,
|
|
@@ -535,12 +551,12 @@ class Ue {
|
|
|
535
551
|
video: t.quests?.video ?? "",
|
|
536
552
|
// Quest service reuses the feedback API key unless overridden.
|
|
537
553
|
apiKey: t.quests?.apiKey ?? t.apiKey ?? "",
|
|
538
|
-
moduleUrl: t.quests?.moduleUrl ??
|
|
554
|
+
moduleUrl: t.quests?.moduleUrl ?? Ye
|
|
539
555
|
}
|
|
540
|
-
}, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId =
|
|
556
|
+
}, this.boundKeyDown = this.handleKeyDown.bind(this), this.boundResize = this.handleResize.bind(this), this.visitorId = oi(), this.init();
|
|
541
557
|
}
|
|
542
558
|
applyVars(t) {
|
|
543
|
-
|
|
559
|
+
Ce(t, this.cssVars);
|
|
544
560
|
}
|
|
545
561
|
/**
|
|
546
562
|
* Announce a message via the shared visually-hidden live regions.
|
|
@@ -550,7 +566,7 @@ class Ue {
|
|
|
550
566
|
*/
|
|
551
567
|
announceMsg(t, e = !1) {
|
|
552
568
|
const o = this.overlayShadowRoot ?? this.shadowRoot;
|
|
553
|
-
o &&
|
|
569
|
+
o && De(o, t, { assertive: e });
|
|
554
570
|
}
|
|
555
571
|
/**
|
|
556
572
|
* Turn a transient surface into an accessible modal dialog: save the
|
|
@@ -558,16 +574,16 @@ class Ue {
|
|
|
558
574
|
* background. Paired with closeDialogA11y() on every close path.
|
|
559
575
|
*/
|
|
560
576
|
openDialogA11y(t, e) {
|
|
561
|
-
this.dialogTrigger =
|
|
577
|
+
this.dialogTrigger = Be(), Oe(t, e), this.dialogTrap = Pe(t), this.dialogRestoreInert = $e(t);
|
|
562
578
|
}
|
|
563
579
|
closeDialogA11y() {
|
|
564
|
-
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null),
|
|
580
|
+
this.dialogTrap?.release(), this.dialogTrap = null, this.dialogRestoreInert && (this.dialogRestoreInert(), this.dialogRestoreInert = null), He(this.dialogTrigger), this.dialogTrigger = null;
|
|
565
581
|
}
|
|
566
582
|
clearActiveThumb() {
|
|
567
583
|
this.activeThumbBtn && (this.activeThumbBtn.setAttribute("aria-pressed", "false"), this.activeThumbBtn = null);
|
|
568
584
|
}
|
|
569
585
|
init() {
|
|
570
|
-
|
|
586
|
+
Se(), this.cssVars = qe({
|
|
571
587
|
positiveColor: this.config.colors.positive,
|
|
572
588
|
negativeColor: this.config.colors.negative,
|
|
573
589
|
markerColor: this.config.colors.marker,
|
|
@@ -576,7 +592,7 @@ class Ue {
|
|
|
576
592
|
backdropOpacity: this.config.backdropOpacity,
|
|
577
593
|
fontFamily: this.config.fontFamily,
|
|
578
594
|
fontSize: this.config.fontSize
|
|
579
|
-
}), !this.config.hideDismiss &&
|
|
595
|
+
}), !this.config.hideDismiss && ii(this.config.apiKey) && (this._startDismissed = !0), this.checkMobile(), window.addEventListener("resize", this.boundResize), this.createEmbed(), this.consoleCapture = We((t) => {
|
|
580
596
|
this.feedbackData.consoleErrors = this.consoleCapture?.errors ?? [];
|
|
581
597
|
}), this.feedbackData.consoleErrors = this.consoleCapture.errors, this.observeDom(), (this.config.captureVideo && this.videoSupported() || this.config.captureScreenshot) && this.schedulePrewarm(() => {
|
|
582
598
|
this.config.captureVideo && this.videoSupported() && this.prewarmVideo(), this.config.captureScreenshot && this.prewarmScreenshot();
|
|
@@ -589,13 +605,13 @@ class Ue {
|
|
|
589
605
|
* swallowed — a failed preload just falls back to an on-demand load.
|
|
590
606
|
*/
|
|
591
607
|
prewarmVideo() {
|
|
592
|
-
this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() =>
|
|
593
|
-
}), Promise.resolve().then(() =>
|
|
608
|
+
this.videoPrewarmed || (this.videoPrewarmed = !0, Promise.resolve().then(() => kt).catch(() => {
|
|
609
|
+
}), Promise.resolve().then(() => Bt).catch(() => {
|
|
594
610
|
}));
|
|
595
611
|
}
|
|
596
612
|
prewarmScreenshot() {
|
|
597
|
-
this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() =>
|
|
598
|
-
}), this.config.annotate && Promise.resolve().then(() =>
|
|
613
|
+
this.screenshotPrewarmed || (this.screenshotPrewarmed = !0, (this.shouldCaptureViaDom() ? Promise.resolve().then(() => vt) : Promise.resolve().then(() => xt)).catch(() => {
|
|
614
|
+
}), this.config.annotate && Promise.resolve().then(() => wt).catch(() => {
|
|
599
615
|
}));
|
|
600
616
|
}
|
|
601
617
|
/** Run fn when the main thread is idle; cancelled by destroy(). */
|
|
@@ -624,7 +640,7 @@ class Ue {
|
|
|
624
640
|
}), this.domObserver.observe(document.body, { childList: !0 });
|
|
625
641
|
}
|
|
626
642
|
checkMobile() {
|
|
627
|
-
this.isMobile =
|
|
643
|
+
this.isMobile = Xe();
|
|
628
644
|
}
|
|
629
645
|
handleResize() {
|
|
630
646
|
this.checkMobile();
|
|
@@ -634,7 +650,7 @@ class Ue {
|
|
|
634
650
|
let t = null;
|
|
635
651
|
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" });
|
|
636
652
|
const e = document.createElement("style");
|
|
637
|
-
if (e.textContent =
|
|
653
|
+
if (e.textContent = at(), this.shadowRoot.appendChild(e), this.config.css) {
|
|
638
654
|
const d = document.createElement("style");
|
|
639
655
|
d.textContent = this.config.css, this.shadowRoot.appendChild(d);
|
|
640
656
|
}
|
|
@@ -658,7 +674,7 @@ class Ue {
|
|
|
658
674
|
const d = document.createElement("div");
|
|
659
675
|
d.className = "qaid-tooltip-wrapper";
|
|
660
676
|
const r = document.createElement("button");
|
|
661
|
-
r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon ||
|
|
677
|
+
r.type = "button", r.className = n ? `${s} qaid-btn-feedback` : "qaid-btn qaid-btn-feedback", r.setAttribute("aria-label", this.config.text.feedbackLabel), r.innerHTML = this.config.feedbackIcon || St, r.addEventListener("click", (h) => this.handleThumbClick("neutral", h.currentTarget, h)), r.addEventListener("mouseenter", () => {
|
|
662
678
|
this.prewarmTargeting(), this.showTooltip(r);
|
|
663
679
|
}), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r), this.buttonsContainer.appendChild(d);
|
|
664
680
|
} else if (!this.config.hideThumbs) {
|
|
@@ -670,18 +686,18 @@ class Ue {
|
|
|
670
686
|
}), r.addEventListener("mouseleave", () => this.hideTooltip()), d.appendChild(r);
|
|
671
687
|
const h = document.createElement("div");
|
|
672
688
|
h.className = "qaid-tooltip-wrapper";
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
this.prewarmTargeting(), this.showTooltip(
|
|
676
|
-
}),
|
|
689
|
+
const f = document.createElement("button");
|
|
690
|
+
f.type = "button", f.className = n ? `${s} qaid-btn-down` : "qaid-btn qaid-btn-down", f.setAttribute("aria-label", this.config.text.negativeLabel), f.innerHTML = this.config.negativeIcon || U, f.addEventListener("click", (b) => this.handleThumbClick("down", b.currentTarget, b)), f.addEventListener("mouseenter", () => {
|
|
691
|
+
this.prewarmTargeting(), this.showTooltip(f);
|
|
692
|
+
}), f.addEventListener("mouseleave", () => this.hideTooltip()), h.appendChild(f), this.buttonsContainer.appendChild(d), this.buttonsContainer.appendChild(h);
|
|
677
693
|
}
|
|
678
694
|
if (this.config.captureVideo && this.videoSupported()) {
|
|
679
695
|
const d = document.createElement("div");
|
|
680
696
|
d.className = "qaid-tooltip-wrapper";
|
|
681
697
|
const r = document.createElement("button");
|
|
682
|
-
r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon ||
|
|
698
|
+
r.type = "button", r.className = n ? `${s} qaid-btn-record` : "qaid-btn qaid-btn-record", r.setAttribute("aria-label", this.config.text.recordLabel), r.innerHTML = this.config.recordIcon || re, r.addEventListener("click", () => {
|
|
683
699
|
this.ensureRecording().then(
|
|
684
|
-
(
|
|
700
|
+
(f) => this.config.videoOptions.redaction ? f.startPicking() : f.startRecording()
|
|
685
701
|
);
|
|
686
702
|
});
|
|
687
703
|
const h = () => this.prewarmVideo();
|
|
@@ -703,7 +719,7 @@ class Ue {
|
|
|
703
719
|
if (this.overlayShadowRoot) return this.overlayShadowRoot;
|
|
704
720
|
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" });
|
|
705
721
|
const t = document.createElement("style");
|
|
706
|
-
if (t.textContent =
|
|
722
|
+
if (t.textContent = at(), this.overlayShadowRoot.appendChild(t), this.config.css) {
|
|
707
723
|
const e = document.createElement("style");
|
|
708
724
|
e.textContent = this.config.css, this.overlayShadowRoot.appendChild(e);
|
|
709
725
|
}
|
|
@@ -713,7 +729,7 @@ class Ue {
|
|
|
713
729
|
showTooltip(t) {
|
|
714
730
|
const e = this.tooltipElement;
|
|
715
731
|
e.style.visibility = "hidden", e.classList.add("qaid-tooltip-visible");
|
|
716
|
-
const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } =
|
|
732
|
+
const o = t.getBoundingClientRect(), n = e.getBoundingClientRect(), { top: s, left: a } = Ue(
|
|
717
733
|
o,
|
|
718
734
|
n,
|
|
719
735
|
{ width: window.innerWidth, height: window.innerHeight }
|
|
@@ -724,10 +740,10 @@ class Ue {
|
|
|
724
740
|
this.tooltipElement.classList.remove("qaid-tooltip-visible");
|
|
725
741
|
}
|
|
726
742
|
handleDismiss() {
|
|
727
|
-
this.buttonsContainer.classList.add("qaid-dismissed"),
|
|
743
|
+
this.buttonsContainer.classList.add("qaid-dismissed"), pt(this.config.apiKey, !0);
|
|
728
744
|
}
|
|
729
745
|
handleThumbClick(t, e, o) {
|
|
730
|
-
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"),
|
|
746
|
+
if (this.buttonsContainer?.classList.contains("qaid-incognito") && (this.buttonsContainer.classList.remove("qaid-incognito"), pt(this.config.apiKey, !1)), this.prewarmModal(), this.config.skipTargeting || this.config.feedbackMode === "annotate")
|
|
731
747
|
this.submitDirectFeedback(t, e);
|
|
732
748
|
else {
|
|
733
749
|
this.activeThumbBtn = e, e.setAttribute("aria-pressed", "true");
|
|
@@ -760,7 +776,7 @@ class Ue {
|
|
|
760
776
|
* instead of the permission-based Screen Capture API. Explicit "dom" wins;
|
|
761
777
|
* otherwise DOM is used on touch devices to avoid the getDisplayMedia prompt. */
|
|
762
778
|
shouldCaptureViaDom() {
|
|
763
|
-
return this.config.screenshotMethod === "dom" ||
|
|
779
|
+
return this.config.screenshotMethod === "dom" || ei();
|
|
764
780
|
}
|
|
765
781
|
/**
|
|
766
782
|
* Open the full-screen annotation editor over the captured screenshot,
|
|
@@ -773,7 +789,7 @@ class Ue {
|
|
|
773
789
|
const e = this.ensureOverlayHost(), o = this.overlayShadowHost, n = o.style.pointerEvents;
|
|
774
790
|
o.style.pointerEvents = "auto";
|
|
775
791
|
try {
|
|
776
|
-
const { openAnnotationEditor: s } = await Promise.resolve().then(() =>
|
|
792
|
+
const { openAnnotationEditor: s } = await Promise.resolve().then(() => wt);
|
|
777
793
|
return await s({
|
|
778
794
|
dataUrl: t,
|
|
779
795
|
root: e,
|
|
@@ -796,10 +812,10 @@ class Ue {
|
|
|
796
812
|
if (this.config.captureScreenshot || this.config.feedbackMode === "annotate")
|
|
797
813
|
try {
|
|
798
814
|
if (this.shouldCaptureViaDom()) {
|
|
799
|
-
const { captureDomScreenshot: a } = await Promise.resolve().then(() =>
|
|
815
|
+
const { captureDomScreenshot: a } = await Promise.resolve().then(() => vt);
|
|
800
816
|
t = await a(this.config.screenshotOptions);
|
|
801
817
|
} else {
|
|
802
|
-
const { captureScreenshot: a } = await Promise.resolve().then(() =>
|
|
818
|
+
const { captureScreenshot: a } = await Promise.resolve().then(() => xt);
|
|
803
819
|
t = await a(this.config.screenshotOptions);
|
|
804
820
|
}
|
|
805
821
|
t && this.announceMsg("Screenshot captured");
|
|
@@ -877,7 +893,7 @@ class Ue {
|
|
|
877
893
|
const o = this.questIdFor(t);
|
|
878
894
|
if (!o) return !1;
|
|
879
895
|
try {
|
|
880
|
-
return this.activeQuest?.destroy(), this.activeQuest = await
|
|
896
|
+
return this.activeQuest?.destroy(), this.activeQuest = await Ze({
|
|
881
897
|
questId: o,
|
|
882
898
|
base: this.config.quests.base,
|
|
883
899
|
apiKey: this.config.quests.apiKey || void 0,
|
|
@@ -906,7 +922,7 @@ class Ue {
|
|
|
906
922
|
*/
|
|
907
923
|
async ensureModal() {
|
|
908
924
|
if (!this.modal) {
|
|
909
|
-
const { ModalController: t } = await Promise.resolve().then(() =>
|
|
925
|
+
const { ModalController: t } = await Promise.resolve().then(() => qt);
|
|
910
926
|
this.modal = new t(this.makeModalHost());
|
|
911
927
|
}
|
|
912
928
|
return this.modal;
|
|
@@ -952,7 +968,7 @@ class Ue {
|
|
|
952
968
|
}
|
|
953
969
|
/** Warm the modal chunk while the user is targeting, so it opens instantly. */
|
|
954
970
|
prewarmModal() {
|
|
955
|
-
this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() =>
|
|
971
|
+
this.modalPrewarmed || (this.modalPrewarmed = !0, Promise.resolve().then(() => qt).catch(() => {
|
|
956
972
|
}));
|
|
957
973
|
}
|
|
958
974
|
/**
|
|
@@ -962,7 +978,7 @@ class Ue {
|
|
|
962
978
|
*/
|
|
963
979
|
async ensureTargeting() {
|
|
964
980
|
if (!this.targeting) {
|
|
965
|
-
const { TargetingController: t } = await Promise.resolve().then(() =>
|
|
981
|
+
const { TargetingController: t } = await Promise.resolve().then(() => Ct);
|
|
966
982
|
this.targeting = new t(this.makeTargetingHost());
|
|
967
983
|
}
|
|
968
984
|
return this.targeting;
|
|
@@ -1007,7 +1023,7 @@ class Ue {
|
|
|
1007
1023
|
}
|
|
1008
1024
|
/** Warm the targeting chunk on thumb-button hover, before the click. */
|
|
1009
1025
|
prewarmTargeting() {
|
|
1010
|
-
this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() =>
|
|
1026
|
+
this.targetingPrewarmed || this.config.skipTargeting || (this.targetingPrewarmed = !0, Promise.resolve().then(() => Ct).catch(() => {
|
|
1011
1027
|
}));
|
|
1012
1028
|
}
|
|
1013
1029
|
// ==================== Video Recording ====================
|
|
@@ -1026,7 +1042,7 @@ class Ue {
|
|
|
1026
1042
|
*/
|
|
1027
1043
|
async ensureRecording() {
|
|
1028
1044
|
if (!this.recording) {
|
|
1029
|
-
const { RecordingController: t } = await Promise.resolve().then(() =>
|
|
1045
|
+
const { RecordingController: t } = await Promise.resolve().then(() => kt);
|
|
1030
1046
|
this.recording = new t(this.makeRecordingHost());
|
|
1031
1047
|
}
|
|
1032
1048
|
return this.recording;
|
|
@@ -1082,13 +1098,13 @@ class Ue {
|
|
|
1082
1098
|
const t = window;
|
|
1083
1099
|
this.prewarmIsTimeout ? clearTimeout(this.prewarmHandle) : t.cancelIdleCallback?.(this.prewarmHandle), this.prewarmHandle = null;
|
|
1084
1100
|
}
|
|
1085
|
-
this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, 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.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.dismissBtn = null, this.tooltipElement = null,
|
|
1101
|
+
this.recording?.destroy(), this.recording = null, this.modal?.destroy(), this.modal = null, 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.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.dismissBtn = null, this.tooltipElement = null, Ee();
|
|
1086
1102
|
}
|
|
1087
1103
|
}
|
|
1088
|
-
function
|
|
1104
|
+
function It(i) {
|
|
1089
1105
|
return document.querySelector(i)?.textContent?.trim() ?? "";
|
|
1090
1106
|
}
|
|
1091
|
-
function
|
|
1107
|
+
function si() {
|
|
1092
1108
|
const i = document.querySelector(
|
|
1093
1109
|
'script[type="application/json"][data-feedback-config]'
|
|
1094
1110
|
);
|
|
@@ -1097,37 +1113,78 @@ function je() {
|
|
|
1097
1113
|
if (!t) return null;
|
|
1098
1114
|
try {
|
|
1099
1115
|
const e = JSON.parse(t);
|
|
1100
|
-
return e.cssSelector && !e.css && (e.css =
|
|
1116
|
+
return e.cssSelector && !e.css && (e.css = It(e.cssSelector), delete e.cssSelector), e;
|
|
1101
1117
|
} catch {
|
|
1102
1118
|
return null;
|
|
1103
1119
|
}
|
|
1104
1120
|
}
|
|
1105
|
-
function
|
|
1121
|
+
function Lt(i, t, e) {
|
|
1122
|
+
console.warn(`[thumbs-embed] Ignoring ${i}="${t}": expected ${e}.`);
|
|
1123
|
+
}
|
|
1124
|
+
function ai(i) {
|
|
1125
|
+
const t = [];
|
|
1126
|
+
let e = 0, o = "";
|
|
1127
|
+
for (const n of i)
|
|
1128
|
+
n === "(" && e++, n === ")" && (e = Math.max(0, e - 1)), n === "," && e === 0 ? (t.push(o.trim()), o = "") : o += n;
|
|
1129
|
+
return t.push(o.trim()), t;
|
|
1130
|
+
}
|
|
1131
|
+
function ri(i, t) {
|
|
1132
|
+
if (t === null) return;
|
|
1133
|
+
const e = t.trim();
|
|
1134
|
+
let o = null;
|
|
1135
|
+
if (e.startsWith("[") || e.startsWith("{"))
|
|
1136
|
+
try {
|
|
1137
|
+
o = JSON.parse(e);
|
|
1138
|
+
} catch {
|
|
1139
|
+
o = null;
|
|
1140
|
+
}
|
|
1141
|
+
else
|
|
1142
|
+
o = ai(e);
|
|
1143
|
+
if (Array.isArray(o) && o.length > 0 && o.every((n) => typeof n == "string" && n.trim() !== ""))
|
|
1144
|
+
return o.map((n) => n.trim());
|
|
1145
|
+
Lt(i, t, "a JSON array of colours or a comma-separated list");
|
|
1146
|
+
}
|
|
1147
|
+
function M(i, t) {
|
|
1148
|
+
if (t !== null) {
|
|
1149
|
+
if (t.trim() === "") {
|
|
1150
|
+
Lt(i, t, "a non-empty label");
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
return t;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
function di(i) {
|
|
1106
1157
|
const t = i.getAttribute("data-endpoint");
|
|
1107
1158
|
if (!t) return null;
|
|
1108
|
-
const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"),
|
|
1159
|
+
const e = i.getAttribute("data-position"), o = i.getAttribute("data-zindex"), n = i.getAttribute("data-positive-color"), s = i.getAttribute("data-negative-color"), a = i.getAttribute("data-marker-color"), c = i.getAttribute("data-container"), l = i.getAttribute("data-button-class"), d = i.getAttribute("data-skip-targeting"), r = i.getAttribute("data-hide-confirmation"), h = i.getAttribute("data-single-button"), f = i.getAttribute("data-feedback-mode"), b = i.getAttribute("data-incognito"), y = i.getAttribute("data-button-size"), g = i.getAttribute("data-offset-x"), w = i.getAttribute("data-offset-y"), x = i.getAttribute("data-modal-width"), u = i.getAttribute("data-backdrop-opacity"), k = i.getAttribute("data-font-family"), v = i.getAttribute("data-font-size"), C = i.getAttribute("data-tooltip"), A = i.getAttribute("data-modal-title"), S = i.getAttribute("data-confirmation-title"), m = i.getAttribute("data-confirmation-message"), E = i.getAttribute("data-confirmation-close"), K = i.getAttribute("data-error-title"), W = i.getAttribute("data-error-message"), X = i.getAttribute("data-modal-subtitle"), Y = i.getAttribute("data-placeholder"), Q = i.getAttribute("data-submit-button"), J = i.getAttribute("data-skip-button"), Nt = i.getAttribute("data-positive-icon"), Ft = i.getAttribute("data-negative-icon"), Vt = i.getAttribute("data-feedback-icon"), G = i.getAttribute("data-feedback-label"), Ut = i.getAttribute("data-api-key"), jt = i.getAttribute("data-capture-screenshot"), Kt = i.getAttribute("data-annotate"), Wt = i.getAttribute("data-annotation-color"), O = i.getAttribute("data-screenshot-quality"), z = i.getAttribute("data-screenshot-max-width"), $ = i.getAttribute("data-screenshot-max-height"), Xt = i.getAttribute("data-capture-video"), Z = i.getAttribute("data-video-redaction"), Yt = i.getAttribute("data-hide-thumbs"), Qt = i.getAttribute("data-hide-dismiss"), _ = i.getAttribute("data-video-max-duration"), Jt = i.getAttribute("data-screenshot-method"), Gt = i.getAttribute("data-direction"), tt = i.getAttribute("data-css-selector"), Zt = i.getAttribute("data-css"), et = M("data-positive-label", i.getAttribute("data-positive-label")), it = M("data-negative-label", i.getAttribute("data-negative-label")), ot = M("data-record-label", i.getAttribute("data-record-label")), nt = M("data-dismiss-label", i.getAttribute("data-dismiss-label")), te = ri(
|
|
1160
|
+
"data-annotation-palette",
|
|
1161
|
+
i.getAttribute("data-annotation-palette")
|
|
1162
|
+
), ee = i.getAttribute("data-record-icon"), st = i.getAttribute("data-quest-base"), ie = i.getAttribute("data-quest-up"), oe = i.getAttribute("data-quest-down"), ne = i.getAttribute("data-quest-video"), se = i.getAttribute("data-quest-api-key"), ae = i.getAttribute("data-quest-module-url");
|
|
1109
1163
|
return {
|
|
1110
1164
|
endpoint: t,
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1165
|
+
// Inline CSS wins over a selector, as `css` wins over `cssSelector` in
|
|
1166
|
+
// the JSON block.
|
|
1167
|
+
css: Zt || (tt ? It(tt) : void 0),
|
|
1168
|
+
apiKey: Ut ?? void 0,
|
|
1169
|
+
captureScreenshot: jt === "true" ? !0 : void 0,
|
|
1114
1170
|
// Annotation is on by default; only an explicit "false" disables it.
|
|
1115
|
-
annotate:
|
|
1116
|
-
annotationColor:
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1171
|
+
annotate: Kt === "false" ? !1 : void 0,
|
|
1172
|
+
annotationColor: Wt ?? void 0,
|
|
1173
|
+
annotationPalette: te,
|
|
1174
|
+
screenshotOptions: O || z || $ ? {
|
|
1175
|
+
quality: O ? parseFloat(O) : void 0,
|
|
1176
|
+
maxWidth: z ? parseInt(z, 10) : void 0,
|
|
1120
1177
|
maxHeight: $ ? parseInt($, 10) : void 0
|
|
1121
1178
|
} : void 0,
|
|
1122
1179
|
container: c ?? void 0,
|
|
1123
1180
|
buttonClass: l ?? void 0,
|
|
1124
|
-
direction:
|
|
1181
|
+
direction: Gt ?? void 0,
|
|
1125
1182
|
position: e ?? void 0,
|
|
1126
1183
|
zIndex: o ? parseInt(o, 10) : void 0,
|
|
1127
1184
|
skipTargeting: d === "true" ? !0 : void 0,
|
|
1128
1185
|
hideConfirmation: r === "true" ? !0 : void 0,
|
|
1129
1186
|
singleButton: h === "true" ? !0 : void 0,
|
|
1130
|
-
feedbackMode:
|
|
1187
|
+
feedbackMode: f ?? void 0,
|
|
1131
1188
|
incognito: b === "true" ? !0 : void 0,
|
|
1132
1189
|
buttonSize: y ?? void 0,
|
|
1133
1190
|
offset: g || w ? {
|
|
@@ -1143,73 +1200,80 @@ function Ke(i) {
|
|
|
1143
1200
|
negative: s ?? void 0,
|
|
1144
1201
|
marker: a ?? void 0
|
|
1145
1202
|
},
|
|
1146
|
-
text: C ||
|
|
1203
|
+
text: C || A || X || Y || Q || J || G || S || m || E || K || W || et || it || ot || nt ? {
|
|
1147
1204
|
tooltip: C ?? void 0,
|
|
1148
|
-
modalTitle:
|
|
1149
|
-
modalSubtitle:
|
|
1150
|
-
placeholder:
|
|
1151
|
-
submitButton:
|
|
1152
|
-
skipButton:
|
|
1153
|
-
feedbackLabel:
|
|
1205
|
+
modalTitle: A ?? void 0,
|
|
1206
|
+
modalSubtitle: X ?? void 0,
|
|
1207
|
+
placeholder: Y ?? void 0,
|
|
1208
|
+
submitButton: Q ?? void 0,
|
|
1209
|
+
skipButton: J ?? void 0,
|
|
1210
|
+
feedbackLabel: G ?? void 0,
|
|
1154
1211
|
confirmationTitle: S ?? void 0,
|
|
1155
|
-
confirmationMessage:
|
|
1156
|
-
confirmationClose:
|
|
1212
|
+
confirmationMessage: m ?? void 0,
|
|
1213
|
+
confirmationClose: E ?? void 0,
|
|
1214
|
+
errorTitle: K ?? void 0,
|
|
1215
|
+
errorMessage: W ?? void 0,
|
|
1216
|
+
positiveLabel: et,
|
|
1217
|
+
negativeLabel: it,
|
|
1218
|
+
recordLabel: ot,
|
|
1219
|
+
dismissLabel: nt
|
|
1157
1220
|
} : void 0,
|
|
1158
|
-
positiveIcon:
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1221
|
+
positiveIcon: Nt ?? void 0,
|
|
1222
|
+
recordIcon: ee ?? void 0,
|
|
1223
|
+
negativeIcon: Ft ?? void 0,
|
|
1224
|
+
feedbackIcon: Vt ?? void 0,
|
|
1225
|
+
screenshotMethod: Jt ?? void 0,
|
|
1226
|
+
captureVideo: Xt === "true" ? !0 : void 0,
|
|
1227
|
+
hideThumbs: Yt === "true" ? !0 : void 0,
|
|
1228
|
+
hideDismiss: Qt === "true" ? !0 : void 0,
|
|
1229
|
+
videoOptions: _ || Z ? {
|
|
1230
|
+
maxDuration: _ ? parseInt(_, 10) : void 0,
|
|
1231
|
+
redaction: Z === "true" ? !0 : void 0
|
|
1168
1232
|
} : void 0,
|
|
1169
|
-
quests:
|
|
1170
|
-
base:
|
|
1171
|
-
up:
|
|
1172
|
-
down:
|
|
1173
|
-
video:
|
|
1174
|
-
apiKey:
|
|
1175
|
-
moduleUrl:
|
|
1233
|
+
quests: st ? {
|
|
1234
|
+
base: st,
|
|
1235
|
+
up: ie ?? void 0,
|
|
1236
|
+
down: oe ?? void 0,
|
|
1237
|
+
video: ne ?? void 0,
|
|
1238
|
+
apiKey: se ?? void 0,
|
|
1239
|
+
moduleUrl: ae ?? void 0
|
|
1176
1240
|
} : void 0
|
|
1177
1241
|
};
|
|
1178
1242
|
}
|
|
1179
|
-
function
|
|
1243
|
+
function ci() {
|
|
1180
1244
|
if (typeof document > "u") return;
|
|
1181
1245
|
const i = () => {
|
|
1182
|
-
const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e =
|
|
1183
|
-
|
|
1246
|
+
const t = document.currentScript ?? document.querySelector("script[data-endpoint]"), e = si() ?? (t ? di(t) : null);
|
|
1247
|
+
e?.endpoint && new ni(e);
|
|
1184
1248
|
};
|
|
1185
1249
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", i) : i();
|
|
1186
1250
|
}
|
|
1187
|
-
const
|
|
1188
|
-
function
|
|
1251
|
+
const li = 20, mt = 4096;
|
|
1252
|
+
function P(i) {
|
|
1189
1253
|
const t = typeof i == "string" ? i : JSON.stringify(i);
|
|
1190
|
-
return t.length >
|
|
1254
|
+
return t.length > mt ? t.slice(0, mt) + "…[truncated]" : t;
|
|
1191
1255
|
}
|
|
1192
|
-
function
|
|
1193
|
-
i.length >=
|
|
1256
|
+
function bt(i, t) {
|
|
1257
|
+
i.length >= li && i.shift(), i.push(t);
|
|
1194
1258
|
}
|
|
1195
|
-
async function
|
|
1259
|
+
async function hi(i) {
|
|
1196
1260
|
try {
|
|
1197
1261
|
const t = await i.clone().text();
|
|
1198
|
-
return
|
|
1262
|
+
return P(t);
|
|
1199
1263
|
} catch {
|
|
1200
1264
|
return;
|
|
1201
1265
|
}
|
|
1202
1266
|
}
|
|
1203
|
-
function
|
|
1267
|
+
function ui() {
|
|
1204
1268
|
const i = [], t = window.fetch;
|
|
1205
1269
|
window.fetch = async function(n, s) {
|
|
1206
1270
|
const a = typeof n == "string" ? n : n instanceof URL ? n.toString() : n.url, c = s?.method ?? (typeof n == "object" && "method" in n ? n.method : "GET");
|
|
1207
1271
|
let l;
|
|
1208
|
-
s?.body && (l =
|
|
1272
|
+
s?.body && (l = P(s.body));
|
|
1209
1273
|
const d = await t.apply(window, [n, s]);
|
|
1210
1274
|
if (d.status >= 400) {
|
|
1211
|
-
const r = await
|
|
1212
|
-
|
|
1275
|
+
const r = await hi(d);
|
|
1276
|
+
bt(i, {
|
|
1213
1277
|
url: a,
|
|
1214
1278
|
method: c.toUpperCase(),
|
|
1215
1279
|
status: d.status,
|
|
@@ -1225,15 +1289,15 @@ function Qe() {
|
|
|
1225
1289
|
return XMLHttpRequest.prototype.open = function(n, s, ...a) {
|
|
1226
1290
|
return this._qaid_method = n, this._qaid_url = typeof s == "string" ? s : s.toString(), e.apply(this, [n, s, ...a]);
|
|
1227
1291
|
}, XMLHttpRequest.prototype.send = function(n) {
|
|
1228
|
-
const s = this, a = n ?
|
|
1292
|
+
const s = this, a = n ? P(n) : void 0;
|
|
1229
1293
|
return s.addEventListener("load", function() {
|
|
1230
|
-
s.status >= 400 &&
|
|
1294
|
+
s.status >= 400 && bt(i, {
|
|
1231
1295
|
url: s._qaid_url,
|
|
1232
1296
|
method: s._qaid_method.toUpperCase(),
|
|
1233
1297
|
status: s.status,
|
|
1234
1298
|
statusText: s.statusText,
|
|
1235
1299
|
requestBody: a,
|
|
1236
|
-
responseBody:
|
|
1300
|
+
responseBody: P(s.responseText),
|
|
1237
1301
|
timestamp: Date.now()
|
|
1238
1302
|
});
|
|
1239
1303
|
}), o.apply(this, [n]);
|
|
@@ -1244,27 +1308,27 @@ function Qe() {
|
|
|
1244
1308
|
}
|
|
1245
1309
|
};
|
|
1246
1310
|
}
|
|
1247
|
-
function
|
|
1311
|
+
function pi() {
|
|
1248
1312
|
const i = navigator.userAgent || "";
|
|
1249
1313
|
return /iP(hone|ad|od)/.test(i) || // iPadOS 13+ masquerades as "MacIntel" but is a multi-touch device.
|
|
1250
1314
|
navigator.platform === "MacIntel" && (navigator.maxTouchPoints || 0) > 1;
|
|
1251
1315
|
}
|
|
1252
|
-
function
|
|
1316
|
+
function fi(i, t, e, o, n) {
|
|
1253
1317
|
const s = i >= t, a = e >= o;
|
|
1254
1318
|
return s === a ? { width: i, height: t, rotate: 0 } : { width: t, height: i, rotate: n === 270 ? -90 : 90 };
|
|
1255
1319
|
}
|
|
1256
|
-
function
|
|
1320
|
+
function mi(i, t, e) {
|
|
1257
1321
|
if (e.rotate === 0) {
|
|
1258
1322
|
i.drawImage(t, 0, 0, e.width, e.height);
|
|
1259
1323
|
return;
|
|
1260
1324
|
}
|
|
1261
1325
|
i.save(), e.rotate === 90 ? (i.translate(e.width, 0), i.rotate(Math.PI / 2)) : (i.translate(0, e.height), i.rotate(-Math.PI / 2)), i.drawImage(t, 0, 0, e.height, e.width), i.restore();
|
|
1262
1326
|
}
|
|
1263
|
-
function
|
|
1327
|
+
function bi() {
|
|
1264
1328
|
const i = typeof screen < "u" ? screen.orientation : void 0;
|
|
1265
1329
|
return i && typeof i.angle == "number" ? i.angle : 0;
|
|
1266
1330
|
}
|
|
1267
|
-
function
|
|
1331
|
+
function Dt(i) {
|
|
1268
1332
|
return new Promise((t) => {
|
|
1269
1333
|
if (i.videoWidth > 0) {
|
|
1270
1334
|
t();
|
|
@@ -1273,30 +1337,30 @@ function xt(i) {
|
|
|
1273
1337
|
i.addEventListener("loadedmetadata", () => t(), { once: !0 });
|
|
1274
1338
|
});
|
|
1275
1339
|
}
|
|
1276
|
-
async function
|
|
1340
|
+
async function Mt(i) {
|
|
1277
1341
|
try {
|
|
1278
1342
|
await i.play();
|
|
1279
1343
|
} catch {
|
|
1280
1344
|
}
|
|
1281
1345
|
}
|
|
1282
|
-
async function
|
|
1346
|
+
async function gi(i, t = 15) {
|
|
1283
1347
|
const e = document.createElement("canvas");
|
|
1284
1348
|
if (typeof e.captureStream != "function") return null;
|
|
1285
1349
|
const o = e.getContext("2d");
|
|
1286
1350
|
if (!o) return null;
|
|
1287
1351
|
const n = document.createElement("video");
|
|
1288
|
-
n.muted = !0, n.playsInline = !0, n.srcObject = i, await
|
|
1289
|
-
const s =
|
|
1352
|
+
n.muted = !0, n.playsInline = !0, n.srcObject = i, await Dt(n);
|
|
1353
|
+
const s = fi(
|
|
1290
1354
|
n.videoWidth,
|
|
1291
1355
|
n.videoHeight,
|
|
1292
1356
|
window.innerWidth,
|
|
1293
1357
|
window.innerHeight,
|
|
1294
|
-
|
|
1358
|
+
bi()
|
|
1295
1359
|
);
|
|
1296
|
-
e.width = s.width, e.height = s.height, await
|
|
1360
|
+
e.width = s.width, e.height = s.height, await Mt(n);
|
|
1297
1361
|
let a = 0;
|
|
1298
1362
|
const c = () => {
|
|
1299
|
-
|
|
1363
|
+
mi(o, n, s), a = requestAnimationFrame(c);
|
|
1300
1364
|
};
|
|
1301
1365
|
c();
|
|
1302
1366
|
const l = e.captureStream(t);
|
|
@@ -1307,15 +1371,15 @@ async function ei(i, t = 15) {
|
|
|
1307
1371
|
}
|
|
1308
1372
|
};
|
|
1309
1373
|
}
|
|
1310
|
-
function
|
|
1374
|
+
function vi(i, t, e, o, n) {
|
|
1311
1375
|
const s = Math.max(0, Math.min(o, i.left * t)), a = Math.max(0, Math.min(n, i.top * e)), c = Math.max(0, Math.min(o, (i.left + i.width) * t)), l = Math.max(0, Math.min(n, (i.top + i.height) * e)), d = c - s, r = l - a;
|
|
1312
1376
|
return d <= 0 || r <= 0 ? null : { x: s, y: a, w: d, h: r };
|
|
1313
1377
|
}
|
|
1314
|
-
function
|
|
1378
|
+
function yi(i, t, e, o, n, s, a) {
|
|
1315
1379
|
i.drawImage(t, 0, 0, o, n);
|
|
1316
1380
|
const c = o / Math.max(1, window.innerWidth), l = n / Math.max(1, window.innerHeight);
|
|
1317
1381
|
for (const d of e) {
|
|
1318
|
-
const r =
|
|
1382
|
+
const r = vi(
|
|
1319
1383
|
d.getBoundingClientRect(),
|
|
1320
1384
|
c,
|
|
1321
1385
|
l,
|
|
@@ -1325,16 +1389,16 @@ function oi(i, t, e, o, n, s, a) {
|
|
|
1325
1389
|
r && (i.save(), a ? (i.filter = `blur(${s}px)`, i.drawImage(t, r.x, r.y, r.w, r.h, r.x, r.y, r.w, r.h)) : (i.fillStyle = "#0b0b0b", i.fillRect(r.x, r.y, r.w, r.h)), i.restore());
|
|
1326
1390
|
}
|
|
1327
1391
|
}
|
|
1328
|
-
async function
|
|
1392
|
+
async function wi(i, t, e = {}) {
|
|
1329
1393
|
const o = e.frameRate ?? 15, n = e.blurRadius ?? 12, s = document.createElement("canvas");
|
|
1330
1394
|
if (typeof s.captureStream != "function") return null;
|
|
1331
1395
|
const a = s.getContext("2d");
|
|
1332
1396
|
if (!a) return null;
|
|
1333
1397
|
const c = "filter" in a, l = document.createElement("video");
|
|
1334
|
-
l.muted = !0, l.playsInline = !0, l.srcObject = i, await
|
|
1398
|
+
l.muted = !0, l.playsInline = !0, l.srcObject = i, await Dt(l), s.width = l.videoWidth, s.height = l.videoHeight, await Mt(l);
|
|
1335
1399
|
let d = 0;
|
|
1336
1400
|
const r = () => {
|
|
1337
|
-
|
|
1401
|
+
yi(
|
|
1338
1402
|
a,
|
|
1339
1403
|
l,
|
|
1340
1404
|
t,
|
|
@@ -1349,14 +1413,15 @@ async function ni(i, t, e = {}) {
|
|
|
1349
1413
|
return {
|
|
1350
1414
|
stream: h,
|
|
1351
1415
|
stop: () => {
|
|
1352
|
-
d && cancelAnimationFrame(d), d = 0, h.getTracks().forEach((
|
|
1416
|
+
d && cancelAnimationFrame(d), d = 0, h.getTracks().forEach((f) => f.stop()), l.pause(), l.srcObject = null;
|
|
1353
1417
|
}
|
|
1354
1418
|
};
|
|
1355
1419
|
}
|
|
1356
|
-
|
|
1420
|
+
const Rt = "This browser cannot blur the areas you picked, so the recording was not started.";
|
|
1421
|
+
function ki() {
|
|
1357
1422
|
return typeof navigator < "u" && !!navigator.mediaDevices && typeof navigator.mediaDevices.getDisplayMedia == "function" && typeof MediaRecorder < "u";
|
|
1358
1423
|
}
|
|
1359
|
-
function
|
|
1424
|
+
function Pt() {
|
|
1360
1425
|
if (typeof MediaRecorder > "u") return "";
|
|
1361
1426
|
const i = [
|
|
1362
1427
|
"video/webm;codecs=vp9",
|
|
@@ -1369,11 +1434,11 @@ function Ct() {
|
|
|
1369
1434
|
return t;
|
|
1370
1435
|
return "";
|
|
1371
1436
|
}
|
|
1372
|
-
function
|
|
1437
|
+
function xi(i = {}) {
|
|
1373
1438
|
const t = i.maxDuration ?? 15, e = i.videoBitsPerSecond ?? 8e5, o = i.redactionElements ?? [], n = i.redactionBlurRadius;
|
|
1374
|
-
let s = null, a = null, c = null, l = null, d = [], r = null, h = null,
|
|
1439
|
+
let s = null, a = null, c = null, l = null, d = [], r = null, h = null, f = null, b = 0, y = null, g = null, w = !1, x = null;
|
|
1375
1440
|
function u() {
|
|
1376
|
-
|
|
1441
|
+
f !== null && (clearInterval(f), f = null), x !== null && (clearTimeout(x), x = null), a && (a.stop(), a = null), c && (c.stop(), c = null), s && (s.getTracks().forEach((v) => v.stop()), s = null), l = null, d = [], r = null, h = null, y = null, g = null;
|
|
1377
1442
|
}
|
|
1378
1443
|
function k() {
|
|
1379
1444
|
w || (w = !0, l && l.state !== "inactive" && l.stop());
|
|
@@ -1381,7 +1446,7 @@ function ai(i = {}) {
|
|
|
1381
1446
|
return {
|
|
1382
1447
|
async start() {
|
|
1383
1448
|
w = !1, d = [];
|
|
1384
|
-
const v =
|
|
1449
|
+
const v = Pt();
|
|
1385
1450
|
if (!v)
|
|
1386
1451
|
throw new Error("No supported video MIME type found");
|
|
1387
1452
|
s = await navigator.mediaDevices.getDisplayMedia({
|
|
@@ -1396,37 +1461,40 @@ function ai(i = {}) {
|
|
|
1396
1461
|
monitorTypeSurfaces: "exclude",
|
|
1397
1462
|
surfaceSwitching: "exclude"
|
|
1398
1463
|
});
|
|
1399
|
-
const C = s.getVideoTracks()[0],
|
|
1400
|
-
if (
|
|
1401
|
-
throw s.getTracks().forEach((
|
|
1464
|
+
const C = s.getVideoTracks()[0], A = C?.getSettings?.()?.displaySurface;
|
|
1465
|
+
if (A === "monitor" || A === "window")
|
|
1466
|
+
throw s.getTracks().forEach((m) => m.stop()), s = null, new Error(
|
|
1402
1467
|
"qaid records only the current tab — please share this tab, not a window or your whole screen."
|
|
1403
1468
|
);
|
|
1404
1469
|
C && C.addEventListener("ended", () => {
|
|
1405
1470
|
k();
|
|
1406
1471
|
});
|
|
1407
1472
|
let S = s;
|
|
1408
|
-
if (
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1473
|
+
if (pi()) {
|
|
1474
|
+
const m = await gi(s);
|
|
1475
|
+
m && (a = m, S = m.stream);
|
|
1476
|
+
}
|
|
1477
|
+
if (o.length > 0) {
|
|
1478
|
+
const m = await wi(S, o, {
|
|
1413
1479
|
blurRadius: n
|
|
1414
1480
|
});
|
|
1415
|
-
|
|
1481
|
+
if (!m)
|
|
1482
|
+
throw a && (a.stop(), a = null), s.getTracks().forEach((E) => E.stop()), s = null, new Error(Rt);
|
|
1483
|
+
c = m, S = m.stream;
|
|
1416
1484
|
}
|
|
1417
1485
|
l = new MediaRecorder(S, {
|
|
1418
1486
|
mimeType: v,
|
|
1419
1487
|
videoBitsPerSecond: e
|
|
1420
|
-
}), l.ondataavailable = (
|
|
1421
|
-
|
|
1488
|
+
}), l.ondataavailable = (m) => {
|
|
1489
|
+
m.data.size > 0 && d.push(m.data);
|
|
1422
1490
|
}, l.onstop = () => {
|
|
1423
|
-
const
|
|
1424
|
-
y && y(
|
|
1491
|
+
const m = new Blob(d, { type: v });
|
|
1492
|
+
y && y(m), h && h(m), a && (a.stop(), a = null), c && (c.stop(), c = null), s && s.getTracks().forEach((E) => E.stop());
|
|
1425
1493
|
}, l.onerror = () => {
|
|
1426
1494
|
g && g(new Error("MediaRecorder error"));
|
|
1427
|
-
}, l.start(1e3), b = Date.now(),
|
|
1428
|
-
const
|
|
1429
|
-
r && r(
|
|
1495
|
+
}, l.start(1e3), b = Date.now(), f = setInterval(() => {
|
|
1496
|
+
const m = Math.floor((Date.now() - b) / 1e3);
|
|
1497
|
+
r && r(m);
|
|
1430
1498
|
}, 1e3), x = setTimeout(() => {
|
|
1431
1499
|
k();
|
|
1432
1500
|
}, t * 1e3);
|
|
@@ -1447,45 +1515,46 @@ function ai(i = {}) {
|
|
|
1447
1515
|
}
|
|
1448
1516
|
};
|
|
1449
1517
|
}
|
|
1450
|
-
const
|
|
1518
|
+
const Bt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1451
1519
|
__proto__: null,
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1520
|
+
REDACTION_UNAVAILABLE: Rt,
|
|
1521
|
+
createVideoRecorder: xi,
|
|
1522
|
+
getSupportedMimeType: Pt,
|
|
1523
|
+
isVideoRecordingSupported: ki
|
|
1524
|
+
}, Symbol.toStringTag, { value: "Module" })), gt = "https://qaid.dev/lib/html2canvas.min.js", qi = 1e4, Ci = 50;
|
|
1456
1525
|
let L = null;
|
|
1457
|
-
function
|
|
1526
|
+
function Si() {
|
|
1458
1527
|
if (typeof document > "u" || typeof window > "u")
|
|
1459
1528
|
return !1;
|
|
1460
1529
|
const i = document.createElement("canvas");
|
|
1461
1530
|
return typeof i.getContext == "function" && !!i.getContext("2d");
|
|
1462
1531
|
}
|
|
1463
|
-
function
|
|
1532
|
+
function Ei() {
|
|
1464
1533
|
return window.html2canvas ? Promise.resolve(!0) : L || (L = new Promise((i) => {
|
|
1465
1534
|
if (!document.querySelector(
|
|
1466
|
-
`script[src="${
|
|
1535
|
+
`script[src="${gt}"]`
|
|
1467
1536
|
)) {
|
|
1468
1537
|
const n = document.createElement("script");
|
|
1469
|
-
n.src =
|
|
1538
|
+
n.src = gt, n.async = !0, document.head.appendChild(n);
|
|
1470
1539
|
}
|
|
1471
1540
|
const e = Date.now(), o = () => {
|
|
1472
1541
|
if (window.html2canvas) {
|
|
1473
1542
|
i(!0);
|
|
1474
1543
|
return;
|
|
1475
1544
|
}
|
|
1476
|
-
if (Date.now() - e >
|
|
1545
|
+
if (Date.now() - e > qi) {
|
|
1477
1546
|
L = null, i(!1);
|
|
1478
1547
|
return;
|
|
1479
1548
|
}
|
|
1480
|
-
setTimeout(o,
|
|
1549
|
+
setTimeout(o, Ci);
|
|
1481
1550
|
};
|
|
1482
1551
|
o();
|
|
1483
1552
|
}), L);
|
|
1484
1553
|
}
|
|
1485
|
-
async function
|
|
1554
|
+
async function Ti(i = {}) {
|
|
1486
1555
|
const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
|
|
1487
1556
|
try {
|
|
1488
|
-
if (!await
|
|
1557
|
+
if (!await Ei() || !window.html2canvas)
|
|
1489
1558
|
return console.warn("html2canvas failed to load"), null;
|
|
1490
1559
|
const s = await window.html2canvas(document.body, {
|
|
1491
1560
|
useCORS: !0,
|
|
@@ -1502,31 +1571,34 @@ async function hi(i = {}) {
|
|
|
1502
1571
|
if (l < 1) {
|
|
1503
1572
|
const d = Math.round(a * l), r = Math.round(c * l), h = document.createElement("canvas");
|
|
1504
1573
|
h.width = d, h.height = r;
|
|
1505
|
-
const
|
|
1506
|
-
return
|
|
1574
|
+
const f = h.getContext("2d");
|
|
1575
|
+
return f ? (f.drawImage(s, 0, 0, d, r), h.toDataURL("image/webp", t)) : null;
|
|
1507
1576
|
}
|
|
1508
1577
|
return s.toDataURL("image/webp", t);
|
|
1509
1578
|
} catch (n) {
|
|
1510
1579
|
return console.warn("DOM screenshot capture failed:", n), null;
|
|
1511
1580
|
}
|
|
1512
1581
|
}
|
|
1513
|
-
const
|
|
1582
|
+
const vt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1514
1583
|
__proto__: null,
|
|
1515
|
-
captureDomScreenshot:
|
|
1516
|
-
isDomScreenshotSupported:
|
|
1517
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
1584
|
+
captureDomScreenshot: Ti,
|
|
1585
|
+
isDomScreenshotSupported: Si
|
|
1586
|
+
}, Symbol.toStringTag, { value: "Module" })), T = 12, Ai = "#ef4444", Ii = ["#ef4444", "#f59e0b", "#22c55e", "#3b82f6", "#111827", "#ffffff"], Li = {
|
|
1518
1587
|
"#ef4444": "red",
|
|
1519
1588
|
"#f59e0b": "amber",
|
|
1520
1589
|
"#22c55e": "green",
|
|
1521
1590
|
"#3b82f6": "blue",
|
|
1522
1591
|
"#111827": "black",
|
|
1523
1592
|
"#ffffff": "white",
|
|
1593
|
+
// The default marker (nudged from #6366f1 so white text on it clears 4.5:1);
|
|
1594
|
+
// the old value keeps its name for sites that pass it explicitly.
|
|
1595
|
+
"#6365f1": "indigo",
|
|
1524
1596
|
"#6366f1": "indigo"
|
|
1525
1597
|
};
|
|
1526
|
-
function
|
|
1527
|
-
return
|
|
1598
|
+
function yt(i) {
|
|
1599
|
+
return Li[i.toLowerCase()] ?? i;
|
|
1528
1600
|
}
|
|
1529
|
-
const
|
|
1601
|
+
const Di = 4, Mi = 0.8, Ri = {
|
|
1530
1602
|
title: "Annotate screenshot",
|
|
1531
1603
|
instructions: "Draw on the screenshot to highlight or hide details, then choose Done to attach it or Skip to send the original.",
|
|
1532
1604
|
rectangle: "Rectangle",
|
|
@@ -1538,7 +1610,7 @@ const mi = 4, bi = 0.8, gi = {
|
|
|
1538
1610
|
done: "Done",
|
|
1539
1611
|
colors: "Drawing colour"
|
|
1540
1612
|
};
|
|
1541
|
-
function
|
|
1613
|
+
function B(i, t) {
|
|
1542
1614
|
return {
|
|
1543
1615
|
x: Math.min(i.x, t.x),
|
|
1544
1616
|
y: Math.min(i.y, t.y),
|
|
@@ -1546,12 +1618,12 @@ function P(i, t) {
|
|
|
1546
1618
|
h: Math.abs(i.y - t.y)
|
|
1547
1619
|
};
|
|
1548
1620
|
}
|
|
1549
|
-
function
|
|
1621
|
+
function Pi(i) {
|
|
1550
1622
|
if (i.type === "pen") return i.points.length < 2;
|
|
1551
|
-
const t =
|
|
1623
|
+
const t = B(i.points[0], i.points[1]);
|
|
1552
1624
|
return t.w < 3 && t.h < 3;
|
|
1553
1625
|
}
|
|
1554
|
-
function
|
|
1626
|
+
function Bi(i, t, e, o) {
|
|
1555
1627
|
i.beginPath(), i.moveTo(t.x, t.y), i.lineTo(e.x, e.y), i.stroke();
|
|
1556
1628
|
const n = Math.atan2(e.y - t.y, e.x - t.x), s = Math.max(10, o * 3);
|
|
1557
1629
|
i.beginPath(), i.moveTo(e.x, e.y), i.lineTo(
|
|
@@ -1562,7 +1634,7 @@ function yi(i, t, e, o) {
|
|
|
1562
1634
|
e.y - s * Math.sin(n + Math.PI / 6)
|
|
1563
1635
|
), i.stroke();
|
|
1564
1636
|
}
|
|
1565
|
-
function
|
|
1637
|
+
function Hi(i, t) {
|
|
1566
1638
|
if (t.length !== 0) {
|
|
1567
1639
|
i.beginPath(), i.moveTo(t[0].x, t[0].y);
|
|
1568
1640
|
for (let e = 1; e < t.length; e++)
|
|
@@ -1570,49 +1642,49 @@ function wi(i, t) {
|
|
|
1570
1642
|
i.stroke();
|
|
1571
1643
|
}
|
|
1572
1644
|
}
|
|
1573
|
-
function
|
|
1645
|
+
function Oi(i, t, e, o, n) {
|
|
1574
1646
|
i.fillStyle = "rgb(15, 23, 42)", i.fillRect(t, e, o, n), i.fillStyle = "rgb(37, 47, 63)";
|
|
1575
|
-
for (let s = e; s < e + n; s +=
|
|
1576
|
-
for (let a = t; a < t + o; a +=
|
|
1577
|
-
(Math.floor((a - t) /
|
|
1647
|
+
for (let s = e; s < e + n; s += T)
|
|
1648
|
+
for (let a = t; a < t + o; a += T)
|
|
1649
|
+
(Math.floor((a - t) / T) + Math.floor((s - e) / T)) % 2 === 0 && i.fillRect(
|
|
1578
1650
|
a,
|
|
1579
1651
|
s,
|
|
1580
|
-
Math.min(
|
|
1581
|
-
Math.min(
|
|
1652
|
+
Math.min(T, t + o - a),
|
|
1653
|
+
Math.min(T, e + n - s)
|
|
1582
1654
|
);
|
|
1583
1655
|
}
|
|
1584
|
-
function
|
|
1656
|
+
function H(i, t) {
|
|
1585
1657
|
switch (i.save(), i.strokeStyle = t.color, i.fillStyle = t.color, i.lineWidth = t.strokeWidth, i.lineJoin = "round", i.lineCap = "round", t.type) {
|
|
1586
1658
|
case "rect": {
|
|
1587
|
-
const e =
|
|
1659
|
+
const e = B(t.points[0], t.points[1]);
|
|
1588
1660
|
i.strokeRect(e.x, e.y, e.w, e.h);
|
|
1589
1661
|
break;
|
|
1590
1662
|
}
|
|
1591
1663
|
case "arrow":
|
|
1592
|
-
|
|
1664
|
+
Bi(i, t.points[0], t.points[1], t.strokeWidth);
|
|
1593
1665
|
break;
|
|
1594
1666
|
case "pen":
|
|
1595
|
-
|
|
1667
|
+
Hi(i, t.points);
|
|
1596
1668
|
break;
|
|
1597
1669
|
case "blur": {
|
|
1598
|
-
const e =
|
|
1599
|
-
|
|
1670
|
+
const e = B(t.points[0], t.points[1]);
|
|
1671
|
+
Oi(i, e.x, e.y, e.w, e.h);
|
|
1600
1672
|
break;
|
|
1601
1673
|
}
|
|
1602
1674
|
}
|
|
1603
1675
|
i.restore();
|
|
1604
1676
|
}
|
|
1605
|
-
function
|
|
1677
|
+
function Ht(i) {
|
|
1606
1678
|
return new Promise((t, e) => {
|
|
1607
1679
|
const o = new Image();
|
|
1608
1680
|
o.onload = () => t(o), o.onerror = () => e(new Error("Failed to load screenshot")), o.src = i;
|
|
1609
1681
|
});
|
|
1610
1682
|
}
|
|
1611
|
-
async function
|
|
1612
|
-
const o = e.quality ??
|
|
1683
|
+
async function Ot(i, t, e = {}) {
|
|
1684
|
+
const o = e.quality ?? Mi;
|
|
1613
1685
|
let n;
|
|
1614
1686
|
try {
|
|
1615
|
-
n = await
|
|
1687
|
+
n = await Ht(i);
|
|
1616
1688
|
} catch {
|
|
1617
1689
|
return i;
|
|
1618
1690
|
}
|
|
@@ -1622,11 +1694,11 @@ async function Tt(i, t, e = {}) {
|
|
|
1622
1694
|
if (!a) return i;
|
|
1623
1695
|
a.drawImage(n, 0, 0, s.width, s.height);
|
|
1624
1696
|
for (const c of t)
|
|
1625
|
-
|
|
1697
|
+
H(a, c);
|
|
1626
1698
|
return s.toDataURL("image/webp", o);
|
|
1627
1699
|
}
|
|
1628
|
-
let
|
|
1629
|
-
class
|
|
1700
|
+
let zi = 0;
|
|
1701
|
+
class zt {
|
|
1630
1702
|
shapes = [];
|
|
1631
1703
|
tool = "rect";
|
|
1632
1704
|
opts;
|
|
@@ -1634,7 +1706,7 @@ class At {
|
|
|
1634
1706
|
color;
|
|
1635
1707
|
palette;
|
|
1636
1708
|
strokeWidth;
|
|
1637
|
-
uid = `qaid-annotate-${++
|
|
1709
|
+
uid = `qaid-annotate-${++zi}`;
|
|
1638
1710
|
container;
|
|
1639
1711
|
canvas;
|
|
1640
1712
|
ctx = null;
|
|
@@ -1648,7 +1720,7 @@ class At {
|
|
|
1648
1720
|
// after the editor is mounted).
|
|
1649
1721
|
resolveResult;
|
|
1650
1722
|
constructor(t) {
|
|
1651
|
-
this.opts = t, this.labels = { ...
|
|
1723
|
+
this.opts = t, this.labels = { ...Ri, ...t.labels ?? {} }, this.color = t.color ?? Ai, this.palette = (t.palette && t.palette.length ? t.palette : Ii).slice(), this.palette.some((e) => e.toLowerCase() === this.color.toLowerCase()) || this.palette.unshift(this.color), this.strokeWidth = t.strokeWidth ?? Di;
|
|
1652
1724
|
}
|
|
1653
1725
|
/** Mount the editor and resolve when the user commits (Done) or skips. */
|
|
1654
1726
|
open() {
|
|
@@ -1670,7 +1742,7 @@ class At {
|
|
|
1670
1742
|
}
|
|
1671
1743
|
/** A round colour swatch button for the toolbar's colour group. */
|
|
1672
1744
|
swatchButton(t) {
|
|
1673
|
-
const e =
|
|
1745
|
+
const e = yt(t), o = q("button", {
|
|
1674
1746
|
type: "button",
|
|
1675
1747
|
class: "qaid-annotate-swatch",
|
|
1676
1748
|
"data-qaid-color": t,
|
|
@@ -1710,19 +1782,19 @@ class At {
|
|
|
1710
1782
|
"aria-label": this.labels.title
|
|
1711
1783
|
});
|
|
1712
1784
|
const a = q("div", { class: "qaid-annotate-tools" });
|
|
1713
|
-
a.appendChild(this.toolButton("rect",
|
|
1785
|
+
a.appendChild(this.toolButton("rect", de, this.labels.rectangle)), a.appendChild(this.toolButton("arrow", ce, this.labels.arrow)), a.appendChild(this.toolButton("pen", le, this.labels.pen)), a.appendChild(this.toolButton("blur", he, this.labels.blur));
|
|
1714
1786
|
const c = q("div", {
|
|
1715
1787
|
class: "qaid-annotate-colors",
|
|
1716
1788
|
role: "group",
|
|
1717
1789
|
"aria-label": this.labels.colors
|
|
1718
1790
|
});
|
|
1719
1791
|
for (const h of this.palette) c.appendChild(this.swatchButton(h));
|
|
1720
|
-
this.undoBtn = this.actionButton("undo",
|
|
1721
|
-
const l = this.actionButton("skip",
|
|
1792
|
+
this.undoBtn = this.actionButton("undo", ue, this.labels.undo, "qaid-annotate-undo"), this.undoBtn.disabled = !0;
|
|
1793
|
+
const l = this.actionButton("skip", fe, this.labels.skip, "qaid-annotate-skip"), d = this.actionButton("done", Et, this.labels.done, "qaid-annotate-done"), r = q("div", { class: "qaid-annotate-actions" });
|
|
1722
1794
|
r.appendChild(this.undoBtn), r.appendChild(l), r.appendChild(d), this.toolbar.appendChild(a), this.toolbar.appendChild(c), this.toolbar.appendChild(r), this.container.appendChild(o), this.container.appendChild(n), this.container.appendChild(s), this.container.appendChild(this.toolbar), this.opts.root.appendChild(this.container), this.toolbar.addEventListener("click", this.onToolbarClick), this.canvas.addEventListener("pointerdown", this.onPointerDown), this.container.addEventListener("pointermove", this.onPointerMove), this.container.addEventListener("pointerup", this.onPointerUp), this.container.addEventListener("keydown", this.onKeyDown), this.opts.openDialog?.(this.container, {
|
|
1723
1795
|
labelledbyId: t,
|
|
1724
1796
|
describedbyId: e
|
|
1725
|
-
}), this.opts.announce?.(this.labels.instructions),
|
|
1797
|
+
}), this.opts.announce?.(this.labels.instructions), Ht(this.opts.dataUrl).then((h) => {
|
|
1726
1798
|
this.img = h, this.canvas.width = h.naturalWidth || h.width || 1, this.canvas.height = h.naturalHeight || h.height || 1, this.redraw();
|
|
1727
1799
|
}).catch(() => {
|
|
1728
1800
|
this.img = null, this.redraw();
|
|
@@ -1742,8 +1814,8 @@ class At {
|
|
|
1742
1814
|
if (t) {
|
|
1743
1815
|
t.clearRect(0, 0, this.canvas.width, this.canvas.height), this.img && t.drawImage(this.img, 0, 0, this.canvas.width, this.canvas.height);
|
|
1744
1816
|
for (const e of this.shapes)
|
|
1745
|
-
|
|
1746
|
-
this.current &&
|
|
1817
|
+
H(t, e);
|
|
1818
|
+
this.current && H(t, this.current);
|
|
1747
1819
|
}
|
|
1748
1820
|
}
|
|
1749
1821
|
/** Select the active drawing tool and reflect it on the toolbar. */
|
|
@@ -1754,7 +1826,7 @@ class At {
|
|
|
1754
1826
|
n.getAttribute("data-qaid-tool") === t ? "true" : "false"
|
|
1755
1827
|
);
|
|
1756
1828
|
});
|
|
1757
|
-
const o = this.labels[
|
|
1829
|
+
const o = this.labels[$i[t]];
|
|
1758
1830
|
this.opts.announce?.(`${o} tool selected`);
|
|
1759
1831
|
}
|
|
1760
1832
|
/** Set the active drawing colour; subsequent shapes use it. */
|
|
@@ -1764,7 +1836,7 @@ class At {
|
|
|
1764
1836
|
"aria-pressed",
|
|
1765
1837
|
(o.getAttribute("data-qaid-color") ?? "").toLowerCase() === t.toLowerCase() ? "true" : "false"
|
|
1766
1838
|
);
|
|
1767
|
-
}), this.opts.announce?.(`${
|
|
1839
|
+
}), this.opts.announce?.(`${yt(t)} colour selected`);
|
|
1768
1840
|
}
|
|
1769
1841
|
onToolbarClick = (t) => {
|
|
1770
1842
|
const o = t.target?.closest(
|
|
@@ -1803,7 +1875,7 @@ class At {
|
|
|
1803
1875
|
if (!this.drawing || !this.current) return;
|
|
1804
1876
|
this.drawing = !1;
|
|
1805
1877
|
const t = this.current;
|
|
1806
|
-
if (this.current = null,
|
|
1878
|
+
if (this.current = null, Pi(t)) {
|
|
1807
1879
|
this.redraw();
|
|
1808
1880
|
return;
|
|
1809
1881
|
}
|
|
@@ -1832,7 +1904,7 @@ class At {
|
|
|
1832
1904
|
/** Composite the annotations and resolve with the new WebP data URL. */
|
|
1833
1905
|
async done() {
|
|
1834
1906
|
if (this.settled) return;
|
|
1835
|
-
const t = await
|
|
1907
|
+
const t = await Ot(this.opts.dataUrl, this.shapes, {
|
|
1836
1908
|
quality: this.opts.quality
|
|
1837
1909
|
});
|
|
1838
1910
|
this.opts.announce?.("Annotated screenshot attached"), this.settle(t);
|
|
@@ -1848,27 +1920,27 @@ class At {
|
|
|
1848
1920
|
this.toolbar.removeEventListener("click", this.onToolbarClick), this.canvas.removeEventListener("pointerdown", this.onPointerDown), this.container.removeEventListener("pointermove", this.onPointerMove), this.container.removeEventListener("pointerup", this.onPointerUp), this.container.removeEventListener("keydown", this.onKeyDown), this.opts.closeDialog?.(), this.container.remove();
|
|
1849
1921
|
}
|
|
1850
1922
|
}
|
|
1851
|
-
const
|
|
1923
|
+
const $i = {
|
|
1852
1924
|
rect: "rectangle",
|
|
1853
1925
|
arrow: "arrow",
|
|
1854
1926
|
pen: "pen",
|
|
1855
1927
|
blur: "blur"
|
|
1856
1928
|
};
|
|
1857
|
-
function
|
|
1858
|
-
return new
|
|
1929
|
+
function _i(i) {
|
|
1930
|
+
return new zt(i).open();
|
|
1859
1931
|
}
|
|
1860
|
-
const
|
|
1932
|
+
const wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1861
1933
|
__proto__: null,
|
|
1862
|
-
AnnotationEditor:
|
|
1863
|
-
compositeAnnotations:
|
|
1864
|
-
drawShape:
|
|
1865
|
-
openAnnotationEditor:
|
|
1866
|
-
rectFromPoints:
|
|
1934
|
+
AnnotationEditor: zt,
|
|
1935
|
+
compositeAnnotations: Ot,
|
|
1936
|
+
drawShape: H,
|
|
1937
|
+
openAnnotationEditor: _i,
|
|
1938
|
+
rectFromPoints: B
|
|
1867
1939
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1868
|
-
|
|
1869
|
-
const
|
|
1870
|
-
function
|
|
1871
|
-
const o =
|
|
1940
|
+
ci();
|
|
1941
|
+
const Ni = document;
|
|
1942
|
+
function p(i, t, ...e) {
|
|
1943
|
+
const o = Ni.createElement(i);
|
|
1872
1944
|
if (t) {
|
|
1873
1945
|
if (t.class && (o.className = t.class), t.style && (o.style.cssText = t.style), t.html != null && (o.innerHTML = t.html), t.text != null && (o.textContent = t.text), t.attrs)
|
|
1874
1946
|
for (const n in t.attrs) o.setAttribute(n, t.attrs[n]);
|
|
@@ -1879,7 +1951,7 @@ function m(i, t, ...e) {
|
|
|
1879
1951
|
n != null && n !== !1 && o.append(n);
|
|
1880
1952
|
return o;
|
|
1881
1953
|
}
|
|
1882
|
-
class
|
|
1954
|
+
class Fi {
|
|
1883
1955
|
constructor(t) {
|
|
1884
1956
|
this.host = t;
|
|
1885
1957
|
}
|
|
@@ -1906,8 +1978,8 @@ class Ei {
|
|
|
1906
1978
|
async startRecording(t = []) {
|
|
1907
1979
|
if (!(this.isRecording || this.host.state !== "IDLE"))
|
|
1908
1980
|
try {
|
|
1909
|
-
this.networkCapture =
|
|
1910
|
-
const { createVideoRecorder: e } = await Promise.resolve().then(() =>
|
|
1981
|
+
this.networkCapture = ui();
|
|
1982
|
+
const { createVideoRecorder: e } = await Promise.resolve().then(() => Bt);
|
|
1911
1983
|
this.videoRecorder = e({
|
|
1912
1984
|
maxDuration: this.host.config.videoOptions.maxDuration,
|
|
1913
1985
|
redactionElements: t
|
|
@@ -1917,7 +1989,7 @@ class Ei {
|
|
|
1917
1989
|
this.isRecording && (this.recordedBlob = o, this.isRecording = !1, this.host.announceMsg("Recording stopped"), this.removeRecordingIndicator(), document.removeEventListener("keydown", this.host.boundKeyDown), this.host.setButtonsDisabled(!1), o && o.size > 0 ? this.showRecordingPreview() : this.cleanupRecording());
|
|
1918
1990
|
}), await this.videoRecorder.start(), this.isRecording = !0, this.host.announceMsg("Recording started"), this.host.setButtonsDisabled(!0), this.showRecordingIndicator(), document.addEventListener("keydown", this.host.boundKeyDown);
|
|
1919
1991
|
} catch (e) {
|
|
1920
|
-
e instanceof Error && /current tab/i.test(e.message) && this.host.announceMsg(e.message), this.cleanupRecording();
|
|
1992
|
+
e instanceof Error && /current tab|cannot blur/i.test(e.message) && this.host.announceMsg(e.message), this.cleanupRecording();
|
|
1921
1993
|
}
|
|
1922
1994
|
}
|
|
1923
1995
|
async stopRecording() {
|
|
@@ -1937,27 +2009,27 @@ class Ei {
|
|
|
1937
2009
|
startPicking() {
|
|
1938
2010
|
if (this.isRecording || this.host.state !== "IDLE") return;
|
|
1939
2011
|
this.host.setState("REDACT_PICKING"), this.redactPicks = [];
|
|
1940
|
-
const t = this.host.ensureOverlayHost(), e =
|
|
2012
|
+
const t = this.host.ensureOverlayHost(), e = p("div", { style: "position:absolute;inset:0;" }), o = p(
|
|
1941
2013
|
"div",
|
|
1942
2014
|
{ class: "qaid-redact-picker", style: "position:fixed;inset:0;pointer-events:none;" },
|
|
1943
2015
|
e,
|
|
1944
2016
|
// Control bar — the only pointer-interactive part of the overlay.
|
|
1945
|
-
|
|
2017
|
+
p(
|
|
1946
2018
|
"div",
|
|
1947
2019
|
{
|
|
1948
2020
|
style: "position:fixed;left:50%;bottom:24px;transform:translateX(-50%);display:flex;gap:12px;align-items:center;pointer-events:auto;background:#0b1220;color:#fff;border:1px solid #ff6b6b;border-radius:9999px;padding:10px 16px;font:600 13px system-ui,sans-serif;box-shadow:0 8px 30px rgba(0,0,0,.5);"
|
|
1949
2021
|
},
|
|
1950
|
-
|
|
2022
|
+
p("span", {
|
|
1951
2023
|
text: "Click sensitive areas to blur",
|
|
1952
2024
|
attrs: { "data-qaid-redact-label": "" }
|
|
1953
2025
|
}),
|
|
1954
|
-
|
|
2026
|
+
p("button", {
|
|
1955
2027
|
text: "Start recording",
|
|
1956
2028
|
attrs: { type: "button" },
|
|
1957
2029
|
style: "cursor:pointer;border:0;border-radius:9999px;padding:8px 14px;background:#ff6b6b;color:#0b1220;font:inherit;",
|
|
1958
2030
|
on: { click: () => this.finishRedactionPicking(!0) }
|
|
1959
2031
|
}),
|
|
1960
|
-
|
|
2032
|
+
p("button", {
|
|
1961
2033
|
text: "Cancel",
|
|
1962
2034
|
attrs: { type: "button" },
|
|
1963
2035
|
style: "cursor:pointer;border:0;background:transparent;color:#9fb3c8;font:inherit;",
|
|
@@ -1973,7 +2045,7 @@ class Ei {
|
|
|
1973
2045
|
}
|
|
1974
2046
|
handleRedactPickClick(t) {
|
|
1975
2047
|
const e = t.target instanceof Element ? t.target : null;
|
|
1976
|
-
if (!e ||
|
|
2048
|
+
if (!e || R(e) || this.redactPickerRoot?.contains(e)) return;
|
|
1977
2049
|
t.preventDefault(), t.stopPropagation();
|
|
1978
2050
|
const o = this.redactPicks.indexOf(e);
|
|
1979
2051
|
o >= 0 ? this.redactPicks.splice(o, 1) : this.redactPicks.push(e);
|
|
@@ -1988,7 +2060,7 @@ class Ei {
|
|
|
1988
2060
|
for (const e of this.redactPicks) {
|
|
1989
2061
|
const o = e.getBoundingClientRect();
|
|
1990
2062
|
o.width <= 0 || o.height <= 0 || t.appendChild(
|
|
1991
|
-
|
|
2063
|
+
p("div", {
|
|
1992
2064
|
style: `position:fixed;left:${o.left}px;top:${o.top}px;width:${o.width}px;height:${o.height}px;border:2px solid #ff6b6b;border-radius:4px;background:rgba(255,107,107,.18);pointer-events:none;`
|
|
1993
2065
|
})
|
|
1994
2066
|
);
|
|
@@ -2001,15 +2073,15 @@ class Ei {
|
|
|
2001
2073
|
}
|
|
2002
2074
|
showRecordingIndicator() {
|
|
2003
2075
|
const t = this.host.ensureOverlayHost();
|
|
2004
|
-
this.recordingIndicator =
|
|
2076
|
+
this.recordingIndicator = p(
|
|
2005
2077
|
"div",
|
|
2006
2078
|
{ class: "qaid-recording-indicator", style: `z-index:${this.host.config.zIndex + 100}` },
|
|
2007
|
-
|
|
2008
|
-
|
|
2079
|
+
p("div", { class: "qaid-recording-dot" }),
|
|
2080
|
+
p("span", {
|
|
2009
2081
|
class: "qaid-recording-time",
|
|
2010
2082
|
text: this.formatTime(this.host.config.videoOptions.maxDuration)
|
|
2011
2083
|
}),
|
|
2012
|
-
|
|
2084
|
+
p("button", {
|
|
2013
2085
|
class: "qaid-recording-stop",
|
|
2014
2086
|
text: "Stop",
|
|
2015
2087
|
attrs: { type: "button" },
|
|
@@ -2033,34 +2105,34 @@ class Ei {
|
|
|
2033
2105
|
this.recordingIndicator && (this.recordingIndicator.remove(), this.recordingIndicator = null);
|
|
2034
2106
|
}
|
|
2035
2107
|
showRecordingPreview() {
|
|
2036
|
-
const t = this.host.ensureOverlayHost(), e = URL.createObjectURL(this.recordedBlob), o = `qaid-video-title-${this.host.uid}`, n =
|
|
2108
|
+
const t = this.host.ensureOverlayHost(), e = URL.createObjectURL(this.recordedBlob), o = `qaid-video-title-${this.host.uid}`, n = p("h3", { text: "Review your recording", attrs: { id: o } }), s = p("video");
|
|
2037
2109
|
s.src = e, s.controls = !0, s.autoplay = !0, s.muted = !0;
|
|
2038
|
-
const a =
|
|
2110
|
+
const a = p("textarea", {
|
|
2039
2111
|
attrs: {
|
|
2040
2112
|
placeholder: "Optional: Describe the issue you recorded...",
|
|
2041
2113
|
"aria-label": "Describe the issue you recorded"
|
|
2042
2114
|
}
|
|
2043
|
-
}), c =
|
|
2115
|
+
}), c = p("button", {
|
|
2044
2116
|
class: "qaid-video-btn qaid-video-btn-send",
|
|
2045
2117
|
text: "Send",
|
|
2046
2118
|
attrs: { type: "button" },
|
|
2047
2119
|
on: { click: () => this.submitVideoFeedback(a.value.trim() || null, c) }
|
|
2048
|
-
}), l =
|
|
2120
|
+
}), l = p(
|
|
2049
2121
|
"div",
|
|
2050
2122
|
{ class: "qaid-video-preview-box" },
|
|
2051
2123
|
n,
|
|
2052
2124
|
s,
|
|
2053
2125
|
a,
|
|
2054
|
-
|
|
2126
|
+
p(
|
|
2055
2127
|
"div",
|
|
2056
2128
|
{ class: "qaid-video-preview-actions" },
|
|
2057
|
-
|
|
2129
|
+
p("button", {
|
|
2058
2130
|
class: "qaid-video-btn qaid-video-btn-cancel",
|
|
2059
2131
|
text: "Cancel",
|
|
2060
2132
|
attrs: { type: "button" },
|
|
2061
2133
|
on: { click: () => this.cancelRecordingPreview() }
|
|
2062
2134
|
}),
|
|
2063
|
-
|
|
2135
|
+
p("button", {
|
|
2064
2136
|
class: "qaid-video-btn qaid-video-btn-rerecord",
|
|
2065
2137
|
text: "Re-record",
|
|
2066
2138
|
attrs: { type: "button" },
|
|
@@ -2073,7 +2145,7 @@ class Ei {
|
|
|
2073
2145
|
c
|
|
2074
2146
|
)
|
|
2075
2147
|
);
|
|
2076
|
-
this.videoPreview =
|
|
2148
|
+
this.videoPreview = p(
|
|
2077
2149
|
"div",
|
|
2078
2150
|
{ class: "qaid-video-preview", style: `z-index:${this.host.config.zIndex + 100}` },
|
|
2079
2151
|
l
|
|
@@ -2094,35 +2166,52 @@ class Ei {
|
|
|
2094
2166
|
this.isSendingVideo = !0, e.disabled = !0, e.textContent = "Sending...";
|
|
2095
2167
|
const o = new FormData();
|
|
2096
2168
|
o.append("video", this.recordedBlob, `recording.${this.recordedBlob.type.includes("mp4") ? "mp4" : "webm"}`), o.append("pageUrl", window.location.href), o.append("visitorId", this.host.visitorId), this.host.config.apiKey && o.append("apiKey", this.host.config.apiKey), t && o.append("message", t), this.host.consoleCapture && o.append("consoleErrors", JSON.stringify(this.host.consoleCapture.errors)), this.networkCapture && o.append("networkErrors", JSON.stringify(this.networkCapture.errors));
|
|
2097
|
-
let n = null;
|
|
2169
|
+
let n = null, s = null;
|
|
2098
2170
|
try {
|
|
2099
|
-
const
|
|
2171
|
+
const a = await fetch(`${this.host.config.endpoint}/video`, {
|
|
2100
2172
|
method: "POST",
|
|
2101
2173
|
body: o
|
|
2102
2174
|
});
|
|
2103
|
-
if (
|
|
2175
|
+
if (a.ok) {
|
|
2104
2176
|
this.host.announceMsg("Recording sent");
|
|
2105
2177
|
try {
|
|
2106
|
-
n = (await
|
|
2178
|
+
n = (await a.json())?.id ?? null;
|
|
2107
2179
|
} catch {
|
|
2108
2180
|
}
|
|
2109
2181
|
} else
|
|
2110
|
-
console.error("Failed to submit video feedback:", await
|
|
2111
|
-
} catch (
|
|
2112
|
-
console.error("Failed to submit video feedback:",
|
|
2182
|
+
console.error("Failed to submit video feedback:", await a.text()), s = a.status === 413 ? "This recording is too large to send. Try a shorter one." : "Your recording could not be sent.";
|
|
2183
|
+
} catch (a) {
|
|
2184
|
+
console.error("Failed to submit video feedback:", a), s = "Your recording could not be sent. Check your connection and try again.";
|
|
2185
|
+
}
|
|
2186
|
+
if (this.isSendingVideo = !1, s) {
|
|
2187
|
+
this.showSendError(s, e);
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
|
|
2191
|
+
}
|
|
2192
|
+
/**
|
|
2193
|
+
* Keep the preview open and say the upload failed. Closing it, as a success
|
|
2194
|
+
* does, told the visitor their recording had arrived when it had not. Send
|
|
2195
|
+
* is re-enabled for another try; Cancel and Re-record still work.
|
|
2196
|
+
*/
|
|
2197
|
+
showSendError(t, e) {
|
|
2198
|
+
this.host.announceMsg(`Failed to send recording. ${t}`, !0), e.disabled = !1, e.textContent = "Send";
|
|
2199
|
+
const o = this.videoPreview?.querySelector(".qaid-video-preview-actions");
|
|
2200
|
+
if (o) {
|
|
2201
|
+
let n = this.videoPreview.querySelector(".qaid-video-error");
|
|
2202
|
+
n || (n = p("p", { class: "qaid-video-error" }), o.before(n)), n.textContent = t;
|
|
2113
2203
|
}
|
|
2114
|
-
this.isSendingVideo = !1, this.removeVideoPreview(), this.cleanupRecording(), await this.host.tryLaunchQuest("video", n);
|
|
2115
2204
|
}
|
|
2116
2205
|
cleanupRecording() {
|
|
2117
2206
|
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.host.setButtonsDisabled(!1), this.host.overlayShadowHost && this.host.state === "IDLE" && (this.host.overlayShadowHost.style.pointerEvents = "none");
|
|
2118
2207
|
}
|
|
2119
2208
|
}
|
|
2120
|
-
const
|
|
2209
|
+
const kt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2121
2210
|
__proto__: null,
|
|
2122
|
-
RecordingController:
|
|
2211
|
+
RecordingController: Fi
|
|
2123
2212
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2124
|
-
async function
|
|
2125
|
-
const { quality: t =
|
|
2213
|
+
async function Vi(i = {}) {
|
|
2214
|
+
const { quality: t = 0.8, maxWidth: e = 1280, maxHeight: o = 800 } = i;
|
|
2126
2215
|
try {
|
|
2127
2216
|
if (!navigator.mediaDevices?.getDisplayMedia)
|
|
2128
2217
|
return console.warn("Screen Capture API not available"), null;
|
|
@@ -2142,19 +2231,19 @@ async function Ti(i = {}) {
|
|
|
2142
2231
|
};
|
|
2143
2232
|
w();
|
|
2144
2233
|
}), await new Promise((g) => setTimeout(g, 100));
|
|
2145
|
-
const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r),
|
|
2146
|
-
b.width = h, b.height =
|
|
2234
|
+
const l = a.width || c.videoWidth, d = a.height || c.videoHeight, r = Math.min(e / l, o / d, 1), h = Math.round(l * r), f = Math.round(d * r), b = document.createElement("canvas");
|
|
2235
|
+
b.width = h, b.height = f;
|
|
2147
2236
|
const y = b.getContext("2d");
|
|
2148
|
-
return y ? (y.drawImage(c, 0, 0, h,
|
|
2237
|
+
return y ? (y.drawImage(c, 0, 0, h, f), s.stop(), b.toDataURL("image/webp", t)) : (s.stop(), null);
|
|
2149
2238
|
} catch (n) {
|
|
2150
2239
|
return console.warn("Screenshot capture failed:", n), null;
|
|
2151
2240
|
}
|
|
2152
2241
|
}
|
|
2153
|
-
const
|
|
2242
|
+
const xt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2154
2243
|
__proto__: null,
|
|
2155
|
-
captureScreenshot:
|
|
2244
|
+
captureScreenshot: Vi
|
|
2156
2245
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2157
|
-
class
|
|
2246
|
+
class Ui {
|
|
2158
2247
|
constructor(t) {
|
|
2159
2248
|
this.host = t;
|
|
2160
2249
|
}
|
|
@@ -2182,15 +2271,17 @@ class Ai {
|
|
|
2182
2271
|
}
|
|
2183
2272
|
showBottomSheet() {
|
|
2184
2273
|
const t = this.host.ensureOverlayHost(), e = document.createElement("div");
|
|
2185
|
-
e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2274
|
+
e.className = "qaid-bottom-sheet", e.style.zIndex = String(this.host.config.zIndex + 3), e.appendChild(
|
|
2275
|
+
p(
|
|
2276
|
+
"div",
|
|
2277
|
+
{ class: "qaid-bottom-sheet-content" },
|
|
2278
|
+
p("div", { class: "qaid-bottom-sheet-handle" }),
|
|
2279
|
+
this.buildModalContent()
|
|
2280
|
+
)
|
|
2281
|
+
), this.host.applyVars(e), t.appendChild(e), this.modalContainer = e, this.setupModalInteractions();
|
|
2191
2282
|
}
|
|
2192
2283
|
showPositionedModal() {
|
|
2193
|
-
const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } =
|
|
2284
|
+
const t = this.host.ensureOverlayHost(), { modal: e, arrow: o } = je(
|
|
2194
2285
|
this.host.selectedBounds,
|
|
2195
2286
|
window.innerWidth,
|
|
2196
2287
|
window.innerHeight,
|
|
@@ -2206,25 +2297,65 @@ class Ai {
|
|
|
2206
2297
|
const n = document.createElement("div");
|
|
2207
2298
|
n.className = "qaid-modal-arrow", n.style.left = `${o.left}px`;
|
|
2208
2299
|
const s = document.createElement("div");
|
|
2209
|
-
s.className = "qaid-modal-box", s.
|
|
2210
|
-
}
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2300
|
+
s.className = "qaid-modal-box", s.appendChild(this.buildModalContent()), this.modalContainer.appendChild(n), this.modalContainer.appendChild(s), this.host.applyVars(this.modalContainer), t.appendChild(this.modalContainer), this.setupModalInteractions();
|
|
2301
|
+
}
|
|
2302
|
+
/**
|
|
2303
|
+
* The modal's contents, built as nodes rather than an HTML string.
|
|
2304
|
+
*
|
|
2305
|
+
* Every piece of copy (title, subtitle, placeholder, button) goes in as
|
|
2306
|
+
* text, so a `<`, `&` or `"` in a translation shows as written instead of
|
|
2307
|
+
* being parsed as markup or cutting an attribute short. Only the icons are
|
|
2308
|
+
* markup, because they are documented as SVG/HTML strings.
|
|
2309
|
+
*/
|
|
2310
|
+
buildModalContent() {
|
|
2311
|
+
const { config: t, uid: e } = this.host, o = t.text, n = this.host.feedbackData.feedbackType, s = n === "up", a = t.positiveIcon || V, c = t.negativeIcon || U, l = t.buttonClass ? `qaid-type-toggle qaid-type-toggle-custom ${t.buttonClass} ${s ? "qaid-btn-up" : "qaid-btn-down"}` : `qaid-type-toggle ${s ? "qaid-type-up" : "qaid-type-down"}`, d = s ? "Feedback type: positive" : "Feedback type: negative", r = n === "neutral" ? p("span", {
|
|
2312
|
+
class: "qaid-type-static",
|
|
2313
|
+
html: t.feedbackIcon || St,
|
|
2314
|
+
attrs: { "aria-hidden": "true" }
|
|
2315
|
+
}) : p("button", {
|
|
2316
|
+
class: l,
|
|
2317
|
+
html: s ? a : c,
|
|
2318
|
+
attrs: {
|
|
2319
|
+
type: "button",
|
|
2320
|
+
title: "Click to switch",
|
|
2321
|
+
"aria-pressed": String(s),
|
|
2322
|
+
"aria-label": d
|
|
2323
|
+
}
|
|
2324
|
+
}), h = document.createDocumentFragment();
|
|
2325
|
+
return h.append(
|
|
2326
|
+
p(
|
|
2327
|
+
"div",
|
|
2328
|
+
{ class: "qaid-modal-header" },
|
|
2329
|
+
r,
|
|
2330
|
+
p(
|
|
2331
|
+
"div",
|
|
2332
|
+
{ class: "qaid-modal-header-text" },
|
|
2333
|
+
p("h3", {
|
|
2334
|
+
class: "qaid-modal-title",
|
|
2335
|
+
text: o.modalTitle,
|
|
2336
|
+
attrs: { id: `qaid-modal-title-${e}` }
|
|
2337
|
+
}),
|
|
2338
|
+
p("p", {
|
|
2339
|
+
class: "qaid-modal-subtitle",
|
|
2340
|
+
text: o.modalSubtitle,
|
|
2341
|
+
attrs: { id: `qaid-modal-subtitle-${e}` }
|
|
2342
|
+
})
|
|
2343
|
+
)
|
|
2344
|
+
),
|
|
2345
|
+
p("textarea", {
|
|
2346
|
+
class: "qaid-textarea",
|
|
2347
|
+
attrs: { "aria-label": o.modalSubtitle, placeholder: o.placeholder }
|
|
2348
|
+
}),
|
|
2349
|
+
p(
|
|
2350
|
+
"div",
|
|
2351
|
+
{ class: "qaid-btn-row" },
|
|
2352
|
+
p("button", {
|
|
2353
|
+
class: "qaid-btn-submit",
|
|
2354
|
+
text: o.skipButton,
|
|
2355
|
+
attrs: { type: "button" }
|
|
2356
|
+
})
|
|
2357
|
+
)
|
|
2358
|
+
), h;
|
|
2228
2359
|
}
|
|
2229
2360
|
setupModalInteractions() {
|
|
2230
2361
|
this.host.openDialogA11y(this.modalContainer, {
|
|
@@ -2242,7 +2373,7 @@ class Ai {
|
|
|
2242
2373
|
o && o.addEventListener("click", () => {
|
|
2243
2374
|
const n = this.host.feedbackData.feedbackType === "up" ? "down" : "up";
|
|
2244
2375
|
this.host.feedbackData.feedbackType = n, this.host.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"));
|
|
2245
|
-
const s = this.host.config.positiveIcon || V, a = this.host.config.negativeIcon ||
|
|
2376
|
+
const s = this.host.config.positiveIcon || V, a = this.host.config.negativeIcon || U;
|
|
2246
2377
|
o.innerHTML = n === "up" ? s : a;
|
|
2247
2378
|
const c = n === "up" ? "Feedback type: positive" : "Feedback type: negative";
|
|
2248
2379
|
o.setAttribute("aria-pressed", String(n === "up")), o.setAttribute("aria-label", c), this.host.announceMsg(c), this.host.feedbackId && fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
@@ -2253,59 +2384,79 @@ class Ai {
|
|
|
2253
2384
|
});
|
|
2254
2385
|
}
|
|
2255
2386
|
async submitMessage(t) {
|
|
2256
|
-
let e =
|
|
2387
|
+
let e = null;
|
|
2257
2388
|
if (this.host.feedbackId) {
|
|
2258
2389
|
try {
|
|
2259
|
-
await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
2390
|
+
const o = await fetch(`${this.host.config.endpoint}/${this.host.feedbackId}`, {
|
|
2260
2391
|
method: "PATCH",
|
|
2261
2392
|
headers: { "Content-Type": "application/json" },
|
|
2262
2393
|
body: JSON.stringify({ message: t })
|
|
2263
|
-
})
|
|
2394
|
+
});
|
|
2395
|
+
e = o.ok, o.ok || console.error("Failed to submit feedback message: HTTP", o.status);
|
|
2264
2396
|
} catch (o) {
|
|
2265
|
-
console.error("Failed to submit feedback message:", o);
|
|
2397
|
+
console.error("Failed to submit feedback message:", o), e = !1;
|
|
2266
2398
|
}
|
|
2267
2399
|
this.host.setFeedbackId(null);
|
|
2268
2400
|
}
|
|
2401
|
+
if (e === !1) {
|
|
2402
|
+
this.showResult(!1);
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2269
2405
|
if (e && !this.host.config.hideConfirmation) {
|
|
2270
|
-
this.
|
|
2406
|
+
this.showResult(!0);
|
|
2271
2407
|
return;
|
|
2272
2408
|
}
|
|
2273
2409
|
this.close();
|
|
2274
2410
|
}
|
|
2275
2411
|
/**
|
|
2276
|
-
* Replace the modal's contents with a checkmark and a short
|
|
2412
|
+
* Replace the modal's contents with the outcome: a checkmark and a short
|
|
2413
|
+
* acknowledgement, or an error mark and a "not sent" notice.
|
|
2277
2414
|
*
|
|
2278
2415
|
* The submit button that had focus is gone by this point, so focus moves to
|
|
2279
2416
|
* the heading (WCAG 2.4.3) and the message is announced. Mirrors the quests
|
|
2280
|
-
* embed's thank-you screen so the two products confirm the same way.
|
|
2417
|
+
* embed's thank-you screen so the two products confirm the same way. Copy
|
|
2418
|
+
* goes in as text, never markup.
|
|
2281
2419
|
*/
|
|
2282
|
-
|
|
2283
|
-
const
|
|
2284
|
-
if (!
|
|
2420
|
+
showResult(t) {
|
|
2421
|
+
const e = this.modalContainer?.querySelector(".qaid-modal-box") ?? this.modalContainer?.querySelector(".qaid-bottom-sheet-content") ?? this.modalContainer;
|
|
2422
|
+
if (!e) {
|
|
2285
2423
|
this.close();
|
|
2286
2424
|
return;
|
|
2287
2425
|
}
|
|
2288
|
-
const
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
}
|
|
2301
|
-
|
|
2426
|
+
const o = this.host.config.text, n = t ? o.confirmationTitle : o.errorTitle, s = t ? o.confirmationMessage : o.errorMessage, a = p("h3", {
|
|
2427
|
+
class: "qaid-confirm-title",
|
|
2428
|
+
text: n,
|
|
2429
|
+
attrs: { id: `qaid-confirm-title-${this.host.uid}`, tabindex: "-1" }
|
|
2430
|
+
});
|
|
2431
|
+
e.textContent = "", e.appendChild(
|
|
2432
|
+
p(
|
|
2433
|
+
"div",
|
|
2434
|
+
{ class: t ? "qaid-confirm" : "qaid-confirm qaid-confirm-error" },
|
|
2435
|
+
p("span", {
|
|
2436
|
+
class: "qaid-confirm-icon",
|
|
2437
|
+
html: t ? Et : pe,
|
|
2438
|
+
attrs: { "aria-hidden": "true" }
|
|
2439
|
+
}),
|
|
2440
|
+
a,
|
|
2441
|
+
p("p", { class: "qaid-confirm-message", text: s }),
|
|
2442
|
+
p("button", {
|
|
2443
|
+
class: "qaid-btn-submit qaid-confirm-close",
|
|
2444
|
+
text: o.confirmationClose,
|
|
2445
|
+
attrs: { type: "button" },
|
|
2446
|
+
on: { click: () => this.close() }
|
|
2447
|
+
})
|
|
2448
|
+
)
|
|
2449
|
+
), requestAnimationFrame(() => a.focus()), this.host.announceMsg(`${n} ${s}`, !0);
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
const qt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2302
2453
|
__proto__: null,
|
|
2303
|
-
ModalController:
|
|
2304
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
2305
|
-
function
|
|
2454
|
+
ModalController: Ui
|
|
2455
|
+
}, Symbol.toStringTag, { value: "Module" })), $t = ["data-comp", "data-qa", "data-testid", "data-id"];
|
|
2456
|
+
function _t(i, t = document.body) {
|
|
2306
2457
|
let e = i;
|
|
2307
2458
|
for (; e && e !== t; ) {
|
|
2308
|
-
for (const o of
|
|
2459
|
+
for (const o of $t) {
|
|
2309
2460
|
const n = e.getAttribute(o);
|
|
2310
2461
|
if (n)
|
|
2311
2462
|
return `${o}="${n}"`;
|
|
@@ -2314,37 +2465,37 @@ function It(i, t = document.body) {
|
|
|
2314
2465
|
}
|
|
2315
2466
|
return null;
|
|
2316
2467
|
}
|
|
2317
|
-
function
|
|
2468
|
+
function ji(i, t = 100) {
|
|
2318
2469
|
const e = i.textContent?.trim().slice(0, t) || "";
|
|
2319
2470
|
return e.length === t ? e + "..." : e;
|
|
2320
2471
|
}
|
|
2321
|
-
function
|
|
2472
|
+
function Ki(i) {
|
|
2322
2473
|
let t = 1, e = i.previousElementSibling;
|
|
2323
2474
|
for (; e; )
|
|
2324
2475
|
t++, e = e.previousElementSibling;
|
|
2325
2476
|
return t;
|
|
2326
2477
|
}
|
|
2327
|
-
function
|
|
2478
|
+
function Wi(i) {
|
|
2328
2479
|
const t = [];
|
|
2329
2480
|
let e = i;
|
|
2330
2481
|
for (; e && e !== document.body && e !== document.documentElement; ) {
|
|
2331
|
-
const o = e.tagName.toLowerCase(), n =
|
|
2482
|
+
const o = e.tagName.toLowerCase(), n = Ki(e);
|
|
2332
2483
|
t.unshift(`${o}:nth-child(${n})`), e = e.parentElement;
|
|
2333
2484
|
}
|
|
2334
2485
|
return t.length > 0 ? `body > ${t.join(" > ")}` : "body";
|
|
2335
2486
|
}
|
|
2336
|
-
function
|
|
2487
|
+
function Xi(i) {
|
|
2337
2488
|
return i.replace(/([!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~])/g, "\\$1");
|
|
2338
2489
|
}
|
|
2339
|
-
function
|
|
2340
|
-
const t =
|
|
2341
|
-
return t ? `[${t}]` : i.id ? `#${
|
|
2490
|
+
function Yi(i) {
|
|
2491
|
+
const t = _t(i);
|
|
2492
|
+
return t ? `[${t}]` : i.id ? `#${Xi(i.id)}` : Wi(i);
|
|
2342
2493
|
}
|
|
2343
2494
|
function F(i) {
|
|
2344
|
-
const t =
|
|
2345
|
-
return { selector:
|
|
2495
|
+
const t = ji(i), e = _t(i);
|
|
2496
|
+
return { selector: Yi(i), text: t, dataAttr: e };
|
|
2346
2497
|
}
|
|
2347
|
-
const
|
|
2498
|
+
const Qi = [
|
|
2348
2499
|
"a[href]",
|
|
2349
2500
|
"button",
|
|
2350
2501
|
"input:not([type=hidden])",
|
|
@@ -2363,9 +2514,9 @@ const Pi = [
|
|
|
2363
2514
|
"p",
|
|
2364
2515
|
"li",
|
|
2365
2516
|
"label",
|
|
2366
|
-
|
|
2367
|
-
].join(","),
|
|
2368
|
-
function
|
|
2517
|
+
...$t.map((i) => `[${i}]`)
|
|
2518
|
+
].join(","), Ji = /^(?:A|BUTTON|INPUT|SELECT|TEXTAREA|SUMMARY)$/;
|
|
2519
|
+
function Gi(i) {
|
|
2369
2520
|
if (i.hasAttribute("hidden") || i.getAttribute("aria-hidden") === "true") return !1;
|
|
2370
2521
|
const t = i.ownerDocument?.defaultView;
|
|
2371
2522
|
if (t && typeof t.getComputedStyle == "function") {
|
|
@@ -2374,14 +2525,14 @@ function Hi(i) {
|
|
|
2374
2525
|
}
|
|
2375
2526
|
return !0;
|
|
2376
2527
|
}
|
|
2377
|
-
function
|
|
2378
|
-
const t = i.root ?? document.body, e = i.selector ??
|
|
2528
|
+
function Zi(i = {}) {
|
|
2529
|
+
const t = i.root ?? document.body, e = i.selector ?? Qi, o = i.isExcluded ?? (() => !1), n = i.isVisible ?? Gi;
|
|
2379
2530
|
return Array.from(t.querySelectorAll(e)).filter(
|
|
2380
2531
|
(s) => !o(s) && n(s)
|
|
2381
2532
|
);
|
|
2382
2533
|
}
|
|
2383
|
-
function
|
|
2384
|
-
const t = i.candidates ??
|
|
2534
|
+
function to(i) {
|
|
2535
|
+
const t = i.candidates ?? Zi({
|
|
2385
2536
|
root: i.root,
|
|
2386
2537
|
selector: i.selector,
|
|
2387
2538
|
isExcluded: i.isExcluded,
|
|
@@ -2398,7 +2549,7 @@ function $i(i) {
|
|
|
2398
2549
|
if (!e) return;
|
|
2399
2550
|
const k = u;
|
|
2400
2551
|
if (typeof k.focus == "function") {
|
|
2401
|
-
u.getAttribute("tabindex") === null && !
|
|
2552
|
+
u.getAttribute("tabindex") === null && !Ji.test(u.tagName) && (u.setAttribute("tabindex", "-1"), n.add(u));
|
|
2402
2553
|
try {
|
|
2403
2554
|
k.focus();
|
|
2404
2555
|
} catch {
|
|
@@ -2417,7 +2568,7 @@ function $i(i) {
|
|
|
2417
2568
|
function h() {
|
|
2418
2569
|
r(s + 1);
|
|
2419
2570
|
}
|
|
2420
|
-
function
|
|
2571
|
+
function f() {
|
|
2421
2572
|
r(s - 1);
|
|
2422
2573
|
}
|
|
2423
2574
|
function b() {
|
|
@@ -2438,7 +2589,7 @@ function $i(i) {
|
|
|
2438
2589
|
if (!a)
|
|
2439
2590
|
switch (u.key) {
|
|
2440
2591
|
case "Tab":
|
|
2441
|
-
u.preventDefault(), u.stopPropagation(), u.shiftKey ?
|
|
2592
|
+
u.preventDefault(), u.stopPropagation(), u.shiftKey ? f() : h();
|
|
2442
2593
|
break;
|
|
2443
2594
|
case "ArrowDown":
|
|
2444
2595
|
case "ArrowRight":
|
|
@@ -2446,7 +2597,7 @@ function $i(i) {
|
|
|
2446
2597
|
break;
|
|
2447
2598
|
case "ArrowUp":
|
|
2448
2599
|
case "ArrowLeft":
|
|
2449
|
-
u.preventDefault(), u.stopPropagation(),
|
|
2600
|
+
u.preventDefault(), u.stopPropagation(), f();
|
|
2450
2601
|
break;
|
|
2451
2602
|
case "Enter":
|
|
2452
2603
|
case " ":
|
|
@@ -2464,7 +2615,7 @@ function $i(i) {
|
|
|
2464
2615
|
getIndex: () => s,
|
|
2465
2616
|
getCurrent: b,
|
|
2466
2617
|
next: h,
|
|
2467
|
-
prev:
|
|
2618
|
+
prev: f,
|
|
2468
2619
|
moveTo: r,
|
|
2469
2620
|
select: g,
|
|
2470
2621
|
cancel: w,
|
|
@@ -2472,8 +2623,8 @@ function $i(i) {
|
|
|
2472
2623
|
stop: y
|
|
2473
2624
|
};
|
|
2474
2625
|
}
|
|
2475
|
-
const
|
|
2476
|
-
class
|
|
2626
|
+
const eo = 12;
|
|
2627
|
+
class io {
|
|
2477
2628
|
constructor(t) {
|
|
2478
2629
|
this.host = t;
|
|
2479
2630
|
}
|
|
@@ -2502,8 +2653,8 @@ class _i {
|
|
|
2502
2653
|
* KeyboardTargetingController owns Tab/Arrow/Enter/Space/Escape.
|
|
2503
2654
|
*/
|
|
2504
2655
|
startKeyboard(t) {
|
|
2505
|
-
this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.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 =
|
|
2506
|
-
isExcluded: (e) =>
|
|
2656
|
+
this.host.setState("TARGETING"), this.host.feedbackData.feedbackType = t, this.host.feedbackData.elementSelector = null, this.host.feedbackData.elementText = null, this.host.selectedBounds.visible = !1, document.body.style.setProperty("--qaid-positive", this.host.cssVars["--qaid-positive"]), document.body.style.setProperty("--qaid-negative", this.host.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 = to({
|
|
2657
|
+
isExcluded: (e) => R(e),
|
|
2507
2658
|
onHighlight: (e) => {
|
|
2508
2659
|
const o = e.getBoundingClientRect(), n = this.highlightBox;
|
|
2509
2660
|
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");
|
|
@@ -2515,7 +2666,7 @@ class _i {
|
|
|
2515
2666
|
});
|
|
2516
2667
|
}
|
|
2517
2668
|
selectKeyboardTarget(t) {
|
|
2518
|
-
const e =
|
|
2669
|
+
const e = lt(t, 8);
|
|
2519
2670
|
Object.assign(this.host.selectedBounds, e, {
|
|
2520
2671
|
clickX: e.x + e.width / 2,
|
|
2521
2672
|
clickY: e.y + e.height / 2,
|
|
@@ -2540,8 +2691,8 @@ class _i {
|
|
|
2540
2691
|
/** Move the crosshair/scope reticle and highlight the element under (x, y). */
|
|
2541
2692
|
updateReticleAt(t, e) {
|
|
2542
2693
|
if (this.mousePos.x = t, this.mousePos.y = e, this.crosshairH && (this.crosshairH.style.top = `${e}px`), this.crosshairV && (this.crosshairV.style.left = `${t}px`), this.scope && (this.scope.style.left = `${t}px`, this.scope.style.top = `${e}px`), this.captureLayer && this.host.shadowHost) {
|
|
2543
|
-
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n =
|
|
2544
|
-
if (n && !
|
|
2694
|
+
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ct(t, e, o);
|
|
2695
|
+
if (n && !R(n)) {
|
|
2545
2696
|
if (this.highlightBox) {
|
|
2546
2697
|
const s = n.getBoundingClientRect();
|
|
2547
2698
|
this.highlightBox.style.transform = `translate(${s.left}px, ${s.top}px)`, this.highlightBox.style.width = `${s.width}px`, this.highlightBox.style.height = `${s.height}px`, this.highlightBox.style.display = "block";
|
|
@@ -2559,14 +2710,14 @@ class _i {
|
|
|
2559
2710
|
}
|
|
2560
2711
|
handleTouchEnd(t) {
|
|
2561
2712
|
const e = t.changedTouches[0], o = this.touchStartPos;
|
|
2562
|
-
this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) >
|
|
2713
|
+
this.touchStartPos = null, !(!e || !o || Math.hypot(e.clientX - o.x, e.clientY - o.y) > eo) && (t.preventDefault(), this.selectAt(e.clientX, e.clientY));
|
|
2563
2714
|
}
|
|
2564
2715
|
/** Select the element under (x, y) and tear down targeting. */
|
|
2565
2716
|
selectAt(t, e) {
|
|
2566
|
-
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n =
|
|
2567
|
-
if (!n ||
|
|
2717
|
+
const o = [this.host.shadowHost, this.host.overlayShadowHost].filter(Boolean), n = ct(t, e, o);
|
|
2718
|
+
if (!n || R(n))
|
|
2568
2719
|
return;
|
|
2569
|
-
const s =
|
|
2720
|
+
const s = lt(n, 8);
|
|
2570
2721
|
Object.assign(this.host.selectedBounds, s, { clickX: t, clickY: e, visible: !0 });
|
|
2571
2722
|
const { selector: a, text: c } = F(n);
|
|
2572
2723
|
this.host.feedbackData.elementSelector = a, this.host.feedbackData.elementText = c, this.stopTargetingListeners(), document.body.classList.remove("qaid-targeting", "qaid-type-up"), document.body.style.removeProperty("--qaid-positive"), document.body.style.removeProperty("--qaid-negative"), this.host.setState("SELECTED"), this.host.clearActiveThumb(), this.showSelectedMarker(), this.host.submitFeedback();
|
|
@@ -2592,22 +2743,22 @@ class _i {
|
|
|
2592
2743
|
this.keyboardController?.stop(), this.keyboardController = null, this.stopTargetingListeners(), this.hideMarker();
|
|
2593
2744
|
}
|
|
2594
2745
|
}
|
|
2595
|
-
const
|
|
2746
|
+
const Ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2596
2747
|
__proto__: null,
|
|
2597
|
-
TargetingController:
|
|
2748
|
+
TargetingController: io
|
|
2598
2749
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2599
2750
|
export {
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2751
|
+
zt as AnnotationEditor,
|
|
2752
|
+
ni as QaidFeedback,
|
|
2753
|
+
Ti as captureDomScreenshot,
|
|
2754
|
+
ui as captureNetworkErrors,
|
|
2755
|
+
Ot as compositeAnnotations,
|
|
2756
|
+
xi as createVideoRecorder,
|
|
2757
|
+
H as drawShape,
|
|
2758
|
+
Pt as getSupportedMimeType,
|
|
2759
|
+
Si as isDomScreenshotSupported,
|
|
2760
|
+
ki as isVideoRecordingSupported,
|
|
2761
|
+
_i as openAnnotationEditor,
|
|
2762
|
+
B as rectFromPoints
|
|
2612
2763
|
};
|
|
2613
2764
|
//# sourceMappingURL=index.js.map
|