makethisbetter 1.9.2 → 1.11.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 +49 -4
- package/dist/annotate/toolbar.d.ts +7 -0
- package/dist/annotate/toolbar.d.ts.map +1 -1
- package/dist/api/client.d.ts +9 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/context/breadcrumbs.d.ts +1 -7
- package/dist/context/breadcrumbs.d.ts.map +1 -1
- package/dist/context/frustration-state.d.ts +12 -0
- package/dist/context/frustration-state.d.ts.map +1 -0
- package/dist/context/frustration-state.test.d.ts +2 -0
- package/dist/context/frustration-state.test.d.ts.map +1 -0
- package/dist/context/frustration.d.ts +5 -5
- package/dist/context/frustration.d.ts.map +1 -1
- package/dist/context/history-patch.d.ts +4 -0
- package/dist/context/history-patch.d.ts.map +1 -0
- package/dist/context/history-patch.test.d.ts +2 -0
- package/dist/context/history-patch.test.d.ts.map +1 -0
- package/dist/i18n/de.d.ts +2 -0
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/es.d.ts +2 -0
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/fr.d.ts +2 -0
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/ja.d.ts +2 -0
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ko.d.ts +2 -0
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/zh-CN.d.ts +2 -0
- package/dist/i18n/zh-CN.d.ts.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/makethisbetter.cjs +52 -43
- package/dist/makethisbetter.cjs.map +1 -1
- package/dist/makethisbetter.esm.js +929 -635
- package/dist/makethisbetter.esm.js.map +1 -1
- package/dist/makethisbetter.js +52 -43
- package/dist/makethisbetter.js.map +1 -1
- package/dist/popup/clarify.d.ts +12 -1
- package/dist/popup/clarify.d.ts.map +1 -1
- package/dist/popup/comment.d.ts +1 -0
- package/dist/popup/comment.d.ts.map +1 -1
- package/dist/record/session.d.ts +6 -1
- package/dist/record/session.d.ts.map +1 -1
- package/dist/record/session.destroy-during-load.test.d.ts +2 -0
- package/dist/record/session.destroy-during-load.test.d.ts.map +1 -0
- package/dist/screenshot/capture.d.ts.map +1 -1
- package/dist/screenshot/crop.d.ts +19 -0
- package/dist/screenshot/crop.d.ts.map +1 -0
- package/dist/screenshot/crop.test.d.ts +2 -0
- package/dist/screenshot/crop.test.d.ts.map +1 -0
- package/dist/styles.d.ts +2 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/widget/controller.d.ts +1 -1
- package/dist/widget/controller.d.ts.map +1 -1
- package/dist/widget/frustration-prompt.d.ts +7 -4
- package/dist/widget/frustration-prompt.d.ts.map +1 -1
- package/dist/widget/recording-manager.d.ts +2 -1
- package/dist/widget/recording-manager.d.ts.map +1 -1
- package/dist/widget/tab.d.ts +3 -0
- package/dist/widget/tab.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/annotate/toolbar.ts +48 -0
- package/src/api/client.ts +43 -3
- package/src/context/breadcrumbs.ts +5 -48
- package/src/context/frustration-state.ts +83 -0
- package/src/context/frustration.ts +49 -44
- package/src/context/history-patch.ts +86 -0
- package/src/i18n/de.ts +2 -0
- package/src/i18n/en.ts +2 -0
- package/src/i18n/es.ts +2 -0
- package/src/i18n/fr.ts +2 -0
- package/src/i18n/ja.ts +2 -0
- package/src/i18n/ko.ts +2 -0
- package/src/i18n/zh-CN.ts +2 -0
- package/src/index.ts +8 -1
- package/src/popup/clarify.ts +170 -52
- package/src/popup/comment.ts +15 -11
- package/src/record/session.ts +32 -2
- package/src/screenshot/capture.ts +73 -12
- package/src/screenshot/crop.ts +131 -0
- package/src/styles/widget.css +29 -9
- package/src/styles.ts +8 -1
- package/src/types.ts +20 -1
- package/src/widget/controller.ts +38 -7
- package/src/widget/frustration-prompt.ts +19 -2
- package/src/widget/recording-manager.ts +3 -1
- package/src/widget/tab.ts +10 -0
- package/src/annotate/draw-note-bar.test.ts +0 -90
- package/src/annotate/draw.test.ts +0 -158
- package/src/annotate/highlighter.test.ts +0 -70
- package/src/annotate/overlay.test.ts +0 -91
- package/src/annotate/pin.test.ts +0 -83
- package/src/annotate/session.test.ts +0 -344
- package/src/annotate/toolbar.test.ts +0 -132
- package/src/api/client.test.ts +0 -285
- package/src/context/breadcrumbs.test.ts +0 -154
- package/src/context/collector.test.ts +0 -14
- package/src/context/console.test.ts +0 -44
- package/src/context/error-source.test.ts +0 -128
- package/src/context/frustration.test.ts +0 -485
- package/src/i18n/index.test.ts +0 -36
- package/src/popup/clarify.test.ts +0 -725
- package/src/popup/comment.test.ts +0 -168
- package/src/popup/success.test.ts +0 -190
- package/src/record/control-bar.test.ts +0 -110
- package/src/record/session.cdn.test.ts +0 -89
- package/src/record/session.test.ts +0 -160
- package/src/screenshot/capture.test.ts +0 -98
- package/src/widget/anon-id.test.ts +0 -42
- package/src/widget/controller.test.ts +0 -1054
- package/src/widget/dim-overlay.test.ts +0 -27
- package/src/widget/frustration-prompt.test.ts +0 -86
- package/src/widget/payload.test.ts +0 -222
- package/src/widget/pet.test.ts +0 -65
- package/src/widget/recording-manager.test.ts +0 -136
- package/src/widget/shadow.test.ts +0 -44
- package/src/widget/tab.test.ts +0 -107
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const vt = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;line-height:1.5;color:#191a1c;-webkit-font-smoothing:antialiased}:host([data-mtb-theme="dark"]) .mtb-popup,:host([data-mtb-theme="dark"]) .mtb-success{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-popup-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="dark"]) .mtb-popup-title,:host([data-mtb-theme="dark"]) .mtb-success-title{color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-quick-option,:host([data-mtb-theme="dark"]) .mtb-textarea{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-popup-close,:host([data-mtb-theme="dark"]) .mtb-success-msg,:host([data-mtb-theme="dark"]) .mtb-close-link{color:#ffffffad}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-popup,:host([data-mtb-theme="auto"]) .mtb-success{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-popup-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="auto"]) .mtb-popup-title,:host([data-mtb-theme="auto"]) .mtb-success-title{color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-quick-option,:host([data-mtb-theme="auto"]) .mtb-textarea{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-popup-close,:host([data-mtb-theme="auto"]) .mtb-success-msg,:host([data-mtb-theme="auto"]) .mtb-close-link{color:#ffffffad}}.mtb-tab{position:fixed;top:50%;right:0;transform:translateY(-50%);z-index:2147483646;display:flex;align-items:center;justify-content:center;width:32px;padding:14px 0;background:#059669;color:#fff;border-radius:8px 0 0 8px;cursor:pointer;box-shadow:-2px 0 14px #05966959;transition:background .15s,box-shadow .15s,width .15s;writing-mode:vertical-lr;text-orientation:mixed;font-size:12px;font-weight:600;letter-spacing:.04em;user-select:none;border:none;outline:none}.mtb-tab.left{right:auto;left:0;border-radius:0 8px 8px 0;box-shadow:2px 0 14px #05966959}.mtb-tab:hover{background:#047857;box-shadow:-3px 0 20px #05966973}.mtb-tab.active{background:#065f46}.mtb-toolbar{position:fixed;top:18px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:11px;height:46px;padding:0 7px;border-radius:13px;background:linear-gradient(120deg,#10b981,#059669);box-shadow:0 10px 26px #0f172a38;animation:mtbBarIn .2s ease;white-space:nowrap}@keyframes mtbBarIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}.mtb-toolbar-modes{display:flex;align-items:center;gap:3px;background:#ffffff29;border-radius:9px;padding:3px}.mtb-toolbar-mode-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;border-radius:7px;border:none;cursor:pointer;font-family:inherit;font-size:12px;font-weight:550;white-space:nowrap;background:transparent;color:#fffffff2;transition:all .12s}.mtb-toolbar-mode-btn.active{background:#fff;color:#047857}.mtb-toolbar-hint{font-size:12px;color:#fffffff2;white-space:nowrap}.mtb-toolbar-sep{width:1px;height:20px;background:#ffffff38}.mtb-exit-btn{display:inline-flex;align-items:center;gap:5px;height:30px;padding:0 12px;border-radius:8px;font-size:11.5px;font-weight:500;color:#fff;cursor:pointer;background:#ffffff29;border:none;font-family:inherit;transition:background .12s}.mtb-exit-btn:hover{background:#ffffff47}@media (max-width: 480px){.mtb-toolbar{max-width:calc(100vw - 16px);gap:6px}.mtb-toolbar-hint,.mtb-toolbar-sep{display:none}.mtb-toolbar-mode-btn,.mtb-exit-btn{padding-right:10px;padding-left:10px}}.mtb-overlay{position:fixed;inset:0;z-index:2147483640;cursor:crosshair}.mtb-dim{position:fixed;inset:0;z-index:2147483639;background:#00000014}.mtb-highlight{position:fixed;z-index:2147483641;pointer-events:none;border:2px solid #10b981;border-radius:6px;background:#10b9810f;transition:all .08s ease}.mtb-highlight.selected{border-color:#3b82f6;background:#3b82f60a}.mtb-highlight-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%,-100%);max-width:240px;overflow:hidden;text-overflow:ellipsis;background:#064e3b;color:#fff;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:0 4px 12px #0000002e;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-highlight-tooltip.below{transform:translate(-50%)}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:#064e3b}.mtb-highlight-tooltip.below:after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:#064e3b}.mtb-draw-svg{position:fixed;inset:0;z-index:2147483643;pointer-events:none;width:100%;height:100%;overflow:visible}.mtb-pin{position:fixed;z-index:2147483644;pointer-events:none;width:22px;height:22px;border-radius:50% 50% 50% 2px;background:#059669;border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:10px;color:#fff;font-weight:700;box-shadow:0 2px 8px #05966973;animation:mtbPinPop .25s cubic-bezier(.34,1.56,.64,1);transform:translate(-50%,-50%)}@keyframes mtbPinPop{0%{transform:translate(-50%,-50%) scale(.4)}to{transform:translate(-50%,-50%) scale(1)}}.mtb-popup{position:fixed;z-index:2147483645;display:flex;flex-direction:column;width:min(320px,calc(100vw - 56px));background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 24px 64px #0000003d;overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-popup-header{flex-shrink:0;padding:11px 13px 11px 14px;border-bottom:1px solid rgba(0,0,0,.06);display:flex;align-items:center;gap:8px}.mtb-popup-icon{width:20px;height:20px;border-radius:5px;background:#10b9811a;display:flex;align-items:center;justify-content:center;flex-shrink:0}.mtb-popup-title{flex:1;font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#191a1c}.mtb-popup-close{background:none;border:none;cursor:pointer;padding:3px;color:#00000061;display:flex;align-items:center;border-radius:4px;transition:color .12s}.mtb-popup-close:hover{color:#000000b3}.mtb-popup-body{min-height:0;padding:13px;overflow-y:auto;overscroll-behavior:contain}.mtb-quick-options{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.mtb-quick-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border:1px solid rgba(0,0,0,.09);border-radius:10px;background:#fafafa;cursor:pointer;font-family:inherit;font-size:13px;color:#191a1c;text-align:left;transition:all .12s}.mtb-quick-option:hover{background:#10b9810f;border-color:#10b9814d}.mtb-quick-option-emoji{font-size:15px;flex-shrink:0;line-height:1}.mtb-textarea-wrap{position:relative}.mtb-textarea{width:100%;height:64px;padding:9px 11px;border:1px solid rgba(0,0,0,.12);border-radius:10px;font-family:inherit;font-size:12.5px;line-height:1.5;color:#191a1c;outline:none;background:#fff;resize:none;transition:border-color .12s,box-shadow .12s}.mtb-textarea:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b98126}.mtb-textarea::placeholder{color:#00000057}.mtb-popup-error{margin-top:8px;color:#dc2626;font-size:11.5px}.mtb-popup-error:empty,.mtb-popup-error[hidden]{display:none}.mtb-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:12px}.mtb-cancel-btn,.mtb-submit-btn{min-width:72px;height:32px;border:none;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0 12px;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-cancel-btn{background:#f3f4f6;color:#000000ad}.mtb-cancel-btn:hover{background:#e5e7eb}.mtb-submit-btn{background:#d1d5db;color:#fff}.mtb-submit-btn.ready{background:#059669}.mtb-submit-btn.ready:hover{background:#047857}.mtb-submit-btn.loading{background:#059669;opacity:.7;cursor:wait}.mtb-submit-btn:disabled{cursor:not-allowed}.mtb-success{position:fixed;z-index:2147483645;width:332px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 24px 64px #0000003d;padding:24px 22px;text-align:center;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-success-icon{width:46px;height:46px;border-radius:50%;background:#05966917;display:flex;align-items:center;justify-content:center;margin:0 auto 12px}.mtb-success-title{font-size:16px;font-weight:700;margin-bottom:5px;letter-spacing:-.01em;color:#191a1c}.mtb-success-msg{font-size:13px;color:#0000008c;margin-bottom:16px;line-height:1.6}.mtb-view-feedback-link{display:inline-flex;align-items:center;gap:5px;color:#047857;text-decoration:none;font-size:13px;font-weight:500;font-family:JetBrains Mono,monospace;background:none;border:none;cursor:pointer;transition:text-decoration .12s}.mtb-view-feedback-link:hover{text-decoration:underline}.mtb-close-link{margin-top:13px;background:none;border:none;cursor:pointer;font-size:12px;color:#0006;font-family:inherit;transition:color .12s}.mtb-close-link:hover{color:#000000b3}.mtb-email-capture{margin-bottom:14px;text-align:left}.mtb-email-prompt{font-size:12px;color:#0000008c;line-height:1.5;margin-bottom:8px}.mtb-email-row{display:flex;gap:6px}.mtb-email-input{flex:1;min-width:0;font-size:12.5px;font-family:inherit;padding:7px 10px;border:1px solid rgba(0,0,0,.14);border-radius:8px;outline:none}.mtb-email-input:focus{border-color:#059669}.mtb-email-input.mtb-email-invalid{border-color:#dc2626}.mtb-email-submit{font-size:12px;font-weight:600;font-family:inherit;color:#fff;background:#059669;border:none;border-radius:8px;padding:7px 12px;cursor:pointer;white-space:nowrap}.mtb-email-submit:disabled{opacity:.6;cursor:default}.mtb-email-error{font-size:11.5px;color:#dc2626;margin-top:6px}.mtb-email-saved{font-size:12px;color:#059669;line-height:1.5}.mtb-my-feedback{display:block;margin:8px auto 0;background:none;border:none;cursor:pointer;font-size:11.5px;font-family:inherit;color:#0006;text-decoration:underline;text-underline-offset:2px;transition:color .12s}.mtb-my-feedback:hover{color:#059669}.mtb-pet{position:fixed;bottom:20px;right:20px;z-index:2147483646;cursor:pointer;width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:transparent;animation:mtbPetBounce 3s ease-in-out infinite;transition:transform .2s;user-select:none;outline:none;filter:drop-shadow(0 4px 12px rgba(5,150,105,.35))}.mtb-pet:hover{transform:scale(1.12);animation-play-state:paused}.mtb-pet:hover .mtb-pet-bubble{opacity:1;transform:translate(-50%) translateY(0);pointer-events:auto}.mtb-pet.active{animation:none;opacity:.6}.mtb-pet-svg{display:block}@keyframes mtbPetBounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.mtb-pet-bubble{position:absolute;bottom:100%;left:50%;transform:translate(-50%) translateY(4px);margin-bottom:8px;background:#064e3b;color:#fff;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:500;white-space:nowrap;box-shadow:0 4px 14px #0000002e;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}.mtb-pet-bubble.visible{opacity:1;transform:translate(-50%) translateY(0);pointer-events:auto}.mtb-pet-bubble.hidden{opacity:0;pointer-events:none}.mtb-pet-bubble:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-top-color:#064e3b}.mtb-frustration-prompt{position:fixed;bottom:20px;right:20px;z-index:2147483645;display:flex;align-items:center;gap:10px;padding:12px 16px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:12px;box-shadow:0 8px 30px #0000001f;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}:host([data-mtb-theme="dark"]) .mtb-frustration-prompt{background:#151719;border-color:#ffffff1f;color:#f9fafb}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-frustration-prompt{background:#151719;border-color:#ffffff1f;color:#f9fafb}}.mtb-frustration-icon{width:32px;height:32px;border-radius:50%;background:#eab3081a;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:16px;line-height:1}.mtb-frustration-text{font-size:13px;font-weight:500;color:inherit;line-height:1.4}.mtb-frustration-actions{display:flex;gap:6px;flex-shrink:0}.mtb-frustration-tell{height:28px;padding:0 12px;border:none;border-radius:7px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-frustration-tell:hover{background:#047857}.mtb-frustration-dismiss{height:28px;padding:0 8px;border:none;border-radius:7px;background:transparent;color:#0006;cursor:pointer;font-family:inherit;font-size:12px;transition:color .12s}.mtb-frustration-dismiss:hover{color:#000000b3}:host([data-mtb-theme="dark"]) .mtb-frustration-dismiss{color:#fff6}:host([data-mtb-theme="dark"]) .mtb-frustration-dismiss:hover{color:#ffffffb3}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-frustration-dismiss{color:#fff6}:host([data-mtb-theme="auto"]) .mtb-frustration-dismiss:hover{color:#ffffffb3}}.mtb-record-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:12px;height:42px;padding:0 8px 0 14px;border-radius:12px;background:#0f172aeb;box-shadow:0 8px 24px #00000040;animation:mtbBarIn .2s ease}.mtb-record-dot{width:8px;height:8px;border-radius:50%;background:#ef4444;animation:mtbRecordPulse 1.2s ease-in-out infinite;flex-shrink:0}@keyframes mtbRecordPulse{0%,to{opacity:1}50%{opacity:.3}}.mtb-record-timer{font-family:JetBrains Mono,SF Mono,Fira Code,Cascadia Code,monospace;font-size:13px;font-weight:500;color:#fff;font-variant-numeric:tabular-nums;letter-spacing:.02em;min-width:38px}.mtb-record-stop{height:28px;padding:0 14px;border:none;border-radius:7px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-record-stop:hover{background:#047857}.mtb-click-ripple{position:fixed;z-index:2147483644;width:24px;height:24px;border-radius:50%;border:2px solid #10b981;background:#10b98133;pointer-events:none;transform:translate(-50%,-50%) scale(.5);animation:mtbClickRipple .3s ease-out forwards}@keyframes mtbClickRipple{0%{transform:translate(-50%,-50%) scale(.5);opacity:1}to{transform:translate(-50%,-50%) scale(2);opacity:0}}.mtb-dot{display:inline-block;width:4px;height:4px;border-radius:50%;background:#fff;animation:mtbDot 1.2s infinite}.mtb-dot:nth-child(2){animation-delay:.2s}.mtb-dot:nth-child(3){animation-delay:.4s}@keyframes mtbDot{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}.mtb-clarify{position:fixed;z-index:2147483645;width:min(346px,calc(100vw - 56px));background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 24px 64px #0000003d;display:flex;flex-direction:column;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;overflow:hidden}.mtb-clarify-continuation{width:min(320px,calc(100vw - 56px));animation:none}.mtb-clarify-header{padding:8px 10px;display:flex;align-items:center;gap:7px;border-bottom:1px solid rgba(0,0,0,.06)}.mtb-clarify-icon{width:20px;height:20px;border-radius:6px;background:linear-gradient(140deg,#10b981,#059669);box-shadow:0 1px 3px #05966966;display:flex;align-items:center;justify-content:center;flex-shrink:0}.mtb-clarify-titles{flex:1;min-width:0}.mtb-clarify-title{font-size:12px;font-weight:650;line-height:1.2;color:#191a1c}.mtb-clarify-subtitle{font-size:9.5px;color:#0000006b}.mtb-clarify-close{background:none;border:none;cursor:pointer;padding:3px;color:#00000061;display:flex;transition:color .12s}.mtb-clarify-close:hover{color:#000000b3}.mtb-clarify-messages{flex:1;overflow-y:auto;padding:8px 10px 4px;display:flex;flex-direction:column;gap:6px}.mtb-clarify-bubble{max-width:82%;padding:6px 10px;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-word}.mtb-clarify-ai{align-self:flex-start;background:#fff;color:#191a1c;border:1px solid rgba(0,0,0,.09);border-radius:11px 11px 11px 3px}.mtb-clarify-user{align-self:flex-end;background:#059669;color:#fff;border:1px solid #059669;border-radius:11px 11px 3px}.mtb-clarify-thinking{display:flex;align-items:center;gap:4px;padding:8px 12px}.mtb-clarify-thinking .mtb-dot{width:6px;height:6px;background:#059669b3}.mtb-clarify-footer{padding:3px 10px 10px;display:flex;flex-direction:column}.mtb-clarify-input{width:100%;height:40px;padding:7px 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:12px;line-height:1.4;color:#191a1c;outline:none;background:#fafafa;resize:none;box-sizing:border-box;transition:border-color .12s,box-shadow .12s,background .12s}.mtb-clarify-input:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b98126;background:#fff}.mtb-clarify-input::placeholder{color:#00000057}.mtb-clarify-actions{display:flex;gap:6px;margin-top:6px}.mtb-clarify-skip{flex:0 0 auto;height:30px;padding:0 12px;border:1px solid rgba(0,0,0,.12);border-radius:8px;background:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:550;color:#0000008c;white-space:nowrap;transition:background .12s}.mtb-clarify-skip:hover{background:#0000000a}.mtb-clarify-send{flex:1;height:30px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:none;border-radius:8px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-clarify-send:not(:disabled):hover{background:#047857}.mtb-clarify-send:disabled{background:#00000026;cursor:not-allowed}.mtb-clarify-send-feedback{width:100%;height:34px;display:inline-flex;align-items:center;justify-content:center;gap:6px;border:none;border-radius:9px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-clarify-send-feedback:not(:disabled):hover{background:#047857}.mtb-clarify-send-feedback:disabled{background:#00000026;cursor:not-allowed}.mtb-clarify-error{margin-bottom:8px;color:#dc2626;font-size:11.5px;line-height:1.4;text-align:center}:host([data-mtb-theme="dark"]) .mtb-clarify{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-clarify-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="dark"]) .mtb-clarify-title{color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-clarify-subtitle{color:#ffffff73}:host([data-mtb-theme="dark"]) .mtb-clarify-close{color:#ffffff73}:host([data-mtb-theme="dark"]) .mtb-clarify-close:hover{color:#ffffffbf}:host([data-mtb-theme="dark"]) .mtb-clarify-skip{background:#1f2327;border-color:#ffffff24;color:#ffffffb3}:host([data-mtb-theme="dark"]) .mtb-clarify-skip:hover{background:#ffffff0f}:host([data-mtb-theme="dark"]) .mtb-clarify-ai{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-clarify-input{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-clarify{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="auto"]) .mtb-clarify-title{color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-subtitle{color:#ffffff73}:host([data-mtb-theme="auto"]) .mtb-clarify-close{color:#ffffff73}:host([data-mtb-theme="auto"]) .mtb-clarify-close:hover{color:#ffffffbf}:host([data-mtb-theme="auto"]) .mtb-clarify-skip{background:#1f2327;border-color:#ffffff24;color:#ffffffb3}:host([data-mtb-theme="auto"]) .mtb-clarify-skip:hover{background:#ffffff0f}:host([data-mtb-theme="auto"]) .mtb-clarify-ai{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-input{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}}.mtb-dim-clickable{z-index:2147483643;pointer-events:auto;cursor:default;background:#0000001f}.mtb-draw-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:8px;height:46px;padding:0 8px 0 12px;border-radius:13px;background:#fff;border:1px solid rgba(0,0,0,.08);box-shadow:0 10px 30px #0f172a38;animation:mtbBarIn .2s ease;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-draw-input{width:220px;height:32px;padding:0 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:13px;color:#191a1c;outline:none;background:#fafafa;transition:border-color .12s,box-shadow .12s,background .12s}.mtb-draw-input:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b98126;background:#fff}.mtb-draw-input::placeholder{color:#00000057}.mtb-draw-icon-btn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:8px;background:transparent;color:#374151;cursor:pointer;transition:background .12s,color .12s}.mtb-draw-icon-btn:hover:not(:disabled){background:#0000000f}.mtb-draw-icon-btn:disabled{color:#00000038;cursor:default}.mtb-draw-sep{width:1px;height:22px;background:#0000001a}.mtb-draw-cancel{height:32px;padding:0 12px;border:1px solid rgba(0,0,0,.12);border-radius:8px;background:#fff;color:#0000008c;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:550;transition:background .12s}.mtb-draw-cancel:hover{background:#0000000a}.mtb-draw-submit{height:32px;padding:0 14px;border:none;border-radius:8px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-draw-submit:hover:not(:disabled){background:#047857}.mtb-draw-submit:disabled{opacity:.6;cursor:default}.mtb-draw-error{position:absolute;bottom:100%;left:12px;margin-bottom:6px;color:#dc2626;font-size:11.5px}.mtb-record-preview{margin-bottom:12px}.mtb-record-preview-stage{position:relative;width:100%;height:132px;border-radius:10px;overflow:hidden;background:#0f172a;display:flex;align-items:center;justify-content:center}.mtb-record-preview-stage.playing{align-items:flex-start;justify-content:flex-start}.mtb-record-preview-play{width:44px;height:44px;border-radius:50%;border:none;background:#ffffffeb;color:#059669;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .12s,background .12s}.mtb-record-preview-play:hover:not(:disabled){transform:scale(1.06);background:#fff}.mtb-record-preview-play:disabled{cursor:default;opacity:.6}.mtb-record-preview-badge{position:absolute;right:8px;bottom:8px;padding:2px 7px;border-radius:6px;background:#0009;color:#fff;font-size:11px;font-variant-numeric:tabular-nums;font-family:JetBrains Mono,SF Mono,monospace}.mtb-record-preview-fallback{color:#ffffffd9;font-size:12px}.mtb-record-preview-name{display:block;margin-top:5px;font-size:11px;color:#0000006b}';
|
|
2
|
-
class
|
|
1
|
+
const Wt = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;line-height:1.5;color:#191a1c;-webkit-font-smoothing:antialiased}:host([data-mtb-theme="dark"]) .mtb-popup,:host([data-mtb-theme="dark"]) .mtb-success{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-popup-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="dark"]) .mtb-popup-title,:host([data-mtb-theme="dark"]) .mtb-success-title{color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-quick-option,:host([data-mtb-theme="dark"]) .mtb-textarea{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-popup-close,:host([data-mtb-theme="dark"]) .mtb-success-msg,:host([data-mtb-theme="dark"]) .mtb-close-link{color:#ffffffad}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-popup,:host([data-mtb-theme="auto"]) .mtb-success{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-popup-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="auto"]) .mtb-popup-title,:host([data-mtb-theme="auto"]) .mtb-success-title{color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-quick-option,:host([data-mtb-theme="auto"]) .mtb-textarea{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-popup-close,:host([data-mtb-theme="auto"]) .mtb-success-msg,:host([data-mtb-theme="auto"]) .mtb-close-link{color:#ffffffad}}.mtb-tab{position:fixed;top:50%;right:0;transform:translateY(-50%);z-index:2147483646;display:flex;align-items:center;justify-content:center;width:32px;padding:14px 0;background:#059669;color:#fff;border-radius:8px 0 0 8px;cursor:pointer;box-shadow:-2px 0 14px #05966959;transition:background .15s,box-shadow .15s,width .15s;writing-mode:vertical-lr;text-orientation:mixed;font-size:12px;font-weight:600;letter-spacing:.04em;user-select:none;border:none;outline:none}.mtb-tab.left{right:auto;left:0;border-radius:0 8px 8px 0;box-shadow:2px 0 14px #05966959}.mtb-tab:hover{background:#047857;box-shadow:-3px 0 20px #05966973}.mtb-tab.active{background:#065f46}.mtb-toolbar{position:fixed;top:18px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:11px;height:46px;padding:0 7px;border-radius:13px;background:linear-gradient(120deg,#10b981,#059669);box-shadow:0 10px 26px #0f172a38;animation:mtbBarIn .2s ease;white-space:nowrap;transition:opacity .15s ease}@keyframes mtbBarIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}.mtb-toolbar-faded{opacity:.3;pointer-events:none}.mtb-toolbar-modes{display:flex;align-items:center;gap:3px;background:#ffffff29;border-radius:9px;padding:3px}.mtb-toolbar-mode-btn{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;border-radius:7px;border:none;cursor:pointer;font-family:inherit;font-size:12px;font-weight:550;white-space:nowrap;background:transparent;color:#fffffff2;transition:all .12s}.mtb-toolbar-mode-btn.active{background:#fff;color:#047857}.mtb-toolbar-hint{font-size:12px;color:#fffffff2;white-space:nowrap}.mtb-toolbar-sep{width:1px;height:20px;background:#ffffff38}.mtb-exit-btn{display:inline-flex;align-items:center;gap:5px;height:30px;padding:0 12px;border-radius:8px;font-size:11.5px;font-weight:500;color:#fff;cursor:pointer;background:#ffffff29;border:none;font-family:inherit;transition:background .12s}.mtb-exit-btn:hover{background:#ffffff47}@media (max-width: 480px){.mtb-toolbar{max-width:calc(100vw - 16px);gap:6px}.mtb-toolbar-hint,.mtb-toolbar-sep{display:none}.mtb-toolbar-mode-btn,.mtb-exit-btn{padding-right:10px;padding-left:10px}}.mtb-overlay{position:fixed;inset:0;z-index:2147483640;cursor:crosshair}.mtb-dim{position:fixed;inset:0;z-index:2147483639;background:#00000014}.mtb-highlight{position:fixed;z-index:2147483641;pointer-events:none;border:2px solid #10b981;border-radius:6px;background:#10b9810f;transition:all .08s ease}.mtb-highlight.selected{border-color:#3b82f6;background:#3b82f60a}.mtb-highlight-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%,-100%);max-width:240px;overflow:hidden;text-overflow:ellipsis;background:#064e3b;color:#fff;padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:0 4px 12px #0000002e;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-highlight-tooltip.below{transform:translate(-50%)}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:#064e3b}.mtb-highlight-tooltip.below:after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:#064e3b}.mtb-draw-svg{position:fixed;inset:0;z-index:2147483643;pointer-events:none;width:100%;height:100%;overflow:visible}.mtb-pin{position:fixed;z-index:2147483644;pointer-events:none;width:22px;height:22px;border-radius:50% 50% 50% 2px;background:#059669;border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:10px;color:#fff;font-weight:700;box-shadow:0 2px 8px #05966973;animation:mtbPinPop .25s cubic-bezier(.34,1.56,.64,1);transform:translate(-50%,-50%)}@keyframes mtbPinPop{0%{transform:translate(-50%,-50%) scale(.4)}to{transform:translate(-50%,-50%) scale(1)}}.mtb-popup{position:fixed;z-index:2147483645;display:flex;flex-direction:column;width:min(320px,calc(100vw - 56px));background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 24px 64px #0000003d;overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-popup-header{flex-shrink:0;padding:11px 13px 11px 14px;border-bottom:1px solid rgba(0,0,0,.06);display:flex;align-items:center;gap:8px}.mtb-popup-icon{width:20px;height:20px;border-radius:5px;background:#10b9811a;display:flex;align-items:center;justify-content:center;flex-shrink:0}.mtb-popup-title{flex:1;font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#191a1c}.mtb-popup-close{background:none;border:none;cursor:pointer;padding:3px;color:#00000061;display:flex;align-items:center;border-radius:4px;transition:color .12s}.mtb-popup-close:hover{color:#000000b3}.mtb-popup-body{min-height:0;padding:13px;overflow-y:auto;overscroll-behavior:contain}.mtb-quick-options{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}.mtb-quick-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border:1px solid rgba(0,0,0,.09);border-radius:10px;background:#fafafa;cursor:pointer;font-family:inherit;font-size:13px;color:#191a1c;text-align:left;transition:all .12s}.mtb-quick-option:hover{background:#10b9810f;border-color:#10b9814d}.mtb-quick-option.selected{background:#10b9811a;border-color:#10b98180}.mtb-quick-option-emoji{font-size:15px;flex-shrink:0;line-height:1}.mtb-textarea-wrap{position:relative}.mtb-textarea{width:100%;height:64px;padding:9px 11px;border:1px solid rgba(0,0,0,.12);border-radius:10px;font-family:inherit;font-size:12.5px;line-height:1.5;color:#191a1c;outline:none;background:#fff;resize:none;transition:border-color .12s,box-shadow .12s}.mtb-textarea:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b98126}.mtb-textarea::placeholder{color:#00000057}.mtb-popup-error{margin-top:8px;color:#dc2626;font-size:11.5px}.mtb-popup-error:empty,.mtb-popup-error[hidden]{display:none}.mtb-popup-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:12px}.mtb-cancel-btn,.mtb-submit-btn{min-width:72px;height:32px;border:none;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0 12px;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-cancel-btn{background:#f3f4f6;color:#000000ad}.mtb-cancel-btn:hover{background:#e5e7eb}.mtb-submit-btn{background:#d1d5db;color:#fff}.mtb-submit-btn.ready{background:#059669}.mtb-submit-btn.ready:hover{background:#047857}.mtb-submit-btn.loading{background:#059669;opacity:.7;cursor:wait}.mtb-submit-btn:disabled{cursor:not-allowed}.mtb-success{position:fixed;z-index:2147483645;width:332px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 24px 64px #0000003d;padding:24px 22px;text-align:center;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-success-icon{width:46px;height:46px;border-radius:50%;background:#05966917;display:flex;align-items:center;justify-content:center;margin:0 auto 12px}.mtb-success-title{font-size:16px;font-weight:700;margin-bottom:5px;letter-spacing:-.01em;color:#191a1c}.mtb-success-msg{font-size:13px;color:#0000008c;margin-bottom:16px;line-height:1.6}.mtb-view-feedback-link{display:inline-flex;align-items:center;gap:5px;color:#047857;text-decoration:none;font-size:13px;font-weight:500;font-family:JetBrains Mono,monospace;background:none;border:none;cursor:pointer;transition:text-decoration .12s}.mtb-view-feedback-link:hover{text-decoration:underline}.mtb-close-link{margin-top:13px;background:none;border:none;cursor:pointer;font-size:12px;color:#0006;font-family:inherit;transition:color .12s}.mtb-close-link:hover{color:#000000b3}.mtb-email-capture{margin-bottom:14px;text-align:left}.mtb-email-prompt{font-size:12px;color:#0000008c;line-height:1.5;margin-bottom:8px}.mtb-email-row{display:flex;gap:6px}.mtb-email-input{flex:1;min-width:0;font-size:12.5px;font-family:inherit;padding:7px 10px;border:1px solid rgba(0,0,0,.14);border-radius:8px;outline:none}.mtb-email-input:focus{border-color:#059669}.mtb-email-input.mtb-email-invalid{border-color:#dc2626}.mtb-email-submit{font-size:12px;font-weight:600;font-family:inherit;color:#fff;background:#059669;border:none;border-radius:8px;padding:7px 12px;cursor:pointer;white-space:nowrap}.mtb-email-submit:disabled{opacity:.6;cursor:default}.mtb-email-error{font-size:11.5px;color:#dc2626;margin-top:6px}.mtb-email-saved{font-size:12px;color:#059669;line-height:1.5}.mtb-my-feedback{display:block;margin:8px auto 0;background:none;border:none;cursor:pointer;font-size:11.5px;font-family:inherit;color:#0006;text-decoration:underline;text-underline-offset:2px;transition:color .12s}.mtb-my-feedback:hover{color:#059669}.mtb-pet{position:fixed;bottom:20px;right:20px;z-index:2147483646;cursor:pointer;width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:transparent;animation:mtbPetBounce 3s ease-in-out infinite;transition:transform .2s;user-select:none;outline:none;filter:drop-shadow(0 4px 12px rgba(5,150,105,.35))}.mtb-pet:hover{transform:scale(1.12);animation-play-state:paused}.mtb-pet:hover .mtb-pet-bubble{opacity:1;transform:translate(-50%) translateY(0);pointer-events:auto}.mtb-pet.active{animation:none;opacity:.6}.mtb-pet-svg{display:block}@keyframes mtbPetBounce{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.mtb-pet-bubble{position:absolute;bottom:100%;left:50%;transform:translate(-50%) translateY(4px);margin-bottom:8px;background:#064e3b;color:#fff;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:500;white-space:nowrap;box-shadow:0 4px 14px #0000002e;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}.mtb-pet-bubble.visible{opacity:1;transform:translate(-50%) translateY(0);pointer-events:auto}.mtb-pet-bubble.hidden{opacity:0;pointer-events:none}.mtb-pet-bubble:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:5px solid transparent;border-top-color:#064e3b}.mtb-frustration-prompt{position:fixed;bottom:20px;right:20px;z-index:2147483645;display:flex;align-items:center;gap:10px;padding:12px 16px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:12px;box-shadow:0 8px 30px #0000001f;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}:host([data-mtb-theme="dark"]) .mtb-frustration-prompt{background:#151719;border-color:#ffffff1f;color:#f9fafb}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-frustration-prompt{background:#151719;border-color:#ffffff1f;color:#f9fafb}}.mtb-frustration-icon{width:32px;height:32px;border-radius:50%;background:#eab3081a;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:16px;line-height:1}.mtb-frustration-text{font-size:13px;font-weight:500;color:inherit;line-height:1.4}.mtb-frustration-actions{display:flex;gap:6px;flex-shrink:0}.mtb-frustration-tell{height:28px;padding:0 12px;border:none;border-radius:7px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-frustration-tell:hover{background:#047857}.mtb-frustration-dismiss{height:28px;padding:0 8px;border:none;border-radius:7px;background:transparent;color:#0006;cursor:pointer;font-family:inherit;font-size:12px;transition:color .12s}.mtb-frustration-dismiss:hover{color:#000000b3}:host([data-mtb-theme="dark"]) .mtb-frustration-dismiss{color:#fff6}:host([data-mtb-theme="dark"]) .mtb-frustration-dismiss:hover{color:#ffffffb3}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-frustration-dismiss{color:#fff6}:host([data-mtb-theme="auto"]) .mtb-frustration-dismiss:hover{color:#ffffffb3}}.mtb-record-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:12px;height:42px;padding:0 8px 0 14px;border-radius:12px;background:#0f172aeb;box-shadow:0 8px 24px #00000040;animation:mtbBarIn .2s ease}.mtb-record-dot{width:8px;height:8px;border-radius:50%;background:#ef4444;animation:mtbRecordPulse 1.2s ease-in-out infinite;flex-shrink:0}@keyframes mtbRecordPulse{0%,to{opacity:1}50%{opacity:.3}}.mtb-record-timer{font-family:JetBrains Mono,SF Mono,Fira Code,Cascadia Code,monospace;font-size:13px;font-weight:500;color:#fff;font-variant-numeric:tabular-nums;letter-spacing:.02em;min-width:38px}.mtb-record-stop{height:28px;padding:0 14px;border:none;border-radius:7px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-record-stop:hover{background:#047857}.mtb-click-ripple{position:fixed;z-index:2147483644;width:24px;height:24px;border-radius:50%;border:2px solid #10b981;background:#10b98133;pointer-events:none;transform:translate(-50%,-50%) scale(.5);animation:mtbClickRipple .3s ease-out forwards}@keyframes mtbClickRipple{0%{transform:translate(-50%,-50%) scale(.5);opacity:1}to{transform:translate(-50%,-50%) scale(2);opacity:0}}.mtb-dot{display:inline-block;width:4px;height:4px;border-radius:50%;background:#fff;animation:mtbDot 1.2s infinite}.mtb-dot:nth-child(2){animation-delay:.2s}.mtb-dot:nth-child(3){animation-delay:.4s}@keyframes mtbDot{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}.mtb-clarify{position:fixed;z-index:2147483645;width:min(346px,calc(100vw - 56px));background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 24px 64px #0000003d;display:flex;flex-direction:column;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;overflow:hidden}.mtb-clarify-continuation{width:min(320px,calc(100vw - 56px));animation:none}.mtb-clarify-header{padding:8px 10px;display:flex;align-items:center;gap:7px;border-bottom:1px solid rgba(0,0,0,.06)}.mtb-clarify-icon{width:20px;height:20px;border-radius:6px;background:linear-gradient(140deg,#10b981,#059669);box-shadow:0 1px 3px #05966966;display:flex;align-items:center;justify-content:center;flex-shrink:0}.mtb-clarify-titles{flex:1;min-width:0}.mtb-clarify-title{font-size:12px;font-weight:650;line-height:1.2;color:#191a1c}.mtb-clarify-subtitle{font-size:9.5px;color:#0000006b}.mtb-clarify-close{background:none;border:none;cursor:pointer;padding:3px;color:#00000061;display:flex;transition:color .12s}.mtb-clarify-close:hover{color:#000000b3}.mtb-clarify-messages{flex:1;overflow-y:auto;padding:8px 10px 4px;display:flex;flex-direction:column;gap:6px}.mtb-clarify-bubble{max-width:82%;padding:6px 10px;font-size:12px;line-height:1.4;white-space:pre-wrap;word-break:break-word}.mtb-clarify-ai{align-self:flex-start;background:#fff;color:#191a1c;border:1px solid rgba(0,0,0,.09);border-radius:11px 11px 11px 3px}.mtb-clarify-user{align-self:flex-end;background:#059669;color:#fff;border:1px solid #059669;border-radius:11px 11px 3px}.mtb-clarify-thinking{display:flex;align-items:center;gap:4px;padding:8px 12px}.mtb-clarify-thinking .mtb-dot{width:6px;height:6px;background:#059669b3}.mtb-clarify-footer{padding:3px 10px 10px;display:flex;flex-direction:column}.mtb-clarify-input{width:100%;height:40px;padding:7px 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:12px;line-height:1.4;color:#191a1c;outline:none;background:#fafafa;resize:none;box-sizing:border-box;transition:border-color .12s,box-shadow .12s,background .12s}.mtb-clarify-input:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b98126;background:#fff}.mtb-clarify-input::placeholder{color:#00000057}.mtb-clarify-actions{display:flex;gap:6px;margin-top:6px}.mtb-clarify-skip,.mtb-clarify-fallback{flex:0 0 auto;height:30px;padding:0 12px;border:1px solid rgba(0,0,0,.12);border-radius:8px;background:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:550;color:#0000008c;white-space:nowrap;transition:background .12s}.mtb-clarify-skip:hover,.mtb-clarify-fallback:hover{background:#0000000a}.mtb-clarify-send,.mtb-clarify-retry{flex:1;height:30px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:none;border-radius:8px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-clarify-send:not(:disabled):hover,.mtb-clarify-retry:not(:disabled):hover{background:#047857}.mtb-clarify-send:disabled,.mtb-clarify-retry:disabled{background:#00000026;cursor:not-allowed}.mtb-clarify-send-feedback{width:100%;height:34px;display:inline-flex;align-items:center;justify-content:center;gap:6px;border:none;border-radius:9px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-clarify-send-feedback:not(:disabled):hover{background:#047857}.mtb-clarify-send-feedback:disabled{background:#00000026;cursor:not-allowed}.mtb-clarify-error{margin-bottom:8px;color:#dc2626;font-size:11.5px;line-height:1.4;text-align:center}:host([data-mtb-theme="dark"]) .mtb-clarify{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-clarify-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="dark"]) .mtb-clarify-title{color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-clarify-subtitle{color:#ffffff73}:host([data-mtb-theme="dark"]) .mtb-clarify-close{color:#ffffff73}:host([data-mtb-theme="dark"]) .mtb-clarify-close:hover{color:#ffffffbf}:host([data-mtb-theme="dark"]) .mtb-clarify-skip,:host([data-mtb-theme="dark"]) .mtb-clarify-fallback{background:#1f2327;border-color:#ffffff24;color:#ffffffb3}:host([data-mtb-theme="dark"]) .mtb-clarify-skip:hover,:host([data-mtb-theme="dark"]) .mtb-clarify-fallback:hover{background:#ffffff0f}:host([data-mtb-theme="dark"]) .mtb-clarify-ai{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="dark"]) .mtb-clarify-input{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-clarify{background:#151719;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-header{border-bottom-color:#ffffff1a}:host([data-mtb-theme="auto"]) .mtb-clarify-title{color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-subtitle{color:#ffffff73}:host([data-mtb-theme="auto"]) .mtb-clarify-close{color:#ffffff73}:host([data-mtb-theme="auto"]) .mtb-clarify-close:hover{color:#ffffffbf}:host([data-mtb-theme="auto"]) .mtb-clarify-skip,:host([data-mtb-theme="auto"]) .mtb-clarify-fallback{background:#1f2327;border-color:#ffffff24;color:#ffffffb3}:host([data-mtb-theme="auto"]) .mtb-clarify-skip:hover,:host([data-mtb-theme="auto"]) .mtb-clarify-fallback:hover{background:#ffffff0f}:host([data-mtb-theme="auto"]) .mtb-clarify-ai{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-input{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}}.mtb-dim-clickable{z-index:2147483643;pointer-events:auto;cursor:default;background:#0000001f}.mtb-draw-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:8px;height:46px;padding:0 8px 0 12px;border-radius:13px;background:#fff;border:1px solid rgba(0,0,0,.08);box-shadow:0 10px 30px #0f172a38;animation:mtbBarIn .2s ease;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-draw-input{width:220px;height:32px;padding:0 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:13px;color:#191a1c;outline:none;background:#fafafa;transition:border-color .12s,box-shadow .12s,background .12s}.mtb-draw-input:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b98126;background:#fff}.mtb-draw-input::placeholder{color:#00000057}.mtb-draw-icon-btn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:8px;background:transparent;color:#374151;cursor:pointer;transition:background .12s,color .12s}.mtb-draw-icon-btn:hover:not(:disabled){background:#0000000f}.mtb-draw-icon-btn:disabled{color:#00000038;cursor:default}.mtb-draw-sep{width:1px;height:22px;background:#0000001a}.mtb-draw-cancel{height:32px;padding:0 12px;border:1px solid rgba(0,0,0,.12);border-radius:8px;background:#fff;color:#0000008c;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:550;transition:background .12s}.mtb-draw-cancel:hover{background:#0000000a}.mtb-draw-submit{height:32px;padding:0 14px;border:none;border-radius:8px;background:#059669;color:#fff;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-draw-submit:hover:not(:disabled){background:#047857}.mtb-draw-submit:disabled{opacity:.6;cursor:default}.mtb-draw-error{position:absolute;bottom:100%;left:12px;margin-bottom:6px;color:#dc2626;font-size:11.5px}.mtb-record-preview{margin-bottom:12px}.mtb-record-preview-stage{position:relative;width:100%;height:132px;border-radius:10px;overflow:hidden;background:#0f172a;display:flex;align-items:center;justify-content:center}.mtb-record-preview-stage.playing{align-items:flex-start;justify-content:flex-start}.mtb-record-preview-play{width:44px;height:44px;border-radius:50%;border:none;background:#ffffffeb;color:#059669;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .12s,background .12s}.mtb-record-preview-play:hover:not(:disabled){transform:scale(1.06);background:#fff}.mtb-record-preview-play:disabled{cursor:default;opacity:.6}.mtb-record-preview-badge{position:absolute;right:8px;bottom:8px;padding:2px 7px;border-radius:6px;background:#0009;color:#fff;font-size:11px;font-variant-numeric:tabular-nums;font-family:JetBrains Mono,SF Mono,monospace}.mtb-record-preview-fallback{color:#ffffffd9;font-size:12px}.mtb-record-preview-name{display:block;margin-top:5px;font-size:11px;color:#0000006b}';
|
|
2
|
+
class Vt {
|
|
3
3
|
constructor(t = "auto") {
|
|
4
4
|
this.host = document.createElement("div"), this.host.id = "mtb-widget-host", this.host.style.cssText = "position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;", this.host.setAttribute("data-mtb-theme", t), document.body.appendChild(this.host), this.root = this.host.attachShadow({ mode: "open" });
|
|
5
5
|
const e = document.createElement("style");
|
|
6
|
-
e.textContent =
|
|
6
|
+
e.textContent = Wt, this.root.appendChild(e);
|
|
7
7
|
}
|
|
8
8
|
el(t, e) {
|
|
9
9
|
const r = document.createElement(t);
|
|
@@ -20,37 +20,40 @@ class kt {
|
|
|
20
20
|
this.host.remove();
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
class
|
|
23
|
+
class Yt {
|
|
24
24
|
constructor(t, e, r, s, n) {
|
|
25
|
-
this.onClick = s, this.el = t.el("button", "mtb-tab"), r === "left" && this.el.classList.add("left"), this.idleLabel = n ?? e.tab, this.activeLabel = e.toolbar.exit, this.setLabel(this.idleLabel), this.el.addEventListener("click", s), t.append(this.el);
|
|
25
|
+
this.active = !1, this.onClick = s, this.customText = n, this.el = t.el("button", "mtb-tab"), r === "left" && this.el.classList.add("left"), this.idleLabel = n ?? e.tab, this.activeLabel = e.toolbar.exit, this.setLabel(this.idleLabel), this.el.addEventListener("click", s), t.append(this.el);
|
|
26
26
|
}
|
|
27
27
|
setLabel(t) {
|
|
28
28
|
this.el.textContent = t, this.el.setAttribute("aria-label", t);
|
|
29
29
|
}
|
|
30
|
+
setMessages(t) {
|
|
31
|
+
this.idleLabel = this.customText ?? t.tab, this.activeLabel = t.toolbar.exit, this.setLabel(this.active ? this.activeLabel : this.idleLabel);
|
|
32
|
+
}
|
|
30
33
|
setActive(t) {
|
|
31
|
-
this.el.classList.toggle("active", t), this.setLabel(t ? this.activeLabel : this.idleLabel);
|
|
34
|
+
this.active = t, this.el.classList.toggle("active", t), this.setLabel(t ? this.activeLabel : this.idleLabel);
|
|
32
35
|
}
|
|
33
36
|
destroy() {
|
|
34
37
|
this.el.removeEventListener("click", this.onClick), this.el.remove();
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
|
-
const
|
|
38
|
-
class
|
|
40
|
+
const Xt = 8e3;
|
|
41
|
+
class Kt {
|
|
39
42
|
constructor(t, e, r) {
|
|
40
|
-
this.el = t.el("div", "mtb-frustration-prompt"), this.el.innerHTML = `
|
|
43
|
+
this.autoHideTimer = null, this.el = t.el("div", "mtb-frustration-prompt"), this.el.innerHTML = `
|
|
41
44
|
<div class="mtb-frustration-icon">⚠️</div>
|
|
42
45
|
<span class="mtb-frustration-text">${e.frustration.prompt}</span>
|
|
43
46
|
<div class="mtb-frustration-actions">
|
|
44
47
|
<button class="mtb-frustration-tell">${e.frustration.action}</button>
|
|
45
48
|
<button class="mtb-frustration-dismiss">${e.frustration.dismiss}</button>
|
|
46
49
|
</div>
|
|
47
|
-
`, this.el.querySelector(".mtb-frustration-tell").addEventListener("click", r.onTell), this.el.querySelector(".mtb-frustration-dismiss").addEventListener("click", r.onDismiss), t.append(this.el), setTimeout(r.
|
|
50
|
+
`, this.el.querySelector(".mtb-frustration-tell").addEventListener("click", r.onTell), this.el.querySelector(".mtb-frustration-dismiss").addEventListener("click", r.onDismiss), t.append(this.el), this.autoHideTimer = setTimeout(r.onAutoHide, Xt);
|
|
48
51
|
}
|
|
49
52
|
destroy() {
|
|
50
|
-
this.el.remove();
|
|
53
|
+
this.autoHideTimer && (clearTimeout(this.autoHideTimer), this.autoHideTimer = null), this.el.remove();
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
|
-
class
|
|
56
|
+
class Gt {
|
|
54
57
|
constructor(t, e) {
|
|
55
58
|
this.onClick = e, this.el = t.el("div", "mtb-dim mtb-dim-clickable"), this.el.addEventListener("click", this.onClick), t.append(this.el);
|
|
56
59
|
}
|
|
@@ -58,13 +61,28 @@ class _t {
|
|
|
58
61
|
this.el.removeEventListener("click", this.onClick), this.el.remove();
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
|
-
|
|
64
|
+
const Jt = 500;
|
|
65
|
+
class Qt {
|
|
62
66
|
constructor(t, e, r, s) {
|
|
63
|
-
this.currentMode = "markup", this.
|
|
67
|
+
this.currentMode = "markup", this.fadeTimer = null, this.faded = !1, this.pointerInside = !1, this.handleDocMouseMove = (n) => {
|
|
68
|
+
const o = this.el.getBoundingClientRect(), a = n.clientX >= o.left && n.clientX <= o.right && n.clientY >= o.top && n.clientY <= o.bottom;
|
|
69
|
+
a && !this.pointerInside ? this.faded ? this.restoreToolbar() : this.startFadeTimer() : !a && this.pointerInside && this.clearFadeTimer(), this.pointerInside = a;
|
|
70
|
+
}, this.messages = e, this.el = t.el("div", "mtb-toolbar"), this.el.innerHTML = this.buildHTML(e), t.append(this.el), this.hintEl = this.el.querySelector(".mtb-toolbar-hint"), this.markupBtn = this.el.querySelector(".mtb-toolbar-mode-markup"), this.recordBtn = this.el.querySelector(".mtb-toolbar-mode-record"), this.markupBtn.addEventListener("click", () => {
|
|
64
71
|
this.setMode("markup"), s?.("markup");
|
|
65
72
|
}), this.recordBtn.addEventListener("click", () => {
|
|
66
73
|
this.setMode("record"), s?.("record");
|
|
67
|
-
}), this.el.querySelector(".mtb-exit-btn").addEventListener("click", r);
|
|
74
|
+
}), this.el.querySelector(".mtb-exit-btn").addEventListener("click", r), this.el.addEventListener("click", () => this.clearFadeTimer()), document.addEventListener("mousemove", this.handleDocMouseMove);
|
|
75
|
+
}
|
|
76
|
+
startFadeTimer() {
|
|
77
|
+
this.clearFadeTimer(), this.fadeTimer = setTimeout(() => {
|
|
78
|
+
this.fadeTimer = null, this.faded = !0, this.el.classList.add("mtb-toolbar-faded");
|
|
79
|
+
}, Jt);
|
|
80
|
+
}
|
|
81
|
+
clearFadeTimer() {
|
|
82
|
+
this.fadeTimer !== null && (clearTimeout(this.fadeTimer), this.fadeTimer = null);
|
|
83
|
+
}
|
|
84
|
+
restoreToolbar() {
|
|
85
|
+
this.faded = !1, this.el.classList.remove("mtb-toolbar-faded");
|
|
68
86
|
}
|
|
69
87
|
buildHTML(t) {
|
|
70
88
|
return `
|
|
@@ -92,10 +110,10 @@ class Tt {
|
|
|
92
110
|
return this.currentMode;
|
|
93
111
|
}
|
|
94
112
|
destroy() {
|
|
95
|
-
this.el.remove();
|
|
113
|
+
this.clearFadeTimer(), document.removeEventListener("mousemove", this.handleDocMouseMove), this.el.remove();
|
|
96
114
|
}
|
|
97
115
|
}
|
|
98
|
-
class
|
|
116
|
+
class Zt {
|
|
99
117
|
constructor(t, e) {
|
|
100
118
|
this.onMouseDown = e.onMouseDown, this.onMouseMove = e.onMouseMove, this.onMouseUp = e.onMouseUp, this.onMouseLeave = e.onMouseLeave, this.overlayEl = t.el("div", "mtb-overlay"), this.overlayEl.addEventListener("mousedown", this.onMouseDown), this.overlayEl.addEventListener("mousemove", this.onMouseMove), this.overlayEl.addEventListener("mouseup", this.onMouseUp), this.overlayEl.addEventListener("mouseleave", this.onMouseLeave), t.append(this.overlayEl), this.dimEl = t.el("div", "mtb-dim"), t.append(this.dimEl);
|
|
101
119
|
}
|
|
@@ -103,7 +121,7 @@ class Lt {
|
|
|
103
121
|
this.overlayEl.removeEventListener("mousedown", this.onMouseDown), this.overlayEl.removeEventListener("mousemove", this.onMouseMove), this.overlayEl.removeEventListener("mouseup", this.onMouseUp), this.overlayEl.removeEventListener("mouseleave", this.onMouseLeave), this.overlayEl.remove(), this.dimEl.remove();
|
|
104
122
|
}
|
|
105
123
|
}
|
|
106
|
-
class
|
|
124
|
+
class te {
|
|
107
125
|
constructor(t) {
|
|
108
126
|
this.highlightEl = t.el("div", "mtb-highlight"), this.tooltipEl = t.el("div", "mtb-highlight-tooltip"), this.hide(), t.append(this.highlightEl, this.tooltipEl);
|
|
109
127
|
}
|
|
@@ -112,7 +130,7 @@ class Mt {
|
|
|
112
130
|
this.highlightEl.style.top = `${e.top - 2}px`, this.highlightEl.style.left = `${e.left - 2}px`, this.highlightEl.style.width = `${e.width + 4}px`, this.highlightEl.style.height = `${e.height + 4}px`, this.highlightEl.style.display = "block", this.showTooltip(t, e);
|
|
113
131
|
}
|
|
114
132
|
showTooltip(t, e) {
|
|
115
|
-
this.tooltipEl.textContent =
|
|
133
|
+
this.tooltipEl.textContent = G(t);
|
|
116
134
|
const r = e.top < 30;
|
|
117
135
|
this.tooltipEl.classList.toggle("below", r), this.tooltipEl.style.left = `${e.left + e.width / 2}px`, this.tooltipEl.style.top = r ? `${e.bottom + 8}px` : `${e.top - 8}px`, this.tooltipEl.style.display = "block";
|
|
118
136
|
}
|
|
@@ -126,7 +144,7 @@ class Mt {
|
|
|
126
144
|
this.highlightEl.remove(), this.tooltipEl.remove();
|
|
127
145
|
}
|
|
128
146
|
}
|
|
129
|
-
function
|
|
147
|
+
function G(i) {
|
|
130
148
|
if (i instanceof HTMLElement) {
|
|
131
149
|
const t = i.getAttribute("aria-label");
|
|
132
150
|
if (t) return t;
|
|
@@ -143,7 +161,7 @@ function F(i) {
|
|
|
143
161
|
}
|
|
144
162
|
return i.tagName.toLowerCase();
|
|
145
163
|
}
|
|
146
|
-
function
|
|
164
|
+
function _t(i) {
|
|
147
165
|
const t = [];
|
|
148
166
|
let e = i;
|
|
149
167
|
for (; e && e !== document.body && t.length < 5; ) {
|
|
@@ -168,7 +186,7 @@ function at(i) {
|
|
|
168
186
|
}
|
|
169
187
|
return t.join(" > ");
|
|
170
188
|
}
|
|
171
|
-
class
|
|
189
|
+
class ee {
|
|
172
190
|
constructor(t) {
|
|
173
191
|
this.pins = [], this.shadow = t;
|
|
174
192
|
}
|
|
@@ -184,14 +202,18 @@ class Pt {
|
|
|
184
202
|
this.clearAll();
|
|
185
203
|
}
|
|
186
204
|
}
|
|
187
|
-
const
|
|
188
|
-
|
|
205
|
+
const O = "#059669", ie = "5,150,105";
|
|
206
|
+
function J(i) {
|
|
207
|
+
return `rgba(${ie},${i})`;
|
|
208
|
+
}
|
|
209
|
+
const re = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', C = {
|
|
210
|
+
color: O,
|
|
189
211
|
width: "3.5",
|
|
190
212
|
linecap: "round",
|
|
191
213
|
linejoin: "round",
|
|
192
|
-
filter:
|
|
214
|
+
filter: `drop-shadow(0 1px 2px ${J(0.35)})`
|
|
193
215
|
};
|
|
194
|
-
class
|
|
216
|
+
class se {
|
|
195
217
|
constructor(t) {
|
|
196
218
|
this.currentPath = null, this.currentPoints = [], this.isDrawing = !1, this.committed = [], this.redoStack = [], this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.setAttribute("class", "mtb-draw-svg"), t.append(this.svg);
|
|
197
219
|
}
|
|
@@ -199,12 +221,12 @@ class Dt {
|
|
|
199
221
|
this.isDrawing = !0, this.currentPoints = [[t, e]], this.currentPath = this.createPath(), this.svg.appendChild(this.currentPath);
|
|
200
222
|
}
|
|
201
223
|
continueDraw(t, e) {
|
|
202
|
-
!this.isDrawing || !this.currentPath || (this.currentPoints.push([t, e]), this.currentPath.setAttribute("d",
|
|
224
|
+
!this.isDrawing || !this.currentPath || (this.currentPoints.push([t, e]), this.currentPath.setAttribute("d", et(this.currentPoints)));
|
|
203
225
|
}
|
|
204
226
|
// Commits the in-progress stroke to the undo stack and clears the redo stack.
|
|
205
227
|
// Callers decide whether the stroke has enough points before committing.
|
|
206
228
|
commitStroke() {
|
|
207
|
-
return !this.isDrawing || !this.currentPath ? !1 : (this.isDrawing = !1, this.committed.push({ path: this.currentPath, d:
|
|
229
|
+
return !this.isDrawing || !this.currentPath ? !1 : (this.isDrawing = !1, this.committed.push({ path: this.currentPath, d: et(this.currentPoints), points: this.currentPoints }), this.redoStack = [], this.currentPath = null, this.currentPoints = [], !0);
|
|
208
230
|
}
|
|
209
231
|
cancelCurrentDraw() {
|
|
210
232
|
this.currentPath?.remove(), this.currentPath = null, this.isDrawing = !1, this.currentPoints = [];
|
|
@@ -230,7 +252,7 @@ class Dt {
|
|
|
230
252
|
}
|
|
231
253
|
getAnnotation() {
|
|
232
254
|
if (this.committed.length === 0) return null;
|
|
233
|
-
const t = this.committed.flatMap((s) => s.points), [e, r] =
|
|
255
|
+
const t = this.committed.flatMap((s) => s.points), [e, r] = ne(t);
|
|
234
256
|
return {
|
|
235
257
|
type: "draw",
|
|
236
258
|
x: e,
|
|
@@ -253,10 +275,10 @@ class Dt {
|
|
|
253
275
|
}
|
|
254
276
|
createPath() {
|
|
255
277
|
const t = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
256
|
-
return t.setAttribute("fill", "none"), t.setAttribute("stroke",
|
|
278
|
+
return t.setAttribute("fill", "none"), t.setAttribute("stroke", C.color), t.setAttribute("stroke-width", C.width), t.setAttribute("stroke-linecap", C.linecap), t.setAttribute("stroke-linejoin", C.linejoin), t.setAttribute("style", `filter:${C.filter}`), t;
|
|
257
279
|
}
|
|
258
280
|
}
|
|
259
|
-
function
|
|
281
|
+
function et(i) {
|
|
260
282
|
if (i.length === 0) return "";
|
|
261
283
|
const [t, e] = i[0];
|
|
262
284
|
let r = `M ${t} ${e}`;
|
|
@@ -266,14 +288,14 @@ function j(i) {
|
|
|
266
288
|
}
|
|
267
289
|
return r;
|
|
268
290
|
}
|
|
269
|
-
function
|
|
291
|
+
function ne(i) {
|
|
270
292
|
const t = i.map((n) => n[0]), e = i.map((n) => n[1]), r = (Math.min(...t) + Math.max(...t)) / 2, s = (Math.min(...e) + Math.max(...e)) / 2;
|
|
271
293
|
return [r, s];
|
|
272
294
|
}
|
|
273
|
-
const
|
|
274
|
-
class
|
|
295
|
+
const oe = 5;
|
|
296
|
+
class ae {
|
|
275
297
|
constructor(t, e, r) {
|
|
276
|
-
this.messages = e, this.handlers = r, this.interactionActive = !0, this.pendingHighlightFrame = null, this.lastMoveX = 0, this.lastMoveY = 0, this.highlighter = new
|
|
298
|
+
this.messages = e, this.handlers = r, this.interactionActive = !0, this.pendingHighlightFrame = null, this.lastMoveX = 0, this.lastMoveY = 0, this.highlighter = new te(t), this.pinMarker = new ee(t), this.drawLayer = new se(t), this.overlay = new Zt(t, {
|
|
277
299
|
onMouseDown: (s) => this.handleMouseDown(s),
|
|
278
300
|
onMouseMove: (s) => this.handleMouseMove(s),
|
|
279
301
|
onMouseUp: (s) => this.handleMouseUp(s),
|
|
@@ -296,7 +318,7 @@ class It {
|
|
|
296
318
|
}
|
|
297
319
|
updateHighlight() {
|
|
298
320
|
if (!this.interactionActive || this.drawLayer.isCurrentlyDrawing() || this.drawSessionActive()) return;
|
|
299
|
-
const t =
|
|
321
|
+
const t = it(this.lastMoveX, this.lastMoveY);
|
|
300
322
|
t ? this.highlighter.highlight(t) : this.highlighter.hide();
|
|
301
323
|
}
|
|
302
324
|
cancelPendingHighlight() {
|
|
@@ -309,16 +331,16 @@ class It {
|
|
|
309
331
|
// draw note bar; a tap on an element becomes a pin. Stray taps while a
|
|
310
332
|
// drawing already exists are ignored so they don't hijack the draw flow.
|
|
311
333
|
finishStroke(t) {
|
|
312
|
-
if (this.drawLayer.getCurrentPointCount() >=
|
|
334
|
+
if (this.drawLayer.getCurrentPointCount() >= oe) {
|
|
313
335
|
this.drawLayer.commitStroke(), this.highlighter.hide(), this.handlers.onDrawStroke();
|
|
314
336
|
return;
|
|
315
337
|
}
|
|
316
338
|
if (this.drawLayer.cancelCurrentDraw(), this.drawLayer.hasStrokes() || !t) return;
|
|
317
|
-
const e =
|
|
339
|
+
const e = it(t.clientX, t.clientY), r = e ? G(e) : this.messages.annotation.element, s = e?.getBoundingClientRect(), n = {
|
|
318
340
|
type: "pin",
|
|
319
341
|
x: t.clientX,
|
|
320
342
|
y: t.clientY,
|
|
321
|
-
targetSelector: e ?
|
|
343
|
+
targetSelector: e ? _t(e) : void 0,
|
|
322
344
|
targetText: e?.textContent?.trim().slice(0, 200) ?? "",
|
|
323
345
|
targetName: r,
|
|
324
346
|
targetRect: s ? { top: s.top, left: s.left, width: s.width, height: s.height, bottom: s.bottom } : void 0
|
|
@@ -359,18 +381,18 @@ class It {
|
|
|
359
381
|
this.dismissInteraction(), this.highlighter.destroy(), this.pinMarker.destroy(), this.drawLayer.destroy();
|
|
360
382
|
}
|
|
361
383
|
}
|
|
362
|
-
function
|
|
384
|
+
function it(i, t) {
|
|
363
385
|
return document.elementsFromPoint(i, t).find((e) => e.id !== "mtb-widget-host") ?? null;
|
|
364
386
|
}
|
|
365
|
-
const
|
|
366
|
-
function
|
|
367
|
-
const t = document.getElementById(
|
|
387
|
+
const le = "mtb-widget-host";
|
|
388
|
+
function S(i) {
|
|
389
|
+
const t = document.getElementById(le);
|
|
368
390
|
return t ? t === i || t.contains(i) : !1;
|
|
369
391
|
}
|
|
370
|
-
function
|
|
392
|
+
function h(i) {
|
|
371
393
|
return i.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
372
394
|
}
|
|
373
|
-
class
|
|
395
|
+
class ce {
|
|
374
396
|
constructor(t, e) {
|
|
375
397
|
this.loading = !1, this.onSubmit = e.onSubmit, this.submitLabel = e.messages.draw.submit, this.el = t.el("div", "mtb-draw-bar"), this.el.innerHTML = this.buildHTML(e.messages), t.append(this.el), this.input = this.el.querySelector(".mtb-draw-input"), this.undoBtn = this.el.querySelector(".mtb-draw-undo"), this.redoBtn = this.el.querySelector(".mtb-draw-redo"), this.submitBtn = this.el.querySelector(".mtb-draw-submit"), this.errorEl = this.el.querySelector(".mtb-draw-error"), this.undoBtn.addEventListener("click", e.onUndo), this.redoBtn.addEventListener("click", e.onRedo), this.el.querySelector(".mtb-draw-cancel").addEventListener("click", e.onCancel), this.submitBtn.addEventListener("click", () => this.submit()), this.input.addEventListener("keydown", (r) => {
|
|
376
398
|
r.isComposing || r.keyCode === 229 || r.key === "Enter" && !r.shiftKey && (r.preventDefault(), this.submit());
|
|
@@ -378,16 +400,16 @@ class Bt {
|
|
|
378
400
|
}
|
|
379
401
|
buildHTML(t) {
|
|
380
402
|
return `
|
|
381
|
-
<input class="mtb-draw-input" type="text" placeholder="${
|
|
382
|
-
<button class="mtb-draw-icon-btn mtb-draw-undo" type="button" title="${
|
|
403
|
+
<input class="mtb-draw-input" type="text" placeholder="${h(t.draw.note_placeholder)}" />
|
|
404
|
+
<button class="mtb-draw-icon-btn mtb-draw-undo" type="button" title="${h(t.draw.undo)}" aria-label="${h(t.draw.undo)}" disabled>
|
|
383
405
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 14L4 9l5-5"/><path d="M4 9h11a5 5 0 0 1 0 10h-1"/></svg>
|
|
384
406
|
</button>
|
|
385
|
-
<button class="mtb-draw-icon-btn mtb-draw-redo" type="button" title="${
|
|
407
|
+
<button class="mtb-draw-icon-btn mtb-draw-redo" type="button" title="${h(t.draw.redo)}" aria-label="${h(t.draw.redo)}" disabled>
|
|
386
408
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 14l5-5-5-5"/><path d="M20 9H9a5 5 0 0 0 0 10h1"/></svg>
|
|
387
409
|
</button>
|
|
388
410
|
<span class="mtb-draw-sep"></span>
|
|
389
|
-
<button class="mtb-draw-cancel" type="button">${
|
|
390
|
-
<button class="mtb-draw-submit" type="button">${
|
|
411
|
+
<button class="mtb-draw-cancel" type="button">${h(t.draw.cancel)}</button>
|
|
412
|
+
<button class="mtb-draw-submit" type="button">${h(t.draw.submit)}</button>
|
|
391
413
|
<div class="mtb-draw-error" role="alert" hidden></div>
|
|
392
414
|
`;
|
|
393
415
|
}
|
|
@@ -407,16 +429,16 @@ class Bt {
|
|
|
407
429
|
this.el.remove();
|
|
408
430
|
}
|
|
409
431
|
}
|
|
410
|
-
class
|
|
432
|
+
class de {
|
|
411
433
|
constructor(t, e) {
|
|
412
|
-
this.loading = !1, this.onSubmit = e.onSubmit, this.onClose = e.onClose, this.submitLabel = e.messages.popup.submit, this.messages = e.messages, this.el = t.el("div", "mtb-popup"), this.el.innerHTML = this.buildHTML(e), t.append(this.el), this.textarea = this.el.querySelector(".mtb-textarea"), this.submitBtn = this.el.querySelector(".mtb-submit-btn"), this.positionPopup(e.x, e.y, e.targetRect, e.position ?? "right"), this.bindEvents(e.messages), e.onMyFeedback && this.el.querySelector(".mtb-my-feedback").addEventListener("click", e.onMyFeedback), this.textarea.focus();
|
|
434
|
+
this.loading = !1, this.selectedQuickOption = null, this.onSubmit = e.onSubmit, this.onClose = e.onClose, this.submitLabel = e.messages.popup.submit, this.messages = e.messages, this.el = t.el("div", "mtb-popup"), this.el.innerHTML = this.buildHTML(e), t.append(this.el), this.textarea = this.el.querySelector(".mtb-textarea"), this.submitBtn = this.el.querySelector(".mtb-submit-btn"), this.positionPopup(e.x, e.y, e.targetRect, e.position ?? "right"), this.bindEvents(e.messages), e.onMyFeedback && this.el.querySelector(".mtb-my-feedback").addEventListener("click", e.onMyFeedback), this.textarea.focus();
|
|
413
435
|
}
|
|
414
436
|
buildHTML(t) {
|
|
415
437
|
const e = t.messages, r = e.popup.quickOptions.map(
|
|
416
438
|
(s) => `
|
|
417
|
-
<button class="mtb-quick-option" data-quick="${
|
|
439
|
+
<button class="mtb-quick-option" data-quick="${h(s.label)}">
|
|
418
440
|
<span class="mtb-quick-option-emoji">${s.emoji}</span>
|
|
419
|
-
<span>${
|
|
441
|
+
<span>${h(s.label)}</span>
|
|
420
442
|
</button>`
|
|
421
443
|
).join("");
|
|
422
444
|
return `
|
|
@@ -426,7 +448,7 @@ class Ft {
|
|
|
426
448
|
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>
|
|
427
449
|
</svg>
|
|
428
450
|
</div>
|
|
429
|
-
<span class="mtb-popup-title">${e.popup.about} "${
|
|
451
|
+
<span class="mtb-popup-title">${e.popup.about} "${h(t.targetName)}"</span>
|
|
430
452
|
<button class="mtb-popup-close" aria-label="Close">
|
|
431
453
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
432
454
|
<path d="M18 6L6 18M6 6l12 12"/>
|
|
@@ -438,27 +460,33 @@ class Ft {
|
|
|
438
460
|
${r}
|
|
439
461
|
</div>
|
|
440
462
|
<div class="mtb-textarea-wrap">
|
|
441
|
-
<textarea class="mtb-textarea" placeholder="${
|
|
463
|
+
<textarea class="mtb-textarea" placeholder="${h(e.popup.placeholder)}"></textarea>
|
|
442
464
|
</div>
|
|
443
465
|
<div class="mtb-popup-error" role="alert"></div>
|
|
444
466
|
<div class="mtb-popup-actions">
|
|
445
|
-
<button class="mtb-cancel-btn" type="button">${
|
|
446
|
-
<button class="mtb-submit-btn" type="button" disabled>${
|
|
467
|
+
<button class="mtb-cancel-btn" type="button">${h(e.popup.cancel)}</button>
|
|
468
|
+
<button class="mtb-submit-btn" type="button" disabled>${h(e.popup.submit)}</button>
|
|
447
469
|
</div>
|
|
448
|
-
${t.onMyFeedback ? `<button class="mtb-my-feedback" type="button">${
|
|
470
|
+
${t.onMyFeedback ? `<button class="mtb-my-feedback" type="button">${h(e.popup.my_feedback)}</button>` : ""}
|
|
449
471
|
</div>
|
|
450
472
|
`;
|
|
451
473
|
}
|
|
452
474
|
positionPopup(t, e, r, s) {
|
|
453
|
-
const n = window.innerWidth, o = window.innerHeight, a = 12, l = 8, c = 32,
|
|
454
|
-
let
|
|
455
|
-
r ? (
|
|
475
|
+
const n = window.innerWidth, o = window.innerHeight, a = 12, l = 8, c = 32, d = Math.min(320, n - 2 * a - c), u = this.el.offsetHeight || 260, m = a + (s === "left" ? c : 0), p = n - a - (s === "right" ? c : 0);
|
|
476
|
+
let g, y;
|
|
477
|
+
r ? (g = r.left, y = r.bottom + l, y + u > o - a && (y = r.top - u - l), y < a && (y = Math.min(r.bottom + l, o - u - a))) : (g = t + 12, y = e + 12), g + d > p && (g = p - d), g < m && (g = m), y < a && (y = a), this.el.style.left = `${g}px`, this.el.style.top = `${y}px`, this.el.style.maxHeight = `${o - y - a}px`;
|
|
456
478
|
}
|
|
457
479
|
bindEvents(t) {
|
|
458
480
|
this.el.querySelector(".mtb-popup-close").addEventListener("click", () => this.onClose()), this.el.querySelector(".mtb-cancel-btn").addEventListener("click", () => this.onClose()), this.errorEl = this.el.querySelector(".mtb-popup-error"), this.el.querySelectorAll(".mtb-quick-option").forEach((e) => {
|
|
459
481
|
e.addEventListener("click", () => {
|
|
460
482
|
const r = e.dataset.quick ?? "";
|
|
461
|
-
this.textarea.value
|
|
483
|
+
if (this.textarea.value.trim().length === 0) {
|
|
484
|
+
this.textarea.value = r, this.updateSubmitState(), this.submit();
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
this.selectedQuickOption = r, this.el.querySelectorAll(".mtb-quick-option").forEach((s) => {
|
|
488
|
+
s.classList.toggle("selected", s === e);
|
|
489
|
+
});
|
|
462
490
|
});
|
|
463
491
|
}), this.textarea.addEventListener("input", () => this.updateSubmitState()), this.textarea.addEventListener("keydown", (e) => {
|
|
464
492
|
e.isComposing || e.keyCode === 229 || e.key === "Enter" && !e.shiftKey && (e.preventDefault(), this.submit());
|
|
@@ -470,7 +498,9 @@ class Ft {
|
|
|
470
498
|
}
|
|
471
499
|
submit() {
|
|
472
500
|
const t = this.textarea.value.trim();
|
|
473
|
-
!t || this.loading
|
|
501
|
+
if (!t || this.loading) return;
|
|
502
|
+
const e = this.selectedQuickOption ? `[${this.selectedQuickOption}] ${t}` : t;
|
|
503
|
+
this.onSubmit(e);
|
|
474
504
|
}
|
|
475
505
|
setLoading(t) {
|
|
476
506
|
this.loading = t, t ? (this.submitBtn.classList.add("loading"), this.submitBtn.innerHTML = '<span class="mtb-dot"></span><span class="mtb-dot"></span><span class="mtb-dot"></span>', this.textarea.disabled = !0) : (this.submitBtn.classList.remove("loading"), this.submitBtn.textContent = this.submitLabel, this.textarea.disabled = !1), this.updateSubmitState();
|
|
@@ -485,24 +515,208 @@ class Ft {
|
|
|
485
515
|
this.el.remove();
|
|
486
516
|
}
|
|
487
517
|
}
|
|
488
|
-
|
|
489
|
-
|
|
518
|
+
class Tt extends Error {
|
|
519
|
+
constructor(t) {
|
|
520
|
+
super(`HTTP ${t}`), this.name = "ApiError", this.status = t;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
function he(i) {
|
|
524
|
+
return i instanceof Tt && i.status === 409;
|
|
525
|
+
}
|
|
526
|
+
const ue = "https://makethisbetter.dev/api/v1";
|
|
527
|
+
class me {
|
|
528
|
+
constructor(t, e, r = 1e3, s, n) {
|
|
529
|
+
this.projectKey = t, this.apiUrl = (e ?? ue).replace(/\/$/, ""), this.retryDelayMs = r, this.userToken = s, this.userTokenFn = n;
|
|
530
|
+
}
|
|
531
|
+
async resolveUserToken() {
|
|
532
|
+
return this.userTokenFn ? this.userTokenFn() : this.userToken;
|
|
533
|
+
}
|
|
534
|
+
async authHeaders(t) {
|
|
535
|
+
const e = { "X-Project-Key": this.projectKey }, r = await this.resolveUserToken();
|
|
536
|
+
return r && (e["X-User-Token"] = r), t && (e["Content-Type"] = t), e;
|
|
537
|
+
}
|
|
538
|
+
async submissionHeaders(t, e) {
|
|
539
|
+
const r = await this.authHeaders(e);
|
|
540
|
+
return r["X-Submission-Token"] = t, r;
|
|
541
|
+
}
|
|
542
|
+
async createSubmissionSession(t, e) {
|
|
543
|
+
const r = pe(), s = new FormData();
|
|
544
|
+
if (s.append("feedback[description]", t.description), s.append("feedback[page_url]", t.page_url), s.append("feedback[user_agent]", t.user_agent), s.append("feedback[browser]", t.browser), s.append("feedback[os]", t.os), s.append("feedback[screen_width]", String(t.screen_width)), s.append("feedback[screen_height]", String(t.screen_height)), s.append("feedback[console_errors]", JSON.stringify(t.console_errors)), s.append("feedback[annotations]", JSON.stringify(t.annotations)), t.target_element && s.append("feedback[target_element]", JSON.stringify(t.target_element)), t.user_id && s.append("feedback[user_id]", t.user_id), t.reporter_external_id && s.append("feedback[reporter_external_id]", t.reporter_external_id), t.reporter_email && s.append("feedback[reporter_email]", t.reporter_email), t.user_email && s.append("feedback[user_email]", t.user_email), t.user_name && s.append("feedback[user_name]", t.user_name), t.breadcrumbs && t.breadcrumbs.length > 0 && s.append("feedback[breadcrumbs]", JSON.stringify(t.breadcrumbs)), t.recording_events && t.recording_events.length > 0) {
|
|
545
|
+
const l = JSON.stringify(t.recording_events), c = new Blob([l], { type: "application/json" });
|
|
546
|
+
s.append("feedback[recording]", c, "interaction-replay.json"), s.append("feedback[recording_duration]", String(t.recording_duration ?? 0));
|
|
547
|
+
}
|
|
548
|
+
if (e) {
|
|
549
|
+
const l = e.type === "image/jpeg" ? "jpg" : "png";
|
|
550
|
+
s.append("feedback[screenshot]", e, `screenshot.${l}`);
|
|
551
|
+
}
|
|
552
|
+
const n = await this.authHeaders();
|
|
553
|
+
return n["X-Submission-Token"] = r, n["X-Idempotency-Key"] = be(), { ...(await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions`, {
|
|
554
|
+
method: "POST",
|
|
555
|
+
headers: n,
|
|
556
|
+
body: s
|
|
557
|
+
})).json()).submission_session, token: r };
|
|
558
|
+
}
|
|
559
|
+
async createIdentityToken(t) {
|
|
560
|
+
const e = await this.authHeaders("application/json");
|
|
561
|
+
try {
|
|
562
|
+
return await (await this.fetchWithRetry(`${this.apiUrl}/widget/identity_tokens`, {
|
|
563
|
+
method: "POST",
|
|
564
|
+
headers: e,
|
|
565
|
+
body: JSON.stringify({ reporter_external_id: t })
|
|
566
|
+
})).json();
|
|
567
|
+
} catch {
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async updateReporter(t, e, r) {
|
|
572
|
+
const s = await this.authHeaders("application/json");
|
|
573
|
+
s["X-Identity-Token"] = r;
|
|
574
|
+
try {
|
|
575
|
+
return await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${t}/reporter`, {
|
|
576
|
+
method: "PATCH",
|
|
577
|
+
headers: s,
|
|
578
|
+
body: JSON.stringify({ reporter: { email: e } })
|
|
579
|
+
}), !0;
|
|
580
|
+
} catch {
|
|
581
|
+
return !1;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
async startClarification(t, e, r) {
|
|
585
|
+
const s = {};
|
|
586
|
+
return r && (s.message = r), this.requestClarification(t, e, s);
|
|
587
|
+
}
|
|
588
|
+
async retryClarification(t, e) {
|
|
589
|
+
return this.requestClarification(t, e, { retry: !0 });
|
|
590
|
+
}
|
|
591
|
+
async requestClarification(t, e, r) {
|
|
592
|
+
const s = await this.submissionHeaders(e, "application/json");
|
|
593
|
+
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
594
|
+
method: "POST",
|
|
595
|
+
headers: s,
|
|
596
|
+
body: JSON.stringify(r)
|
|
597
|
+
})).json()).clarification;
|
|
598
|
+
}
|
|
599
|
+
async getClarification(t, e) {
|
|
600
|
+
const r = await this.submissionHeaders(e);
|
|
601
|
+
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
602
|
+
method: "GET",
|
|
603
|
+
headers: r
|
|
604
|
+
})).json()).clarification;
|
|
605
|
+
}
|
|
606
|
+
// Streams a clarification turn over SSE. Calls onDelta for each token and
|
|
607
|
+
// resolves with the committed result. Throws if the server doesn't stream
|
|
608
|
+
// (e.g. old backend returns JSON) so the caller can fall back to polling.
|
|
609
|
+
async streamClarification(t, e, r, s) {
|
|
610
|
+
const n = await this.submissionHeaders(e, "application/json");
|
|
611
|
+
n.Accept = "text/event-stream";
|
|
612
|
+
const o = await fetch(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
613
|
+
method: "POST",
|
|
614
|
+
headers: n,
|
|
615
|
+
body: JSON.stringify({}),
|
|
616
|
+
signal: s
|
|
617
|
+
}), a = o.headers.get("Content-Type") ?? "";
|
|
618
|
+
if (!o.ok || !o.body || !a.includes("text/event-stream"))
|
|
619
|
+
throw new Error("clarify stream unavailable");
|
|
620
|
+
return fe(o.body, r);
|
|
621
|
+
}
|
|
622
|
+
async finalizeSubmissionSession(t, e) {
|
|
623
|
+
const r = await this.submissionHeaders(e);
|
|
624
|
+
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/feedback`, {
|
|
625
|
+
method: "POST",
|
|
626
|
+
headers: r
|
|
627
|
+
})).json()).feedback;
|
|
628
|
+
}
|
|
629
|
+
async abandonSubmissionSession(t, e) {
|
|
630
|
+
const r = await this.submissionHeaders(e);
|
|
631
|
+
await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}`, {
|
|
632
|
+
method: "DELETE",
|
|
633
|
+
headers: r
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
async fetchWithRetry(t, e, r = 1) {
|
|
637
|
+
let s;
|
|
638
|
+
try {
|
|
639
|
+
s = await fetch(t, e);
|
|
640
|
+
} catch (n) {
|
|
641
|
+
if (r > 0)
|
|
642
|
+
return await rt(this.retryDelayMs), this.fetchWithRetry(t, e, r - 1);
|
|
643
|
+
throw n;
|
|
644
|
+
}
|
|
645
|
+
if (s.ok) return s;
|
|
646
|
+
if (s.status >= 500 && r > 0)
|
|
647
|
+
return await rt(this.retryDelayMs), this.fetchWithRetry(t, e, r - 1);
|
|
648
|
+
throw new Tt(s.status);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
function rt(i) {
|
|
652
|
+
return i <= 0 ? Promise.resolve() : new Promise((t) => setTimeout(t, i));
|
|
653
|
+
}
|
|
654
|
+
async function fe(i, t) {
|
|
655
|
+
const e = i.getReader(), r = new TextDecoder();
|
|
656
|
+
let s = "", n = null;
|
|
657
|
+
const o = (a) => {
|
|
658
|
+
const l = a.split(`
|
|
659
|
+
`).find((m) => m.startsWith("event:")), c = a.split(`
|
|
660
|
+
`).find((m) => m.startsWith("data:"));
|
|
661
|
+
if (!c) return;
|
|
662
|
+
const d = l?.slice(6).trim(), u = JSON.parse(c.slice(5).trim());
|
|
663
|
+
d === "delta" && typeof u.text == "string" ? t(u.text) : d === "done" && (n = {
|
|
664
|
+
messages: Array.isArray(u.messages) ? u.messages : [],
|
|
665
|
+
done: u.done !== !1,
|
|
666
|
+
failed: u.error === !0
|
|
667
|
+
});
|
|
668
|
+
};
|
|
669
|
+
for (; ; ) {
|
|
670
|
+
const { done: a, value: l } = await e.read();
|
|
671
|
+
if (a) break;
|
|
672
|
+
s += r.decode(l, { stream: !0 });
|
|
673
|
+
let c;
|
|
674
|
+
for (; (c = s.indexOf(`
|
|
675
|
+
|
|
676
|
+
`)) !== -1; ) {
|
|
677
|
+
const d = s.slice(0, c);
|
|
678
|
+
s = s.slice(c + 2);
|
|
679
|
+
try {
|
|
680
|
+
o(d);
|
|
681
|
+
} catch {
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (s += r.decode(), s.trim())
|
|
686
|
+
try {
|
|
687
|
+
o(s);
|
|
688
|
+
} catch {
|
|
689
|
+
}
|
|
690
|
+
if (!n) throw new Error("clarify stream ended before done");
|
|
691
|
+
return n;
|
|
692
|
+
}
|
|
693
|
+
function be() {
|
|
694
|
+
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
695
|
+
}
|
|
696
|
+
function pe() {
|
|
697
|
+
if (typeof crypto > "u" || typeof crypto.getRandomValues != "function")
|
|
698
|
+
throw new Error("Secure random generation is unavailable");
|
|
699
|
+
const i = crypto.getRandomValues(new Uint8Array(32));
|
|
700
|
+
return Array.from(i, (t) => t.toString(16).padStart(2, "0")).join("");
|
|
701
|
+
}
|
|
702
|
+
const ge = 2e3, ye = 45e3, we = 346, ve = 270;
|
|
703
|
+
class xe {
|
|
490
704
|
constructor(t, e) {
|
|
491
|
-
this.pollTimer = null, this.pollDeadline = 0, this.streamingBubble = null, this.lastMessages = [], this.done = !1, this.sending = !1, this.finalizing = !1, this.destroyed = !1, this.submissionSessionId = e.submissionSessionId, this.submissionToken = e.submissionToken, this.apiClient = e.apiClient, this.onFinalize = e.onFinalize, this.i18n = e.messages, this.preloadedResult = e.preloadedResult, this.pendingClarification = e.pendingClarification;
|
|
705
|
+
this.pollTimer = null, this.pollDeadline = 0, this.streamingBubble = null, this.lastMessages = [], this.done = !1, this.sending = !1, this.finalizing = !1, this.destroyed = !1, this.unrecoverable = !1, this.submissionSessionId = e.submissionSessionId, this.submissionToken = e.submissionToken, this.apiClient = e.apiClient, this.onFinalize = e.onFinalize, this.i18n = e.messages, this.preloadedResult = e.preloadedResult, this.pendingClarification = e.pendingClarification;
|
|
492
706
|
const r = e.element;
|
|
493
|
-
this.el = r ?? t.el("div", "mtb-clarify"), this.el.className = r ? "mtb-clarify mtb-clarify-continuation" : "mtb-clarify", this.el.innerHTML = this.buildHTML(e.messages), r || (t.append(this.el), this.positionCard(e.x, e.y, e.position ?? "right")), this.messagesEl = this.el.querySelector(".mtb-clarify-messages"), this.
|
|
707
|
+
this.el = r ?? t.el("div", "mtb-clarify"), this.el.className = r ? "mtb-clarify mtb-clarify-continuation" : "mtb-clarify", this.el.innerHTML = this.buildHTML(e.messages), r || (t.append(this.el), this.positionCard(e.x, e.y, e.position ?? "right")), this.messagesEl = this.el.querySelector(".mtb-clarify-messages"), this.bindEvents(), this.startConversation();
|
|
494
708
|
}
|
|
495
709
|
// Anchors the card near the annotation point, clamped to the viewport so it
|
|
496
710
|
// never overflows a screen edge (mirrors CommentPopup.positionPopup).
|
|
497
711
|
positionCard(t, e, r) {
|
|
498
|
-
const s = window.innerWidth, n = window.innerHeight, o = 12, a = 32, l = Math.min(
|
|
712
|
+
const s = window.innerWidth, n = window.innerHeight, o = 12, a = 32, l = Math.min(we, s - 2 * o - a), c = this.el.offsetHeight || ve, d = o + (r === "left" ? a : 0), u = s - o - (r === "right" ? a : 0);
|
|
499
713
|
if (t === void 0 || e === void 0) {
|
|
500
|
-
const
|
|
501
|
-
this.el.style.left = `${Math.min(
|
|
714
|
+
const g = Math.max(d, (s - l) / 2);
|
|
715
|
+
this.el.style.left = `${Math.min(g, u - l)}px`, this.el.style.top = `${Math.max(o, (n - c) / 2)}px`, this.el.style.maxHeight = `${n - 2 * o}px`;
|
|
502
716
|
return;
|
|
503
717
|
}
|
|
504
|
-
let m = t + 12,
|
|
505
|
-
m + l > u && (m = t - l - 12), m + l > u && (m = u - l), m <
|
|
718
|
+
let m = t + 12, p = e + 12;
|
|
719
|
+
m + l > u && (m = t - l - 12), m + l > u && (m = u - l), m < d && (m = d), p + c > n - o && (p = n - c - o), p < o && (p = o), this.el.style.left = `${m}px`, this.el.style.top = `${p}px`, this.el.style.maxHeight = `${n - p - o}px`;
|
|
506
720
|
}
|
|
507
721
|
buildHTML(t) {
|
|
508
722
|
return `
|
|
@@ -513,44 +727,50 @@ class qt {
|
|
|
513
727
|
</svg>
|
|
514
728
|
</span>
|
|
515
729
|
<div class="mtb-clarify-titles">
|
|
516
|
-
<div class="mtb-clarify-title">${
|
|
517
|
-
<div class="mtb-clarify-subtitle">${
|
|
730
|
+
<div class="mtb-clarify-title">${h(t.clarify.title)}</div>
|
|
731
|
+
<div class="mtb-clarify-subtitle">${h(t.clarify.subtitle)}</div>
|
|
518
732
|
</div>
|
|
519
|
-
<button class="mtb-clarify-close" type="button" title="${
|
|
733
|
+
<button class="mtb-clarify-close" type="button" title="${h(t.clarify.skip)}" aria-label="${h(t.clarify.skip)}">
|
|
520
734
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
521
735
|
<path d="M18 6L6 18M6 6l12 12"/>
|
|
522
736
|
</svg>
|
|
523
737
|
</button>
|
|
524
738
|
</div>
|
|
525
739
|
<div class="mtb-clarify-messages"></div>
|
|
526
|
-
<div class="mtb-clarify-footer">
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
740
|
+
<div class="mtb-clarify-footer">${this.buildConversationControls(t)}</div>
|
|
741
|
+
`;
|
|
742
|
+
}
|
|
743
|
+
buildConversationControls(t) {
|
|
744
|
+
return `
|
|
745
|
+
<textarea class="mtb-clarify-input" rows="1" placeholder="${h(t.clarify.placeholder)}"></textarea>
|
|
746
|
+
<div class="mtb-clarify-actions">
|
|
747
|
+
<button class="mtb-clarify-skip" type="button">${h(t.clarify.skip)}</button>
|
|
748
|
+
<button class="mtb-clarify-send" type="button" disabled>
|
|
749
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
750
|
+
<line x1="22" y1="2" x2="11" y2="13"/>
|
|
751
|
+
<polygon points="22 2 15 22 11 13 2 9 22 2"/>
|
|
752
|
+
</svg>
|
|
753
|
+
<span>${h(t.clarify.send)}</span>
|
|
754
|
+
</button>
|
|
538
755
|
</div>
|
|
539
756
|
`;
|
|
540
757
|
}
|
|
541
758
|
bindEvents() {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
this.el.querySelector(".mtb-clarify-
|
|
759
|
+
this.el.querySelector(".mtb-clarify-close").addEventListener("click", () => this.skipAndFinalize()), this.bindConversationControls();
|
|
760
|
+
}
|
|
761
|
+
bindConversationControls() {
|
|
762
|
+
this.inputEl = this.el.querySelector(".mtb-clarify-input"), this.sendBtn = this.el.querySelector(".mtb-clarify-send"), this.el.querySelector(".mtb-clarify-skip").addEventListener("click", () => this.skipAndFinalize()), this.inputEl.addEventListener("input", () => {
|
|
546
763
|
this.sendBtn.disabled = !this.inputEl.value.trim();
|
|
547
|
-
}), this.inputEl.addEventListener("keydown", (
|
|
548
|
-
|
|
764
|
+
}), this.inputEl.addEventListener("keydown", (t) => {
|
|
765
|
+
t.isComposing || t.keyCode === 229 || t.key === "Enter" && !t.shiftKey && (t.preventDefault(), this.sendMessage());
|
|
549
766
|
}), this.sendBtn.addEventListener("click", () => this.sendMessage());
|
|
550
767
|
}
|
|
768
|
+
skipAndFinalize() {
|
|
769
|
+
this.stopPolling(), this.finalize();
|
|
770
|
+
}
|
|
551
771
|
async startConversation() {
|
|
552
772
|
if (this.preloadedResult) {
|
|
553
|
-
this.
|
|
773
|
+
this.applyResult(this.preloadedResult);
|
|
554
774
|
return;
|
|
555
775
|
}
|
|
556
776
|
if (this.pendingClarification) {
|
|
@@ -558,7 +778,7 @@ class qt {
|
|
|
558
778
|
try {
|
|
559
779
|
const t = await this.pendingClarification;
|
|
560
780
|
if (this.destroyed) return;
|
|
561
|
-
t ?
|
|
781
|
+
t ? this.applyResult(t) || this.startPolling() : await this.runInitialTurnViaPolling();
|
|
562
782
|
} catch {
|
|
563
783
|
if (this.destroyed) return;
|
|
564
784
|
await this.runInitialTurnViaPolling();
|
|
@@ -591,7 +811,7 @@ class qt {
|
|
|
591
811
|
(e) => this.appendStreamDelta(e)
|
|
592
812
|
);
|
|
593
813
|
if (this.destroyed) return;
|
|
594
|
-
this.endStreamingBubble(), this.
|
|
814
|
+
this.endStreamingBubble(), this.applyResult(t) || this.startPolling();
|
|
595
815
|
} catch {
|
|
596
816
|
if (this.destroyed) return;
|
|
597
817
|
this.endStreamingBubble(), await this.runInitialTurnViaPolling();
|
|
@@ -604,10 +824,10 @@ class qt {
|
|
|
604
824
|
this.submissionToken
|
|
605
825
|
);
|
|
606
826
|
if (this.destroyed) return;
|
|
607
|
-
this.
|
|
827
|
+
this.applyResult(t) || this.startPolling();
|
|
608
828
|
} catch {
|
|
609
829
|
if (this.destroyed) return;
|
|
610
|
-
this.
|
|
830
|
+
this.handleFailure();
|
|
611
831
|
}
|
|
612
832
|
}
|
|
613
833
|
async runAnswerTurn(t) {
|
|
@@ -616,7 +836,7 @@ class qt {
|
|
|
616
836
|
this.submissionToken,
|
|
617
837
|
t
|
|
618
838
|
);
|
|
619
|
-
this.destroyed ||
|
|
839
|
+
this.destroyed || this.applyResult(e) || this.startPolling();
|
|
620
840
|
}
|
|
621
841
|
showError() {
|
|
622
842
|
const t = this.el.querySelector(".mtb-clarify-footer"), e = document.createElement("div");
|
|
@@ -632,14 +852,14 @@ class qt {
|
|
|
632
852
|
this.streamingBubble = null;
|
|
633
853
|
}
|
|
634
854
|
startPolling() {
|
|
635
|
-
this.stopPolling(), this.pollDeadline = Date.now() +
|
|
855
|
+
this.stopPolling(), this.pollDeadline = Date.now() + ye, this.pollTimer = setInterval(() => this.poll(), ge);
|
|
636
856
|
}
|
|
637
857
|
stopPolling() {
|
|
638
858
|
this.pollTimer !== null && (clearInterval(this.pollTimer), this.pollTimer = null);
|
|
639
859
|
}
|
|
640
860
|
async poll() {
|
|
641
861
|
if (Date.now() > this.pollDeadline) {
|
|
642
|
-
this.stopPolling(), this.
|
|
862
|
+
this.stopPolling(), this.handleFailure();
|
|
643
863
|
return;
|
|
644
864
|
}
|
|
645
865
|
try {
|
|
@@ -648,15 +868,61 @@ class qt {
|
|
|
648
868
|
this.submissionToken
|
|
649
869
|
);
|
|
650
870
|
if (this.destroyed) return;
|
|
651
|
-
this.
|
|
871
|
+
this.applyResult(t) && this.stopPolling();
|
|
652
872
|
} catch {
|
|
653
873
|
if (this.destroyed) return;
|
|
654
|
-
this.stopPolling(), this.
|
|
874
|
+
this.stopPolling(), this.handleFailure();
|
|
655
875
|
}
|
|
656
876
|
}
|
|
657
877
|
handleDone() {
|
|
658
878
|
this.done || (this.done = !0, this.stopPolling(), this.removeThinking(), this.showFinalizeButton());
|
|
659
879
|
}
|
|
880
|
+
handleFailure() {
|
|
881
|
+
this.done || (this.done = !0, this.stopPolling(), this.removeThinking(), this.showClarificationFailureActions());
|
|
882
|
+
}
|
|
883
|
+
showClarificationFailureActions() {
|
|
884
|
+
const t = this.el.querySelector(".mtb-clarify-footer");
|
|
885
|
+
t.innerHTML = `
|
|
886
|
+
<div class="mtb-clarify-error">${h(this.i18n.clarify.error)}</div>
|
|
887
|
+
<div class="mtb-clarify-actions">
|
|
888
|
+
<button class="mtb-clarify-fallback" type="button">${h(this.i18n.clarify.send_feedback)}</button>
|
|
889
|
+
<button class="mtb-clarify-retry" type="button">${h(this.i18n.clarify.retry)}</button>
|
|
890
|
+
</div>
|
|
891
|
+
`, t.querySelector(".mtb-clarify-fallback").addEventListener("click", () => this.skipAndFinalize()), t.querySelector(".mtb-clarify-retry").addEventListener("click", () => {
|
|
892
|
+
this.destroyed || this.retryClarification();
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
async retryClarification() {
|
|
896
|
+
if (!(this.sending || this.destroyed)) {
|
|
897
|
+
this.sending = !0, this.done = !1, this.showConversationControls(), this.inputEl.disabled = !0, this.sendBtn.disabled = !0, this.renderConversation(this.lastMessages, !1);
|
|
898
|
+
try {
|
|
899
|
+
const t = await this.apiClient.getClarification(this.submissionSessionId, this.submissionToken);
|
|
900
|
+
if (this.destroyed) return;
|
|
901
|
+
let e = t;
|
|
902
|
+
if (t.status === "failed" ? e = await this.apiClient.retryClarification(this.submissionSessionId, this.submissionToken) : t.status === "idle" && (e = await this.apiClient.startClarification(this.submissionSessionId, this.submissionToken)), this.destroyed) return;
|
|
903
|
+
this.applyResult(e) || (this.showConversationControls(), this.startPolling());
|
|
904
|
+
} catch {
|
|
905
|
+
if (this.destroyed) return;
|
|
906
|
+
this.handleFailure();
|
|
907
|
+
} finally {
|
|
908
|
+
this.sending = !1;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
showConversationControls() {
|
|
913
|
+
const t = this.el.querySelector(".mtb-clarify-footer");
|
|
914
|
+
t.innerHTML = this.buildConversationControls(this.i18n), this.bindConversationControls();
|
|
915
|
+
}
|
|
916
|
+
// Returns true when the exchange has settled — the caller uses that to decide
|
|
917
|
+
// whether it still needs to poll.
|
|
918
|
+
applyResult(t) {
|
|
919
|
+
this.renderConversation(t.messages, t.done);
|
|
920
|
+
const e = "status" in t ? t.status : void 0;
|
|
921
|
+
return ("status" in t ? t.status === "failed" : t.failed === !0) ? (this.handleFailure(), !0) : t.done ? (this.handleDone(), !0) : e === "awaiting_response" ? (this.stopPolling(), this.removeThinking(), this.enableInput(), !0) : !1;
|
|
922
|
+
}
|
|
923
|
+
enableInput() {
|
|
924
|
+
this.el.contains(this.inputEl) || this.showConversationControls(), this.inputEl.disabled = !1, this.sendBtn.disabled = !this.inputEl.value.trim();
|
|
925
|
+
}
|
|
660
926
|
showFinalizeButton() {
|
|
661
927
|
const t = this.el.querySelector(".mtb-clarify-footer");
|
|
662
928
|
t.innerHTML = `
|
|
@@ -665,28 +931,43 @@ class qt {
|
|
|
665
931
|
<line x1="22" y1="2" x2="11" y2="13"/>
|
|
666
932
|
<polygon points="22 2 15 22 11 13 2 9 22 2"/>
|
|
667
933
|
</svg>
|
|
668
|
-
<span>${
|
|
934
|
+
<span>${h(this.i18n.clarify.send_feedback)}</span>
|
|
669
935
|
</button>
|
|
670
936
|
`, t.querySelector(".mtb-clarify-send-feedback").addEventListener("click", () => {
|
|
671
937
|
this.destroyed || this.finalize();
|
|
672
938
|
});
|
|
673
939
|
}
|
|
674
940
|
async finalize() {
|
|
675
|
-
if (!(this.finalizing || this.destroyed)) {
|
|
941
|
+
if (!(this.finalizing || this.destroyed || this.unrecoverable)) {
|
|
676
942
|
this.finalizing = !0, this.el.querySelectorAll("button").forEach((t) => {
|
|
677
943
|
t.disabled = !0;
|
|
678
944
|
});
|
|
679
945
|
try {
|
|
680
946
|
await this.onFinalize();
|
|
681
|
-
} catch {
|
|
947
|
+
} catch (t) {
|
|
682
948
|
if (this.destroyed) return;
|
|
683
|
-
this.finalizing = !1, this.clearError(),
|
|
949
|
+
if (this.finalizing = !1, this.clearError(), he(t)) {
|
|
950
|
+
this.showUnrecoverable();
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
this.showFinalizeRetry();
|
|
684
954
|
}
|
|
685
955
|
}
|
|
686
956
|
}
|
|
687
|
-
|
|
957
|
+
showUnrecoverable() {
|
|
958
|
+
this.unrecoverable = !0, this.stopPolling();
|
|
959
|
+
const t = this.el.querySelector(".mtb-clarify-footer");
|
|
960
|
+
t.innerHTML = `<div class="mtb-clarify-error">${h(this.i18n.clarify.expired)}</div>`;
|
|
961
|
+
}
|
|
962
|
+
// Renders the reason and the retry together: replacing the footer wholesale is
|
|
963
|
+
// what used to discard the error message showError() had just prepended, so the
|
|
964
|
+
// reporter saw a bare Retry button with no explanation.
|
|
965
|
+
showFinalizeRetry() {
|
|
688
966
|
const t = this.el.querySelector(".mtb-clarify-footer");
|
|
689
|
-
t.innerHTML =
|
|
967
|
+
t.innerHTML = `
|
|
968
|
+
<div class="mtb-clarify-error">${h(this.i18n.error.submit)}</div>
|
|
969
|
+
<button class="mtb-clarify-send-feedback mtb-clarify-retry" type="button">${h(this.i18n.clarify.retry)}</button>
|
|
970
|
+
`, t.querySelector(".mtb-clarify-retry").addEventListener("click", () => {
|
|
690
971
|
this.destroyed || this.finalize();
|
|
691
972
|
});
|
|
692
973
|
}
|
|
@@ -717,8 +998,8 @@ class qt {
|
|
|
717
998
|
this.destroyed = !0, this.stopPolling(), this.el.remove();
|
|
718
999
|
}
|
|
719
1000
|
}
|
|
720
|
-
const
|
|
721
|
-
class
|
|
1001
|
+
const ke = 5e3, Se = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1002
|
+
class Ee {
|
|
722
1003
|
constructor(t, e, r, s, n) {
|
|
723
1004
|
this.messages = e, this.el = t.el("div", "mtb-success"), this.el.style.right = "20px", this.el.style.bottom = "20px";
|
|
724
1005
|
const o = n?.skipFollowup ? e.success.title_no_ai : e.success.title, a = n?.skipFollowup ? e.success.message_no_ai : e.success.message, l = s ? `<button class="mtb-view-feedback-link">${e.success.view_feedback} <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></button>` : "", c = n?.emailCapture ? `
|
|
@@ -732,7 +1013,7 @@ class Vt {
|
|
|
732
1013
|
</div>` : "";
|
|
733
1014
|
this.el.innerHTML = `
|
|
734
1015
|
<div class="mtb-success-icon">
|
|
735
|
-
<svg width="23" height="23" viewBox="0 0 24 24" fill="none" stroke="${
|
|
1016
|
+
<svg width="23" height="23" viewBox="0 0 24 24" fill="none" stroke="${O}" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round">
|
|
736
1017
|
<polyline points="20 6 9 17 4 12"/>
|
|
737
1018
|
</svg>
|
|
738
1019
|
</div>
|
|
@@ -741,12 +1022,12 @@ class Vt {
|
|
|
741
1022
|
${c}
|
|
742
1023
|
${l}
|
|
743
1024
|
<button class="mtb-close-link">${e.success.close}</button>
|
|
744
|
-
`, t.append(this.el), this.el.querySelector(".mtb-close-link").addEventListener("click", r), s && this.el.querySelector(".mtb-view-feedback-link").addEventListener("click", s), n?.emailCapture ? this.bindEmailCapture(n.emailCapture.onSubmit) : setTimeout(() => r(),
|
|
1025
|
+
`, t.append(this.el), this.el.querySelector(".mtb-close-link").addEventListener("click", r), s && this.el.querySelector(".mtb-view-feedback-link").addEventListener("click", s), n?.emailCapture ? this.bindEmailCapture(n.emailCapture.onSubmit) : setTimeout(() => r(), ke);
|
|
745
1026
|
}
|
|
746
1027
|
bindEmailCapture(t) {
|
|
747
1028
|
const e = this.el.querySelector(".mtb-email-input"), r = this.el.querySelector(".mtb-email-submit"), s = this.el.querySelector(".mtb-email-error"), n = async () => {
|
|
748
1029
|
const o = e.value.trim();
|
|
749
|
-
if (!
|
|
1030
|
+
if (!Se.test(o)) {
|
|
750
1031
|
e.classList.add("mtb-email-invalid");
|
|
751
1032
|
return;
|
|
752
1033
|
}
|
|
@@ -760,7 +1041,7 @@ class Vt {
|
|
|
760
1041
|
this.el.remove();
|
|
761
1042
|
}
|
|
762
1043
|
}
|
|
763
|
-
function
|
|
1044
|
+
function Ce(i, t) {
|
|
764
1045
|
if (i.match(/^[a-z]+:\/\//i))
|
|
765
1046
|
return i;
|
|
766
1047
|
if (i.match(/^\/\//))
|
|
@@ -770,7 +1051,7 @@ function Yt(i, t) {
|
|
|
770
1051
|
const e = document.implementation.createHTMLDocument(), r = e.createElement("base"), s = e.createElement("a");
|
|
771
1052
|
return e.head.appendChild(r), e.body.appendChild(s), t && (r.href = t), s.href = i, s.href;
|
|
772
1053
|
}
|
|
773
|
-
const
|
|
1054
|
+
const _e = /* @__PURE__ */ (() => {
|
|
774
1055
|
let i = 0;
|
|
775
1056
|
const t = () => (
|
|
776
1057
|
// eslint-disable-next-line no-bitwise
|
|
@@ -778,33 +1059,33 @@ const Kt = /* @__PURE__ */ (() => {
|
|
|
778
1059
|
);
|
|
779
1060
|
return () => (i += 1, `u${t()}${i}`);
|
|
780
1061
|
})();
|
|
781
|
-
function
|
|
1062
|
+
function v(i) {
|
|
782
1063
|
const t = [];
|
|
783
1064
|
for (let e = 0, r = i.length; e < r; e++)
|
|
784
1065
|
t.push(i[e]);
|
|
785
1066
|
return t;
|
|
786
1067
|
}
|
|
787
|
-
let
|
|
788
|
-
function
|
|
789
|
-
return
|
|
1068
|
+
let x = null;
|
|
1069
|
+
function Mt(i = {}) {
|
|
1070
|
+
return x || (i.includeStyleProperties ? (x = i.includeStyleProperties, x) : (x = v(window.getComputedStyle(document.documentElement)), x));
|
|
790
1071
|
}
|
|
791
|
-
function
|
|
1072
|
+
function $(i, t) {
|
|
792
1073
|
const r = (i.ownerDocument.defaultView || window).getComputedStyle(i).getPropertyValue(t);
|
|
793
1074
|
return r ? parseFloat(r.replace("px", "")) : 0;
|
|
794
1075
|
}
|
|
795
|
-
function
|
|
796
|
-
const t =
|
|
1076
|
+
function Te(i) {
|
|
1077
|
+
const t = $(i, "border-left-width"), e = $(i, "border-right-width");
|
|
797
1078
|
return i.clientWidth + t + e;
|
|
798
1079
|
}
|
|
799
|
-
function
|
|
800
|
-
const t =
|
|
1080
|
+
function Me(i) {
|
|
1081
|
+
const t = $(i, "border-top-width"), e = $(i, "border-bottom-width");
|
|
801
1082
|
return i.clientHeight + t + e;
|
|
802
1083
|
}
|
|
803
|
-
function
|
|
804
|
-
const e = t.width ||
|
|
1084
|
+
function Lt(i, t = {}) {
|
|
1085
|
+
const e = t.width || Te(i), r = t.height || Me(i);
|
|
805
1086
|
return { width: e, height: r };
|
|
806
1087
|
}
|
|
807
|
-
function
|
|
1088
|
+
function Le() {
|
|
808
1089
|
let i, t;
|
|
809
1090
|
try {
|
|
810
1091
|
t = process;
|
|
@@ -813,11 +1094,11 @@ function Jt() {
|
|
|
813
1094
|
const e = t && t.env ? t.env.devicePixelRatio : null;
|
|
814
1095
|
return e && (i = parseInt(e, 10), Number.isNaN(i) && (i = 1)), i || window.devicePixelRatio || 1;
|
|
815
1096
|
}
|
|
816
|
-
const
|
|
817
|
-
function
|
|
818
|
-
(i.width >
|
|
1097
|
+
const b = 16384;
|
|
1098
|
+
function Ae(i) {
|
|
1099
|
+
(i.width > b || i.height > b) && (i.width > b && i.height > b ? i.width > i.height ? (i.height *= b / i.width, i.width = b) : (i.width *= b / i.height, i.height = b) : i.width > b ? (i.height *= b / i.width, i.width = b) : (i.width *= b / i.height, i.height = b));
|
|
819
1100
|
}
|
|
820
|
-
function
|
|
1101
|
+
function F(i) {
|
|
821
1102
|
return new Promise((t, e) => {
|
|
822
1103
|
const r = new Image();
|
|
823
1104
|
r.onload = () => {
|
|
@@ -827,12 +1108,12 @@ function P(i) {
|
|
|
827
1108
|
}, r.onerror = e, r.crossOrigin = "anonymous", r.decoding = "async", r.src = i;
|
|
828
1109
|
});
|
|
829
1110
|
}
|
|
830
|
-
async function
|
|
1111
|
+
async function Pe(i) {
|
|
831
1112
|
return Promise.resolve().then(() => new XMLSerializer().serializeToString(i)).then(encodeURIComponent).then((t) => `data:image/svg+xml;charset=utf-8,${t}`);
|
|
832
1113
|
}
|
|
833
|
-
async function
|
|
1114
|
+
async function Re(i, t, e) {
|
|
834
1115
|
const r = "http://www.w3.org/2000/svg", s = document.createElementNS(r, "svg"), n = document.createElementNS(r, "foreignObject");
|
|
835
|
-
return s.setAttribute("width", `${t}`), s.setAttribute("height", `${e}`), s.setAttribute("viewBox", `0 0 ${t} ${e}`), n.setAttribute("width", "100%"), n.setAttribute("height", "100%"), n.setAttribute("x", "0"), n.setAttribute("y", "0"), n.setAttribute("externalResourcesRequired", "true"), s.appendChild(n), n.appendChild(i),
|
|
1116
|
+
return s.setAttribute("width", `${t}`), s.setAttribute("height", `${e}`), s.setAttribute("viewBox", `0 0 ${t} ${e}`), n.setAttribute("width", "100%"), n.setAttribute("height", "100%"), n.setAttribute("x", "0"), n.setAttribute("y", "0"), n.setAttribute("externalResourcesRequired", "true"), s.appendChild(n), n.appendChild(i), Pe(s);
|
|
836
1117
|
}
|
|
837
1118
|
const f = (i, t) => {
|
|
838
1119
|
if (i instanceof t)
|
|
@@ -840,67 +1121,67 @@ const f = (i, t) => {
|
|
|
840
1121
|
const e = Object.getPrototypeOf(i);
|
|
841
1122
|
return e === null ? !1 : e.constructor.name === t.name || f(e, t);
|
|
842
1123
|
};
|
|
843
|
-
function
|
|
1124
|
+
function De(i) {
|
|
844
1125
|
const t = i.getPropertyValue("content");
|
|
845
1126
|
return `${i.cssText} content: '${t.replace(/'|"/g, "")}';`;
|
|
846
1127
|
}
|
|
847
|
-
function
|
|
848
|
-
return
|
|
1128
|
+
function Ie(i, t) {
|
|
1129
|
+
return Mt(t).map((e) => {
|
|
849
1130
|
const r = i.getPropertyValue(e), s = i.getPropertyPriority(e);
|
|
850
1131
|
return `${e}: ${r}${s ? " !important" : ""};`;
|
|
851
1132
|
}).join(" ");
|
|
852
1133
|
}
|
|
853
|
-
function
|
|
854
|
-
const s = `.${i}:${t}`, n = e.cssText ?
|
|
1134
|
+
function He(i, t, e, r) {
|
|
1135
|
+
const s = `.${i}:${t}`, n = e.cssText ? De(e) : Ie(e, r);
|
|
855
1136
|
return document.createTextNode(`${s}{${n}}`);
|
|
856
1137
|
}
|
|
857
|
-
function
|
|
1138
|
+
function st(i, t, e, r) {
|
|
858
1139
|
const s = window.getComputedStyle(i, e), n = s.getPropertyValue("content");
|
|
859
1140
|
if (n === "" || n === "none")
|
|
860
1141
|
return;
|
|
861
|
-
const o =
|
|
1142
|
+
const o = _e();
|
|
862
1143
|
try {
|
|
863
1144
|
t.className = `${t.className} ${o}`;
|
|
864
1145
|
} catch {
|
|
865
1146
|
return;
|
|
866
1147
|
}
|
|
867
1148
|
const a = document.createElement("style");
|
|
868
|
-
a.appendChild(
|
|
1149
|
+
a.appendChild(He(o, e, s, r)), t.appendChild(a);
|
|
869
1150
|
}
|
|
870
|
-
function
|
|
871
|
-
|
|
1151
|
+
function $e(i, t, e) {
|
|
1152
|
+
st(i, t, ":before", e), st(i, t, ":after", e);
|
|
872
1153
|
}
|
|
873
|
-
const
|
|
874
|
-
woff:
|
|
875
|
-
woff2:
|
|
1154
|
+
const nt = "application/font-woff", ot = "image/jpeg", Fe = {
|
|
1155
|
+
woff: nt,
|
|
1156
|
+
woff2: nt,
|
|
876
1157
|
ttf: "application/font-truetype",
|
|
877
1158
|
eot: "application/vnd.ms-fontobject",
|
|
878
1159
|
png: "image/png",
|
|
879
|
-
jpg:
|
|
880
|
-
jpeg:
|
|
1160
|
+
jpg: ot,
|
|
1161
|
+
jpeg: ot,
|
|
881
1162
|
gif: "image/gif",
|
|
882
1163
|
tiff: "image/tiff",
|
|
883
1164
|
svg: "image/svg+xml",
|
|
884
1165
|
webp: "image/webp"
|
|
885
1166
|
};
|
|
886
|
-
function
|
|
1167
|
+
function Be(i) {
|
|
887
1168
|
const t = /\.([^./]*?)$/g.exec(i);
|
|
888
1169
|
return t ? t[1] : "";
|
|
889
1170
|
}
|
|
890
|
-
function
|
|
891
|
-
const t =
|
|
892
|
-
return
|
|
1171
|
+
function Q(i) {
|
|
1172
|
+
const t = Be(i).toLowerCase();
|
|
1173
|
+
return Fe[t] || "";
|
|
893
1174
|
}
|
|
894
|
-
function
|
|
1175
|
+
function Ue(i) {
|
|
895
1176
|
return i.split(/,/)[1];
|
|
896
1177
|
}
|
|
897
|
-
function
|
|
1178
|
+
function V(i) {
|
|
898
1179
|
return i.search(/^(data:)/) !== -1;
|
|
899
1180
|
}
|
|
900
|
-
function
|
|
1181
|
+
function Oe(i, t) {
|
|
901
1182
|
return `data:${t};base64,${i}`;
|
|
902
1183
|
}
|
|
903
|
-
async function
|
|
1184
|
+
async function At(i, t, e) {
|
|
904
1185
|
const r = await fetch(i, t);
|
|
905
1186
|
if (r.status === 404)
|
|
906
1187
|
throw new Error(`Resource "${r.url}" not found`);
|
|
@@ -916,86 +1197,86 @@ async function dt(i, t, e) {
|
|
|
916
1197
|
}, a.readAsDataURL(s);
|
|
917
1198
|
});
|
|
918
1199
|
}
|
|
919
|
-
const
|
|
920
|
-
function
|
|
1200
|
+
const j = {};
|
|
1201
|
+
function ze(i, t, e) {
|
|
921
1202
|
let r = i.replace(/\?.*/, "");
|
|
922
1203
|
return e && (r = i), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), t ? `[${t}]${r}` : r;
|
|
923
1204
|
}
|
|
924
|
-
async function
|
|
925
|
-
const r =
|
|
926
|
-
if (
|
|
927
|
-
return
|
|
1205
|
+
async function Z(i, t, e) {
|
|
1206
|
+
const r = ze(i, t, e.includeQueryParams);
|
|
1207
|
+
if (j[r] != null)
|
|
1208
|
+
return j[r];
|
|
928
1209
|
e.cacheBust && (i += (/\?/.test(i) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
|
|
929
1210
|
let s;
|
|
930
1211
|
try {
|
|
931
|
-
const n = await
|
|
932
|
-
s =
|
|
1212
|
+
const n = await At(i, e.fetchRequestInit, ({ res: o, result: a }) => (t || (t = o.headers.get("Content-Type") || ""), Ue(a)));
|
|
1213
|
+
s = Oe(n, t);
|
|
933
1214
|
} catch (n) {
|
|
934
1215
|
s = e.imagePlaceholder || "";
|
|
935
1216
|
let o = `Failed to fetch resource: ${i}`;
|
|
936
1217
|
n && (o = typeof n == "string" ? n : n.message), o && console.warn(o);
|
|
937
1218
|
}
|
|
938
|
-
return
|
|
1219
|
+
return j[r] = s, s;
|
|
939
1220
|
}
|
|
940
|
-
async function
|
|
1221
|
+
async function je(i) {
|
|
941
1222
|
const t = i.toDataURL();
|
|
942
|
-
return t === "data:," ? i.cloneNode(!1) :
|
|
1223
|
+
return t === "data:," ? i.cloneNode(!1) : F(t);
|
|
943
1224
|
}
|
|
944
|
-
async function
|
|
1225
|
+
async function qe(i, t) {
|
|
945
1226
|
if (i.currentSrc) {
|
|
946
1227
|
const n = document.createElement("canvas"), o = n.getContext("2d");
|
|
947
1228
|
n.width = i.clientWidth, n.height = i.clientHeight, o?.drawImage(i, 0, 0, n.width, n.height);
|
|
948
1229
|
const a = n.toDataURL();
|
|
949
|
-
return
|
|
1230
|
+
return F(a);
|
|
950
1231
|
}
|
|
951
|
-
const e = i.poster, r =
|
|
952
|
-
return
|
|
1232
|
+
const e = i.poster, r = Q(e), s = await Z(e, r, t);
|
|
1233
|
+
return F(s);
|
|
953
1234
|
}
|
|
954
|
-
async function
|
|
1235
|
+
async function Ne(i, t) {
|
|
955
1236
|
var e;
|
|
956
1237
|
try {
|
|
957
1238
|
if (!((e = i?.contentDocument) === null || e === void 0) && e.body)
|
|
958
|
-
return await
|
|
1239
|
+
return await z(i.contentDocument.body, t, !0);
|
|
959
1240
|
} catch {
|
|
960
1241
|
}
|
|
961
1242
|
return i.cloneNode(!1);
|
|
962
1243
|
}
|
|
963
|
-
async function
|
|
964
|
-
return f(i, HTMLCanvasElement) ?
|
|
1244
|
+
async function We(i, t) {
|
|
1245
|
+
return f(i, HTMLCanvasElement) ? je(i) : f(i, HTMLVideoElement) ? qe(i, t) : f(i, HTMLIFrameElement) ? Ne(i, t) : i.cloneNode(Pt(i));
|
|
965
1246
|
}
|
|
966
|
-
const
|
|
967
|
-
async function
|
|
1247
|
+
const Ve = (i) => i.tagName != null && i.tagName.toUpperCase() === "SLOT", Pt = (i) => i.tagName != null && i.tagName.toUpperCase() === "SVG";
|
|
1248
|
+
async function Ye(i, t, e) {
|
|
968
1249
|
var r, s;
|
|
969
|
-
if (
|
|
1250
|
+
if (Pt(t))
|
|
970
1251
|
return t;
|
|
971
1252
|
let n = [];
|
|
972
|
-
return
|
|
1253
|
+
return Ve(i) && i.assignedNodes ? n = v(i.assignedNodes()) : f(i, HTMLIFrameElement) && (!((r = i.contentDocument) === null || r === void 0) && r.body) ? n = v(i.contentDocument.body.childNodes) : n = v(((s = i.shadowRoot) !== null && s !== void 0 ? s : i).childNodes), n.length === 0 || f(i, HTMLVideoElement) || await n.reduce((o, a) => o.then(() => z(a, e)).then((l) => {
|
|
973
1254
|
l && t.appendChild(l);
|
|
974
1255
|
}), Promise.resolve()), t;
|
|
975
1256
|
}
|
|
976
|
-
function
|
|
1257
|
+
function Xe(i, t, e) {
|
|
977
1258
|
const r = t.style;
|
|
978
1259
|
if (!r)
|
|
979
1260
|
return;
|
|
980
1261
|
const s = window.getComputedStyle(i);
|
|
981
|
-
s.cssText ? (r.cssText = s.cssText, r.transformOrigin = s.transformOrigin) :
|
|
1262
|
+
s.cssText ? (r.cssText = s.cssText, r.transformOrigin = s.transformOrigin) : Mt(e).forEach((n) => {
|
|
982
1263
|
let o = s.getPropertyValue(n);
|
|
983
1264
|
n === "font-size" && o.endsWith("px") && (o = `${Math.floor(parseFloat(o.substring(0, o.length - 2))) - 0.1}px`), f(i, HTMLIFrameElement) && n === "display" && o === "inline" && (o = "block"), n === "d" && t.getAttribute("d") && (o = `path(${t.getAttribute("d")})`), r.setProperty(n, o, s.getPropertyPriority(n));
|
|
984
1265
|
});
|
|
985
1266
|
}
|
|
986
|
-
function
|
|
1267
|
+
function Ke(i, t) {
|
|
987
1268
|
f(i, HTMLTextAreaElement) && (t.innerHTML = i.value), f(i, HTMLInputElement) && t.setAttribute("value", i.value);
|
|
988
1269
|
}
|
|
989
|
-
function
|
|
1270
|
+
function Ge(i, t) {
|
|
990
1271
|
if (f(i, HTMLSelectElement)) {
|
|
991
1272
|
const e = t, r = Array.from(e.children).find((s) => i.value === s.getAttribute("value"));
|
|
992
1273
|
r && r.setAttribute("selected", "");
|
|
993
1274
|
}
|
|
994
1275
|
}
|
|
995
|
-
function
|
|
996
|
-
return f(t, Element) && (
|
|
1276
|
+
function Je(i, t, e) {
|
|
1277
|
+
return f(t, Element) && (Xe(i, t, e), $e(i, t, e), Ke(i, t), Ge(i, t)), t;
|
|
997
1278
|
}
|
|
998
|
-
async function
|
|
1279
|
+
async function Qe(i, t) {
|
|
999
1280
|
const e = i.querySelectorAll ? i.querySelectorAll("use") : [];
|
|
1000
1281
|
if (e.length === 0)
|
|
1001
1282
|
return i;
|
|
@@ -1004,7 +1285,7 @@ async function xe(i, t) {
|
|
|
1004
1285
|
const a = e[n].getAttribute("xlink:href");
|
|
1005
1286
|
if (a) {
|
|
1006
1287
|
const l = i.querySelector(a), c = document.querySelector(a);
|
|
1007
|
-
!l && c && !r[a] && (r[a] = await
|
|
1288
|
+
!l && c && !r[a] && (r[a] = await z(c, t, !0));
|
|
1008
1289
|
}
|
|
1009
1290
|
}
|
|
1010
1291
|
const s = Object.values(r);
|
|
@@ -1019,31 +1300,31 @@ async function xe(i, t) {
|
|
|
1019
1300
|
}
|
|
1020
1301
|
return i;
|
|
1021
1302
|
}
|
|
1022
|
-
async function
|
|
1023
|
-
return !e && t.filter && !t.filter(i) ? null : Promise.resolve(i).then((r) =>
|
|
1303
|
+
async function z(i, t, e) {
|
|
1304
|
+
return !e && t.filter && !t.filter(i) ? null : Promise.resolve(i).then((r) => We(r, t)).then((r) => Ye(i, r, t)).then((r) => Je(i, r, t)).then((r) => Qe(r, t));
|
|
1024
1305
|
}
|
|
1025
|
-
const
|
|
1026
|
-
function
|
|
1306
|
+
const Rt = /url\((['"]?)([^'"]+?)\1\)/g, Ze = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, ti = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
|
|
1307
|
+
function ei(i) {
|
|
1027
1308
|
const t = i.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
|
|
1028
1309
|
return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`, "g");
|
|
1029
1310
|
}
|
|
1030
|
-
function
|
|
1311
|
+
function ii(i) {
|
|
1031
1312
|
const t = [];
|
|
1032
|
-
return i.replace(
|
|
1313
|
+
return i.replace(Rt, (e, r, s) => (t.push(s), e)), t.filter((e) => !V(e));
|
|
1033
1314
|
}
|
|
1034
|
-
async function
|
|
1315
|
+
async function ri(i, t, e, r, s) {
|
|
1035
1316
|
try {
|
|
1036
|
-
const n = e ?
|
|
1317
|
+
const n = e ? Ce(t, e) : t, o = Q(t);
|
|
1037
1318
|
let a;
|
|
1038
|
-
return s || (a = await
|
|
1319
|
+
return s || (a = await Z(n, o, r)), i.replace(ei(t), `$1${a}$3`);
|
|
1039
1320
|
} catch {
|
|
1040
1321
|
}
|
|
1041
1322
|
return i;
|
|
1042
1323
|
}
|
|
1043
|
-
function
|
|
1044
|
-
return t ? i.replace(
|
|
1324
|
+
function si(i, { preferredFontFormat: t }) {
|
|
1325
|
+
return t ? i.replace(ti, (e) => {
|
|
1045
1326
|
for (; ; ) {
|
|
1046
|
-
const [r, , s] =
|
|
1327
|
+
const [r, , s] = Ze.exec(e) || [];
|
|
1047
1328
|
if (!s)
|
|
1048
1329
|
return "";
|
|
1049
1330
|
if (s === t)
|
|
@@ -1051,32 +1332,32 @@ function _e(i, { preferredFontFormat: t }) {
|
|
|
1051
1332
|
}
|
|
1052
1333
|
}) : i;
|
|
1053
1334
|
}
|
|
1054
|
-
function
|
|
1055
|
-
return i.search(
|
|
1335
|
+
function Dt(i) {
|
|
1336
|
+
return i.search(Rt) !== -1;
|
|
1056
1337
|
}
|
|
1057
|
-
async function
|
|
1058
|
-
if (!
|
|
1338
|
+
async function It(i, t, e) {
|
|
1339
|
+
if (!Dt(i))
|
|
1059
1340
|
return i;
|
|
1060
|
-
const r =
|
|
1061
|
-
return
|
|
1341
|
+
const r = si(i, e);
|
|
1342
|
+
return ii(r).reduce((n, o) => n.then((a) => ri(a, o, t, e)), Promise.resolve(r));
|
|
1062
1343
|
}
|
|
1063
1344
|
async function k(i, t, e) {
|
|
1064
1345
|
var r;
|
|
1065
1346
|
const s = (r = t.style) === null || r === void 0 ? void 0 : r.getPropertyValue(i);
|
|
1066
1347
|
if (s) {
|
|
1067
|
-
const n = await
|
|
1348
|
+
const n = await It(s, null, e);
|
|
1068
1349
|
return t.style.setProperty(i, n, t.style.getPropertyPriority(i)), !0;
|
|
1069
1350
|
}
|
|
1070
1351
|
return !1;
|
|
1071
1352
|
}
|
|
1072
|
-
async function
|
|
1353
|
+
async function ni(i, t) {
|
|
1073
1354
|
await k("background", i, t) || await k("background-image", i, t), await k("mask", i, t) || await k("-webkit-mask", i, t) || await k("mask-image", i, t) || await k("-webkit-mask-image", i, t);
|
|
1074
1355
|
}
|
|
1075
|
-
async function
|
|
1356
|
+
async function oi(i, t) {
|
|
1076
1357
|
const e = f(i, HTMLImageElement);
|
|
1077
|
-
if (!(e && !
|
|
1358
|
+
if (!(e && !V(i.src)) && !(f(i, SVGImageElement) && !V(i.href.baseVal)))
|
|
1078
1359
|
return;
|
|
1079
|
-
const r = e ? i.src : i.href.baseVal, s = await
|
|
1360
|
+
const r = e ? i.src : i.href.baseVal, s = await Z(r, Q(r), t);
|
|
1080
1361
|
await new Promise((n, o) => {
|
|
1081
1362
|
i.onload = n, i.onerror = t.onImageErrorHandler ? (...l) => {
|
|
1082
1363
|
try {
|
|
@@ -1089,14 +1370,14 @@ async function Le(i, t) {
|
|
|
1089
1370
|
a.decode && (a.decode = n), a.loading === "lazy" && (a.loading = "eager"), e ? (i.srcset = "", i.src = s) : i.href.baseVal = s;
|
|
1090
1371
|
});
|
|
1091
1372
|
}
|
|
1092
|
-
async function
|
|
1093
|
-
const r =
|
|
1373
|
+
async function ai(i, t) {
|
|
1374
|
+
const r = v(i.childNodes).map((s) => Ht(s, t));
|
|
1094
1375
|
await Promise.all(r).then(() => i);
|
|
1095
1376
|
}
|
|
1096
|
-
async function
|
|
1097
|
-
f(i, Element) && (await
|
|
1377
|
+
async function Ht(i, t) {
|
|
1378
|
+
f(i, Element) && (await ni(i, t), await oi(i, t), await ai(i, t));
|
|
1098
1379
|
}
|
|
1099
|
-
function
|
|
1380
|
+
function li(i, t) {
|
|
1100
1381
|
const { style: e } = i;
|
|
1101
1382
|
t.backgroundColor && (e.backgroundColor = t.backgroundColor), t.width && (e.width = `${t.width}px`), t.height && (e.height = `${t.height}px`);
|
|
1102
1383
|
const r = t.style;
|
|
@@ -1104,23 +1385,23 @@ function Pe(i, t) {
|
|
|
1104
1385
|
e[s] = r[s];
|
|
1105
1386
|
}), i;
|
|
1106
1387
|
}
|
|
1107
|
-
const
|
|
1108
|
-
async function
|
|
1109
|
-
let t =
|
|
1388
|
+
const at = {};
|
|
1389
|
+
async function lt(i) {
|
|
1390
|
+
let t = at[i];
|
|
1110
1391
|
if (t != null)
|
|
1111
1392
|
return t;
|
|
1112
1393
|
const r = await (await fetch(i)).text();
|
|
1113
|
-
return t = { url: i, cssText: r },
|
|
1394
|
+
return t = { url: i, cssText: r }, at[i] = t, t;
|
|
1114
1395
|
}
|
|
1115
|
-
async function
|
|
1396
|
+
async function ct(i, t) {
|
|
1116
1397
|
let e = i.cssText;
|
|
1117
1398
|
const r = /url\(["']?([^"')]+)["']?\)/g, n = (e.match(/url\([^)]+\)/g) || []).map(async (o) => {
|
|
1118
1399
|
let a = o.replace(r, "$1");
|
|
1119
|
-
return a.startsWith("https://") || (a = new URL(a, i.url).href),
|
|
1400
|
+
return a.startsWith("https://") || (a = new URL(a, i.url).href), At(a, t.fetchRequestInit, ({ result: l }) => (e = e.replace(o, `url(${l})`), [o, l]));
|
|
1120
1401
|
});
|
|
1121
1402
|
return Promise.all(n).then(() => e);
|
|
1122
1403
|
}
|
|
1123
|
-
function
|
|
1404
|
+
function dt(i) {
|
|
1124
1405
|
if (i == null)
|
|
1125
1406
|
return [];
|
|
1126
1407
|
const t = [], e = /(\/\*[\s\S]*?\*\/)/gi;
|
|
@@ -1146,15 +1427,15 @@ function G(i) {
|
|
|
1146
1427
|
}
|
|
1147
1428
|
return t;
|
|
1148
1429
|
}
|
|
1149
|
-
async function
|
|
1430
|
+
async function ci(i, t) {
|
|
1150
1431
|
const e = [], r = [];
|
|
1151
1432
|
return i.forEach((s) => {
|
|
1152
1433
|
if ("cssRules" in s)
|
|
1153
1434
|
try {
|
|
1154
|
-
|
|
1435
|
+
v(s.cssRules || []).forEach((n, o) => {
|
|
1155
1436
|
if (n.type === CSSRule.IMPORT_RULE) {
|
|
1156
1437
|
let a = o + 1;
|
|
1157
|
-
const l = n.href, c =
|
|
1438
|
+
const l = n.href, c = lt(l).then((d) => ct(d, t)).then((d) => dt(d).forEach((u) => {
|
|
1158
1439
|
try {
|
|
1159
1440
|
s.insertRule(u, u.startsWith("@import") ? a += 1 : s.cssRules.length);
|
|
1160
1441
|
} catch (m) {
|
|
@@ -1163,15 +1444,15 @@ async function Re(i, t) {
|
|
|
1163
1444
|
error: m
|
|
1164
1445
|
});
|
|
1165
1446
|
}
|
|
1166
|
-
})).catch((
|
|
1167
|
-
console.error("Error loading remote css",
|
|
1447
|
+
})).catch((d) => {
|
|
1448
|
+
console.error("Error loading remote css", d.toString());
|
|
1168
1449
|
});
|
|
1169
1450
|
r.push(c);
|
|
1170
1451
|
}
|
|
1171
1452
|
});
|
|
1172
1453
|
} catch (n) {
|
|
1173
1454
|
const o = i.find((a) => a.href == null) || document.styleSheets[0];
|
|
1174
|
-
s.href != null && r.push(
|
|
1455
|
+
s.href != null && r.push(lt(s.href).then((a) => ct(a, t)).then((a) => dt(a).forEach((l) => {
|
|
1175
1456
|
o.insertRule(l, o.cssRules.length);
|
|
1176
1457
|
})).catch((a) => {
|
|
1177
1458
|
console.error("Error loading remote stylesheet", a);
|
|
@@ -1180,7 +1461,7 @@ async function Re(i, t) {
|
|
|
1180
1461
|
}), Promise.all(r).then(() => (i.forEach((s) => {
|
|
1181
1462
|
if ("cssRules" in s)
|
|
1182
1463
|
try {
|
|
1183
|
-
|
|
1464
|
+
v(s.cssRules || []).forEach((n) => {
|
|
1184
1465
|
e.push(n);
|
|
1185
1466
|
});
|
|
1186
1467
|
} catch (n) {
|
|
@@ -1188,100 +1469,164 @@ async function Re(i, t) {
|
|
|
1188
1469
|
}
|
|
1189
1470
|
}), e));
|
|
1190
1471
|
}
|
|
1191
|
-
function
|
|
1192
|
-
return i.filter((t) => t.type === CSSRule.FONT_FACE_RULE).filter((t) =>
|
|
1472
|
+
function di(i) {
|
|
1473
|
+
return i.filter((t) => t.type === CSSRule.FONT_FACE_RULE).filter((t) => Dt(t.style.getPropertyValue("src")));
|
|
1193
1474
|
}
|
|
1194
|
-
async function
|
|
1475
|
+
async function hi(i, t) {
|
|
1195
1476
|
if (i.ownerDocument == null)
|
|
1196
1477
|
throw new Error("Provided element is not within a Document");
|
|
1197
|
-
const e =
|
|
1198
|
-
return
|
|
1478
|
+
const e = v(i.ownerDocument.styleSheets), r = await ci(e, t);
|
|
1479
|
+
return di(r);
|
|
1199
1480
|
}
|
|
1200
|
-
function
|
|
1481
|
+
function $t(i) {
|
|
1201
1482
|
return i.trim().replace(/["']/g, "");
|
|
1202
1483
|
}
|
|
1203
|
-
function
|
|
1484
|
+
function ui(i) {
|
|
1204
1485
|
const t = /* @__PURE__ */ new Set();
|
|
1205
1486
|
function e(r) {
|
|
1206
1487
|
(r.style.fontFamily || getComputedStyle(r).fontFamily).split(",").forEach((n) => {
|
|
1207
|
-
t.add(
|
|
1488
|
+
t.add($t(n));
|
|
1208
1489
|
}), Array.from(r.children).forEach((n) => {
|
|
1209
1490
|
n instanceof HTMLElement && e(n);
|
|
1210
1491
|
});
|
|
1211
1492
|
}
|
|
1212
1493
|
return e(i), t;
|
|
1213
1494
|
}
|
|
1214
|
-
async function
|
|
1215
|
-
const e = await
|
|
1216
|
-
return (await Promise.all(e.filter((n) => r.has(
|
|
1495
|
+
async function mi(i, t) {
|
|
1496
|
+
const e = await hi(i, t), r = ui(i);
|
|
1497
|
+
return (await Promise.all(e.filter((n) => r.has($t(n.style.fontFamily))).map((n) => {
|
|
1217
1498
|
const o = n.parentStyleSheet ? n.parentStyleSheet.href : null;
|
|
1218
|
-
return
|
|
1499
|
+
return It(n.cssText, o, t);
|
|
1219
1500
|
}))).join(`
|
|
1220
1501
|
`);
|
|
1221
1502
|
}
|
|
1222
|
-
async function
|
|
1223
|
-
const e = t.fontEmbedCSS != null ? t.fontEmbedCSS : t.skipFonts ? null : await
|
|
1503
|
+
async function fi(i, t) {
|
|
1504
|
+
const e = t.fontEmbedCSS != null ? t.fontEmbedCSS : t.skipFonts ? null : await mi(i, t);
|
|
1224
1505
|
if (e) {
|
|
1225
1506
|
const r = document.createElement("style"), s = document.createTextNode(e);
|
|
1226
1507
|
r.appendChild(s), i.firstChild ? i.insertBefore(r, i.firstChild) : i.appendChild(r);
|
|
1227
1508
|
}
|
|
1228
1509
|
}
|
|
1229
|
-
async function
|
|
1230
|
-
const { width: e, height: r } =
|
|
1231
|
-
return await
|
|
1510
|
+
async function bi(i, t = {}) {
|
|
1511
|
+
const { width: e, height: r } = Lt(i, t), s = await z(i, t, !0);
|
|
1512
|
+
return await fi(s, t), await Ht(s, t), li(s, t), await Re(s, e, r);
|
|
1232
1513
|
}
|
|
1233
|
-
async function
|
|
1234
|
-
const { width: e, height: r } =
|
|
1235
|
-
return o.width = c * l, o.height =
|
|
1514
|
+
async function pi(i, t = {}) {
|
|
1515
|
+
const { width: e, height: r } = Lt(i, t), s = await bi(i, t), n = await F(s), o = document.createElement("canvas"), a = o.getContext("2d"), l = t.pixelRatio || Le(), c = t.canvasWidth || e, d = t.canvasHeight || r;
|
|
1516
|
+
return o.width = c * l, o.height = d * l, t.skipAutoScale || Ae(o), o.style.width = `${c}`, o.style.height = `${d}`, t.backgroundColor && (a.fillStyle = t.backgroundColor, a.fillRect(0, 0, o.width, o.height)), a.drawImage(n, 0, 0, o.width, o.height), o;
|
|
1236
1517
|
}
|
|
1237
|
-
async function
|
|
1238
|
-
return (await
|
|
1518
|
+
async function gi(i, t = {}) {
|
|
1519
|
+
return (await pi(i, t)).toDataURL("image/jpeg", t.quality || 1);
|
|
1239
1520
|
}
|
|
1240
|
-
|
|
1521
|
+
const q = 400, N = 300, ht = 150, ut = 0.3, mt = 0.85;
|
|
1522
|
+
function yi(i) {
|
|
1523
|
+
let t = 1 / 0, e = 1 / 0, r = -1 / 0, s = -1 / 0;
|
|
1524
|
+
for (const n of i)
|
|
1525
|
+
if (n.type === "pin") {
|
|
1526
|
+
if (t = Math.min(t, n.x), e = Math.min(e, n.y), r = Math.max(r, n.x), s = Math.max(s, n.y), n.targetRect) {
|
|
1527
|
+
const o = n.targetRect;
|
|
1528
|
+
t = Math.min(t, o.left), e = Math.min(e, o.top), r = Math.max(r, o.left + o.width), s = Math.max(s, o.bottom);
|
|
1529
|
+
}
|
|
1530
|
+
} else if (n.type === "draw" && n.drawPath)
|
|
1531
|
+
for (const o of Ft(n.drawPath))
|
|
1532
|
+
for (const [a, l] of o)
|
|
1533
|
+
t = Math.min(t, a), e = Math.min(e, l), r = Math.max(r, a), s = Math.max(s, l);
|
|
1534
|
+
return !isFinite(t) || !isFinite(e) ? null : { minX: t, minY: e, maxX: r, maxY: s };
|
|
1535
|
+
}
|
|
1536
|
+
function wi(i, t, e) {
|
|
1537
|
+
const r = yi(i);
|
|
1538
|
+
if (!r) return null;
|
|
1539
|
+
const s = Math.max(ht, t * ut), n = Math.max(ht, e * ut);
|
|
1540
|
+
let o = r.minX - s, a = r.minY - n, l = r.maxX - r.minX + s * 2, c = r.maxY - r.minY + n * 2;
|
|
1541
|
+
return l < q && (o -= (q - l) / 2, l = q), c < N && (a -= (N - c) / 2, c = N), o = Math.max(0, o), a = Math.max(0, a), l = Math.min(l, t - o), c = Math.min(c, e - a), l >= t * mt && c >= e * mt ? null : {
|
|
1542
|
+
x: Math.round(o),
|
|
1543
|
+
y: Math.round(a),
|
|
1544
|
+
width: Math.round(l),
|
|
1545
|
+
height: Math.round(c)
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
function vi(i, t) {
|
|
1549
|
+
const e = document.createElement("canvas");
|
|
1550
|
+
e.width = t.width, e.height = t.height;
|
|
1551
|
+
const r = e.getContext("2d");
|
|
1552
|
+
return r && r.drawImage(i, t.x, t.y, t.width, t.height, 0, 0, t.width, t.height), e;
|
|
1553
|
+
}
|
|
1554
|
+
async function xi(i = []) {
|
|
1241
1555
|
try {
|
|
1242
|
-
const t = await
|
|
1556
|
+
const t = Ei(document.body), e = await gi(document.body, {
|
|
1243
1557
|
quality: 0.85,
|
|
1244
1558
|
pixelRatio: 1,
|
|
1245
1559
|
backgroundColor: "#ffffff",
|
|
1246
1560
|
skipFonts: !0,
|
|
1247
1561
|
skipAutoScale: !1,
|
|
1248
|
-
filter: (
|
|
1562
|
+
filter: (r) => !(r instanceof HTMLElement && r.id === "mtb-widget-host")
|
|
1249
1563
|
});
|
|
1250
1564
|
if (i.length > 0) {
|
|
1251
|
-
const
|
|
1252
|
-
if (
|
|
1565
|
+
const r = await ki(e, i, t);
|
|
1566
|
+
if (r) return r;
|
|
1253
1567
|
}
|
|
1254
|
-
return
|
|
1568
|
+
return Ti(e);
|
|
1255
1569
|
} catch {
|
|
1256
1570
|
return null;
|
|
1257
1571
|
}
|
|
1258
1572
|
}
|
|
1259
|
-
async function
|
|
1260
|
-
const
|
|
1261
|
-
if (!r) return null;
|
|
1262
|
-
const s = await We(i);
|
|
1573
|
+
async function ki(i, t, e) {
|
|
1574
|
+
const r = document.createElement("canvas"), s = r.getContext("2d");
|
|
1263
1575
|
if (!s) return null;
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1576
|
+
const n = await _i(i);
|
|
1577
|
+
if (!n) return null;
|
|
1578
|
+
r.width = n.naturalWidth || window.innerWidth, r.height = n.naturalHeight || window.innerHeight, s.drawImage(n, 0, 0);
|
|
1579
|
+
const o = r.width / e.width, a = r.height / e.height;
|
|
1580
|
+
let l = 0;
|
|
1581
|
+
for (const d of t)
|
|
1582
|
+
d.type === "draw" && d.drawPath ? Si(s, d.drawPath, e, o, a) : d.type === "pin" && Ci(
|
|
1583
|
+
s,
|
|
1584
|
+
(d.x - e.left) * o,
|
|
1585
|
+
(d.y - e.top) * a,
|
|
1586
|
+
++l
|
|
1587
|
+
);
|
|
1588
|
+
const c = wi(t, window.innerWidth, window.innerHeight);
|
|
1589
|
+
if (c) {
|
|
1590
|
+
const d = Math.max(0, Math.round((c.x - e.left) * o)), u = Math.max(0, Math.round((c.y - e.top) * a)), m = Math.min(r.width, Math.round((c.x + c.width - e.left) * o)), p = Math.min(r.height, Math.round((c.y + c.height - e.top) * a)), g = {
|
|
1591
|
+
x: d,
|
|
1592
|
+
y: u,
|
|
1593
|
+
width: m - d,
|
|
1594
|
+
height: p - u
|
|
1595
|
+
};
|
|
1596
|
+
return ft(vi(r, g));
|
|
1597
|
+
}
|
|
1598
|
+
return ft(r);
|
|
1599
|
+
}
|
|
1600
|
+
function Si(i, t, e, r, s) {
|
|
1601
|
+
i.save(), i.strokeStyle = O, i.lineWidth = 3.5, i.lineCap = "round", i.lineJoin = "round", i.shadowColor = J(0.35), i.shadowOffsetY = 1, i.shadowBlur = 2;
|
|
1602
|
+
for (const n of Ft(t))
|
|
1603
|
+
if (n.length !== 0) {
|
|
1604
|
+
i.beginPath(), i.moveTo(
|
|
1605
|
+
(n[0][0] - e.left) * r,
|
|
1606
|
+
(n[0][1] - e.top) * s
|
|
1607
|
+
);
|
|
1608
|
+
for (let o = 1; o < n.length; o++)
|
|
1609
|
+
i.lineTo(
|
|
1610
|
+
(n[o][0] - e.left) * r,
|
|
1611
|
+
(n[o][1] - e.top) * s
|
|
1612
|
+
);
|
|
1277
1613
|
i.stroke();
|
|
1278
1614
|
}
|
|
1279
1615
|
i.restore();
|
|
1280
1616
|
}
|
|
1281
|
-
function
|
|
1282
|
-
|
|
1617
|
+
function Ei(i) {
|
|
1618
|
+
const t = i.getBoundingClientRect(), e = window.getComputedStyle(i), r = parseFloat(e.borderLeftWidth) + parseFloat(e.borderRightWidth), s = parseFloat(e.borderTopWidth) + parseFloat(e.borderBottomWidth);
|
|
1619
|
+
return {
|
|
1620
|
+
left: t.left,
|
|
1621
|
+
top: t.top,
|
|
1622
|
+
width: i.clientWidth + (Number.isFinite(r) ? r : 0) || window.innerWidth,
|
|
1623
|
+
height: i.clientHeight + (Number.isFinite(s) ? s : 0) || window.innerHeight
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
function Ci(i, t, e, r) {
|
|
1627
|
+
i.save(), i.shadowColor = J(0.45), i.shadowOffsetY = 2, i.shadowBlur = 8, i.fillStyle = O, i.beginPath(), i.arc(t, e, 11, 0, Math.PI * 2), i.fill(), i.shadowColor = "transparent", i.lineWidth = 2, i.strokeStyle = "#ffffff", i.stroke(), i.fillStyle = "#ffffff", i.font = `700 10px ${re}`, i.textAlign = "center", i.textBaseline = "middle", i.fillText(String(r), t, e), i.restore();
|
|
1283
1628
|
}
|
|
1284
|
-
function
|
|
1629
|
+
function Ft(i) {
|
|
1285
1630
|
const t = [];
|
|
1286
1631
|
let e = null;
|
|
1287
1632
|
const r = i.match(/[ML]\s*[-\d.]+\s+[-\d.]+/g) ?? [];
|
|
@@ -1291,13 +1636,13 @@ function Ne(i) {
|
|
|
1291
1636
|
}
|
|
1292
1637
|
return t;
|
|
1293
1638
|
}
|
|
1294
|
-
function
|
|
1639
|
+
function _i(i) {
|
|
1295
1640
|
return new Promise((t) => {
|
|
1296
1641
|
const e = new Image();
|
|
1297
1642
|
e.onload = () => t(e), e.onerror = () => t(null), e.src = i;
|
|
1298
1643
|
});
|
|
1299
1644
|
}
|
|
1300
|
-
function
|
|
1645
|
+
function ft(i) {
|
|
1301
1646
|
return new Promise((t) => {
|
|
1302
1647
|
try {
|
|
1303
1648
|
i.toBlob((e) => t(e), "image/jpeg", 0.85);
|
|
@@ -1306,13 +1651,13 @@ function Ve(i) {
|
|
|
1306
1651
|
}
|
|
1307
1652
|
});
|
|
1308
1653
|
}
|
|
1309
|
-
function
|
|
1654
|
+
function Ti(i) {
|
|
1310
1655
|
const [t, e] = i.split(","), r = t.match(/:(.*?);/)?.[1] ?? "image/png", s = atob(e), n = new Uint8Array(s.length);
|
|
1311
1656
|
for (let o = 0; o < s.length; o++)
|
|
1312
1657
|
n[o] = s.charCodeAt(o);
|
|
1313
1658
|
return new Blob([n], { type: r });
|
|
1314
1659
|
}
|
|
1315
|
-
class
|
|
1660
|
+
class Mi {
|
|
1316
1661
|
constructor() {
|
|
1317
1662
|
this.listeners = /* @__PURE__ */ new Set(), this.originalOnError = null, this.installedOnError = null, this.rejectionHandler = null, this.hooked = !1;
|
|
1318
1663
|
}
|
|
@@ -1334,20 +1679,20 @@ class Ke {
|
|
|
1334
1679
|
for (const e of this.listeners) e(t);
|
|
1335
1680
|
}
|
|
1336
1681
|
}
|
|
1337
|
-
const
|
|
1338
|
-
class
|
|
1682
|
+
const tt = new Mi(), Li = 20;
|
|
1683
|
+
class Ai {
|
|
1339
1684
|
constructor() {
|
|
1340
1685
|
this.errors = [], this.unsubscribe = null;
|
|
1341
1686
|
}
|
|
1342
1687
|
start() {
|
|
1343
|
-
this.unsubscribe || (this.unsubscribe =
|
|
1688
|
+
this.unsubscribe || (this.unsubscribe = tt.subscribe((t) => this.record(t)));
|
|
1344
1689
|
}
|
|
1345
1690
|
record(t) {
|
|
1346
1691
|
const e = t.line != null ? ` (${t.line}:${t.col ?? 0})` : "";
|
|
1347
1692
|
this.addError(`${t.message}${e}`);
|
|
1348
1693
|
}
|
|
1349
1694
|
addError(t) {
|
|
1350
|
-
this.errors.length >=
|
|
1695
|
+
this.errors.length >= Li || this.errors.includes(t) || this.errors.push(t);
|
|
1351
1696
|
}
|
|
1352
1697
|
getErrors() {
|
|
1353
1698
|
return [...this.errors];
|
|
@@ -1356,40 +1701,69 @@ class Ge {
|
|
|
1356
1701
|
this.unsubscribe?.(), this.unsubscribe = null;
|
|
1357
1702
|
}
|
|
1358
1703
|
}
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1704
|
+
const I = /* @__PURE__ */ new Set();
|
|
1705
|
+
let M = null, L = null, A = null, B = null, P = null;
|
|
1706
|
+
function Bt(i) {
|
|
1707
|
+
I.add(i), Pi();
|
|
1708
|
+
let t = !1;
|
|
1709
|
+
return () => {
|
|
1710
|
+
t || (t = !0, I.delete(i), I.size === 0 && Ri());
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
function W() {
|
|
1714
|
+
for (const i of [...I])
|
|
1715
|
+
try {
|
|
1716
|
+
i();
|
|
1717
|
+
} catch {
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
function Pi() {
|
|
1721
|
+
if (A) return;
|
|
1722
|
+
P = () => W(), window.addEventListener("popstate", P), M = history.pushState, L = history.replaceState;
|
|
1723
|
+
const i = M, t = L;
|
|
1724
|
+
A = function(e, r, s) {
|
|
1725
|
+
i.call(history, e, r, s), W();
|
|
1726
|
+
}, B = function(e, r, s) {
|
|
1727
|
+
t.call(history, e, r, s), W();
|
|
1728
|
+
}, history.pushState = A, history.replaceState = B;
|
|
1729
|
+
}
|
|
1730
|
+
function Ri() {
|
|
1731
|
+
P && (window.removeEventListener("popstate", P), P = null), M && history.pushState === A && (history.pushState = M), L && history.replaceState === B && (history.replaceState = L), M = null, L = null, A = null, B = null;
|
|
1732
|
+
}
|
|
1733
|
+
const Di = 20;
|
|
1734
|
+
class Ii {
|
|
1361
1735
|
constructor() {
|
|
1362
|
-
this.breadcrumbs = [], this.active = !1, this.unsubscribeErrors = null, this.
|
|
1736
|
+
this.breadcrumbs = [], this.active = !1, this.unsubscribeErrors = null, this.unsubscribeNavigation = null, this.lastUrl = "", this.boundClickHandler = (t) => this.handleClick(t), this.boundChangeHandler = (t) => this.handleChange(t);
|
|
1363
1737
|
}
|
|
1364
1738
|
start() {
|
|
1365
|
-
this.active || (this.active = !0, this.lastUrl = location.href, document.addEventListener("click", this.boundClickHandler, { capture: !0, passive: !0 }), document.addEventListener("change", this.boundChangeHandler, { capture: !0, passive: !0 }), this.unsubscribeErrors =
|
|
1739
|
+
this.active || (this.active = !0, this.lastUrl = location.href, document.addEventListener("click", this.boundClickHandler, { capture: !0, passive: !0 }), document.addEventListener("change", this.boundChangeHandler, { capture: !0, passive: !0 }), this.unsubscribeErrors = tt.subscribe((t) => this.recordError(t)), this.unsubscribeNavigation = Bt(() => this.handleNavigation()));
|
|
1366
1740
|
}
|
|
1367
1741
|
stop() {
|
|
1368
|
-
this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), document.removeEventListener("change", this.boundChangeHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.
|
|
1742
|
+
this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), document.removeEventListener("change", this.boundChangeHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.unsubscribeNavigation?.(), this.unsubscribeNavigation = null);
|
|
1369
1743
|
}
|
|
1370
1744
|
getBreadcrumbs() {
|
|
1371
1745
|
return [...this.breadcrumbs];
|
|
1372
1746
|
}
|
|
1373
1747
|
add(t) {
|
|
1374
|
-
this.breadcrumbs.push(t), this.breadcrumbs.length >
|
|
1748
|
+
this.breadcrumbs.push(t), this.breadcrumbs.length > Di && this.breadcrumbs.shift();
|
|
1375
1749
|
}
|
|
1376
1750
|
handleClick(t) {
|
|
1377
1751
|
const e = t.target;
|
|
1378
|
-
if (e && !
|
|
1752
|
+
if (e && !S(e))
|
|
1379
1753
|
try {
|
|
1380
1754
|
this.add({
|
|
1381
1755
|
type: "ui",
|
|
1382
1756
|
category: "ui.click",
|
|
1383
1757
|
timestamp: Date.now(),
|
|
1384
|
-
message:
|
|
1385
|
-
data: { selector:
|
|
1758
|
+
message: G(e),
|
|
1759
|
+
data: { selector: _t(e) }
|
|
1386
1760
|
});
|
|
1387
1761
|
} catch {
|
|
1388
1762
|
}
|
|
1389
1763
|
}
|
|
1390
1764
|
handleChange(t) {
|
|
1391
1765
|
const e = t.target;
|
|
1392
|
-
if (e && !
|
|
1766
|
+
if (e && !S(e))
|
|
1393
1767
|
try {
|
|
1394
1768
|
const r = e, s = r.name || r.placeholder || e.getAttribute("aria-label") || e.tagName;
|
|
1395
1769
|
this.add({
|
|
@@ -1411,18 +1785,6 @@ class Qe {
|
|
|
1411
1785
|
data: { message: t.message }
|
|
1412
1786
|
});
|
|
1413
1787
|
}
|
|
1414
|
-
startNavigationTracking() {
|
|
1415
|
-
this.boundPopstateHandler = () => this.handleNavigation(), window.addEventListener("popstate", this.boundPopstateHandler), this.originalPushState = history.pushState.bind(history), this.originalReplaceState = history.replaceState.bind(history);
|
|
1416
|
-
const t = this.originalPushState, e = this.originalReplaceState, r = () => this.handleNavigation();
|
|
1417
|
-
this.installedPushState = function(s, n, o) {
|
|
1418
|
-
t(s, n, o), r();
|
|
1419
|
-
}, this.installedReplaceState = function(s, n, o) {
|
|
1420
|
-
e(s, n, o), r();
|
|
1421
|
-
}, history.pushState = this.installedPushState, history.replaceState = this.installedReplaceState;
|
|
1422
|
-
}
|
|
1423
|
-
stopNavigationTracking() {
|
|
1424
|
-
this.boundPopstateHandler && (window.removeEventListener("popstate", this.boundPopstateHandler), this.boundPopstateHandler = null), this.originalPushState && history.pushState === this.installedPushState && (history.pushState = this.originalPushState), this.originalReplaceState && history.replaceState === this.installedReplaceState && (history.replaceState = this.originalReplaceState), this.originalPushState = null, this.originalReplaceState = null, this.installedPushState = null, this.installedReplaceState = null;
|
|
1425
|
-
}
|
|
1426
1788
|
handleNavigation() {
|
|
1427
1789
|
if (!this.active) return;
|
|
1428
1790
|
const t = this.lastUrl, e = location.href;
|
|
@@ -1435,7 +1797,40 @@ class Qe {
|
|
|
1435
1797
|
}));
|
|
1436
1798
|
}
|
|
1437
1799
|
}
|
|
1438
|
-
const
|
|
1800
|
+
const Ut = "mtb_frustration_state";
|
|
1801
|
+
let Y = null;
|
|
1802
|
+
function U() {
|
|
1803
|
+
try {
|
|
1804
|
+
const i = window.sessionStorage.getItem(Ut);
|
|
1805
|
+
return H(i ? JSON.parse(i) : Y);
|
|
1806
|
+
} catch {
|
|
1807
|
+
return H(Y);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
function Ot(i) {
|
|
1811
|
+
const t = H(i);
|
|
1812
|
+
Y = t;
|
|
1813
|
+
try {
|
|
1814
|
+
window.sessionStorage.setItem(Ut, JSON.stringify(t));
|
|
1815
|
+
} catch {
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
function Hi() {
|
|
1819
|
+
return U().dismissedByUser;
|
|
1820
|
+
}
|
|
1821
|
+
function $i() {
|
|
1822
|
+
Ot({ ...U(), dismissedByUser: !0 });
|
|
1823
|
+
}
|
|
1824
|
+
function H(i) {
|
|
1825
|
+
const t = i ?? {};
|
|
1826
|
+
return {
|
|
1827
|
+
navTimestamps: Array.isArray(t.navTimestamps) ? t.navTimestamps.filter((e) => typeof e == "number") : [],
|
|
1828
|
+
cooldownUntil: typeof t.cooldownUntil == "number" ? t.cooldownUntil : 0,
|
|
1829
|
+
errorPageUrls: Array.isArray(t.errorPageUrls) ? t.errorPageUrls.filter((e) => typeof e == "string").slice(-20) : [],
|
|
1830
|
+
dismissedByUser: t.dismissedByUser === !0
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
const Fi = 3, Bi = 1e3, Ui = 3, Oi = 5e3, bt = 500, zi = 500, ji = 300, qi = /* @__PURE__ */ new Set([
|
|
1439
1834
|
"A",
|
|
1440
1835
|
"BUTTON",
|
|
1441
1836
|
"INPUT",
|
|
@@ -1444,7 +1839,7 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1444
1839
|
"LABEL",
|
|
1445
1840
|
"SUMMARY",
|
|
1446
1841
|
"DETAILS"
|
|
1447
|
-
]),
|
|
1842
|
+
]), Ni = /* @__PURE__ */ new Set([
|
|
1448
1843
|
"button",
|
|
1449
1844
|
"link",
|
|
1450
1845
|
"checkbox",
|
|
@@ -1458,19 +1853,19 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1458
1853
|
"listbox",
|
|
1459
1854
|
"slider",
|
|
1460
1855
|
"spinbutton"
|
|
1461
|
-
]),
|
|
1856
|
+
]), pt = [
|
|
1462
1857
|
"404",
|
|
1463
1858
|
"500",
|
|
1464
1859
|
"not found",
|
|
1465
1860
|
"page not found",
|
|
1466
1861
|
"server error",
|
|
1467
1862
|
"internal server error"
|
|
1468
|
-
],
|
|
1863
|
+
], R = class R {
|
|
1469
1864
|
constructor(t) {
|
|
1470
|
-
this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.errorCount = 0, this.deadClickCount = 0, this.cooldownUntil = 0, this.navTimestamps = [], this.
|
|
1865
|
+
this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.errorCount = 0, this.deadClickCount = 0, this.cooldownUntil = 0, this.navTimestamps = [], this.unsubscribeNavigation = null, this.boundSubmitHandler = null, this.boundInvalidHandler = null, this.recentSubmitForms = /* @__PURE__ */ new WeakSet(), this.errorPageUrls = /* @__PURE__ */ new Set(), this.domObserver = null, this.pendingDomChecks = 0, this.lastMutationAt = -1, this.onFrustration = t, this.boundClickHandler = (e) => this.handleClick(e);
|
|
1471
1866
|
}
|
|
1472
1867
|
start() {
|
|
1473
|
-
this.active || (this.active = !0, document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors =
|
|
1868
|
+
this.active || (this.active = !0, this.restoreState(), document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors = tt.subscribe((t) => {
|
|
1474
1869
|
this.errorCount++;
|
|
1475
1870
|
}), this.startNavigationTracking(), this.startFormTracking(), this.checkErrorPage());
|
|
1476
1871
|
}
|
|
@@ -1478,16 +1873,27 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1478
1873
|
this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.clickHistory = [], this.stopNavigationTracking(), this.stopFormTracking(), this.errorPageUrls.clear(), this.disconnectDomObserver());
|
|
1479
1874
|
}
|
|
1480
1875
|
startNavigationTracking() {
|
|
1481
|
-
this.
|
|
1482
|
-
const t = this.originalPushState, e = this.originalReplaceState, r = () => this.handleNavigation();
|
|
1483
|
-
this.installedPushState = function(s, n, o) {
|
|
1484
|
-
t(s, n, o), r();
|
|
1485
|
-
}, this.installedReplaceState = function(s, n, o) {
|
|
1486
|
-
e(s, n, o), r();
|
|
1487
|
-
}, history.pushState = this.installedPushState, history.replaceState = this.installedReplaceState;
|
|
1876
|
+
this.unsubscribeNavigation = Bt(() => this.handleNavigation());
|
|
1488
1877
|
}
|
|
1489
1878
|
stopNavigationTracking() {
|
|
1490
|
-
this.
|
|
1879
|
+
this.unsubscribeNavigation?.(), this.unsubscribeNavigation = null, this.navTimestamps = [];
|
|
1880
|
+
}
|
|
1881
|
+
// Rehydrates the state a Turbo Drive visit would otherwise reset. Without this,
|
|
1882
|
+
// a fresh detector on every page starts with an empty nav history (so
|
|
1883
|
+
// `rapid_navigation` can never reach its 3-in-5s threshold), no cooldown, and no
|
|
1884
|
+
// memory of which error pages it already reported.
|
|
1885
|
+
restoreState() {
|
|
1886
|
+
const t = U();
|
|
1887
|
+
this.navTimestamps = t.navTimestamps, this.cooldownUntil = t.cooldownUntil, this.errorPageUrls = new Set(t.errorPageUrls);
|
|
1888
|
+
}
|
|
1889
|
+
persistState() {
|
|
1890
|
+
const t = U();
|
|
1891
|
+
Ot({
|
|
1892
|
+
...t,
|
|
1893
|
+
navTimestamps: this.navTimestamps,
|
|
1894
|
+
cooldownUntil: this.cooldownUntil,
|
|
1895
|
+
errorPageUrls: [...this.errorPageUrls]
|
|
1896
|
+
});
|
|
1491
1897
|
}
|
|
1492
1898
|
startFormTracking() {
|
|
1493
1899
|
this.boundSubmitHandler = (t) => this.handleFormSubmit(t), this.boundInvalidHandler = (t) => this.handleFormInvalid(t), document.addEventListener("submit", this.boundSubmitHandler, !0), document.addEventListener("invalid", this.boundInvalidHandler, !0);
|
|
@@ -1497,54 +1903,62 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1497
1903
|
}
|
|
1498
1904
|
handleClick(t) {
|
|
1499
1905
|
const e = t.target;
|
|
1500
|
-
if (!e ||
|
|
1906
|
+
if (!e || S(e)) return;
|
|
1907
|
+
this.trackFormSubmitIntent(e);
|
|
1501
1908
|
const r = Date.now();
|
|
1502
1909
|
this.clickHistory.push({ target: e, time: r });
|
|
1503
|
-
const s = r -
|
|
1504
|
-
if (this.clickHistory = this.clickHistory.filter((o) => o.time > s), this.clickHistory.filter((o) => o.target === e).length >=
|
|
1910
|
+
const s = r - Bi;
|
|
1911
|
+
if (this.clickHistory = this.clickHistory.filter((o) => o.time > s), this.clickHistory.filter((o) => o.target === e).length >= Fi) {
|
|
1505
1912
|
this.clickHistory = [], this.emitHighPriority({
|
|
1506
1913
|
signal: "rage_click",
|
|
1507
|
-
target:
|
|
1914
|
+
target: _(e),
|
|
1508
1915
|
timestamp: r
|
|
1509
1916
|
});
|
|
1510
1917
|
return;
|
|
1511
1918
|
}
|
|
1512
1919
|
this.isInteractive(e) || (this.deadClickCount++, this.deadClickCount >= 3 && this.errorCount > 0 && (this.deadClickCount = 0, this.errorCount = 0, this.emitIfReady({
|
|
1513
1920
|
signal: "dead_click",
|
|
1514
|
-
target:
|
|
1921
|
+
target: _(e),
|
|
1515
1922
|
timestamp: r
|
|
1516
1923
|
}))), this.checkDeadClickDom(e, r);
|
|
1517
1924
|
}
|
|
1518
1925
|
handleNavigation() {
|
|
1519
1926
|
const t = Date.now();
|
|
1520
1927
|
this.navTimestamps.push(t);
|
|
1521
|
-
const e = t -
|
|
1522
|
-
this.navTimestamps = this.navTimestamps.filter((r) => r > e), this.navTimestamps.length >=
|
|
1928
|
+
const e = t - Oi;
|
|
1929
|
+
this.navTimestamps = this.navTimestamps.filter((r) => r > e), this.navTimestamps.length >= Ui && (this.navTimestamps = [], this.emitIfReady({
|
|
1523
1930
|
signal: "rapid_navigation",
|
|
1524
1931
|
timestamp: t
|
|
1525
|
-
})), setTimeout(() => {
|
|
1932
|
+
})), this.persistState(), setTimeout(() => {
|
|
1526
1933
|
this.active && this.checkErrorPage();
|
|
1527
|
-
},
|
|
1934
|
+
}, ji);
|
|
1528
1935
|
}
|
|
1529
1936
|
handleFormSubmit(t) {
|
|
1530
1937
|
const e = t.target;
|
|
1531
|
-
e instanceof HTMLFormElement && (
|
|
1532
|
-
this.recentSubmitForms.delete(e);
|
|
1533
|
-
}, J), setTimeout(() => {
|
|
1938
|
+
e instanceof HTMLFormElement && (S(e) || (this.rememberSubmitAttempt(e), setTimeout(() => {
|
|
1534
1939
|
this.active && e.querySelector('[aria-invalid="true"], .is-invalid') && this.emitIfReady({
|
|
1535
1940
|
signal: "form_failure",
|
|
1536
|
-
target:
|
|
1941
|
+
target: _(e),
|
|
1537
1942
|
timestamp: Date.now()
|
|
1538
1943
|
});
|
|
1539
|
-
},
|
|
1944
|
+
}, bt)));
|
|
1945
|
+
}
|
|
1946
|
+
trackFormSubmitIntent(t) {
|
|
1947
|
+
const e = t.closest("button, input");
|
|
1948
|
+
(e instanceof HTMLButtonElement || e instanceof HTMLInputElement) && (e.type !== "submit" && e.type !== "image" || !e.form || S(e.form) || this.rememberSubmitAttempt(e.form));
|
|
1949
|
+
}
|
|
1950
|
+
rememberSubmitAttempt(t) {
|
|
1951
|
+
this.recentSubmitForms.add(t), setTimeout(() => {
|
|
1952
|
+
this.recentSubmitForms.delete(t);
|
|
1953
|
+
}, bt);
|
|
1540
1954
|
}
|
|
1541
1955
|
handleFormInvalid(t) {
|
|
1542
1956
|
const e = t.target;
|
|
1543
|
-
if (!e ||
|
|
1957
|
+
if (!e || S(e)) return;
|
|
1544
1958
|
const r = e.closest("form");
|
|
1545
1959
|
!r || !this.recentSubmitForms.has(r) || this.emitIfReady({
|
|
1546
1960
|
signal: "form_failure",
|
|
1547
|
-
target:
|
|
1961
|
+
target: _(r),
|
|
1548
1962
|
timestamp: Date.now()
|
|
1549
1963
|
});
|
|
1550
1964
|
}
|
|
@@ -1552,7 +1966,7 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1552
1966
|
const t = location.href;
|
|
1553
1967
|
if (this.errorPageUrls.has(t)) return;
|
|
1554
1968
|
const e = document.title.toLowerCase();
|
|
1555
|
-
if (
|
|
1969
|
+
if (pt.some((s) => e.includes(s))) {
|
|
1556
1970
|
this.errorPageUrls.add(t), this.emitHighPriority({
|
|
1557
1971
|
signal: "error_page",
|
|
1558
1972
|
detail: document.title,
|
|
@@ -1565,7 +1979,7 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1565
1979
|
);
|
|
1566
1980
|
for (const s of r) {
|
|
1567
1981
|
const n = s.textContent ?? "";
|
|
1568
|
-
if (n.length < 200 &&
|
|
1982
|
+
if (n.length < 200 && pt.some((o) => n.toLowerCase().includes(o))) {
|
|
1569
1983
|
this.errorPageUrls.add(t), this.emitHighPriority({
|
|
1570
1984
|
signal: "error_page",
|
|
1571
1985
|
detail: n.trim().slice(0, 60),
|
|
@@ -1584,10 +1998,10 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1584
1998
|
const r = this.lastMutationAt >= e;
|
|
1585
1999
|
this.pendingDomChecks === 0 && this.disconnectDomObserver(), !r && this.active && this.emitIfReady({
|
|
1586
2000
|
signal: "dead_click_dom",
|
|
1587
|
-
target:
|
|
2001
|
+
target: _(t),
|
|
1588
2002
|
timestamp: e
|
|
1589
2003
|
});
|
|
1590
|
-
},
|
|
2004
|
+
}, zi));
|
|
1591
2005
|
}
|
|
1592
2006
|
ensureDomObserver() {
|
|
1593
2007
|
this.domObserver || (this.domObserver = new MutationObserver(() => {
|
|
@@ -1612,206 +2026,43 @@ const Ze = 3, ti = 1e3, ei = 3, ii = 5e3, J = 500, ri = 500, si = 300, ni = /* @
|
|
|
1612
2026
|
return !1;
|
|
1613
2027
|
}
|
|
1614
2028
|
isInteractive(t) {
|
|
1615
|
-
if (
|
|
2029
|
+
if (qi.has(t.tagName)) return !0;
|
|
1616
2030
|
const e = t.getAttribute("role");
|
|
1617
|
-
return !!(e &&
|
|
2031
|
+
return !!(e && Ni.has(e) || t.hasAttribute("onclick") || t.hasAttribute("tabindex") || t.contentEditable === "true" || window.getComputedStyle(t).cursor === "pointer" || t.closest('a, button, [role="button"], [role="link"], label'));
|
|
1618
2032
|
}
|
|
1619
2033
|
emitIfReady(t) {
|
|
1620
2034
|
const e = Date.now();
|
|
1621
|
-
e < this.cooldownUntil || (this.cooldownUntil = e +
|
|
2035
|
+
e < this.cooldownUntil || (this.cooldownUntil = e + R.COOLDOWN_MS, this.persistState(), this.onFrustration(t));
|
|
1622
2036
|
}
|
|
1623
2037
|
emitHighPriority(t) {
|
|
1624
|
-
this.cooldownUntil = Date.now() +
|
|
2038
|
+
this.cooldownUntil = Date.now() + R.COOLDOWN_MS, this.persistState(), this.onFrustration(t);
|
|
1625
2039
|
}
|
|
1626
2040
|
};
|
|
1627
|
-
|
|
1628
|
-
let
|
|
1629
|
-
function
|
|
2041
|
+
R.COOLDOWN_MS = 6e4;
|
|
2042
|
+
let X = R;
|
|
2043
|
+
function _(i) {
|
|
1630
2044
|
const t = i.tagName.toLowerCase(), e = i.id ? `#${i.id}` : "", r = i.className && typeof i.className == "string" ? "." + i.className.trim().split(/\s+/).slice(0, 2).join(".") : "", s = i.textContent?.trim().slice(0, 30) ?? "";
|
|
1631
2045
|
return `<${t}${e}${r}>${s ? ` "${s}"` : ""}`;
|
|
1632
2046
|
}
|
|
1633
|
-
function
|
|
2047
|
+
function Wi() {
|
|
1634
2048
|
return {
|
|
1635
2049
|
page_url: window.location.href,
|
|
1636
2050
|
user_agent: navigator.userAgent,
|
|
1637
|
-
browser:
|
|
1638
|
-
os:
|
|
2051
|
+
browser: Vi(),
|
|
2052
|
+
os: Yi(),
|
|
1639
2053
|
screen_width: window.screen.width,
|
|
1640
2054
|
screen_height: window.screen.height
|
|
1641
2055
|
};
|
|
1642
2056
|
}
|
|
1643
|
-
function
|
|
2057
|
+
function Vi() {
|
|
1644
2058
|
const i = navigator.userAgent;
|
|
1645
2059
|
return /Edg\//.test(i) ? `Edge ${i.match(/Edg\/(\S+)/)?.[1] ?? ""}` : /OPR\//.test(i) ? `Opera ${i.match(/OPR\/(\S+)/)?.[1] ?? ""}` : /Chrome\//.test(i) ? `Chrome ${i.match(/Chrome\/(\S+)/)?.[1] ?? ""}` : /Safari\//.test(i) && /Version\//.test(i) ? `Safari ${i.match(/Version\/(\S+)/)?.[1] ?? ""}` : /Firefox\//.test(i) ? `Firefox ${i.match(/Firefox\/(\S+)/)?.[1] ?? ""}` : "Unknown";
|
|
1646
2060
|
}
|
|
1647
|
-
function
|
|
2061
|
+
function Yi() {
|
|
1648
2062
|
const i = navigator.userAgent;
|
|
1649
2063
|
return /Windows NT 10/.test(i) ? "Windows 10/11" : /Windows NT/.test(i) ? "Windows" : /Mac OS X 10_15|macOS 1[56789]/.test(i) || /Mac OS X/.test(i) ? "macOS" : /Android/.test(i) ? `Android ${i.match(/Android (\d+)/)?.[1] ?? ""}` : /iPhone|iPad|iPod/.test(i) ? "iOS" : /Linux/.test(i) ? "Linux" : "Unknown";
|
|
1650
2064
|
}
|
|
1651
|
-
|
|
1652
|
-
class hi {
|
|
1653
|
-
constructor(t, e, r = 1e3, s, n) {
|
|
1654
|
-
this.projectKey = t, this.apiUrl = (e ?? di).replace(/\/$/, ""), this.retryDelayMs = r, this.userToken = s, this.userTokenFn = n;
|
|
1655
|
-
}
|
|
1656
|
-
async resolveUserToken() {
|
|
1657
|
-
return this.userTokenFn ? this.userTokenFn() : this.userToken;
|
|
1658
|
-
}
|
|
1659
|
-
async authHeaders(t) {
|
|
1660
|
-
const e = { "X-Project-Key": this.projectKey }, r = await this.resolveUserToken();
|
|
1661
|
-
return r && (e["X-User-Token"] = r), t && (e["Content-Type"] = t), e;
|
|
1662
|
-
}
|
|
1663
|
-
async submissionHeaders(t, e) {
|
|
1664
|
-
const r = await this.authHeaders(e);
|
|
1665
|
-
return r["X-Submission-Token"] = t, r;
|
|
1666
|
-
}
|
|
1667
|
-
async createSubmissionSession(t, e) {
|
|
1668
|
-
const r = fi(), s = new FormData();
|
|
1669
|
-
if (s.append("feedback[description]", t.description), s.append("feedback[page_url]", t.page_url), s.append("feedback[user_agent]", t.user_agent), s.append("feedback[browser]", t.browser), s.append("feedback[os]", t.os), s.append("feedback[screen_width]", String(t.screen_width)), s.append("feedback[screen_height]", String(t.screen_height)), s.append("feedback[console_errors]", JSON.stringify(t.console_errors)), s.append("feedback[annotations]", JSON.stringify(t.annotations)), t.target_element && s.append("feedback[target_element]", JSON.stringify(t.target_element)), t.user_id && s.append("feedback[user_id]", t.user_id), t.reporter_external_id && s.append("feedback[reporter_external_id]", t.reporter_external_id), t.reporter_email && s.append("feedback[reporter_email]", t.reporter_email), t.user_email && s.append("feedback[user_email]", t.user_email), t.user_name && s.append("feedback[user_name]", t.user_name), t.breadcrumbs && t.breadcrumbs.length > 0 && s.append("feedback[breadcrumbs]", JSON.stringify(t.breadcrumbs)), t.recording_events && t.recording_events.length > 0) {
|
|
1670
|
-
const l = JSON.stringify(t.recording_events), c = new Blob([l], { type: "application/json" });
|
|
1671
|
-
s.append("feedback[recording]", c, "interaction-replay.json"), s.append("feedback[recording_duration]", String(t.recording_duration ?? 0));
|
|
1672
|
-
}
|
|
1673
|
-
if (e) {
|
|
1674
|
-
const l = e.type === "image/jpeg" ? "jpg" : "png";
|
|
1675
|
-
s.append("feedback[screenshot]", e, `screenshot.${l}`);
|
|
1676
|
-
}
|
|
1677
|
-
const n = await this.authHeaders();
|
|
1678
|
-
return n["X-Submission-Token"] = r, n["X-Idempotency-Key"] = mi(), { ...(await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions`, {
|
|
1679
|
-
method: "POST",
|
|
1680
|
-
headers: n,
|
|
1681
|
-
body: s
|
|
1682
|
-
})).json()).submission_session, token: r };
|
|
1683
|
-
}
|
|
1684
|
-
async createIdentityToken(t) {
|
|
1685
|
-
const e = await this.authHeaders("application/json");
|
|
1686
|
-
try {
|
|
1687
|
-
return await (await this.fetchWithRetry(`${this.apiUrl}/widget/identity_tokens`, {
|
|
1688
|
-
method: "POST",
|
|
1689
|
-
headers: e,
|
|
1690
|
-
body: JSON.stringify({ reporter_external_id: t })
|
|
1691
|
-
})).json();
|
|
1692
|
-
} catch {
|
|
1693
|
-
return null;
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
async updateReporter(t, e, r) {
|
|
1697
|
-
const s = await this.authHeaders("application/json");
|
|
1698
|
-
s["X-Identity-Token"] = r;
|
|
1699
|
-
try {
|
|
1700
|
-
return await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${t}/reporter`, {
|
|
1701
|
-
method: "PATCH",
|
|
1702
|
-
headers: s,
|
|
1703
|
-
body: JSON.stringify({ reporter: { email: e } })
|
|
1704
|
-
}), !0;
|
|
1705
|
-
} catch {
|
|
1706
|
-
return !1;
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
async startClarification(t, e, r) {
|
|
1710
|
-
const s = {};
|
|
1711
|
-
r && (s.message = r);
|
|
1712
|
-
const n = await this.submissionHeaders(e, "application/json");
|
|
1713
|
-
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
1714
|
-
method: "POST",
|
|
1715
|
-
headers: n,
|
|
1716
|
-
body: JSON.stringify(s)
|
|
1717
|
-
})).json()).clarification;
|
|
1718
|
-
}
|
|
1719
|
-
async getClarification(t, e) {
|
|
1720
|
-
const r = await this.submissionHeaders(e);
|
|
1721
|
-
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
1722
|
-
method: "GET",
|
|
1723
|
-
headers: r
|
|
1724
|
-
})).json()).clarification;
|
|
1725
|
-
}
|
|
1726
|
-
// Streams a clarification turn over SSE. Calls onDelta for each token and
|
|
1727
|
-
// resolves with the committed result. Throws if the server doesn't stream
|
|
1728
|
-
// (e.g. old backend returns JSON) so the caller can fall back to polling.
|
|
1729
|
-
async streamClarification(t, e, r) {
|
|
1730
|
-
const s = await this.submissionHeaders(e, "application/json");
|
|
1731
|
-
s.Accept = "text/event-stream";
|
|
1732
|
-
const n = await fetch(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
1733
|
-
method: "POST",
|
|
1734
|
-
headers: s,
|
|
1735
|
-
body: JSON.stringify({})
|
|
1736
|
-
}), o = n.headers.get("Content-Type") ?? "";
|
|
1737
|
-
if (!n.ok || !n.body || !o.includes("text/event-stream"))
|
|
1738
|
-
throw new Error("clarify stream unavailable");
|
|
1739
|
-
return ui(n.body, r);
|
|
1740
|
-
}
|
|
1741
|
-
async finalizeSubmissionSession(t, e) {
|
|
1742
|
-
const r = await this.submissionHeaders(e);
|
|
1743
|
-
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/feedback`, {
|
|
1744
|
-
method: "POST",
|
|
1745
|
-
headers: r
|
|
1746
|
-
})).json()).feedback;
|
|
1747
|
-
}
|
|
1748
|
-
async abandonSubmissionSession(t, e) {
|
|
1749
|
-
const r = await this.submissionHeaders(e);
|
|
1750
|
-
await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}`, {
|
|
1751
|
-
method: "DELETE",
|
|
1752
|
-
headers: r
|
|
1753
|
-
});
|
|
1754
|
-
}
|
|
1755
|
-
async fetchWithRetry(t, e, r = 1) {
|
|
1756
|
-
let s;
|
|
1757
|
-
try {
|
|
1758
|
-
s = await fetch(t, e);
|
|
1759
|
-
} catch (n) {
|
|
1760
|
-
if (r > 0)
|
|
1761
|
-
return await Z(this.retryDelayMs), this.fetchWithRetry(t, e, r - 1);
|
|
1762
|
-
throw n;
|
|
1763
|
-
}
|
|
1764
|
-
if (s.ok) return s;
|
|
1765
|
-
if (s.status >= 500 && r > 0)
|
|
1766
|
-
return await Z(this.retryDelayMs), this.fetchWithRetry(t, e, r - 1);
|
|
1767
|
-
throw new Error(`HTTP ${s.status}`);
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
function Z(i) {
|
|
1771
|
-
return i <= 0 ? Promise.resolve() : new Promise((t) => setTimeout(t, i));
|
|
1772
|
-
}
|
|
1773
|
-
async function ui(i, t) {
|
|
1774
|
-
const e = i.getReader(), r = new TextDecoder();
|
|
1775
|
-
let s = "", n = { messages: [], done: !0 };
|
|
1776
|
-
const o = (a) => {
|
|
1777
|
-
const l = a.split(`
|
|
1778
|
-
`).find((m) => m.startsWith("event:")), c = a.split(`
|
|
1779
|
-
`).find((m) => m.startsWith("data:"));
|
|
1780
|
-
if (!c) return;
|
|
1781
|
-
const h = l?.slice(6).trim(), u = JSON.parse(c.slice(5).trim());
|
|
1782
|
-
h === "delta" && typeof u.text == "string" ? t(u.text) : h === "done" && (n = {
|
|
1783
|
-
messages: Array.isArray(u.messages) ? u.messages : [],
|
|
1784
|
-
done: u.done !== !1
|
|
1785
|
-
});
|
|
1786
|
-
};
|
|
1787
|
-
for (; ; ) {
|
|
1788
|
-
const { done: a, value: l } = await e.read();
|
|
1789
|
-
if (a) break;
|
|
1790
|
-
s += r.decode(l, { stream: !0 });
|
|
1791
|
-
let c;
|
|
1792
|
-
for (; (c = s.indexOf(`
|
|
1793
|
-
|
|
1794
|
-
`)) !== -1; ) {
|
|
1795
|
-
const h = s.slice(0, c);
|
|
1796
|
-
s = s.slice(c + 2);
|
|
1797
|
-
try {
|
|
1798
|
-
o(h);
|
|
1799
|
-
} catch {
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
return n;
|
|
1804
|
-
}
|
|
1805
|
-
function mi() {
|
|
1806
|
-
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
1807
|
-
}
|
|
1808
|
-
function fi() {
|
|
1809
|
-
if (typeof crypto > "u" || typeof crypto.getRandomValues != "function")
|
|
1810
|
-
throw new Error("Secure random generation is unavailable");
|
|
1811
|
-
const i = crypto.getRandomValues(new Uint8Array(32));
|
|
1812
|
-
return Array.from(i, (t) => t.toString(16).padStart(2, "0")).join("");
|
|
1813
|
-
}
|
|
1814
|
-
function pi(i, t, e, r, s, n, o, a, l) {
|
|
2065
|
+
function Xi(i, t, e, r, s, n, o, a, l) {
|
|
1815
2066
|
return {
|
|
1816
2067
|
description: i,
|
|
1817
2068
|
...t,
|
|
@@ -1832,50 +2083,50 @@ function pi(i, t, e, r, s, n, o, a, l) {
|
|
|
1832
2083
|
breadcrumbs: l
|
|
1833
2084
|
};
|
|
1834
2085
|
}
|
|
1835
|
-
const
|
|
1836
|
-
let
|
|
1837
|
-
function
|
|
2086
|
+
const gt = "mtb_anon_id", zt = "mtb_reporter_email", jt = "mtb_board_url";
|
|
2087
|
+
let yt = null, qt = null, Nt = null;
|
|
2088
|
+
function wt() {
|
|
1838
2089
|
try {
|
|
1839
|
-
const i = window.localStorage.getItem(
|
|
2090
|
+
const i = window.localStorage.getItem(gt);
|
|
1840
2091
|
if (i?.startsWith("anon_")) return i;
|
|
1841
|
-
const t =
|
|
1842
|
-
return window.localStorage.setItem(
|
|
2092
|
+
const t = kt();
|
|
2093
|
+
return window.localStorage.setItem(gt, t), t;
|
|
1843
2094
|
} catch {
|
|
1844
|
-
return
|
|
2095
|
+
return yt ?? (yt = kt()), yt;
|
|
1845
2096
|
}
|
|
1846
2097
|
}
|
|
1847
|
-
function
|
|
2098
|
+
function vt() {
|
|
1848
2099
|
try {
|
|
1849
|
-
return window.localStorage.getItem(
|
|
2100
|
+
return window.localStorage.getItem(zt) ?? void 0;
|
|
1850
2101
|
} catch {
|
|
1851
|
-
return
|
|
2102
|
+
return qt ?? void 0;
|
|
1852
2103
|
}
|
|
1853
2104
|
}
|
|
1854
|
-
function
|
|
1855
|
-
|
|
2105
|
+
function Ki(i) {
|
|
2106
|
+
qt = i;
|
|
1856
2107
|
try {
|
|
1857
|
-
window.localStorage.setItem(
|
|
2108
|
+
window.localStorage.setItem(zt, i);
|
|
1858
2109
|
} catch {
|
|
1859
2110
|
}
|
|
1860
2111
|
}
|
|
1861
|
-
function
|
|
2112
|
+
function Gi() {
|
|
1862
2113
|
try {
|
|
1863
|
-
return window.localStorage.getItem(
|
|
2114
|
+
return window.localStorage.getItem(jt) ?? void 0;
|
|
1864
2115
|
} catch {
|
|
1865
|
-
return
|
|
2116
|
+
return Nt ?? void 0;
|
|
1866
2117
|
}
|
|
1867
2118
|
}
|
|
1868
|
-
function
|
|
1869
|
-
|
|
2119
|
+
function xt(i) {
|
|
2120
|
+
Nt = i;
|
|
1870
2121
|
try {
|
|
1871
|
-
window.localStorage.setItem(
|
|
2122
|
+
window.localStorage.setItem(jt, i);
|
|
1872
2123
|
} catch {
|
|
1873
2124
|
}
|
|
1874
2125
|
}
|
|
1875
|
-
function
|
|
2126
|
+
function kt() {
|
|
1876
2127
|
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? `anon_${crypto.randomUUID()}` : `anon_${`${Date.now().toString(16)}-${Math.random().toString(16).slice(2, 10)}`}`;
|
|
1877
2128
|
}
|
|
1878
|
-
const
|
|
2129
|
+
const Ji = {
|
|
1879
2130
|
tab: "Feedback",
|
|
1880
2131
|
toolbar: {
|
|
1881
2132
|
markup: "Mark up",
|
|
@@ -1948,9 +2199,11 @@ const yi = {
|
|
|
1948
2199
|
send: "Send",
|
|
1949
2200
|
send_feedback: "Send feedback",
|
|
1950
2201
|
skip: "Skip & send",
|
|
1951
|
-
retry: "Retry"
|
|
2202
|
+
retry: "Retry",
|
|
2203
|
+
error: "AI clarification failed. Please try again.",
|
|
2204
|
+
expired: "This feedback session expired before it could be sent. Please close the widget and submit again."
|
|
1952
2205
|
}
|
|
1953
|
-
},
|
|
2206
|
+
}, Qi = {
|
|
1954
2207
|
tab: "反馈",
|
|
1955
2208
|
toolbar: {
|
|
1956
2209
|
markup: "标注",
|
|
@@ -2023,9 +2276,11 @@ const yi = {
|
|
|
2023
2276
|
send: "发送",
|
|
2024
2277
|
send_feedback: "发送反馈",
|
|
2025
2278
|
skip: "跳过并发送",
|
|
2026
|
-
retry: "重试"
|
|
2279
|
+
retry: "重试",
|
|
2280
|
+
error: "AI 澄清失败,请重试。",
|
|
2281
|
+
expired: "这条反馈在发送前已过期。请关闭组件后重新提交。"
|
|
2027
2282
|
}
|
|
2028
|
-
},
|
|
2283
|
+
}, Zi = {
|
|
2029
2284
|
tab: "フィードバック",
|
|
2030
2285
|
toolbar: {
|
|
2031
2286
|
markup: "マークアップ",
|
|
@@ -2098,9 +2353,11 @@ const yi = {
|
|
|
2098
2353
|
send: "送信",
|
|
2099
2354
|
send_feedback: "フィードバックを送信",
|
|
2100
2355
|
skip: "スキップして送信",
|
|
2101
|
-
retry: "再試行"
|
|
2356
|
+
retry: "再試行",
|
|
2357
|
+
error: "AIによる確認に失敗しました。もう一度お試しください。",
|
|
2358
|
+
expired: "このフィードバックは送信される前に有効期限が切れました。ウィジェットを閉じて、もう一度送信してください。"
|
|
2102
2359
|
}
|
|
2103
|
-
},
|
|
2360
|
+
}, tr = {
|
|
2104
2361
|
tab: "피드백",
|
|
2105
2362
|
toolbar: {
|
|
2106
2363
|
markup: "마크업",
|
|
@@ -2173,9 +2430,11 @@ const yi = {
|
|
|
2173
2430
|
send: "보내기",
|
|
2174
2431
|
send_feedback: "피드백 보내기",
|
|
2175
2432
|
skip: "건너뛰고 보내기",
|
|
2176
|
-
retry: "재시도"
|
|
2433
|
+
retry: "재시도",
|
|
2434
|
+
error: "AI 확인에 실패했습니다. 다시 시도해 주세요.",
|
|
2435
|
+
expired: "이 피드백 세션은 전송되기 전에 만료되었습니다. 위젯을 닫고 다시 보내 주세요."
|
|
2177
2436
|
}
|
|
2178
|
-
},
|
|
2437
|
+
}, er = {
|
|
2179
2438
|
tab: "Comentarios",
|
|
2180
2439
|
toolbar: {
|
|
2181
2440
|
markup: "Anotar",
|
|
@@ -2248,9 +2507,11 @@ const yi = {
|
|
|
2248
2507
|
send: "Enviar",
|
|
2249
2508
|
send_feedback: "Enviar comentario",
|
|
2250
2509
|
skip: "Omitir y enviar",
|
|
2251
|
-
retry: "Reintentar"
|
|
2510
|
+
retry: "Reintentar",
|
|
2511
|
+
error: "No se pudo completar la aclaración con IA. Inténtalo de nuevo.",
|
|
2512
|
+
expired: "Esta sesión de comentarios caducó antes de poder enviarse. Cierra el widget y envíalo de nuevo."
|
|
2252
2513
|
}
|
|
2253
|
-
},
|
|
2514
|
+
}, ir = {
|
|
2254
2515
|
tab: "Avis",
|
|
2255
2516
|
toolbar: {
|
|
2256
2517
|
markup: "Annoter",
|
|
@@ -2323,9 +2584,11 @@ const yi = {
|
|
|
2323
2584
|
send: "Envoyer",
|
|
2324
2585
|
send_feedback: "Envoyer le retour",
|
|
2325
2586
|
skip: "Ignorer et envoyer",
|
|
2326
|
-
retry: "Réessayer"
|
|
2587
|
+
retry: "Réessayer",
|
|
2588
|
+
error: "La clarification par IA a échoué. Réessayez.",
|
|
2589
|
+
expired: "Cette session de retour a expiré avant d'avoir pu être envoyée. Fermez le widget et renvoyez-la."
|
|
2327
2590
|
}
|
|
2328
|
-
},
|
|
2591
|
+
}, rr = {
|
|
2329
2592
|
tab: "Feedback",
|
|
2330
2593
|
toolbar: {
|
|
2331
2594
|
markup: "Markieren",
|
|
@@ -2398,58 +2661,67 @@ const yi = {
|
|
|
2398
2661
|
send: "Senden",
|
|
2399
2662
|
send_feedback: "Feedback senden",
|
|
2400
2663
|
skip: "Überspringen & senden",
|
|
2401
|
-
retry: "Erneut versuchen"
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2664
|
+
retry: "Erneut versuchen",
|
|
2665
|
+
error: "Die KI-Klärung ist fehlgeschlagen. Bitte erneut versuchen.",
|
|
2666
|
+
expired: "Diese Feedback-Sitzung ist abgelaufen, bevor sie gesendet werden konnte. Bitte schließe das Widget und sende erneut."
|
|
2667
|
+
}
|
|
2668
|
+
}, T = {
|
|
2669
|
+
en: Ji,
|
|
2670
|
+
"zh-CN": Qi,
|
|
2671
|
+
ja: Zi,
|
|
2672
|
+
ko: tr,
|
|
2673
|
+
es: er,
|
|
2674
|
+
fr: ir,
|
|
2675
|
+
de: rr
|
|
2411
2676
|
};
|
|
2412
|
-
function
|
|
2413
|
-
if (
|
|
2677
|
+
function St(i) {
|
|
2678
|
+
if (T[i]) return T[i];
|
|
2414
2679
|
const t = i.split("-")[0];
|
|
2415
|
-
return
|
|
2680
|
+
return T[t] ? T[t] : T.en;
|
|
2416
2681
|
}
|
|
2417
|
-
const
|
|
2418
|
-
let
|
|
2419
|
-
function
|
|
2420
|
-
return
|
|
2682
|
+
const sr = 60, nr = "rr-block", or = "rr-mask", ar = "https://cdn.jsdelivr.net/npm/@rrweb/record@2.1.0/umd/record.min.js", lr = "sha384-MrD66HBNSykaP2N95+6hQCFlF5oH2tvL3TD/zyvHNkP/sAFWZx98DX9MEDy8MdVT";
|
|
2683
|
+
let D = null;
|
|
2684
|
+
function cr() {
|
|
2685
|
+
return D || (D = dr().catch(() => hr()), D);
|
|
2421
2686
|
}
|
|
2422
|
-
async function
|
|
2687
|
+
async function dr() {
|
|
2423
2688
|
return (await import("@rrweb/record")).record;
|
|
2424
2689
|
}
|
|
2425
|
-
function
|
|
2690
|
+
function Et() {
|
|
2426
2691
|
const i = globalThis;
|
|
2427
2692
|
return i.rrwebRecord?.record ?? i.rrweb?.record;
|
|
2428
2693
|
}
|
|
2429
|
-
function
|
|
2694
|
+
function hr() {
|
|
2430
2695
|
return new Promise((i, t) => {
|
|
2431
|
-
const e =
|
|
2696
|
+
const e = Et();
|
|
2432
2697
|
if (e) {
|
|
2433
2698
|
i(e);
|
|
2434
2699
|
return;
|
|
2435
2700
|
}
|
|
2436
2701
|
const r = document.createElement("script");
|
|
2437
|
-
r.src =
|
|
2438
|
-
const s =
|
|
2702
|
+
r.src = ar, r.integrity = lr, r.crossOrigin = "anonymous", r.onload = () => {
|
|
2703
|
+
const s = Et();
|
|
2439
2704
|
s ? i(s) : t(new Error("rrweb record global not found after script load"));
|
|
2440
2705
|
}, r.onerror = () => t(new Error("Failed to load rrweb from CDN")), document.head.appendChild(r);
|
|
2441
2706
|
});
|
|
2442
2707
|
}
|
|
2443
|
-
class
|
|
2444
|
-
constructor(t, e) {
|
|
2445
|
-
this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.shadow = t, this.onMaxReached = e;
|
|
2708
|
+
class ur {
|
|
2709
|
+
constructor(t, e, r = {}) {
|
|
2710
|
+
this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.destroyed = !1, this.shadow = t, this.onMaxReached = e, this.options = r;
|
|
2446
2711
|
}
|
|
2447
2712
|
async start() {
|
|
2448
|
-
const t = await
|
|
2449
|
-
this.startedAt = Date.now(), this.stopped = !1, this.stopFn = t({
|
|
2713
|
+
const t = await cr();
|
|
2714
|
+
this.destroyed || (this.startedAt = Date.now(), this.stopped = !1, this.stopFn = t({
|
|
2450
2715
|
emit: (e) => {
|
|
2451
2716
|
this.stopped || this.events.push(e);
|
|
2452
|
-
}
|
|
2717
|
+
},
|
|
2718
|
+
// Default to masking every input value, not just password fields (rrweb's
|
|
2719
|
+
// own default). A replay is captured from whatever page the reporter happens
|
|
2720
|
+
// to be on, which may be a checkout or a 2FA prompt, and nothing downstream
|
|
2721
|
+
// scrubs it. Customers who need real values in replays must opt in.
|
|
2722
|
+
maskAllInputs: this.options.maskAllInputs ?? !0,
|
|
2723
|
+
blockClass: nr,
|
|
2724
|
+
maskTextClass: or
|
|
2453
2725
|
}), this.clickHandler = (e) => {
|
|
2454
2726
|
this.showClickRipple(e.clientX, e.clientY), t.addCustomEvent?.("mtb-click", {
|
|
2455
2727
|
x: e.clientX,
|
|
@@ -2458,7 +2730,7 @@ class Di {
|
|
|
2458
2730
|
});
|
|
2459
2731
|
}, document.addEventListener("click", this.clickHandler, !0), this.timer = setTimeout(() => {
|
|
2460
2732
|
this.onMaxReached?.();
|
|
2461
|
-
},
|
|
2733
|
+
}, sr * 1e3));
|
|
2462
2734
|
}
|
|
2463
2735
|
stop() {
|
|
2464
2736
|
return this.stopped = !0, this.stopFn?.(), this.stopFn = null, this.cleanupTimer(), this.cleanupClickHandler(), {
|
|
@@ -2470,7 +2742,7 @@ class Di {
|
|
|
2470
2742
|
return this.startedAt === 0 ? 0 : Math.max(1, Math.round((Date.now() - this.startedAt) / 1e3));
|
|
2471
2743
|
}
|
|
2472
2744
|
destroy() {
|
|
2473
|
-
this.stopped = !0, this.stopFn?.(), this.stopFn = null, this.cleanupTimer(), this.cleanupClickHandler(), this.events = [], this.startedAt = 0;
|
|
2745
|
+
this.destroyed = !0, this.stopped = !0, this.stopFn?.(), this.stopFn = null, this.cleanupTimer(), this.cleanupClickHandler(), this.events = [], this.startedAt = 0;
|
|
2474
2746
|
}
|
|
2475
2747
|
cleanupTimer() {
|
|
2476
2748
|
this.timer && (clearTimeout(this.timer), this.timer = null);
|
|
@@ -2483,7 +2755,7 @@ class Di {
|
|
|
2483
2755
|
r.style.left = `${t}px`, r.style.top = `${e}px`, this.shadow.append(r), r.addEventListener("animationend", () => r.remove());
|
|
2484
2756
|
}
|
|
2485
2757
|
}
|
|
2486
|
-
class
|
|
2758
|
+
class mr {
|
|
2487
2759
|
constructor(t, e, r, s) {
|
|
2488
2760
|
this.intervalId = null, this.getDuration = r, this.el = t.el("div", "mtb-record-bar"), this.el.innerHTML = `
|
|
2489
2761
|
<span class="mtb-record-dot"></span>
|
|
@@ -2499,12 +2771,12 @@ class Ai {
|
|
|
2499
2771
|
this.intervalId && (clearInterval(this.intervalId), this.intervalId = null), this.el.remove();
|
|
2500
2772
|
}
|
|
2501
2773
|
}
|
|
2502
|
-
class
|
|
2774
|
+
class fr {
|
|
2503
2775
|
constructor() {
|
|
2504
2776
|
this.session = null, this.bar = null, this.result = null;
|
|
2505
2777
|
}
|
|
2506
|
-
async start(t, e, r) {
|
|
2507
|
-
this.session = new
|
|
2778
|
+
async start(t, e, r, s = {}) {
|
|
2779
|
+
this.session = new ur(t, r, s), this.bar = new mr(
|
|
2508
2780
|
t,
|
|
2509
2781
|
e,
|
|
2510
2782
|
() => this.session?.getDuration() ?? 0,
|
|
@@ -2524,10 +2796,10 @@ class Hi {
|
|
|
2524
2796
|
this.session?.destroy(), this.session = null, this.bar?.destroy(), this.bar = null;
|
|
2525
2797
|
}
|
|
2526
2798
|
}
|
|
2527
|
-
const
|
|
2528
|
-
class
|
|
2799
|
+
const br = 3e3, Ct = 12e3;
|
|
2800
|
+
class K {
|
|
2529
2801
|
constructor(t) {
|
|
2530
|
-
this.tab = null, this.toolbar = null, this.session = null, this.drawBar = null, this.dim = null, this.popup = null, this.clarify = null, this.success = null, this.frustrationPrompt = null, this.frustrationDetector = null, this.mode = "idle", this.via = "pin", this.currentAnnotation = null, this.submittingUi = null, this.lastPopupPos = null, this.recordingManager = null, this.activeSubmission = null, this.submissionAttempt = 0, this.lastHandoff = {}, this.
|
|
2802
|
+
this.tab = null, this.toolbar = null, this.session = null, this.drawBar = null, this.dim = null, this.popup = null, this.clarify = null, this.success = null, this.frustrationPrompt = null, this.frustrationDetector = null, this.mode = "idle", this.via = "pin", this.currentAnnotation = null, this.submittingUi = null, this.lastPopupPos = null, this.recordingManager = null, this.activeSubmission = null, this.submissionAttempt = 0, this.lastHandoff = {}, this.handleKeydown = (e) => {
|
|
2531
2803
|
if (e.key === "Escape")
|
|
2532
2804
|
switch (this.mode) {
|
|
2533
2805
|
case "annotating":
|
|
@@ -2543,10 +2815,10 @@ class B {
|
|
|
2543
2815
|
}
|
|
2544
2816
|
}, this.handleRecordStop = () => {
|
|
2545
2817
|
this.recordingManager && (this.recordingManager.stop(), this.via = "record", this.showPopup(window.innerWidth / 2, window.innerHeight / 2, this.messages.record.timer_label));
|
|
2546
|
-
}, this.config = t, this.messages =
|
|
2818
|
+
}, this.config = t, this.messages = St(t.locale ?? document.documentElement.lang ?? "en"), this.apiClient = new me(t.projectKey, t.apiUrl, void 0, t.userToken, t.userTokenFn), this.consoleCollector = new Ai(), this.consoleCollector.start(), this.breadcrumbCollector = new Ii(), this.breadcrumbCollector.start(), this.buildUI(), t.frustrationDetection !== !1 && (this.frustrationDetector = new X(() => this.handleFrustration()), this.frustrationDetector.start()), document.addEventListener("keydown", this.handleKeydown, !0);
|
|
2547
2819
|
}
|
|
2548
2820
|
buildUI() {
|
|
2549
|
-
this.shadow = new
|
|
2821
|
+
this.shadow = new Vt(this.config.theme ?? "auto"), this.tab = new Yt(
|
|
2550
2822
|
this.shadow,
|
|
2551
2823
|
this.messages,
|
|
2552
2824
|
this.config.position ?? "right",
|
|
@@ -2554,24 +2826,33 @@ class B {
|
|
|
2554
2826
|
this.config.tabText
|
|
2555
2827
|
);
|
|
2556
2828
|
}
|
|
2829
|
+
// Takes effect for anything opened afterwards. Components already on screen keep
|
|
2830
|
+
// the language they were opened in rather than being re-rendered underneath a
|
|
2831
|
+
// reporter who may be mid-sentence.
|
|
2832
|
+
setLocale(t) {
|
|
2833
|
+
this.config.locale = t, this.messages = St(t), this.tab?.setMessages(this.messages);
|
|
2834
|
+
}
|
|
2557
2835
|
handleTabClick() {
|
|
2558
2836
|
this.mode === "idle" ? (this.dismissFrustrationPrompt(), this.enterAnnotationMode()) : this.exitAll();
|
|
2559
2837
|
}
|
|
2560
2838
|
handleFrustration() {
|
|
2561
|
-
this.mode !== "idle" || this.frustrationPrompt ||
|
|
2839
|
+
this.mode !== "idle" || this.frustrationPrompt || Hi() || (this.frustrationPrompt = new Kt(this.shadow, this.messages, {
|
|
2562
2840
|
onTell: () => {
|
|
2563
2841
|
this.dismissFrustrationPrompt(), this.enterAnnotationMode();
|
|
2564
2842
|
},
|
|
2565
2843
|
onDismiss: () => {
|
|
2566
|
-
|
|
2567
|
-
}
|
|
2844
|
+
$i(), this.dismissFrustrationPrompt();
|
|
2845
|
+
},
|
|
2846
|
+
// An unnoticed card is not a refusal, so it must not suppress later
|
|
2847
|
+
// prompts. The detector's own 60s cooldown does the rate limiting.
|
|
2848
|
+
onAutoHide: () => this.dismissFrustrationPrompt()
|
|
2568
2849
|
}));
|
|
2569
2850
|
}
|
|
2570
2851
|
dismissFrustrationPrompt() {
|
|
2571
2852
|
this.frustrationPrompt?.destroy(), this.frustrationPrompt = null;
|
|
2572
2853
|
}
|
|
2573
2854
|
enterAnnotationMode() {
|
|
2574
|
-
this.mode = "annotating", this.tab?.setActive(!0), this.toolbar = new
|
|
2855
|
+
this.mode = "annotating", this.tab?.setActive(!0), this.toolbar = new Qt(
|
|
2575
2856
|
this.shadow,
|
|
2576
2857
|
this.messages,
|
|
2577
2858
|
() => this.exitAll(),
|
|
@@ -2579,7 +2860,7 @@ class B {
|
|
|
2579
2860
|
), this.session = this.createSession();
|
|
2580
2861
|
}
|
|
2581
2862
|
createSession() {
|
|
2582
|
-
return new
|
|
2863
|
+
return new ae(this.shadow, this.messages, {
|
|
2583
2864
|
onPin: (t, e) => {
|
|
2584
2865
|
this.currentAnnotation = t, this.via = "pin", this.showPopup(t.x, t.y, e, t.targetRect);
|
|
2585
2866
|
},
|
|
@@ -2593,14 +2874,19 @@ class B {
|
|
|
2593
2874
|
}
|
|
2594
2875
|
if (t === "record") {
|
|
2595
2876
|
if (this.mode === "recording") return;
|
|
2596
|
-
this.mode = "recording", this.currentAnnotation = null, this.teardownDraw(), this.session?.destroy(), this.session = null, this.recordingManager = new
|
|
2877
|
+
this.mode = "recording", this.currentAnnotation = null, this.teardownDraw(), this.session?.destroy(), this.session = null, this.recordingManager = new fr(), this.recordingManager.start(
|
|
2878
|
+
this.shadow,
|
|
2879
|
+
this.messages,
|
|
2880
|
+
this.handleRecordStop,
|
|
2881
|
+
this.config.recording ?? {}
|
|
2882
|
+
).catch((e) => {
|
|
2597
2883
|
console.warn("[MakeThisBetter] Interaction replay unavailable, falling back to markup:", e), this.mode === "recording" && (this.toolbar?.setMode("markup"), this.handleToolbarModeChange("markup"));
|
|
2598
2884
|
});
|
|
2599
2885
|
} else
|
|
2600
2886
|
this.recordingManager?.destroy(), this.recordingManager = null, this.teardownDraw(), this.session || (this.session = this.createSession()), this.mode = "annotating";
|
|
2601
2887
|
}
|
|
2602
2888
|
handleDrawStroke() {
|
|
2603
|
-
this.mode !== "drawing" && (this.mode = "drawing", this.drawBar = new
|
|
2889
|
+
this.mode !== "drawing" && (this.mode = "drawing", this.drawBar = new ce(this.shadow, {
|
|
2604
2890
|
messages: this.messages,
|
|
2605
2891
|
onUndo: () => this.handleDrawUndoRedo("undo"),
|
|
2606
2892
|
onRedo: () => this.handleDrawUndoRedo("redo"),
|
|
@@ -2629,7 +2915,7 @@ class B {
|
|
|
2629
2915
|
this.currentAnnotation = e, this.via = "draw", this.session?.dismissInteraction(), this.submittingUi = this.drawBar, this.handleSubmit(t || this.messages.annotation.drawing);
|
|
2630
2916
|
}
|
|
2631
2917
|
showPopup(t, e, r, s) {
|
|
2632
|
-
this.mode = "popup", this.lastPopupPos = { x: t, y: e }, this.teardownDraw(), this.session?.dismissInteraction(), this.popup?.destroy(), this.popup = null, this.dim?.destroy(), this.dim = null, this.dim = new
|
|
2918
|
+
this.mode = "popup", this.lastPopupPos = { x: t, y: e }, this.teardownDraw(), this.session?.dismissInteraction(), this.popup?.destroy(), this.popup = null, this.dim?.destroy(), this.dim = null, this.dim = new Gt(this.shadow, () => this.exitAll()), this.popup = new de(this.shadow, {
|
|
2633
2919
|
targetName: r,
|
|
2634
2920
|
x: t,
|
|
2635
2921
|
y: e,
|
|
@@ -2642,29 +2928,29 @@ class B {
|
|
|
2642
2928
|
}), this.submittingUi = this.popup;
|
|
2643
2929
|
}
|
|
2644
2930
|
buildMyFeedbackHandler() {
|
|
2645
|
-
if (!this.config.user &&
|
|
2931
|
+
if (!this.config.user && Gi())
|
|
2646
2932
|
return async () => {
|
|
2647
|
-
const t = await this.apiClient.createIdentityToken(
|
|
2648
|
-
!t?.identity_token || !t.board_url || (
|
|
2933
|
+
const t = await this.apiClient.createIdentityToken(wt());
|
|
2934
|
+
!t?.identity_token || !t.board_url || (xt(t.board_url), window.open(`${t.board_url}?identity=${encodeURIComponent(t.identity_token)}`, "_blank"));
|
|
2649
2935
|
};
|
|
2650
2936
|
}
|
|
2651
2937
|
async handleSubmit(t) {
|
|
2652
2938
|
const e = this.submittingUi;
|
|
2653
2939
|
if (!e) return;
|
|
2654
2940
|
const r = ++this.submissionAttempt;
|
|
2655
|
-
e.setLoading(!0), await
|
|
2941
|
+
e.setLoading(!0), await pr();
|
|
2656
2942
|
const s = this.currentAnnotation, n = this.recordingManager?.getRecording() ?? void 0, [o, a] = await Promise.all([
|
|
2657
|
-
|
|
2658
|
-
Promise.resolve(
|
|
2659
|
-
]), l =
|
|
2943
|
+
xi(s ? [s] : []),
|
|
2944
|
+
Promise.resolve(Wi())
|
|
2945
|
+
]), l = Xi(
|
|
2660
2946
|
t,
|
|
2661
2947
|
a,
|
|
2662
2948
|
this.consoleCollector.getErrors(),
|
|
2663
2949
|
s,
|
|
2664
2950
|
this.config.user,
|
|
2665
2951
|
n,
|
|
2666
|
-
this.config.user ? void 0 :
|
|
2667
|
-
this.config.user ? void 0 :
|
|
2952
|
+
this.config.user ? void 0 : wt(),
|
|
2953
|
+
this.config.user ? void 0 : vt(),
|
|
2668
2954
|
this.breadcrumbCollector.getBreadcrumbs()
|
|
2669
2955
|
);
|
|
2670
2956
|
try {
|
|
@@ -2682,31 +2968,35 @@ class B {
|
|
|
2682
2968
|
}
|
|
2683
2969
|
async speculativeClarify(t, e, r) {
|
|
2684
2970
|
if (!t.ai_clarify_available) {
|
|
2685
|
-
const
|
|
2971
|
+
const u = this.teardownSubmittingUi(!0);
|
|
2686
2972
|
this.showClarify(t, e, {
|
|
2687
|
-
element:
|
|
2973
|
+
element: u,
|
|
2688
2974
|
preloadedResult: { messages: [], done: !0 }
|
|
2689
2975
|
});
|
|
2690
2976
|
return;
|
|
2691
2977
|
}
|
|
2692
|
-
const s =
|
|
2978
|
+
const s = new AbortController();
|
|
2979
|
+
let n = setTimeout(() => s.abort(), Ct);
|
|
2980
|
+
const o = () => {
|
|
2981
|
+
clearTimeout(n), n = setTimeout(() => s.abort(), Ct);
|
|
2982
|
+
}, a = this.apiClient.streamClarification(
|
|
2693
2983
|
t.id,
|
|
2694
2984
|
t.token,
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
).catch(() => null)
|
|
2698
|
-
(
|
|
2699
|
-
),
|
|
2985
|
+
o,
|
|
2986
|
+
s.signal
|
|
2987
|
+
).catch(() => null).finally(() => clearTimeout(n)), l = new Promise(
|
|
2988
|
+
(u) => setTimeout(() => u(null), br)
|
|
2989
|
+
), c = await Promise.race([a, l]);
|
|
2700
2990
|
if (r !== this.submissionAttempt) return;
|
|
2701
|
-
const
|
|
2702
|
-
|
|
2991
|
+
const d = this.teardownSubmittingUi(!0);
|
|
2992
|
+
c ? this.showClarify(t, e, { element: d, preloadedResult: c }) : this.showClarify(t, e, { element: d, pendingClarification: a });
|
|
2703
2993
|
}
|
|
2704
2994
|
teardownSubmittingUi(t = !1) {
|
|
2705
2995
|
const e = t ? this.popup?.releaseElement() : void 0;
|
|
2706
2996
|
return this.teardownDraw(), e || this.popup?.destroy(), this.popup = null, this.dim?.destroy(), this.dim = null, this.session?.hideHighlight(), this.session?.destroy(), this.session = null, this.recordingManager?.destroy(), this.recordingManager = null, this.submittingUi = null, e;
|
|
2707
2997
|
}
|
|
2708
2998
|
showClarify(t, e, r) {
|
|
2709
|
-
this.mode = "clarifying", this.tab?.setActive(!0), this.clarify = new
|
|
2999
|
+
this.mode = "clarifying", this.tab?.setActive(!0), this.clarify = new xe(this.shadow, {
|
|
2710
3000
|
submissionSessionId: t.id,
|
|
2711
3001
|
submissionToken: t.token,
|
|
2712
3002
|
apiClient: this.apiClient,
|
|
@@ -2728,21 +3018,21 @@ class B {
|
|
|
2728
3018
|
feedbackId: r.id,
|
|
2729
3019
|
boardUrl: r.board_url,
|
|
2730
3020
|
identityToken: r.identity_token
|
|
2731
|
-
}, r.board_url &&
|
|
3021
|
+
}, r.board_url && xt(r.board_url), this.clarify?.destroy(), this.clarify = null, this.toolbar?.destroy(), this.toolbar = null, this.showSuccess({ skipFollowup: t.ai_clarify_available === !1 }));
|
|
2732
3022
|
}
|
|
2733
3023
|
showSuccess(t) {
|
|
2734
|
-
this.mode = "idle", this.tab?.setActive(!1), this.success = new
|
|
3024
|
+
this.mode = "idle", this.tab?.setActive(!1), this.success = new Ee(this.shadow, this.messages, () => {
|
|
2735
3025
|
this.success?.destroy(), this.success = null;
|
|
2736
3026
|
}, this.buildViewFeedbackHandler(), { ...t, emailCapture: this.buildEmailCapture() });
|
|
2737
3027
|
}
|
|
2738
3028
|
buildEmailCapture() {
|
|
2739
3029
|
if (this.config.user) return;
|
|
2740
3030
|
const { feedbackId: t, identityToken: e } = this.lastHandoff;
|
|
2741
|
-
if (!(!t || !e) && !
|
|
3031
|
+
if (!(!t || !e) && !vt())
|
|
2742
3032
|
return {
|
|
2743
3033
|
onSubmit: async (r) => {
|
|
2744
3034
|
const s = await this.apiClient.updateReporter(t, r, e);
|
|
2745
|
-
return s &&
|
|
3035
|
+
return s && Ki(r), s;
|
|
2746
3036
|
}
|
|
2747
3037
|
};
|
|
2748
3038
|
}
|
|
@@ -2770,24 +3060,28 @@ class B {
|
|
|
2770
3060
|
document.removeEventListener("keydown", this.handleKeydown, !0), this.exitAll(), this.consoleCollector.stop(), this.breadcrumbCollector.stop(), this.frustrationDetector?.stop(), this.dismissFrustrationPrompt(), this.clarify?.destroy(), this.success?.destroy(), this.tab?.destroy(), this.recordingManager?.destroy(), this.shadow.destroy();
|
|
2771
3061
|
}
|
|
2772
3062
|
}
|
|
2773
|
-
function
|
|
3063
|
+
function pr() {
|
|
2774
3064
|
return new Promise((i) => requestAnimationFrame(() => setTimeout(i, 0)));
|
|
2775
3065
|
}
|
|
2776
|
-
let w = null,
|
|
2777
|
-
const
|
|
3066
|
+
let w = null, E = null;
|
|
3067
|
+
const gr = {
|
|
2778
3068
|
init(i) {
|
|
2779
|
-
w && (w.destroy(), w = null),
|
|
2780
|
-
w = new
|
|
2781
|
-
}) : w = new
|
|
3069
|
+
w && (w.destroy(), w = null), E = i, document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", () => {
|
|
3070
|
+
w = new K(i);
|
|
3071
|
+
}) : w = new K(i);
|
|
2782
3072
|
},
|
|
2783
3073
|
destroy() {
|
|
2784
|
-
w?.destroy(), w = null,
|
|
3074
|
+
w?.destroy(), w = null, E = null;
|
|
3075
|
+
},
|
|
3076
|
+
setLocale(i) {
|
|
3077
|
+
E && (E.locale = i), w?.setLocale(i);
|
|
2785
3078
|
}
|
|
2786
3079
|
};
|
|
2787
|
-
typeof window < "u" && (window.MakeThisBetter =
|
|
2788
|
-
|
|
3080
|
+
typeof window < "u" && (window.MakeThisBetter = gr, document.addEventListener("turbo:load", () => {
|
|
3081
|
+
const i = document.getElementById("mtb-widget-host");
|
|
3082
|
+
E && (!i || !i.shadowRoot) && (w?.destroy(), i?.remove(), w = new K(E));
|
|
2789
3083
|
}));
|
|
2790
3084
|
export {
|
|
2791
|
-
|
|
3085
|
+
gr as MakeThisBetter
|
|
2792
3086
|
};
|
|
2793
3087
|
//# sourceMappingURL=makethisbetter.esm.js.map
|