makethisbetter 1.0.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +329 -62
  3. package/dist/annotate/session.d.ts +5 -0
  4. package/dist/annotate/session.d.ts.map +1 -1
  5. package/dist/api/client.d.ts +9 -3
  6. package/dist/api/client.d.ts.map +1 -1
  7. package/dist/context/error-source.d.ts +1 -0
  8. package/dist/context/error-source.d.ts.map +1 -1
  9. package/dist/context/frustration.d.ts +25 -1
  10. package/dist/context/frustration.d.ts.map +1 -1
  11. package/dist/i18n/de.d.ts +54 -0
  12. package/dist/i18n/de.d.ts.map +1 -0
  13. package/dist/i18n/en.d.ts +7 -0
  14. package/dist/i18n/en.d.ts.map +1 -1
  15. package/dist/i18n/es.d.ts +54 -0
  16. package/dist/i18n/es.d.ts.map +1 -0
  17. package/dist/i18n/fr.d.ts +54 -0
  18. package/dist/i18n/fr.d.ts.map +1 -0
  19. package/dist/i18n/index.d.ts.map +1 -1
  20. package/dist/i18n/ja.d.ts +54 -0
  21. package/dist/i18n/ja.d.ts.map +1 -0
  22. package/dist/i18n/ko.d.ts +54 -0
  23. package/dist/i18n/ko.d.ts.map +1 -0
  24. package/dist/i18n/zh-CN.d.ts +7 -0
  25. package/dist/i18n/zh-CN.d.ts.map +1 -1
  26. package/dist/makethisbetter.cjs.js +42 -27
  27. package/dist/makethisbetter.cjs.js.map +1 -1
  28. package/dist/makethisbetter.esm.js +1208 -636
  29. package/dist/makethisbetter.esm.js.map +1 -1
  30. package/dist/makethisbetter.js +42 -27
  31. package/dist/makethisbetter.js.map +1 -1
  32. package/dist/popup/clarify.d.ts +37 -0
  33. package/dist/popup/clarify.d.ts.map +1 -0
  34. package/dist/popup/clarify.test.d.ts +2 -0
  35. package/dist/popup/clarify.test.d.ts.map +1 -0
  36. package/dist/popup/success.d.ts +1 -1
  37. package/dist/popup/success.d.ts.map +1 -1
  38. package/dist/record/session.d.ts.map +1 -1
  39. package/dist/types.d.ts +17 -0
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/widget/controller.d.ts +3 -6
  42. package/dist/widget/controller.d.ts.map +1 -1
  43. package/dist/widget/recording-manager.d.ts +15 -0
  44. package/dist/widget/recording-manager.d.ts.map +1 -0
  45. package/dist/widget/recording-manager.test.d.ts +2 -0
  46. package/dist/widget/recording-manager.test.d.ts.map +1 -0
  47. package/dist/widget/tab.d.ts +1 -1
  48. package/dist/widget/tab.d.ts.map +1 -1
  49. package/package.json +13 -3
  50. package/src/annotate/session.test.ts +117 -5
  51. package/src/annotate/session.ts +27 -8
  52. package/src/api/client.test.ts +144 -4
  53. package/src/api/client.ts +56 -5
  54. package/src/context/error-source.test.ts +13 -0
  55. package/src/context/error-source.ts +9 -2
  56. package/src/context/frustration.test.ts +336 -1
  57. package/src/context/frustration.ts +237 -1
  58. package/src/i18n/de.ts +54 -0
  59. package/src/i18n/en.ts +7 -0
  60. package/src/i18n/es.ts +54 -0
  61. package/src/i18n/fr.ts +54 -0
  62. package/src/i18n/index.test.ts +1 -1
  63. package/src/i18n/index.ts +10 -0
  64. package/src/i18n/ja.ts +54 -0
  65. package/src/i18n/ko.ts +54 -0
  66. package/src/i18n/zh-CN.ts +7 -0
  67. package/src/popup/clarify.test.ts +419 -0
  68. package/src/popup/clarify.ts +215 -0
  69. package/src/popup/success.ts +11 -1
  70. package/src/record/session.ts +8 -1
  71. package/src/styles/widget.css +218 -0
  72. package/src/types.ts +20 -0
  73. package/src/widget/controller.test.ts +6 -4
  74. package/src/widget/controller.ts +59 -52
  75. package/src/widget/recording-manager.test.ts +136 -0
  76. package/src/widget/recording-manager.ts +51 -0
  77. package/src/widget/tab.ts +4 -2
@@ -1,28 +1,30 @@
1
- const et = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,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 #05966980}.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}.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-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%);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}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-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;width:320px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:14px;box-shadow:0 12px 40px #00000029;overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-popup-header{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{padding:13px}.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:9px;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 #10b9811f}.mtb-textarea::placeholder{color:#00000057}.mtb-popup-error{margin-top:8px;color:#b91c1c;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:30px;border:none;border-radius:7px;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0 12px;font-family:inherit;font-size:12px;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:300px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 20px 60px #0000001f;padding:26px 22px;text-align:center;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.mtb-success-icon{width:44px;height:44px;border-radius:50%;background:#05966914;display:flex;align-items:center;justify-content:center;margin:0 auto 12px}.mtb-success-title{font-size:16px;font-weight:700;margin-bottom:6px;color:#191a1c}.mtb-success-msg{font-size:13px;color:#0000008c;margin-bottom:16px;line-height:1.6}.mtb-close-link{background:none;border:none;cursor:pointer;font-size:12px;color:#00000073;font-family:inherit;transition:color .12s}.mtb-close-link:hover{color:#000000b3}.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:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,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:24px;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)}}';
2
- class it {
1
+ const st = '*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,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 #05966980}.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}.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-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%);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}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-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;width:320px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:14px;box-shadow:0 12px 40px #00000029;overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-popup-header{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{padding:13px}.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:9px;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 #10b9811f}.mtb-textarea::placeholder{color:#00000057}.mtb-popup-error{margin-top:8px;color:#b91c1c;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:30px;border:none;border-radius:7px;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0 12px;font-family:inherit;font-size:12px;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:300px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 20px 60px #0000001f;padding:26px 22px;text-align:center;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.mtb-success-icon{width:44px;height:44px;border-radius:50%;background:#05966914;display:flex;align-items:center;justify-content:center;margin:0 auto 12px}.mtb-success-title{font-size:16px;font-weight:700;margin-bottom:6px;color:#191a1c}.mtb-success-msg{font-size:13px;color:#0000008c;margin-bottom:16px;line-height:1.6}.mtb-close-link{background:none;border:none;cursor:pointer;font-size:12px;color:#00000073;font-family:inherit;transition:color .12s}.mtb-close-link:hover{color:#000000b3}.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:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,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:24px;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:320px;background:#fff;border:1px solid rgba(0,0,0,.1);border-radius:16px;box-shadow:0 20px 60px #0000001f;display:flex;flex-direction:column;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;overflow:hidden}.mtb-clarify-header{padding:10px 13px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid rgba(0,0,0,.06)}.mtb-clarify-icon{width:26px;height:26px;border-radius:50%;background:#05966914;display:flex;align-items:center;justify-content:center;flex-shrink:0}.mtb-clarify-skip{background:none;border:none;cursor:pointer;font-size:12px;color:#00000073;font-family:inherit;transition:color .12s}.mtb-clarify-skip:hover{color:#000000b3}.mtb-clarify-messages{flex:1;max-height:240px;overflow-y:auto;padding:12px 13px;display:flex;flex-direction:column;gap:8px}.mtb-clarify-bubble{max-width:85%;padding:8px 12px;border-radius:12px;font-size:13px;line-height:1.5;word-wrap:break-word}.mtb-clarify-ai{align-self:flex-start;background:#f3f4f6;color:#191a1c;border-bottom-left-radius:4px}.mtb-clarify-user{align-self:flex-end;background:#059669;color:#fff;border-bottom-right-radius:4px}.mtb-clarify-thinking{display:flex;align-items:center;gap:3px;padding:10px 16px}.mtb-clarify-thinking .mtb-dot{background:#9ca3af}.mtb-clarify-footer{padding:10px 13px;border-top:1px solid rgba(0,0,0,.06);display:flex;gap:8px}.mtb-clarify-input{flex:1;height:32px;padding:0 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:12.5px;color:#191a1c;outline:none;background:#fff;transition:border-color .12s,box-shadow .12s}.mtb-clarify-input:focus{border-color:#10b981;box-shadow:0 0 0 3px #10b9811f}.mtb-clarify-input::placeholder{color:#00000057}.mtb-clarify-send{height:32px;padding:0 14px;border:none;border-radius:8px;background:#d1d5db;color:#fff;cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s;flex-shrink:0}.mtb-clarify-send:not(:disabled){background:#059669}.mtb-clarify-send:not(:disabled):hover{background:#047857}.mtb-clarify-send:disabled{cursor:not-allowed}: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-footer{border-top-color:#ffffff1a}:host([data-mtb-theme="dark"]) .mtb-clarify-skip{color:#ffffff73}:host([data-mtb-theme="dark"]) .mtb-clarify-skip:hover{color:#ffffffb3}:host([data-mtb-theme="dark"]) .mtb-clarify-ai{background:#1f2327;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-footer{border-top-color:#ffffff1a}:host([data-mtb-theme="auto"]) .mtb-clarify-skip{color:#ffffff73}:host([data-mtb-theme="auto"]) .mtb-clarify-skip:hover{color:#ffffffb3}:host([data-mtb-theme="auto"]) .mtb-clarify-ai{background:#1f2327;color:#f9fafb}:host([data-mtb-theme="auto"]) .mtb-clarify-input{background:#1f2327;border-color:#ffffff1f;color:#f9fafb}}';
2
+ class rt {
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
- const i = document.createElement("style");
6
- i.textContent = et, this.root.appendChild(i);
5
+ const e = document.createElement("style");
6
+ e.textContent = st, this.root.appendChild(e);
7
7
  }
8
- el(t, i) {
9
- const r = document.createElement(t);
10
- return i && (r.className = i), r;
8
+ el(t, e) {
9
+ const s = document.createElement(t);
10
+ return e && (s.className = e), s;
11
11
  }
12
12
  append(...t) {
13
- for (const i of t) this.root.appendChild(i);
13
+ for (const e of t) this.root.appendChild(e);
14
14
  }
15
15
  remove(...t) {
16
- for (const i of t)
17
- i.parentNode === this.root && this.root.removeChild(i);
16
+ for (const e of t)
17
+ e.parentNode === this.root && this.root.removeChild(e);
18
18
  }
19
19
  destroy() {
20
20
  document.body.removeChild(this.host);
21
21
  }
22
22
  }
23
- class rt {
24
- constructor(t, i, r, s) {
25
- this.onClick = s, this.el = t.el("button", "mtb-tab"), r === "left" && this.el.classList.add("left"), this.el.textContent = i.tab, this.el.setAttribute("aria-label", i.tab), this.el.addEventListener("click", s), t.append(this.el);
23
+ class nt {
24
+ constructor(t, e, s, r, n) {
25
+ this.onClick = r, this.el = t.el("button", "mtb-tab"), s === "left" && this.el.classList.add("left");
26
+ const o = n ?? e.tab;
27
+ this.el.textContent = o, this.el.setAttribute("aria-label", o), this.el.addEventListener("click", r), t.append(this.el);
26
28
  }
27
29
  setActive(t) {
28
30
  this.el.classList.toggle("active", t);
@@ -31,22 +33,22 @@ class rt {
31
33
  this.el.removeEventListener("click", this.onClick), this.el.remove();
32
34
  }
33
35
  }
34
- const y = "#059669", x = {
35
- color: y,
36
+ const x = "#059669", w = {
37
+ color: x,
36
38
  width: "3.5",
37
39
  linecap: "round",
38
40
  linejoin: "round",
39
41
  filter: "drop-shadow(0 1px 2px rgba(5,150,105,0.35))"
40
42
  };
41
- class st {
42
- constructor(t, i, r) {
43
- this.onClick = r, this.el = t.el("div", "mtb-pet"), this.el.innerHTML = this.buildSVG(), this.el.setAttribute("role", "button"), this.el.setAttribute("aria-label", i.tab), this.el.tabIndex = 0, this.bubble = t.el("div", "mtb-pet-bubble"), this.bubble.textContent = i.pet.bubble, this.el.appendChild(this.bubble), this.el.addEventListener("click", this.onClick), this.el.addEventListener("keydown", (s) => {
44
- (s.key === "Enter" || s.key === " ") && (s.preventDefault(), this.onClick());
43
+ class ot {
44
+ constructor(t, e, s) {
45
+ this.onClick = s, this.el = t.el("div", "mtb-pet"), this.el.innerHTML = this.buildSVG(), this.el.setAttribute("role", "button"), this.el.setAttribute("aria-label", e.tab), this.el.tabIndex = 0, this.bubble = t.el("div", "mtb-pet-bubble"), this.bubble.textContent = e.pet.bubble, this.el.appendChild(this.bubble), this.el.addEventListener("click", this.onClick), this.el.addEventListener("keydown", (r) => {
46
+ (r.key === "Enter" || r.key === " ") && (r.preventDefault(), this.onClick());
45
47
  }), t.append(this.el);
46
48
  }
47
49
  buildSVG() {
48
50
  return `<svg class="mtb-pet-svg" width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
49
- <circle cx="24" cy="28" r="16" fill="${y}"/>
51
+ <circle cx="24" cy="28" r="16" fill="${x}"/>
50
52
  <circle cx="24" cy="28" r="14" fill="#10b981"/>
51
53
  <circle cx="19" cy="25" r="3" fill="#fff"/>
52
54
  <circle cx="29" cy="25" r="3" fill="#fff"/>
@@ -55,8 +57,8 @@ class st {
55
57
  <ellipse cx="19.5" cy="23.5" rx="0.8" ry="0.6" fill="#fff" opacity="0.7"/>
56
58
  <ellipse cx="29.5" cy="23.5" rx="0.8" ry="0.6" fill="#fff" opacity="0.7"/>
57
59
  <path d="M20 31 Q24 34 28 31" stroke="#064e3b" stroke-width="1.5" stroke-linecap="round" fill="none"/>
58
- <circle cx="15" cy="30" r="2.5" fill="${y}" opacity="0.4"/>
59
- <circle cx="33" cy="30" r="2.5" fill="${y}" opacity="0.4"/>
60
+ <circle cx="15" cy="30" r="2.5" fill="${x}" opacity="0.4"/>
61
+ <circle cx="33" cy="30" r="2.5" fill="${x}" opacity="0.4"/>
60
62
  <path d="M14 17 Q16 12 20 15" stroke="#10b981" stroke-width="2" stroke-linecap="round" fill="none"/>
61
63
  <path d="M34 17 Q32 12 28 15" stroke="#10b981" stroke-width="2" stroke-linecap="round" fill="none"/>
62
64
  </svg>`;
@@ -68,29 +70,29 @@ class st {
68
70
  this.el.removeEventListener("click", this.onClick), this.el.remove();
69
71
  }
70
72
  }
71
- const nt = 8e3;
72
- class ot {
73
- constructor(t, i, r) {
73
+ const at = 8e3;
74
+ class lt {
75
+ constructor(t, e, s) {
74
76
  this.el = t.el("div", "mtb-frustration-prompt"), this.el.innerHTML = `
75
77
  <div class="mtb-frustration-icon">&#9888;&#65039;</div>
76
- <span class="mtb-frustration-text">${i.frustration.prompt}</span>
78
+ <span class="mtb-frustration-text">${e.frustration.prompt}</span>
77
79
  <div class="mtb-frustration-actions">
78
- <button class="mtb-frustration-tell">${i.frustration.action}</button>
79
- <button class="mtb-frustration-dismiss">${i.frustration.dismiss}</button>
80
+ <button class="mtb-frustration-tell">${e.frustration.action}</button>
81
+ <button class="mtb-frustration-dismiss">${e.frustration.dismiss}</button>
80
82
  </div>
81
- `, 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.onDismiss, nt);
83
+ `, this.el.querySelector(".mtb-frustration-tell").addEventListener("click", s.onTell), this.el.querySelector(".mtb-frustration-dismiss").addEventListener("click", s.onDismiss), t.append(this.el), setTimeout(s.onDismiss, at);
82
84
  }
83
85
  destroy() {
84
86
  this.el.remove();
85
87
  }
86
88
  }
87
- class at {
88
- constructor(t, i, r, s) {
89
- this.currentMode = "markup", this.messages = i, this.el = t.el("div", "mtb-toolbar"), this.el.innerHTML = this.buildHTML(i), 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", () => {
90
- this.setMode("markup"), s?.("markup");
89
+ class ct {
90
+ constructor(t, e, s, r) {
91
+ this.currentMode = "markup", 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", () => {
92
+ this.setMode("markup"), r?.("markup");
91
93
  }), this.recordBtn.addEventListener("click", () => {
92
- this.setMode("record"), s?.("record");
93
- }), this.el.querySelector(".mtb-exit-btn").addEventListener("click", r);
94
+ this.setMode("record"), r?.("record");
95
+ }), this.el.querySelector(".mtb-exit-btn").addEventListener("click", s);
94
96
  }
95
97
  buildHTML(t) {
96
98
  return `
@@ -121,21 +123,21 @@ class at {
121
123
  this.el.remove();
122
124
  }
123
125
  }
124
- class lt {
125
- constructor(t, i) {
126
- this.onMouseDown = i.onMouseDown, this.onMouseMove = i.onMouseMove, this.onMouseUp = i.onMouseUp, this.onMouseLeave = i.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);
126
+ class ht {
127
+ constructor(t, e) {
128
+ 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);
127
129
  }
128
130
  destroy() {
129
131
  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();
130
132
  }
131
133
  }
132
- class ct {
134
+ class dt {
133
135
  constructor(t) {
134
136
  this.highlightEl = t.el("div", "mtb-highlight"), this.hide(), t.append(this.highlightEl);
135
137
  }
136
138
  highlight(t) {
137
- const i = t.getBoundingClientRect();
138
- this.highlightEl.style.top = `${i.top - 2}px`, this.highlightEl.style.left = `${i.left - 2}px`, this.highlightEl.style.width = `${i.width + 4}px`, this.highlightEl.style.height = `${i.height + 4}px`, this.highlightEl.style.display = "block";
139
+ const e = t.getBoundingClientRect();
140
+ 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";
139
141
  }
140
142
  hide() {
141
143
  this.highlightEl.style.display = "none";
@@ -144,55 +146,55 @@ class ct {
144
146
  this.highlightEl.remove();
145
147
  }
146
148
  }
147
- function ht(e) {
148
- if (e instanceof HTMLElement) {
149
- const t = e.getAttribute("aria-label");
149
+ function ut(i) {
150
+ if (i instanceof HTMLElement) {
151
+ const t = i.getAttribute("aria-label");
150
152
  if (t) return t;
151
- const i = e.getAttribute("title");
152
- if (i) return i;
153
- const r = e.textContent?.trim().slice(0, 40);
154
- if (r) return r;
155
- const s = e.placeholder;
153
+ const e = i.getAttribute("title");
154
+ if (e) return e;
155
+ const s = i.textContent?.trim().slice(0, 40);
156
156
  if (s) return s;
157
- const n = e.alt;
157
+ const r = i.placeholder;
158
+ if (r) return r;
159
+ const n = i.alt;
158
160
  if (n) return n;
159
- const o = e.getAttribute("data-mark");
161
+ const o = i.getAttribute("data-mark");
160
162
  if (o) return o;
161
163
  }
162
- return e.tagName.toLowerCase();
164
+ return i.tagName.toLowerCase();
163
165
  }
164
- function dt(e) {
166
+ function pt(i) {
165
167
  const t = [];
166
- let i = e;
167
- for (; i && i !== document.body && t.length < 5; ) {
168
- let r = i.tagName.toLowerCase();
169
- if (i.id) {
170
- r = `#${i.id}`, t.unshift(r);
168
+ let e = i;
169
+ for (; e && e !== document.body && t.length < 5; ) {
170
+ let s = e.tagName.toLowerCase();
171
+ if (e.id) {
172
+ s = `#${e.id}`, t.unshift(s);
171
173
  break;
172
174
  }
173
- const s = Array.from(i.classList).filter((o) => !o.startsWith("mtb-")).slice(0, 2).join(".");
174
- s && (r += `.${s}`);
175
- const n = i.parentElement;
175
+ const r = Array.from(e.classList).filter((o) => !o.startsWith("mtb-")).slice(0, 2).join(".");
176
+ r && (s += `.${r}`);
177
+ const n = e.parentElement;
176
178
  if (n) {
177
179
  const o = Array.from(n.children).filter(
178
- (a) => a.tagName === i.tagName
180
+ (a) => a.tagName === e.tagName
179
181
  );
180
182
  if (o.length > 1) {
181
- const a = o.indexOf(i) + 1;
182
- r += `:nth-child(${a})`;
183
+ const a = o.indexOf(e) + 1;
184
+ s += `:nth-child(${a})`;
183
185
  }
184
186
  }
185
- t.unshift(r), i = i.parentElement;
187
+ t.unshift(s), e = e.parentElement;
186
188
  }
187
189
  return t.join(" > ");
188
190
  }
189
- class ut {
191
+ class ft {
190
192
  constructor(t) {
191
193
  this.pins = [], this.shadow = t;
192
194
  }
193
- addPin(t, i, r) {
194
- const s = this.shadow.el("div", "mtb-pin");
195
- s.textContent = String(r), s.style.top = `${i}px`, s.style.left = `${t}px`, this.shadow.append(s), this.pins.push(s);
195
+ addPin(t, e, s) {
196
+ const r = this.shadow.el("div", "mtb-pin");
197
+ r.textContent = String(s), r.style.top = `${e}px`, r.style.left = `${t}px`, this.shadow.append(r), this.pins.push(r);
196
198
  }
197
199
  clearAll() {
198
200
  for (const t of this.pins) t.remove();
@@ -202,15 +204,15 @@ class ut {
202
204
  this.clearAll();
203
205
  }
204
206
  }
205
- class pt {
206
- constructor(t, i) {
207
- this.path = null, this.points = [], this.isDrawing = !1, this.onDrawComplete = i, this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.setAttribute("class", "mtb-draw-svg"), t.append(this.svg);
207
+ class mt {
208
+ constructor(t, e) {
209
+ this.path = null, this.points = [], this.isDrawing = !1, this.onDrawComplete = e, this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.setAttribute("class", "mtb-draw-svg"), t.append(this.svg);
208
210
  }
209
- startDraw(t, i) {
210
- this.isDrawing = !0, this.points = [[t, i]], this.path = document.createElementNS("http://www.w3.org/2000/svg", "path"), this.path.setAttribute("fill", "none"), this.path.setAttribute("stroke", x.color), this.path.setAttribute("stroke-width", x.width), this.path.setAttribute("stroke-linecap", x.linecap), this.path.setAttribute("stroke-linejoin", x.linejoin), this.path.setAttribute("style", `filter:${x.filter}`), this.svg.appendChild(this.path);
211
+ startDraw(t, e) {
212
+ this.isDrawing = !0, this.points = [[t, e]], this.path = document.createElementNS("http://www.w3.org/2000/svg", "path"), this.path.setAttribute("fill", "none"), this.path.setAttribute("stroke", w.color), this.path.setAttribute("stroke-width", w.width), this.path.setAttribute("stroke-linecap", w.linecap), this.path.setAttribute("stroke-linejoin", w.linejoin), this.path.setAttribute("style", `filter:${w.filter}`), this.svg.appendChild(this.path);
211
213
  }
212
- continueDraw(t, i) {
213
- !this.isDrawing || !this.path || (this.points.push([t, i]), this.path.setAttribute("d", this.buildPathD()));
214
+ continueDraw(t, e) {
215
+ !this.isDrawing || !this.path || (this.points.push([t, e]), this.path.setAttribute("d", this.buildPathD()));
214
216
  }
215
217
  endDraw() {
216
218
  if (!this.isDrawing || this.points.length < 2) {
@@ -218,27 +220,27 @@ class pt {
218
220
  return;
219
221
  }
220
222
  this.isDrawing = !1;
221
- const t = this.getCenter(), i = this.buildPathD(), r = {
223
+ const t = this.getCenter(), e = this.buildPathD(), s = {
222
224
  type: "draw",
223
225
  x: t[0],
224
226
  y: t[1],
225
- drawPath: i
227
+ drawPath: e
226
228
  };
227
- this.onDrawComplete(r);
229
+ this.onDrawComplete(s);
228
230
  }
229
231
  buildPathD() {
230
232
  if (this.points.length === 0) return "";
231
- const [t, i] = this.points[0];
232
- let r = `M ${t} ${i}`;
233
- for (let s = 1; s < this.points.length; s++) {
234
- const [n, o] = this.points[s];
235
- r += ` L ${n} ${o}`;
233
+ const [t, e] = this.points[0];
234
+ let s = `M ${t} ${e}`;
235
+ for (let r = 1; r < this.points.length; r++) {
236
+ const [n, o] = this.points[r];
237
+ s += ` L ${n} ${o}`;
236
238
  }
237
- return r;
239
+ return s;
238
240
  }
239
241
  getCenter() {
240
- const t = this.points.map((n) => n[0]), i = this.points.map((n) => n[1]), r = (Math.min(...t) + Math.max(...t)) / 2, s = (Math.min(...i) + Math.max(...i)) / 2;
241
- return [r, s];
242
+ const t = this.points.map((n) => n[0]), e = this.points.map((n) => n[1]), s = (Math.min(...t) + Math.max(...t)) / 2, r = (Math.min(...e) + Math.max(...e)) / 2;
243
+ return [s, r];
242
244
  }
243
245
  clearAll() {
244
246
  for (; this.svg.firstChild; ) this.svg.removeChild(this.svg.firstChild);
@@ -257,17 +259,17 @@ class pt {
257
259
  this.svg.remove();
258
260
  }
259
261
  }
260
- const ft = 5;
261
- class P {
262
- constructor(t, i, r) {
263
- this.messages = i, this.onReady = r, this.pinCount = 0, this.interactionActive = !0, this.highlighter = new ct(t), this.pinMarker = new ut(t), this.drawLayer = new pt(t, (s) => {
264
- this.onReady(s, this.messages.annotation.drawing);
265
- }), this.overlay = new lt(t, {
266
- onMouseDown: (s) => this.handleMouseDown(s),
267
- onMouseMove: (s) => this.handleMouseMove(s),
268
- onMouseUp: (s) => this.handleMouseUp(s),
262
+ const bt = 5;
263
+ class H {
264
+ constructor(t, e, s) {
265
+ this.messages = e, this.onReady = s, this.pinCount = 0, this.interactionActive = !0, this.pendingHighlightFrame = null, this.lastMoveX = 0, this.lastMoveY = 0, this.highlighter = new dt(t), this.pinMarker = new ft(t), this.drawLayer = new mt(t, (r) => {
266
+ this.onReady(r, this.messages.annotation.drawing);
267
+ }), this.overlay = new ht(t, {
268
+ onMouseDown: (r) => this.handleMouseDown(r),
269
+ onMouseMove: (r) => this.handleMouseMove(r),
270
+ onMouseUp: (r) => this.handleMouseUp(r),
269
271
  onMouseLeave: () => {
270
- this.drawLayer.isCurrentlyDrawing() && this.drawLayer.endDraw(), this.highlighter.hide();
272
+ this.drawLayer.isCurrentlyDrawing() && this.drawLayer.endDraw(), this.cancelPendingHighlight(), this.highlighter.hide();
271
273
  }
272
274
  });
273
275
  }
@@ -276,52 +278,58 @@ class P {
276
278
  }
277
279
  handleMouseMove(t) {
278
280
  if (this.drawLayer.isCurrentlyDrawing()) {
279
- this.drawLayer.continueDraw(t.clientX, t.clientY), this.highlighter.hide();
281
+ this.cancelPendingHighlight(), this.drawLayer.continueDraw(t.clientX, t.clientY), this.highlighter.hide();
280
282
  return;
281
283
  }
282
- const i = D(t.clientX, t.clientY);
283
- i ? this.highlighter.highlight(i) : this.highlighter.hide();
284
+ this.lastMoveX = t.clientX, this.lastMoveY = t.clientY, this.pendingHighlightFrame === null && (this.pendingHighlightFrame = requestAnimationFrame(() => {
285
+ this.pendingHighlightFrame = null, this.updateHighlight();
286
+ }));
287
+ }
288
+ updateHighlight() {
289
+ if (!this.interactionActive || this.drawLayer.isCurrentlyDrawing()) return;
290
+ const t = $(this.lastMoveX, this.lastMoveY);
291
+ t ? this.highlighter.highlight(t) : this.highlighter.hide();
292
+ }
293
+ cancelPendingHighlight() {
294
+ this.pendingHighlightFrame !== null && (cancelAnimationFrame(this.pendingHighlightFrame), this.pendingHighlightFrame = null);
284
295
  }
285
296
  handleMouseUp(t) {
286
297
  if (!this.drawLayer.isCurrentlyDrawing()) return;
287
- if (this.drawLayer.getPointCount() >= ft) {
298
+ if (this.drawLayer.getPointCount() >= bt) {
288
299
  this.drawLayer.endDraw();
289
300
  return;
290
301
  }
291
302
  this.drawLayer.cancelCurrentDraw();
292
- const i = D(t.clientX, t.clientY), r = i ? ht(i) : this.messages.annotation.element, s = {
303
+ const e = $(t.clientX, t.clientY), s = e ? ut(e) : this.messages.annotation.element, r = {
293
304
  type: "pin",
294
305
  x: t.clientX,
295
306
  y: t.clientY,
296
- targetSelector: i ? dt(i) : void 0,
297
- targetText: i?.textContent?.trim().slice(0, 200) ?? "",
298
- targetName: r
307
+ targetSelector: e ? pt(e) : void 0,
308
+ targetText: e?.textContent?.trim().slice(0, 200) ?? "",
309
+ targetName: s
299
310
  };
300
- this.pinMarker.addPin(t.clientX, t.clientY, ++this.pinCount), this.drawLayer.clearAll(), this.highlighter.hide(), this.onReady(s, r);
311
+ this.pinMarker.addPin(t.clientX, t.clientY, ++this.pinCount), this.drawLayer.clearAll(), this.highlighter.hide(), this.onReady(r, s);
301
312
  }
302
313
  dismissInteraction() {
303
- this.interactionActive && (this.interactionActive = !1, this.overlay.destroy(), this.highlighter.destroy());
314
+ this.interactionActive && (this.interactionActive = !1, this.cancelPendingHighlight(), this.overlay.destroy(), this.highlighter.destroy());
304
315
  }
305
316
  destroy() {
306
317
  this.dismissInteraction(), this.pinMarker.destroy(), this.drawLayer.destroy();
307
318
  }
308
319
  }
309
- function D(e, t) {
310
- const i = document.getElementById("mtb-widget-host");
311
- i && (i.style.display = "none");
312
- const r = document.elementFromPoint(e, t);
313
- return i && (i.style.display = ""), r;
320
+ function $(i, t) {
321
+ return document.elementsFromPoint(i, t).find((e) => e.id !== "mtb-widget-host") ?? null;
314
322
  }
315
- class mt {
316
- constructor(t, i) {
317
- this.loading = !1, this.onSubmit = i.onSubmit, this.onClose = i.onClose, this.submitLabel = i.messages.popup.submit, this.el = t.el("div", "mtb-popup"), this.el.innerHTML = this.buildHTML(i), t.append(this.el), this.textarea = this.el.querySelector(".mtb-textarea"), this.submitBtn = this.el.querySelector(".mtb-submit-btn"), this.positionPopup(i.x, i.y), this.bindEvents(i.messages), this.textarea.focus();
323
+ class gt {
324
+ constructor(t, e) {
325
+ this.loading = !1, this.onSubmit = e.onSubmit, this.onClose = e.onClose, this.submitLabel = e.messages.popup.submit, 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), this.bindEvents(e.messages), this.textarea.focus();
318
326
  }
319
327
  buildHTML(t) {
320
- const i = t.messages, r = i.popup.quickOptions.map(
321
- (s) => `
322
- <button class="mtb-quick-option" data-quick="${m(s.label)}">
323
- <span class="mtb-quick-option-emoji">${s.emoji}</span>
324
- <span>${m(s.label)}</span>
328
+ const e = t.messages, s = e.popup.quickOptions.map(
329
+ (r) => `
330
+ <button class="mtb-quick-option" data-quick="${m(r.label)}">
331
+ <span class="mtb-quick-option-emoji">${r.emoji}</span>
332
+ <span>${m(r.label)}</span>
325
333
  </button>`
326
334
  ).join("");
327
335
  return `
@@ -331,7 +339,7 @@ class mt {
331
339
  <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"/>
332
340
  </svg>
333
341
  </div>
334
- <span class="mtb-popup-title">${i.popup.about} "${m(t.targetName)}"</span>
342
+ <span class="mtb-popup-title">${e.popup.about} "${m(t.targetName)}"</span>
335
343
  <button class="mtb-popup-close" aria-label="Close">
336
344
  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
337
345
  <path d="M18 6L6 18M6 6l12 12"/>
@@ -340,32 +348,32 @@ class mt {
340
348
  </div>
341
349
  <div class="mtb-popup-body">
342
350
  <div class="mtb-quick-options">
343
- ${r}
351
+ ${s}
344
352
  </div>
345
353
  <div class="mtb-textarea-wrap">
346
- <textarea class="mtb-textarea" placeholder="${m(i.popup.placeholder)}"></textarea>
354
+ <textarea class="mtb-textarea" placeholder="${m(e.popup.placeholder)}"></textarea>
347
355
  </div>
348
356
  <div class="mtb-popup-error" role="alert"></div>
349
357
  <div class="mtb-popup-actions">
350
- <button class="mtb-cancel-btn" type="button">${m(i.popup.cancel)}</button>
351
- <button class="mtb-submit-btn" type="button" disabled>${m(i.popup.submit)}</button>
358
+ <button class="mtb-cancel-btn" type="button">${m(e.popup.cancel)}</button>
359
+ <button class="mtb-submit-btn" type="button" disabled>${m(e.popup.submit)}</button>
352
360
  </div>
353
361
  </div>
354
362
  `;
355
363
  }
356
- positionPopup(t, i) {
364
+ positionPopup(t, e) {
357
365
  const n = window.innerWidth, o = window.innerHeight, a = 12;
358
- let l = t + 12, c = i + 12;
366
+ let l = t + 12, c = e + 12;
359
367
  l + 320 > n - a && (l = t - 320 - 12), l < a && (l = a), c + 260 > o - a && (c = o - 260 - a), c < a && (c = a), this.el.style.left = `${l}px`, this.el.style.top = `${c}px`;
360
368
  }
361
369
  bindEvents(t) {
362
- 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((i) => {
363
- i.addEventListener("click", () => {
364
- const r = i.dataset.quick ?? "";
365
- this.textarea.value = r, this.updateSubmitState(), this.textarea.focus();
370
+ 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) => {
371
+ e.addEventListener("click", () => {
372
+ const s = e.dataset.quick ?? "";
373
+ this.textarea.value = s, this.updateSubmitState(), this.textarea.focus();
366
374
  });
367
- }), this.textarea.addEventListener("input", () => this.updateSubmitState()), this.textarea.addEventListener("keydown", (i) => {
368
- i.key === "Enter" && (i.metaKey || i.ctrlKey) && (i.preventDefault(), this.submit());
375
+ }), this.textarea.addEventListener("input", () => this.updateSubmitState()), this.textarea.addEventListener("keydown", (e) => {
376
+ e.key === "Enter" && (e.metaKey || e.ctrlKey) && (e.preventDefault(), this.submit());
369
377
  }), this.submitBtn.addEventListener("click", () => this.submit());
370
378
  }
371
379
  updateSubmitState() {
@@ -386,405 +394,509 @@ class mt {
386
394
  this.el.remove();
387
395
  }
388
396
  }
389
- function m(e) {
390
- return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
397
+ function m(i) {
398
+ return i.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
391
399
  }
392
- const bt = 5e3;
393
- class gt {
394
- constructor(t, i, r) {
395
- this.el = t.el("div", "mtb-success"), this.el.style.right = "20px", this.el.style.bottom = "20px", this.el.innerHTML = `
400
+ const yt = 2e3, xt = 2e3;
401
+ class wt {
402
+ constructor(t, e) {
403
+ this.pollTimer = null, this.doneTimer = null, this.sending = !1, this.destroyed = !1, this.feedbackId = e.feedbackId, this.apiClient = e.apiClient, this.onDone = e.onDone, this.el = t.el("div", "mtb-clarify"), this.el.style.right = "20px", this.el.style.bottom = "20px", this.el.innerHTML = this.buildHTML(e.messages), t.append(this.el), this.messagesEl = this.el.querySelector(".mtb-clarify-messages"), this.inputEl = this.el.querySelector(".mtb-clarify-input"), this.sendBtn = this.el.querySelector(".mtb-clarify-send"), this.bindEvents(e.messages), this.startConversation();
404
+ }
405
+ buildHTML(t) {
406
+ return `
407
+ <div class="mtb-clarify-header">
408
+ <div class="mtb-clarify-icon">
409
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${x}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
410
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
411
+ </svg>
412
+ </div>
413
+ <button class="mtb-clarify-skip">${T(t.clarify.skip)}</button>
414
+ </div>
415
+ <div class="mtb-clarify-messages"></div>
416
+ <div class="mtb-clarify-footer">
417
+ <input class="mtb-clarify-input" type="text" placeholder="${T(t.clarify.placeholder)}" />
418
+ <button class="mtb-clarify-send" disabled>${T(t.clarify.send)}</button>
419
+ </div>
420
+ `;
421
+ }
422
+ bindEvents(t) {
423
+ this.el.querySelector(".mtb-clarify-skip").addEventListener("click", () => {
424
+ this.stopPolling(), this.onDone();
425
+ }), this.inputEl.addEventListener("input", () => {
426
+ const e = this.inputEl.value.trim().length > 0;
427
+ this.sendBtn.disabled = !e || this.sending;
428
+ }), this.inputEl.addEventListener("keydown", (e) => {
429
+ e.key === "Enter" && (e.preventDefault(), this.sendMessage(t));
430
+ }), this.sendBtn.addEventListener("click", () => this.sendMessage(t));
431
+ }
432
+ async startConversation() {
433
+ this.showThinking();
434
+ try {
435
+ const t = await this.apiClient.startClarification(this.feedbackId);
436
+ if (this.destroyed) return;
437
+ this.renderMessages(t.messages), t.done ? this.handleDone() : this.startPolling();
438
+ } catch {
439
+ if (this.destroyed) return;
440
+ this.onDone();
441
+ }
442
+ }
443
+ async sendMessage(t) {
444
+ const e = this.inputEl.value.trim();
445
+ if (!(!e || this.sending)) {
446
+ this.sending = !0, this.inputEl.disabled = !0, this.sendBtn.disabled = !0, this.stopPolling(), this.appendMessage({ role: "user", content: e }), this.inputEl.value = "", this.showThinking();
447
+ try {
448
+ const s = await this.apiClient.startClarification(this.feedbackId, e);
449
+ if (this.destroyed) return;
450
+ this.renderMessages(s.messages), s.done ? this.handleDone() : this.startPolling();
451
+ } catch {
452
+ if (this.destroyed) return;
453
+ this.onDone();
454
+ } finally {
455
+ this.sending = !1, this.inputEl.disabled = !1, this.sendBtn.disabled = this.inputEl.value.trim().length === 0, this.inputEl.focus();
456
+ }
457
+ }
458
+ }
459
+ startPolling() {
460
+ this.stopPolling(), this.pollTimer = setInterval(() => this.poll(), yt);
461
+ }
462
+ stopPolling() {
463
+ this.pollTimer !== null && (clearInterval(this.pollTimer), this.pollTimer = null);
464
+ }
465
+ async poll() {
466
+ try {
467
+ const t = await this.apiClient.getClarification(this.feedbackId);
468
+ if (this.destroyed) return;
469
+ this.renderMessages(t.messages), t.done && (this.stopPolling(), this.handleDone());
470
+ } catch {
471
+ if (this.destroyed) return;
472
+ this.stopPolling();
473
+ }
474
+ }
475
+ handleDone() {
476
+ this.inputEl.disabled = !0, this.sendBtn.disabled = !0, this.doneTimer = setTimeout(() => {
477
+ this.destroyed || this.onDone();
478
+ }, xt);
479
+ }
480
+ renderMessages(t) {
481
+ this.messagesEl.innerHTML = "";
482
+ for (const e of t)
483
+ this.appendMessage(e);
484
+ this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
485
+ }
486
+ appendMessage(t) {
487
+ const e = document.createElement("div");
488
+ e.className = t.role === "user" ? "mtb-clarify-bubble mtb-clarify-user" : "mtb-clarify-bubble mtb-clarify-ai", e.textContent = t.content, this.messagesEl.appendChild(e), this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
489
+ }
490
+ showThinking() {
491
+ const t = document.createElement("div");
492
+ t.className = "mtb-clarify-bubble mtb-clarify-ai mtb-clarify-thinking", t.innerHTML = '<span class="mtb-dot"></span><span class="mtb-dot"></span><span class="mtb-dot"></span>', this.messagesEl.appendChild(t), this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
493
+ }
494
+ destroy() {
495
+ this.destroyed = !0, this.stopPolling(), this.doneTimer !== null && (clearTimeout(this.doneTimer), this.doneTimer = null), this.el.remove();
496
+ }
497
+ }
498
+ function T(i) {
499
+ return i.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
500
+ }
501
+ const kt = 5e3;
502
+ class vt {
503
+ constructor(t, e, s, r) {
504
+ this.el = t.el("div", "mtb-success"), this.el.style.right = "20px", this.el.style.bottom = "20px";
505
+ const n = r ? `<button class="mtb-view-feedback-link">${e.success.view_feedback}</button>` : "";
506
+ this.el.innerHTML = `
396
507
  <div class="mtb-success-icon">
397
- <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="${y}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
508
+ <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="${x}" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
398
509
  <polyline points="20 6 9 17 4 12"/>
399
510
  </svg>
400
511
  </div>
401
- <div class="mtb-success-title">${i.success.title}</div>
402
- <div class="mtb-success-msg">${i.success.message}</div>
403
- <button class="mtb-close-link">${i.success.close}</button>
404
- `, t.append(this.el), this.el.querySelector(".mtb-close-link").addEventListener("click", r), setTimeout(() => r(), bt);
512
+ <div class="mtb-success-title">${e.success.title}</div>
513
+ <div class="mtb-success-msg">${e.success.message}</div>
514
+ ${n}
515
+ <button class="mtb-close-link">${e.success.close}</button>
516
+ `, t.append(this.el), this.el.querySelector(".mtb-close-link").addEventListener("click", s), r && this.el.querySelector(".mtb-view-feedback-link").addEventListener("click", r), setTimeout(() => s(), kt);
405
517
  }
406
518
  destroy() {
407
519
  this.el.remove();
408
520
  }
409
521
  }
410
- function xt(e, t) {
411
- if (e.match(/^[a-z]+:\/\//i))
412
- return e;
413
- if (e.match(/^\/\//))
414
- return window.location.protocol + e;
415
- if (e.match(/^[a-z]+:/i))
416
- return e;
417
- const i = document.implementation.createHTMLDocument(), r = i.createElement("base"), s = i.createElement("a");
418
- return i.head.appendChild(r), i.body.appendChild(s), t && (r.href = t), s.href = e, s.href;
522
+ function Et(i, t) {
523
+ if (i.match(/^[a-z]+:\/\//i))
524
+ return i;
525
+ if (i.match(/^\/\//))
526
+ return window.location.protocol + i;
527
+ if (i.match(/^[a-z]+:/i))
528
+ return i;
529
+ const e = document.implementation.createHTMLDocument(), s = e.createElement("base"), r = e.createElement("a");
530
+ return e.head.appendChild(s), e.body.appendChild(r), t && (s.href = t), r.href = i, r.href;
419
531
  }
420
- const wt = /* @__PURE__ */ (() => {
421
- let e = 0;
532
+ const St = /* @__PURE__ */ (() => {
533
+ let i = 0;
422
534
  const t = () => (
423
535
  // eslint-disable-next-line no-bitwise
424
536
  `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4)
425
537
  );
426
- return () => (e += 1, `u${t()}${e}`);
538
+ return () => (i += 1, `u${t()}${i}`);
427
539
  })();
428
- function p(e) {
540
+ function p(i) {
429
541
  const t = [];
430
- for (let i = 0, r = e.length; i < r; i++)
431
- t.push(e[i]);
542
+ for (let e = 0, s = i.length; e < s; e++)
543
+ t.push(i[e]);
432
544
  return t;
433
545
  }
434
546
  let b = null;
435
- function W(e = {}) {
436
- return b || (e.includeStyleProperties ? (b = e.includeStyleProperties, b) : (b = p(window.getComputedStyle(document.documentElement)), b));
547
+ function V(i = {}) {
548
+ return b || (i.includeStyleProperties ? (b = i.includeStyleProperties, b) : (b = p(window.getComputedStyle(document.documentElement)), b));
437
549
  }
438
- function S(e, t) {
439
- const r = (e.ownerDocument.defaultView || window).getComputedStyle(e).getPropertyValue(t);
440
- return r ? parseFloat(r.replace("px", "")) : 0;
550
+ function S(i, t) {
551
+ const s = (i.ownerDocument.defaultView || window).getComputedStyle(i).getPropertyValue(t);
552
+ return s ? parseFloat(s.replace("px", "")) : 0;
441
553
  }
442
- function yt(e) {
443
- const t = S(e, "border-left-width"), i = S(e, "border-right-width");
444
- return e.clientWidth + t + i;
554
+ function Ct(i) {
555
+ const t = S(i, "border-left-width"), e = S(i, "border-right-width");
556
+ return i.clientWidth + t + e;
445
557
  }
446
- function kt(e) {
447
- const t = S(e, "border-top-width"), i = S(e, "border-bottom-width");
448
- return e.clientHeight + t + i;
558
+ function Mt(i) {
559
+ const t = S(i, "border-top-width"), e = S(i, "border-bottom-width");
560
+ return i.clientHeight + t + e;
449
561
  }
450
- function V(e, t = {}) {
451
- const i = t.width || yt(e), r = t.height || kt(e);
452
- return { width: i, height: r };
562
+ function Y(i, t = {}) {
563
+ const e = t.width || Ct(i), s = t.height || Mt(i);
564
+ return { width: e, height: s };
453
565
  }
454
- function vt() {
455
- let e, t;
566
+ function Lt() {
567
+ let i, t;
456
568
  try {
457
569
  t = process;
458
570
  } catch {
459
571
  }
460
- const i = t && t.env ? t.env.devicePixelRatio : null;
461
- return i && (e = parseInt(i, 10), Number.isNaN(e) && (e = 1)), e || window.devicePixelRatio || 1;
572
+ const e = t && t.env ? t.env.devicePixelRatio : null;
573
+ return e && (i = parseInt(e, 10), Number.isNaN(i) && (i = 1)), i || window.devicePixelRatio || 1;
462
574
  }
463
575
  const d = 16384;
464
- function St(e) {
465
- (e.width > d || e.height > d) && (e.width > d && e.height > d ? e.width > e.height ? (e.height *= d / e.width, e.width = d) : (e.width *= d / e.height, e.height = d) : e.width > d ? (e.height *= d / e.width, e.width = d) : (e.width *= d / e.height, e.height = d));
466
- }
467
- function E(e) {
468
- return new Promise((t, i) => {
469
- const r = new Image();
470
- r.onload = () => {
471
- r.decode().then(() => {
472
- requestAnimationFrame(() => t(r));
576
+ function Tt(i) {
577
+ (i.width > d || i.height > d) && (i.width > d && i.height > d ? i.width > i.height ? (i.height *= d / i.width, i.width = d) : (i.width *= d / i.height, i.height = d) : i.width > d ? (i.height *= d / i.width, i.width = d) : (i.width *= d / i.height, i.height = d));
578
+ }
579
+ function C(i) {
580
+ return new Promise((t, e) => {
581
+ const s = new Image();
582
+ s.onload = () => {
583
+ s.decode().then(() => {
584
+ requestAnimationFrame(() => t(s));
473
585
  });
474
- }, r.onerror = i, r.crossOrigin = "anonymous", r.decoding = "async", r.src = e;
586
+ }, s.onerror = e, s.crossOrigin = "anonymous", s.decoding = "async", s.src = i;
475
587
  });
476
588
  }
477
- async function Et(e) {
478
- return Promise.resolve().then(() => new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then((t) => `data:image/svg+xml;charset=utf-8,${t}`);
589
+ async function At(i) {
590
+ return Promise.resolve().then(() => new XMLSerializer().serializeToString(i)).then(encodeURIComponent).then((t) => `data:image/svg+xml;charset=utf-8,${t}`);
479
591
  }
480
- async function Ct(e, t, i) {
481
- const r = "http://www.w3.org/2000/svg", s = document.createElementNS(r, "svg"), n = document.createElementNS(r, "foreignObject");
482
- return s.setAttribute("width", `${t}`), s.setAttribute("height", `${i}`), s.setAttribute("viewBox", `0 0 ${t} ${i}`), 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(e), Et(s);
592
+ async function Dt(i, t, e) {
593
+ const s = "http://www.w3.org/2000/svg", r = document.createElementNS(s, "svg"), n = document.createElementNS(s, "foreignObject");
594
+ return r.setAttribute("width", `${t}`), r.setAttribute("height", `${e}`), r.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"), r.appendChild(n), n.appendChild(i), At(r);
483
595
  }
484
- const h = (e, t) => {
485
- if (e instanceof t)
596
+ const h = (i, t) => {
597
+ if (i instanceof t)
486
598
  return !0;
487
- const i = Object.getPrototypeOf(e);
488
- return i === null ? !1 : i.constructor.name === t.name || h(i, t);
599
+ const e = Object.getPrototypeOf(i);
600
+ return e === null ? !1 : e.constructor.name === t.name || h(e, t);
489
601
  };
490
- function Lt(e) {
491
- const t = e.getPropertyValue("content");
492
- return `${e.cssText} content: '${t.replace(/'|"/g, "")}';`;
493
- }
494
- function Mt(e, t) {
495
- return W(t).map((i) => {
496
- const r = e.getPropertyValue(i), s = e.getPropertyPriority(i);
497
- return `${i}: ${r}${s ? " !important" : ""};`;
602
+ function Pt(i) {
603
+ const t = i.getPropertyValue("content");
604
+ return `${i.cssText} content: '${t.replace(/'|"/g, "")}';`;
605
+ }
606
+ function Rt(i, t) {
607
+ return V(t).map((e) => {
608
+ const s = i.getPropertyValue(e), r = i.getPropertyPriority(e);
609
+ return `${e}: ${s}${r ? " !important" : ""};`;
498
610
  }).join(" ");
499
611
  }
500
- function Rt(e, t, i, r) {
501
- const s = `.${e}:${t}`, n = i.cssText ? Lt(i) : Mt(i, r);
502
- return document.createTextNode(`${s}{${n}}`);
612
+ function _t(i, t, e, s) {
613
+ const r = `.${i}:${t}`, n = e.cssText ? Pt(e) : Rt(e, s);
614
+ return document.createTextNode(`${r}{${n}}`);
503
615
  }
504
- function _(e, t, i, r) {
505
- const s = window.getComputedStyle(e, i), n = s.getPropertyValue("content");
616
+ function I(i, t, e, s) {
617
+ const r = window.getComputedStyle(i, e), n = r.getPropertyValue("content");
506
618
  if (n === "" || n === "none")
507
619
  return;
508
- const o = wt();
620
+ const o = St();
509
621
  try {
510
622
  t.className = `${t.className} ${o}`;
511
623
  } catch {
512
624
  return;
513
625
  }
514
626
  const a = document.createElement("style");
515
- a.appendChild(Rt(o, i, s, r)), t.appendChild(a);
627
+ a.appendChild(_t(o, e, r, s)), t.appendChild(a);
516
628
  }
517
- function At(e, t, i) {
518
- _(e, t, ":before", i), _(e, t, ":after", i);
629
+ function Ht(i, t, e) {
630
+ I(i, t, ":before", e), I(i, t, ":after", e);
519
631
  }
520
- const I = "application/font-woff", H = "image/jpeg", Tt = {
521
- woff: I,
522
- woff2: I,
632
+ const O = "application/font-woff", F = "image/jpeg", $t = {
633
+ woff: O,
634
+ woff2: O,
523
635
  ttf: "application/font-truetype",
524
636
  eot: "application/vnd.ms-fontobject",
525
637
  png: "image/png",
526
- jpg: H,
527
- jpeg: H,
638
+ jpg: F,
639
+ jpeg: F,
528
640
  gif: "image/gif",
529
641
  tiff: "image/tiff",
530
642
  svg: "image/svg+xml",
531
643
  webp: "image/webp"
532
644
  };
533
- function $t(e) {
534
- const t = /\.([^./]*?)$/g.exec(e);
645
+ function It(i) {
646
+ const t = /\.([^./]*?)$/g.exec(i);
535
647
  return t ? t[1] : "";
536
648
  }
537
- function T(e) {
538
- const t = $t(e).toLowerCase();
539
- return Tt[t] || "";
649
+ function R(i) {
650
+ const t = It(i).toLowerCase();
651
+ return $t[t] || "";
540
652
  }
541
- function Pt(e) {
542
- return e.split(/,/)[1];
653
+ function Ot(i) {
654
+ return i.split(/,/)[1];
543
655
  }
544
- function R(e) {
545
- return e.search(/^(data:)/) !== -1;
656
+ function D(i) {
657
+ return i.search(/^(data:)/) !== -1;
546
658
  }
547
- function Dt(e, t) {
548
- return `data:${t};base64,${e}`;
659
+ function Ft(i, t) {
660
+ return `data:${t};base64,${i}`;
549
661
  }
550
- async function N(e, t, i) {
551
- const r = await fetch(e, t);
552
- if (r.status === 404)
553
- throw new Error(`Resource "${r.url}" not found`);
554
- const s = await r.blob();
662
+ async function X(i, t, e) {
663
+ const s = await fetch(i, t);
664
+ if (s.status === 404)
665
+ throw new Error(`Resource "${s.url}" not found`);
666
+ const r = await s.blob();
555
667
  return new Promise((n, o) => {
556
668
  const a = new FileReader();
557
669
  a.onerror = o, a.onloadend = () => {
558
670
  try {
559
- n(i({ res: r, result: a.result }));
671
+ n(e({ res: s, result: a.result }));
560
672
  } catch (l) {
561
673
  o(l);
562
674
  }
563
- }, a.readAsDataURL(s);
675
+ }, a.readAsDataURL(r);
564
676
  });
565
677
  }
566
- const M = {};
567
- function _t(e, t, i) {
568
- let r = e.replace(/\?.*/, "");
569
- return i && (r = e), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), t ? `[${t}]${r}` : r;
570
- }
571
- async function $(e, t, i) {
572
- const r = _t(e, t, i.includeQueryParams);
573
- if (M[r] != null)
574
- return M[r];
575
- i.cacheBust && (e += (/\?/.test(e) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
576
- let s;
678
+ const A = {};
679
+ function jt(i, t, e) {
680
+ let s = i.replace(/\?.*/, "");
681
+ return e && (s = i), /ttf|otf|eot|woff2?/i.test(s) && (s = s.replace(/.*\//, "")), t ? `[${t}]${s}` : s;
682
+ }
683
+ async function _(i, t, e) {
684
+ const s = jt(i, t, e.includeQueryParams);
685
+ if (A[s] != null)
686
+ return A[s];
687
+ e.cacheBust && (i += (/\?/.test(i) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
688
+ let r;
577
689
  try {
578
- const n = await N(e, i.fetchRequestInit, ({ res: o, result: a }) => (t || (t = o.headers.get("Content-Type") || ""), Pt(a)));
579
- s = Dt(n, t);
690
+ const n = await X(i, e.fetchRequestInit, ({ res: o, result: a }) => (t || (t = o.headers.get("Content-Type") || ""), Ot(a)));
691
+ r = Ft(n, t);
580
692
  } catch (n) {
581
- s = i.imagePlaceholder || "";
582
- let o = `Failed to fetch resource: ${e}`;
693
+ r = e.imagePlaceholder || "";
694
+ let o = `Failed to fetch resource: ${i}`;
583
695
  n && (o = typeof n == "string" ? n : n.message), o && console.warn(o);
584
696
  }
585
- return M[r] = s, s;
697
+ return A[s] = r, r;
586
698
  }
587
- async function It(e) {
588
- const t = e.toDataURL();
589
- return t === "data:," ? e.cloneNode(!1) : E(t);
699
+ async function Ut(i) {
700
+ const t = i.toDataURL();
701
+ return t === "data:," ? i.cloneNode(!1) : C(t);
590
702
  }
591
- async function Ht(e, t) {
592
- if (e.currentSrc) {
703
+ async function zt(i, t) {
704
+ if (i.currentSrc) {
593
705
  const n = document.createElement("canvas"), o = n.getContext("2d");
594
- n.width = e.clientWidth, n.height = e.clientHeight, o?.drawImage(e, 0, 0, n.width, n.height);
706
+ n.width = i.clientWidth, n.height = i.clientHeight, o?.drawImage(i, 0, 0, n.width, n.height);
595
707
  const a = n.toDataURL();
596
- return E(a);
708
+ return C(a);
597
709
  }
598
- const i = e.poster, r = T(i), s = await $(i, r, t);
599
- return E(s);
710
+ const e = i.poster, s = R(e), r = await _(e, s, t);
711
+ return C(r);
600
712
  }
601
- async function Ft(e, t) {
602
- var i;
713
+ async function Bt(i, t) {
714
+ var e;
603
715
  try {
604
- if (!((i = e?.contentDocument) === null || i === void 0) && i.body)
605
- return await C(e.contentDocument.body, t, !0);
716
+ if (!((e = i?.contentDocument) === null || e === void 0) && e.body)
717
+ return await M(i.contentDocument.body, t, !0);
606
718
  } catch {
607
719
  }
608
- return e.cloneNode(!1);
720
+ return i.cloneNode(!1);
609
721
  }
610
- async function Ot(e, t) {
611
- return h(e, HTMLCanvasElement) ? It(e) : h(e, HTMLVideoElement) ? Ht(e, t) : h(e, HTMLIFrameElement) ? Ft(e, t) : e.cloneNode(Y(e));
722
+ async function qt(i, t) {
723
+ return h(i, HTMLCanvasElement) ? Ut(i) : h(i, HTMLVideoElement) ? zt(i, t) : h(i, HTMLIFrameElement) ? Bt(i, t) : i.cloneNode(G(i));
612
724
  }
613
- const Ut = (e) => e.tagName != null && e.tagName.toUpperCase() === "SLOT", Y = (e) => e.tagName != null && e.tagName.toUpperCase() === "SVG";
614
- async function Bt(e, t, i) {
615
- var r, s;
616
- if (Y(t))
725
+ const Wt = (i) => i.tagName != null && i.tagName.toUpperCase() === "SLOT", G = (i) => i.tagName != null && i.tagName.toUpperCase() === "SVG";
726
+ async function Nt(i, t, e) {
727
+ var s, r;
728
+ if (G(t))
617
729
  return t;
618
730
  let n = [];
619
- return Ut(e) && e.assignedNodes ? n = p(e.assignedNodes()) : h(e, HTMLIFrameElement) && (!((r = e.contentDocument) === null || r === void 0) && r.body) ? n = p(e.contentDocument.body.childNodes) : n = p(((s = e.shadowRoot) !== null && s !== void 0 ? s : e).childNodes), n.length === 0 || h(e, HTMLVideoElement) || await n.reduce((o, a) => o.then(() => C(a, i)).then((l) => {
731
+ return Wt(i) && i.assignedNodes ? n = p(i.assignedNodes()) : h(i, HTMLIFrameElement) && (!((s = i.contentDocument) === null || s === void 0) && s.body) ? n = p(i.contentDocument.body.childNodes) : n = p(((r = i.shadowRoot) !== null && r !== void 0 ? r : i).childNodes), n.length === 0 || h(i, HTMLVideoElement) || await n.reduce((o, a) => o.then(() => M(a, e)).then((l) => {
620
732
  l && t.appendChild(l);
621
733
  }), Promise.resolve()), t;
622
734
  }
623
- function jt(e, t, i) {
624
- const r = t.style;
625
- if (!r)
735
+ function Vt(i, t, e) {
736
+ const s = t.style;
737
+ if (!s)
626
738
  return;
627
- const s = window.getComputedStyle(e);
628
- s.cssText ? (r.cssText = s.cssText, r.transformOrigin = s.transformOrigin) : W(i).forEach((n) => {
629
- let o = s.getPropertyValue(n);
630
- n === "font-size" && o.endsWith("px") && (o = `${Math.floor(parseFloat(o.substring(0, o.length - 2))) - 0.1}px`), h(e, HTMLIFrameElement) && n === "display" && o === "inline" && (o = "block"), n === "d" && t.getAttribute("d") && (o = `path(${t.getAttribute("d")})`), r.setProperty(n, o, s.getPropertyPriority(n));
739
+ const r = window.getComputedStyle(i);
740
+ r.cssText ? (s.cssText = r.cssText, s.transformOrigin = r.transformOrigin) : V(e).forEach((n) => {
741
+ let o = r.getPropertyValue(n);
742
+ n === "font-size" && o.endsWith("px") && (o = `${Math.floor(parseFloat(o.substring(0, o.length - 2))) - 0.1}px`), h(i, HTMLIFrameElement) && n === "display" && o === "inline" && (o = "block"), n === "d" && t.getAttribute("d") && (o = `path(${t.getAttribute("d")})`), s.setProperty(n, o, r.getPropertyPriority(n));
631
743
  });
632
744
  }
633
- function zt(e, t) {
634
- h(e, HTMLTextAreaElement) && (t.innerHTML = e.value), h(e, HTMLInputElement) && t.setAttribute("value", e.value);
745
+ function Yt(i, t) {
746
+ h(i, HTMLTextAreaElement) && (t.innerHTML = i.value), h(i, HTMLInputElement) && t.setAttribute("value", i.value);
635
747
  }
636
- function qt(e, t) {
637
- if (h(e, HTMLSelectElement)) {
638
- const i = t, r = Array.from(i.children).find((s) => e.value === s.getAttribute("value"));
639
- r && r.setAttribute("selected", "");
748
+ function Xt(i, t) {
749
+ if (h(i, HTMLSelectElement)) {
750
+ const e = t, s = Array.from(e.children).find((r) => i.value === r.getAttribute("value"));
751
+ s && s.setAttribute("selected", "");
640
752
  }
641
753
  }
642
- function Wt(e, t, i) {
643
- return h(t, Element) && (jt(e, t, i), At(e, t, i), zt(e, t), qt(e, t)), t;
754
+ function Gt(i, t, e) {
755
+ return h(t, Element) && (Vt(i, t, e), Ht(i, t, e), Yt(i, t), Xt(i, t)), t;
644
756
  }
645
- async function Vt(e, t) {
646
- const i = e.querySelectorAll ? e.querySelectorAll("use") : [];
647
- if (i.length === 0)
648
- return e;
649
- const r = {};
650
- for (let n = 0; n < i.length; n++) {
651
- const a = i[n].getAttribute("xlink:href");
757
+ async function Kt(i, t) {
758
+ const e = i.querySelectorAll ? i.querySelectorAll("use") : [];
759
+ if (e.length === 0)
760
+ return i;
761
+ const s = {};
762
+ for (let n = 0; n < e.length; n++) {
763
+ const a = e[n].getAttribute("xlink:href");
652
764
  if (a) {
653
- const l = e.querySelector(a), c = document.querySelector(a);
654
- !l && c && !r[a] && (r[a] = await C(c, t, !0));
765
+ const l = i.querySelector(a), c = document.querySelector(a);
766
+ !l && c && !s[a] && (s[a] = await M(c, t, !0));
655
767
  }
656
768
  }
657
- const s = Object.values(r);
658
- if (s.length) {
769
+ const r = Object.values(s);
770
+ if (r.length) {
659
771
  const n = "http://www.w3.org/1999/xhtml", o = document.createElementNS(n, "svg");
660
772
  o.setAttribute("xmlns", n), o.style.position = "absolute", o.style.width = "0", o.style.height = "0", o.style.overflow = "hidden", o.style.display = "none";
661
773
  const a = document.createElementNS(n, "defs");
662
774
  o.appendChild(a);
663
- for (let l = 0; l < s.length; l++)
664
- a.appendChild(s[l]);
665
- e.appendChild(o);
775
+ for (let l = 0; l < r.length; l++)
776
+ a.appendChild(r[l]);
777
+ i.appendChild(o);
666
778
  }
667
- return e;
779
+ return i;
668
780
  }
669
- async function C(e, t, i) {
670
- return !i && t.filter && !t.filter(e) ? null : Promise.resolve(e).then((r) => Ot(r, t)).then((r) => Bt(e, r, t)).then((r) => Wt(e, r, t)).then((r) => Vt(r, t));
781
+ async function M(i, t, e) {
782
+ return !e && t.filter && !t.filter(i) ? null : Promise.resolve(i).then((s) => qt(s, t)).then((s) => Nt(i, s, t)).then((s) => Gt(i, s, t)).then((s) => Kt(s, t));
671
783
  }
672
- const X = /url\((['"]?)([^'"]+?)\1\)/g, Nt = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, Yt = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
673
- function Xt(e) {
674
- const t = e.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
784
+ const K = /url\((['"]?)([^'"]+?)\1\)/g, Jt = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, Qt = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
785
+ function Zt(i) {
786
+ const t = i.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
675
787
  return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`, "g");
676
788
  }
677
- function Gt(e) {
789
+ function te(i) {
678
790
  const t = [];
679
- return e.replace(X, (i, r, s) => (t.push(s), i)), t.filter((i) => !R(i));
791
+ return i.replace(K, (e, s, r) => (t.push(r), e)), t.filter((e) => !D(e));
680
792
  }
681
- async function Kt(e, t, i, r, s) {
793
+ async function ee(i, t, e, s, r) {
682
794
  try {
683
- const n = i ? xt(t, i) : t, o = T(t);
795
+ const n = e ? Et(t, e) : t, o = R(t);
684
796
  let a;
685
- return s || (a = await $(n, o, r)), e.replace(Xt(t), `$1${a}$3`);
797
+ return r || (a = await _(n, o, s)), i.replace(Zt(t), `$1${a}$3`);
686
798
  } catch {
687
799
  }
688
- return e;
800
+ return i;
689
801
  }
690
- function Jt(e, { preferredFontFormat: t }) {
691
- return t ? e.replace(Yt, (i) => {
802
+ function ie(i, { preferredFontFormat: t }) {
803
+ return t ? i.replace(Qt, (e) => {
692
804
  for (; ; ) {
693
- const [r, , s] = Nt.exec(i) || [];
694
- if (!s)
805
+ const [s, , r] = Jt.exec(e) || [];
806
+ if (!r)
695
807
  return "";
696
- if (s === t)
697
- return `src: ${r};`;
808
+ if (r === t)
809
+ return `src: ${s};`;
698
810
  }
699
- }) : e;
811
+ }) : i;
700
812
  }
701
- function G(e) {
702
- return e.search(X) !== -1;
813
+ function J(i) {
814
+ return i.search(K) !== -1;
703
815
  }
704
- async function K(e, t, i) {
705
- if (!G(e))
706
- return e;
707
- const r = Jt(e, i);
708
- return Gt(r).reduce((n, o) => n.then((a) => Kt(a, o, t, i)), Promise.resolve(r));
816
+ async function Q(i, t, e) {
817
+ if (!J(i))
818
+ return i;
819
+ const s = ie(i, e);
820
+ return te(s).reduce((n, o) => n.then((a) => ee(a, o, t, e)), Promise.resolve(s));
709
821
  }
710
- async function g(e, t, i) {
711
- var r;
712
- const s = (r = t.style) === null || r === void 0 ? void 0 : r.getPropertyValue(e);
713
- if (s) {
714
- const n = await K(s, null, i);
715
- return t.style.setProperty(e, n, t.style.getPropertyPriority(e)), !0;
822
+ async function g(i, t, e) {
823
+ var s;
824
+ const r = (s = t.style) === null || s === void 0 ? void 0 : s.getPropertyValue(i);
825
+ if (r) {
826
+ const n = await Q(r, null, e);
827
+ return t.style.setProperty(i, n, t.style.getPropertyPriority(i)), !0;
716
828
  }
717
829
  return !1;
718
830
  }
719
- async function Qt(e, t) {
720
- await g("background", e, t) || await g("background-image", e, t), await g("mask", e, t) || await g("-webkit-mask", e, t) || await g("mask-image", e, t) || await g("-webkit-mask-image", e, t);
831
+ async function se(i, t) {
832
+ await g("background", i, t) || await g("background-image", i, t), await g("mask", i, t) || await g("-webkit-mask", i, t) || await g("mask-image", i, t) || await g("-webkit-mask-image", i, t);
721
833
  }
722
- async function Zt(e, t) {
723
- const i = h(e, HTMLImageElement);
724
- if (!(i && !R(e.src)) && !(h(e, SVGImageElement) && !R(e.href.baseVal)))
834
+ async function re(i, t) {
835
+ const e = h(i, HTMLImageElement);
836
+ if (!(e && !D(i.src)) && !(h(i, SVGImageElement) && !D(i.href.baseVal)))
725
837
  return;
726
- const r = i ? e.src : e.href.baseVal, s = await $(r, T(r), t);
838
+ const s = e ? i.src : i.href.baseVal, r = await _(s, R(s), t);
727
839
  await new Promise((n, o) => {
728
- e.onload = n, e.onerror = t.onImageErrorHandler ? (...l) => {
840
+ i.onload = n, i.onerror = t.onImageErrorHandler ? (...l) => {
729
841
  try {
730
842
  n(t.onImageErrorHandler(...l));
731
843
  } catch (c) {
732
844
  o(c);
733
845
  }
734
846
  } : o;
735
- const a = e;
736
- a.decode && (a.decode = n), a.loading === "lazy" && (a.loading = "eager"), i ? (e.srcset = "", e.src = s) : e.href.baseVal = s;
847
+ const a = i;
848
+ a.decode && (a.decode = n), a.loading === "lazy" && (a.loading = "eager"), e ? (i.srcset = "", i.src = r) : i.href.baseVal = r;
737
849
  });
738
850
  }
739
- async function te(e, t) {
740
- const r = p(e.childNodes).map((s) => J(s, t));
741
- await Promise.all(r).then(() => e);
851
+ async function ne(i, t) {
852
+ const s = p(i.childNodes).map((r) => Z(r, t));
853
+ await Promise.all(s).then(() => i);
742
854
  }
743
- async function J(e, t) {
744
- h(e, Element) && (await Qt(e, t), await Zt(e, t), await te(e, t));
855
+ async function Z(i, t) {
856
+ h(i, Element) && (await se(i, t), await re(i, t), await ne(i, t));
745
857
  }
746
- function ee(e, t) {
747
- const { style: i } = e;
748
- t.backgroundColor && (i.backgroundColor = t.backgroundColor), t.width && (i.width = `${t.width}px`), t.height && (i.height = `${t.height}px`);
749
- const r = t.style;
750
- return r != null && Object.keys(r).forEach((s) => {
751
- i[s] = r[s];
752
- }), e;
858
+ function oe(i, t) {
859
+ const { style: e } = i;
860
+ t.backgroundColor && (e.backgroundColor = t.backgroundColor), t.width && (e.width = `${t.width}px`), t.height && (e.height = `${t.height}px`);
861
+ const s = t.style;
862
+ return s != null && Object.keys(s).forEach((r) => {
863
+ e[r] = s[r];
864
+ }), i;
753
865
  }
754
- const F = {};
755
- async function O(e) {
756
- let t = F[e];
866
+ const j = {};
867
+ async function U(i) {
868
+ let t = j[i];
757
869
  if (t != null)
758
870
  return t;
759
- const r = await (await fetch(e)).text();
760
- return t = { url: e, cssText: r }, F[e] = t, t;
761
- }
762
- async function U(e, t) {
763
- let i = e.cssText;
764
- const r = /url\(["']?([^"')]+)["']?\)/g, n = (i.match(/url\([^)]+\)/g) || []).map(async (o) => {
765
- let a = o.replace(r, "$1");
766
- return a.startsWith("https://") || (a = new URL(a, e.url).href), N(a, t.fetchRequestInit, ({ result: l }) => (i = i.replace(o, `url(${l})`), [o, l]));
871
+ const s = await (await fetch(i)).text();
872
+ return t = { url: i, cssText: s }, j[i] = t, t;
873
+ }
874
+ async function z(i, t) {
875
+ let e = i.cssText;
876
+ const s = /url\(["']?([^"')]+)["']?\)/g, n = (e.match(/url\([^)]+\)/g) || []).map(async (o) => {
877
+ let a = o.replace(s, "$1");
878
+ return a.startsWith("https://") || (a = new URL(a, i.url).href), X(a, t.fetchRequestInit, ({ result: l }) => (e = e.replace(o, `url(${l})`), [o, l]));
767
879
  });
768
- return Promise.all(n).then(() => i);
880
+ return Promise.all(n).then(() => e);
769
881
  }
770
- function B(e) {
771
- if (e == null)
882
+ function B(i) {
883
+ if (i == null)
772
884
  return [];
773
- const t = [], i = /(\/\*[\s\S]*?\*\/)/gi;
774
- let r = e.replace(i, "");
775
- const s = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi");
885
+ const t = [], e = /(\/\*[\s\S]*?\*\/)/gi;
886
+ let s = i.replace(e, "");
887
+ const r = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi");
776
888
  for (; ; ) {
777
- const l = s.exec(r);
889
+ const l = r.exec(s);
778
890
  if (l === null)
779
891
  break;
780
892
  t.push(l[0]);
781
893
  }
782
- r = r.replace(s, "");
894
+ s = s.replace(r, "");
783
895
  const n = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, o = "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", a = new RegExp(o, "gi");
784
896
  for (; ; ) {
785
- let l = n.exec(r);
897
+ let l = n.exec(s);
786
898
  if (l === null) {
787
- if (l = a.exec(r), l === null)
899
+ if (l = a.exec(s), l === null)
788
900
  break;
789
901
  n.lastIndex = a.lastIndex;
790
902
  } else
@@ -793,126 +905,126 @@ function B(e) {
793
905
  }
794
906
  return t;
795
907
  }
796
- async function ie(e, t) {
797
- const i = [], r = [];
798
- return e.forEach((s) => {
799
- if ("cssRules" in s)
908
+ async function ae(i, t) {
909
+ const e = [], s = [];
910
+ return i.forEach((r) => {
911
+ if ("cssRules" in r)
800
912
  try {
801
- p(s.cssRules || []).forEach((n, o) => {
913
+ p(r.cssRules || []).forEach((n, o) => {
802
914
  if (n.type === CSSRule.IMPORT_RULE) {
803
915
  let a = o + 1;
804
- const l = n.href, c = O(l).then((u) => U(u, t)).then((u) => B(u).forEach((L) => {
916
+ const l = n.href, c = U(l).then((u) => z(u, t)).then((u) => B(u).forEach((L) => {
805
917
  try {
806
- s.insertRule(L, L.startsWith("@import") ? a += 1 : s.cssRules.length);
807
- } catch (tt) {
918
+ r.insertRule(L, L.startsWith("@import") ? a += 1 : r.cssRules.length);
919
+ } catch (it) {
808
920
  console.error("Error inserting rule from remote css", {
809
921
  rule: L,
810
- error: tt
922
+ error: it
811
923
  });
812
924
  }
813
925
  })).catch((u) => {
814
926
  console.error("Error loading remote css", u.toString());
815
927
  });
816
- r.push(c);
928
+ s.push(c);
817
929
  }
818
930
  });
819
931
  } catch (n) {
820
- const o = e.find((a) => a.href == null) || document.styleSheets[0];
821
- s.href != null && r.push(O(s.href).then((a) => U(a, t)).then((a) => B(a).forEach((l) => {
932
+ const o = i.find((a) => a.href == null) || document.styleSheets[0];
933
+ r.href != null && s.push(U(r.href).then((a) => z(a, t)).then((a) => B(a).forEach((l) => {
822
934
  o.insertRule(l, o.cssRules.length);
823
935
  })).catch((a) => {
824
936
  console.error("Error loading remote stylesheet", a);
825
937
  })), console.error("Error inlining remote css file", n);
826
938
  }
827
- }), Promise.all(r).then(() => (e.forEach((s) => {
828
- if ("cssRules" in s)
939
+ }), Promise.all(s).then(() => (i.forEach((r) => {
940
+ if ("cssRules" in r)
829
941
  try {
830
- p(s.cssRules || []).forEach((n) => {
831
- i.push(n);
942
+ p(r.cssRules || []).forEach((n) => {
943
+ e.push(n);
832
944
  });
833
945
  } catch (n) {
834
- console.error(`Error while reading CSS rules from ${s.href}`, n);
946
+ console.error(`Error while reading CSS rules from ${r.href}`, n);
835
947
  }
836
- }), i));
948
+ }), e));
837
949
  }
838
- function re(e) {
839
- return e.filter((t) => t.type === CSSRule.FONT_FACE_RULE).filter((t) => G(t.style.getPropertyValue("src")));
950
+ function le(i) {
951
+ return i.filter((t) => t.type === CSSRule.FONT_FACE_RULE).filter((t) => J(t.style.getPropertyValue("src")));
840
952
  }
841
- async function se(e, t) {
842
- if (e.ownerDocument == null)
953
+ async function ce(i, t) {
954
+ if (i.ownerDocument == null)
843
955
  throw new Error("Provided element is not within a Document");
844
- const i = p(e.ownerDocument.styleSheets), r = await ie(i, t);
845
- return re(r);
956
+ const e = p(i.ownerDocument.styleSheets), s = await ae(e, t);
957
+ return le(s);
846
958
  }
847
- function Q(e) {
848
- return e.trim().replace(/["']/g, "");
959
+ function tt(i) {
960
+ return i.trim().replace(/["']/g, "");
849
961
  }
850
- function ne(e) {
962
+ function he(i) {
851
963
  const t = /* @__PURE__ */ new Set();
852
- function i(r) {
853
- (r.style.fontFamily || getComputedStyle(r).fontFamily).split(",").forEach((n) => {
854
- t.add(Q(n));
855
- }), Array.from(r.children).forEach((n) => {
856
- n instanceof HTMLElement && i(n);
964
+ function e(s) {
965
+ (s.style.fontFamily || getComputedStyle(s).fontFamily).split(",").forEach((n) => {
966
+ t.add(tt(n));
967
+ }), Array.from(s.children).forEach((n) => {
968
+ n instanceof HTMLElement && e(n);
857
969
  });
858
970
  }
859
- return i(e), t;
971
+ return e(i), t;
860
972
  }
861
- async function oe(e, t) {
862
- const i = await se(e, t), r = ne(e);
863
- return (await Promise.all(i.filter((n) => r.has(Q(n.style.fontFamily))).map((n) => {
973
+ async function de(i, t) {
974
+ const e = await ce(i, t), s = he(i);
975
+ return (await Promise.all(e.filter((n) => s.has(tt(n.style.fontFamily))).map((n) => {
864
976
  const o = n.parentStyleSheet ? n.parentStyleSheet.href : null;
865
- return K(n.cssText, o, t);
977
+ return Q(n.cssText, o, t);
866
978
  }))).join(`
867
979
  `);
868
980
  }
869
- async function ae(e, t) {
870
- const i = t.fontEmbedCSS != null ? t.fontEmbedCSS : t.skipFonts ? null : await oe(e, t);
871
- if (i) {
872
- const r = document.createElement("style"), s = document.createTextNode(i);
873
- r.appendChild(s), e.firstChild ? e.insertBefore(r, e.firstChild) : e.appendChild(r);
981
+ async function ue(i, t) {
982
+ const e = t.fontEmbedCSS != null ? t.fontEmbedCSS : t.skipFonts ? null : await de(i, t);
983
+ if (e) {
984
+ const s = document.createElement("style"), r = document.createTextNode(e);
985
+ s.appendChild(r), i.firstChild ? i.insertBefore(s, i.firstChild) : i.appendChild(s);
874
986
  }
875
987
  }
876
- async function le(e, t = {}) {
877
- const { width: i, height: r } = V(e, t), s = await C(e, t, !0);
878
- return await ae(s, t), await J(s, t), ee(s, t), await Ct(s, i, r);
988
+ async function pe(i, t = {}) {
989
+ const { width: e, height: s } = Y(i, t), r = await M(i, t, !0);
990
+ return await ue(r, t), await Z(r, t), oe(r, t), await Dt(r, e, s);
879
991
  }
880
- async function ce(e, t = {}) {
881
- const { width: i, height: r } = V(e, t), s = await le(e, t), n = await E(s), o = document.createElement("canvas"), a = o.getContext("2d"), l = t.pixelRatio || vt(), c = t.canvasWidth || i, u = t.canvasHeight || r;
882
- return o.width = c * l, o.height = u * l, t.skipAutoScale || St(o), o.style.width = `${c}`, o.style.height = `${u}`, t.backgroundColor && (a.fillStyle = t.backgroundColor, a.fillRect(0, 0, o.width, o.height)), a.drawImage(n, 0, 0, o.width, o.height), o;
992
+ async function fe(i, t = {}) {
993
+ const { width: e, height: s } = Y(i, t), r = await pe(i, t), n = await C(r), o = document.createElement("canvas"), a = o.getContext("2d"), l = t.pixelRatio || Lt(), c = t.canvasWidth || e, u = t.canvasHeight || s;
994
+ return o.width = c * l, o.height = u * l, t.skipAutoScale || Tt(o), o.style.width = `${c}`, o.style.height = `${u}`, t.backgroundColor && (a.fillStyle = t.backgroundColor, a.fillRect(0, 0, o.width, o.height)), a.drawImage(n, 0, 0, o.width, o.height), o;
883
995
  }
884
- async function he(e, t = {}) {
885
- return (await ce(e, t)).toDataURL();
996
+ async function me(i, t = {}) {
997
+ return (await fe(i, t)).toDataURL();
886
998
  }
887
- async function de(e = []) {
888
- const t = ue(e);
999
+ async function be(i = []) {
1000
+ const t = ge(i);
889
1001
  try {
890
- const i = await he(document.body, {
1002
+ const e = await me(document.body, {
891
1003
  cacheBust: !0,
892
1004
  skipAutoScale: !1,
893
- filter: (r) => !(r instanceof HTMLElement && r.id === "mtb-widget-host")
1005
+ filter: (s) => !(s instanceof HTMLElement && s.id === "mtb-widget-host")
894
1006
  });
895
- return me(i);
1007
+ return we(e);
896
1008
  } catch {
897
1009
  return null;
898
1010
  } finally {
899
1011
  t?.remove();
900
1012
  }
901
1013
  }
902
- function ue(e) {
903
- if (e.length === 0) return null;
1014
+ function ge(i) {
1015
+ if (i.length === 0) return null;
904
1016
  const t = document.createElement("div");
905
1017
  t.setAttribute("data-mtb-capture-annotations", "true"), t.setAttribute("aria-hidden", "true"), t.style.cssText = "position:fixed;inset:0;pointer-events:none;z-index:2147483645;";
906
- for (const [i, r] of e.entries())
907
- r.type === "pin" ? t.appendChild(pe(r, i + 1)) : r.type === "draw" && r.drawPath && t.appendChild(fe(r.drawPath));
1018
+ for (const [e, s] of i.entries())
1019
+ s.type === "pin" ? t.appendChild(ye(s, e + 1)) : s.type === "draw" && s.drawPath && t.appendChild(xe(s.drawPath));
908
1020
  return document.body.appendChild(t), t;
909
1021
  }
910
- function pe(e, t) {
911
- const i = document.createElement("div");
912
- return i.textContent = String(t), i.style.cssText = [
1022
+ function ye(i, t) {
1023
+ const e = document.createElement("div");
1024
+ return e.textContent = String(t), e.style.cssText = [
913
1025
  "position:fixed",
914
- `left:${e.x}px`,
915
- `top:${e.y}px`,
1026
+ `left:${i.x}px`,
1027
+ `top:${i.y}px`,
916
1028
  "width:22px",
917
1029
  "height:22px",
918
1030
  "border-radius:50% 50% 50% 2px",
@@ -925,23 +1037,23 @@ function pe(e, t) {
925
1037
  "color:#fff",
926
1038
  "box-shadow:0 2px 8px rgba(5,150,105,0.45)",
927
1039
  "transform:translate(-50%,-50%)"
928
- ].join(";"), i;
1040
+ ].join(";"), e;
929
1041
  }
930
- function fe(e) {
1042
+ function xe(i) {
931
1043
  const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
932
1044
  t.setAttribute("width", "100%"), t.setAttribute("height", "100%"), t.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`), t.style.cssText = "position:fixed;inset:0;width:100%;height:100%;overflow:visible;";
933
- const i = document.createElementNS("http://www.w3.org/2000/svg", "path");
934
- return i.setAttribute("d", e), i.setAttribute("fill", "none"), i.setAttribute("stroke", "#059669"), i.setAttribute("stroke-width", "3.5"), i.setAttribute("stroke-linecap", "round"), i.setAttribute("stroke-linejoin", "round"), i.setAttribute("filter", "drop-shadow(0 1px 2px rgba(5,150,105,0.35))"), t.appendChild(i), t;
1045
+ const e = document.createElementNS("http://www.w3.org/2000/svg", "path");
1046
+ return e.setAttribute("d", i), e.setAttribute("fill", "none"), e.setAttribute("stroke", "#059669"), e.setAttribute("stroke-width", "3.5"), e.setAttribute("stroke-linecap", "round"), e.setAttribute("stroke-linejoin", "round"), e.setAttribute("filter", "drop-shadow(0 1px 2px rgba(5,150,105,0.35))"), t.appendChild(e), t;
935
1047
  }
936
- function me(e) {
937
- const [t, i] = e.split(","), r = t.match(/:(.*?);/)?.[1] ?? "image/png", s = atob(i), n = new Uint8Array(s.length);
938
- for (let o = 0; o < s.length; o++)
939
- n[o] = s.charCodeAt(o);
940
- return new Blob([n], { type: r });
1048
+ function we(i) {
1049
+ const [t, e] = i.split(","), s = t.match(/:(.*?);/)?.[1] ?? "image/png", r = atob(e), n = new Uint8Array(r.length);
1050
+ for (let o = 0; o < r.length; o++)
1051
+ n[o] = r.charCodeAt(o);
1052
+ return new Blob([n], { type: s });
941
1053
  }
942
- class be {
1054
+ class ke {
943
1055
  constructor() {
944
- this.listeners = /* @__PURE__ */ new Set(), this.originalOnError = null, this.rejectionHandler = null, this.hooked = !1;
1056
+ this.listeners = /* @__PURE__ */ new Set(), this.originalOnError = null, this.installedOnError = null, this.rejectionHandler = null, this.hooked = !1;
945
1057
  }
946
1058
  subscribe(t) {
947
1059
  return this.listeners.add(t), this.hook(), () => {
@@ -949,32 +1061,32 @@ class be {
949
1061
  };
950
1062
  }
951
1063
  hook() {
952
- this.hooked || (this.hooked = !0, this.originalOnError = window.onerror, window.onerror = (t, i, r, s, n) => (this.emit({ message: String(t), source: i, line: r, col: s, error: n }), this.originalOnError ? this.originalOnError.call(window, t, i, r, s, n) : !1), this.rejectionHandler = (t) => {
953
- const i = t.reason instanceof Error ? t.reason.message : String(t.reason);
954
- this.emit({ message: `Unhandled rejection: ${i}` });
1064
+ this.hooked || (this.hooked = !0, this.originalOnError = window.onerror, this.installedOnError = (t, e, s, r, n) => (this.emit({ message: String(t), source: e, line: s, col: r, error: n }), this.originalOnError ? this.originalOnError.call(window, t, e, s, r, n) : !1), window.onerror = this.installedOnError, this.rejectionHandler = (t) => {
1065
+ const e = t.reason instanceof Error ? t.reason.message : String(t.reason);
1066
+ this.emit({ message: `Unhandled rejection: ${e}` });
955
1067
  }, window.addEventListener("unhandledrejection", this.rejectionHandler));
956
1068
  }
957
1069
  unhook() {
958
- this.hooked && (this.hooked = !1, window.onerror = this.originalOnError, this.originalOnError = null, this.rejectionHandler && (window.removeEventListener("unhandledrejection", this.rejectionHandler), this.rejectionHandler = null));
1070
+ this.hooked && (this.hooked = !1, window.onerror === this.installedOnError && (window.onerror = this.originalOnError), this.installedOnError = null, this.originalOnError = null, this.rejectionHandler && (window.removeEventListener("unhandledrejection", this.rejectionHandler), this.rejectionHandler = null));
959
1071
  }
960
1072
  emit(t) {
961
- for (const i of this.listeners) i(t);
1073
+ for (const e of this.listeners) e(t);
962
1074
  }
963
1075
  }
964
- const Z = new be(), ge = 20;
965
- class xe {
1076
+ const et = new ke(), ve = 20;
1077
+ class Ee {
966
1078
  constructor() {
967
1079
  this.errors = [], this.unsubscribe = null;
968
1080
  }
969
1081
  start() {
970
- this.unsubscribe || (this.unsubscribe = Z.subscribe((t) => this.record(t)));
1082
+ this.unsubscribe || (this.unsubscribe = et.subscribe((t) => this.record(t)));
971
1083
  }
972
1084
  record(t) {
973
- const i = t.line != null ? ` (${t.line}:${t.col ?? 0})` : "";
974
- this.addError(`${t.message}${i}`);
1085
+ const e = t.line != null ? ` (${t.line}:${t.col ?? 0})` : "";
1086
+ this.addError(`${t.message}${e}`);
975
1087
  }
976
1088
  addError(t) {
977
- this.errors.length >= ge || this.errors.includes(t) || this.errors.push(t);
1089
+ this.errors.length >= ve || this.errors.includes(t) || this.errors.push(t);
978
1090
  }
979
1091
  getErrors() {
980
1092
  return [...this.errors];
@@ -983,7 +1095,7 @@ class xe {
983
1095
  this.unsubscribe?.(), this.unsubscribe = null;
984
1096
  }
985
1097
  }
986
- const we = 3, ye = 1e3, ke = /* @__PURE__ */ new Set([
1098
+ const Se = 3, Ce = 1e3, Me = 3, Le = 5e3, Te = 500, Ae = 500, De = 300, Pe = /* @__PURE__ */ new Set([
987
1099
  "A",
988
1100
  "BUTTON",
989
1101
  "INPUT",
@@ -992,7 +1104,7 @@ const we = 3, ye = 1e3, ke = /* @__PURE__ */ new Set([
992
1104
  "LABEL",
993
1105
  "SUMMARY",
994
1106
  "DETAILS"
995
- ]), ve = /* @__PURE__ */ new Set([
1107
+ ]), Re = /* @__PURE__ */ new Set([
996
1108
  "button",
997
1109
  "link",
998
1110
  "checkbox",
@@ -1006,133 +1118,281 @@ const we = 3, ye = 1e3, ke = /* @__PURE__ */ new Set([
1006
1118
  "listbox",
1007
1119
  "slider",
1008
1120
  "spinbutton"
1009
- ]), k = class k {
1121
+ ]), q = [
1122
+ "404",
1123
+ "500",
1124
+ "not found",
1125
+ "page not found",
1126
+ "server error",
1127
+ "internal server error"
1128
+ ], v = class v {
1010
1129
  constructor(t) {
1011
- this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.errorCount = 0, this.deadClickCount = 0, this.cooldownUntil = 0, this.onFrustration = t, this.boundClickHandler = (i) => this.handleClick(i);
1130
+ this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.errorCount = 0, this.deadClickCount = 0, this.cooldownUntil = 0, this.navTimestamps = [], this.boundPopstateHandler = null, this.originalPushState = null, this.originalReplaceState = null, this.installedPushState = null, this.installedReplaceState = null, this.boundSubmitHandler = null, this.boundInvalidHandler = null, this.errorPageUrls = /* @__PURE__ */ new Set(), this.domObserver = null, this.pendingDomChecks = 0, this.lastMutationAt = -1, this.onFrustration = t, this.boundClickHandler = (e) => this.handleClick(e);
1012
1131
  }
1013
1132
  start() {
1014
- this.active || (this.active = !0, document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors = Z.subscribe((t) => {
1133
+ this.active || (this.active = !0, document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors = et.subscribe((t) => {
1015
1134
  this.errorCount++;
1016
- }));
1135
+ }), this.startNavigationTracking(), this.startFormTracking(), this.checkErrorPage());
1017
1136
  }
1018
1137
  stop() {
1019
- this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.clickHistory = []);
1138
+ 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());
1139
+ }
1140
+ startNavigationTracking() {
1141
+ this.boundPopstateHandler = () => this.handleNavigation(), window.addEventListener("popstate", this.boundPopstateHandler), this.originalPushState = history.pushState.bind(history), this.originalReplaceState = history.replaceState.bind(history);
1142
+ const t = this.originalPushState, e = this.originalReplaceState, s = () => this.handleNavigation();
1143
+ this.installedPushState = function(r, n, o) {
1144
+ t(r, n, o), s();
1145
+ }, this.installedReplaceState = function(r, n, o) {
1146
+ e(r, n, o), s();
1147
+ }, history.pushState = this.installedPushState, history.replaceState = this.installedReplaceState;
1148
+ }
1149
+ stopNavigationTracking() {
1150
+ 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, this.navTimestamps = [];
1151
+ }
1152
+ startFormTracking() {
1153
+ this.boundSubmitHandler = (t) => this.handleFormSubmit(t), this.boundInvalidHandler = (t) => this.handleFormInvalid(t), document.addEventListener("submit", this.boundSubmitHandler, !0), document.addEventListener("invalid", this.boundInvalidHandler, !0);
1154
+ }
1155
+ stopFormTracking() {
1156
+ this.boundSubmitHandler && (document.removeEventListener("submit", this.boundSubmitHandler, !0), this.boundSubmitHandler = null), this.boundInvalidHandler && (document.removeEventListener("invalid", this.boundInvalidHandler, !0), this.boundInvalidHandler = null);
1020
1157
  }
1021
1158
  handleClick(t) {
1022
- const i = t.target;
1023
- if (!i || this.isWidgetElement(i)) return;
1024
- const r = Date.now();
1025
- this.clickHistory.push({ target: i, time: r });
1026
- const s = r - ye;
1027
- if (this.clickHistory = this.clickHistory.filter((o) => o.time > s), this.clickHistory.filter((o) => o.target === i).length >= we) {
1159
+ const e = t.target;
1160
+ if (!e || this.isWidgetElement(e)) return;
1161
+ const s = Date.now();
1162
+ this.clickHistory.push({ target: e, time: s });
1163
+ const r = s - Ce;
1164
+ if (this.clickHistory = this.clickHistory.filter((o) => o.time > r), this.clickHistory.filter((o) => o.target === e).length >= Se) {
1028
1165
  this.clickHistory = [], this.emitHighPriority({
1029
1166
  signal: "rage_click",
1030
- target: j(i),
1031
- timestamp: r
1167
+ target: y(e),
1168
+ timestamp: s
1032
1169
  });
1033
1170
  return;
1034
1171
  }
1035
- this.isInteractive(i) || (this.deadClickCount++, this.deadClickCount >= 3 && this.errorCount > 0 && (this.deadClickCount = 0, this.errorCount = 0, this.emitIfReady({
1172
+ this.isInteractive(e) || (this.deadClickCount++, this.deadClickCount >= 3 && this.errorCount > 0 && (this.deadClickCount = 0, this.errorCount = 0, this.emitIfReady({
1036
1173
  signal: "dead_click",
1037
- target: j(i),
1038
- timestamp: r
1039
- })));
1174
+ target: y(e),
1175
+ timestamp: s
1176
+ }))), this.checkDeadClickDom(e, s);
1177
+ }
1178
+ handleNavigation() {
1179
+ const t = Date.now();
1180
+ this.navTimestamps.push(t);
1181
+ const e = t - Le;
1182
+ this.navTimestamps = this.navTimestamps.filter((s) => s > e), this.navTimestamps.length >= Me && (this.navTimestamps = [], this.emitIfReady({
1183
+ signal: "rapid_navigation",
1184
+ timestamp: t
1185
+ })), setTimeout(() => {
1186
+ this.active && this.checkErrorPage();
1187
+ }, De);
1188
+ }
1189
+ handleFormSubmit(t) {
1190
+ const e = t.target;
1191
+ e instanceof HTMLFormElement && (this.isWidgetElement(e) || setTimeout(() => {
1192
+ this.active && e.querySelector('[aria-invalid="true"], .is-invalid') && this.emitIfReady({
1193
+ signal: "form_failure",
1194
+ target: y(e),
1195
+ timestamp: Date.now()
1196
+ });
1197
+ }, Te));
1198
+ }
1199
+ handleFormInvalid(t) {
1200
+ const e = t.target;
1201
+ if (!e || this.isWidgetElement(e)) return;
1202
+ const s = e.closest("form");
1203
+ this.emitIfReady({
1204
+ signal: "form_failure",
1205
+ target: y(s || e),
1206
+ timestamp: Date.now()
1207
+ });
1208
+ }
1209
+ checkErrorPage() {
1210
+ const t = location.href;
1211
+ if (this.errorPageUrls.has(t)) return;
1212
+ const e = document.title.toLowerCase();
1213
+ if (q.some((r) => e.includes(r))) {
1214
+ this.errorPageUrls.add(t), this.emitHighPriority({
1215
+ signal: "error_page",
1216
+ detail: document.title,
1217
+ timestamp: Date.now()
1218
+ });
1219
+ return;
1220
+ }
1221
+ const s = document.querySelectorAll(
1222
+ 'h1, h2, [class*="error"], [class*="not-found"], [id*="error"], [id*="not-found"]'
1223
+ );
1224
+ for (const r of s) {
1225
+ const n = r.textContent ?? "";
1226
+ if (n.length < 200 && q.some((o) => n.toLowerCase().includes(o))) {
1227
+ this.errorPageUrls.add(t), this.emitHighPriority({
1228
+ signal: "error_page",
1229
+ detail: n.trim().slice(0, 60),
1230
+ timestamp: Date.now()
1231
+ });
1232
+ return;
1233
+ }
1234
+ }
1235
+ }
1236
+ // One shared observer for all in-flight dead-click checks, connected only
1237
+ // while at least one check is pending — a full-page observer per click was
1238
+ // too heavy on mutation-busy pages.
1239
+ checkDeadClickDom(t, e) {
1240
+ this.looksInteractive(t) && (this.pendingDomChecks++, this.ensureDomObserver(), setTimeout(() => {
1241
+ this.pendingDomChecks--;
1242
+ const s = this.lastMutationAt >= e;
1243
+ this.pendingDomChecks === 0 && this.disconnectDomObserver(), !s && this.active && this.emitIfReady({
1244
+ signal: "dead_click_dom",
1245
+ target: y(t),
1246
+ timestamp: e
1247
+ });
1248
+ }, Ae));
1249
+ }
1250
+ ensureDomObserver() {
1251
+ this.domObserver || (this.domObserver = new MutationObserver(() => {
1252
+ this.lastMutationAt = Date.now();
1253
+ }), this.domObserver.observe(document.body, {
1254
+ childList: !0,
1255
+ subtree: !0,
1256
+ attributes: !0,
1257
+ characterData: !0
1258
+ }));
1259
+ }
1260
+ disconnectDomObserver() {
1261
+ this.domObserver?.disconnect(), this.domObserver = null;
1262
+ }
1263
+ looksInteractive(t) {
1264
+ if (window.getComputedStyle(t).cursor === "pointer") return !0;
1265
+ if (t.classList)
1266
+ for (const s of t.classList) {
1267
+ const r = s.toLowerCase();
1268
+ if (r.includes("btn") || r.includes("button")) return !0;
1269
+ }
1270
+ return !1;
1040
1271
  }
1041
1272
  isInteractive(t) {
1042
- if (ke.has(t.tagName)) return !0;
1043
- const i = t.getAttribute("role");
1044
- return !!(i && ve.has(i) || t.hasAttribute("onclick") || t.hasAttribute("tabindex") || t.contentEditable === "true" || window.getComputedStyle(t).cursor === "pointer" || t.closest('a, button, [role="button"], [role="link"], label'));
1273
+ if (Pe.has(t.tagName)) return !0;
1274
+ const e = t.getAttribute("role");
1275
+ return !!(e && Re.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'));
1045
1276
  }
1046
1277
  isWidgetElement(t) {
1047
- const i = document.getElementById("mtb-widget-host");
1048
- return i ? i === t || i.contains(t) : !1;
1278
+ const e = document.getElementById("mtb-widget-host");
1279
+ return e ? e === t || e.contains(t) : !1;
1049
1280
  }
1050
1281
  emitIfReady(t) {
1051
- const i = Date.now();
1052
- i < this.cooldownUntil || (this.cooldownUntil = i + k.COOLDOWN_MS, this.onFrustration(t));
1282
+ const e = Date.now();
1283
+ e < this.cooldownUntil || (this.cooldownUntil = e + v.COOLDOWN_MS, this.onFrustration(t));
1053
1284
  }
1054
1285
  emitHighPriority(t) {
1055
- this.cooldownUntil = Date.now() + k.COOLDOWN_MS, this.onFrustration(t);
1286
+ this.cooldownUntil = Date.now() + v.COOLDOWN_MS, this.onFrustration(t);
1056
1287
  }
1057
1288
  };
1058
- k.COOLDOWN_MS = 6e4;
1059
- let A = k;
1060
- function j(e) {
1061
- const t = e.tagName.toLowerCase(), i = e.id ? `#${e.id}` : "", r = e.className && typeof e.className == "string" ? "." + e.className.trim().split(/\s+/).slice(0, 2).join(".") : "", s = e.textContent?.trim().slice(0, 30) ?? "";
1062
- return `<${t}${i}${r}>${s ? ` "${s}"` : ""}`;
1289
+ v.COOLDOWN_MS = 6e4;
1290
+ let P = v;
1291
+ function y(i) {
1292
+ const t = i.tagName.toLowerCase(), e = i.id ? `#${i.id}` : "", s = i.className && typeof i.className == "string" ? "." + i.className.trim().split(/\s+/).slice(0, 2).join(".") : "", r = i.textContent?.trim().slice(0, 30) ?? "";
1293
+ return `<${t}${e}${s}>${r ? ` "${r}"` : ""}`;
1063
1294
  }
1064
- function Se() {
1295
+ function _e() {
1065
1296
  return {
1066
1297
  page_url: window.location.href,
1067
1298
  user_agent: navigator.userAgent,
1068
- browser: Ee(),
1069
- os: Ce(),
1299
+ browser: He(),
1300
+ os: $e(),
1070
1301
  screen_width: window.screen.width,
1071
1302
  screen_height: window.screen.height
1072
1303
  };
1073
1304
  }
1074
- function Ee() {
1075
- const e = navigator.userAgent;
1076
- return /Edg\//.test(e) ? `Edge ${e.match(/Edg\/(\S+)/)?.[1] ?? ""}` : /OPR\//.test(e) ? `Opera ${e.match(/OPR\/(\S+)/)?.[1] ?? ""}` : /Chrome\//.test(e) ? `Chrome ${e.match(/Chrome\/(\S+)/)?.[1] ?? ""}` : /Safari\//.test(e) && /Version\//.test(e) ? `Safari ${e.match(/Version\/(\S+)/)?.[1] ?? ""}` : /Firefox\//.test(e) ? `Firefox ${e.match(/Firefox\/(\S+)/)?.[1] ?? ""}` : "Unknown";
1305
+ function He() {
1306
+ const i = navigator.userAgent;
1307
+ 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";
1077
1308
  }
1078
- function Ce() {
1079
- const e = navigator.userAgent;
1080
- return /Windows NT 10/.test(e) ? "Windows 10/11" : /Windows NT/.test(e) ? "Windows" : /Mac OS X 10_15|macOS 1[56789]/.test(e) || /Mac OS X/.test(e) ? "macOS" : /Android/.test(e) ? `Android ${e.match(/Android (\d+)/)?.[1] ?? ""}` : /iPhone|iPad|iPod/.test(e) ? "iOS" : /Linux/.test(e) ? "Linux" : "Unknown";
1309
+ function $e() {
1310
+ const i = navigator.userAgent;
1311
+ 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";
1081
1312
  }
1082
- const Le = "https://makethisbetter.dev/api/v1";
1083
- class Me {
1084
- constructor(t, i, r = 1e3) {
1085
- this.projectKey = t, this.apiUrl = (i ?? Le).replace(/\/$/, ""), this.retryDelayMs = r;
1313
+ const Ie = "https://makethisbetter.dev/api/v1";
1314
+ class Oe {
1315
+ constructor(t, e, s = 1e3, r, n) {
1316
+ this.projectKey = t, this.apiUrl = (e ?? Ie).replace(/\/$/, ""), this.retryDelayMs = s, this.userToken = r, this.userTokenFn = n;
1317
+ }
1318
+ async resolveUserToken() {
1319
+ return this.userTokenFn ? this.userTokenFn() : this.userToken;
1086
1320
  }
1087
- async submitFeedback(t, i) {
1088
- const r = new FormData();
1089
- if (r.append("feedback[description]", t.description), r.append("feedback[page_url]", t.page_url), r.append("feedback[user_agent]", t.user_agent), r.append("feedback[browser]", t.browser), r.append("feedback[os]", t.os), r.append("feedback[screen_width]", String(t.screen_width)), r.append("feedback[screen_height]", String(t.screen_height)), r.append("feedback[console_errors]", JSON.stringify(t.console_errors)), r.append("feedback[annotations]", JSON.stringify(t.annotations)), t.target_element && r.append("feedback[target_element]", JSON.stringify(t.target_element)), t.user_id && r.append("feedback[user_id]", t.user_id), t.user_email && r.append("feedback[user_email]", t.user_email), t.user_name && r.append("feedback[user_name]", t.user_name), t.recording_events && t.recording_events.length > 0) {
1090
- const s = JSON.stringify(t.recording_events), n = new Blob([s], { type: "application/json" });
1091
- r.append("feedback[recording]", n, "recording.json"), r.append("feedback[recording_duration]", String(t.recording_duration ?? 0));
1321
+ async authHeaders(t) {
1322
+ const e = { "X-Project-Key": this.projectKey }, s = await this.resolveUserToken();
1323
+ return s && (e["X-User-Token"] = s), t && (e["Content-Type"] = t), e;
1324
+ }
1325
+ async submitFeedback(t, e) {
1326
+ const s = new FormData();
1327
+ 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.user_email && s.append("feedback[user_email]", t.user_email), t.user_name && s.append("feedback[user_name]", t.user_name), t.recording_events && t.recording_events.length > 0) {
1328
+ const o = JSON.stringify(t.recording_events), a = new Blob([o], { type: "application/json" });
1329
+ s.append("feedback[recording]", a, "recording.json"), s.append("feedback[recording_duration]", String(t.recording_duration ?? 0));
1092
1330
  }
1093
- i && r.append("feedback[screenshot]", i, "screenshot.png"), await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks`, {
1331
+ e && s.append("feedback[screenshot]", e, "screenshot.png");
1332
+ const r = await this.authHeaders();
1333
+ return r["X-Idempotency-Key"] = Fe(), (await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks`, {
1094
1334
  method: "POST",
1095
- headers: { "X-Project-Key": this.projectKey },
1096
- body: r
1097
- });
1098
- }
1099
- async fetchWithRetry(t, i, r = 1) {
1100
- let s;
1335
+ headers: r,
1336
+ body: s
1337
+ })).json();
1338
+ }
1339
+ async startClarification(t, e) {
1340
+ const s = {};
1341
+ e && (s.message = e);
1342
+ const r = await this.authHeaders("application/json");
1343
+ return (await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${t}/clarify`, {
1344
+ method: "POST",
1345
+ headers: r,
1346
+ body: JSON.stringify(s)
1347
+ })).json();
1348
+ }
1349
+ async getClarification(t) {
1350
+ const e = await this.authHeaders();
1351
+ return (await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${t}/clarify`, {
1352
+ method: "GET",
1353
+ headers: e
1354
+ })).json();
1355
+ }
1356
+ async fetchWithRetry(t, e, s = 1) {
1357
+ let r;
1101
1358
  try {
1102
- s = await fetch(t, i);
1359
+ r = await fetch(t, e);
1103
1360
  } catch (n) {
1104
- if (r > 0)
1105
- return await z(this.retryDelayMs), this.fetchWithRetry(t, i, r - 1);
1361
+ if (s > 0)
1362
+ return await W(this.retryDelayMs), this.fetchWithRetry(t, e, s - 1);
1106
1363
  throw n;
1107
1364
  }
1108
- if (s.ok) return s;
1109
- if (s.status >= 500 && r > 0)
1110
- return await z(this.retryDelayMs), this.fetchWithRetry(t, i, r - 1);
1111
- throw new Error(`HTTP ${s.status}`);
1365
+ if (r.ok) return r;
1366
+ if (r.status >= 500 && s > 0)
1367
+ return await W(this.retryDelayMs), this.fetchWithRetry(t, e, s - 1);
1368
+ throw new Error(`HTTP ${r.status}`);
1112
1369
  }
1113
1370
  }
1114
- function z(e) {
1115
- return e <= 0 ? Promise.resolve() : new Promise((t) => setTimeout(t, e));
1371
+ function W(i) {
1372
+ return i <= 0 ? Promise.resolve() : new Promise((t) => setTimeout(t, i));
1373
+ }
1374
+ function Fe() {
1375
+ return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
1116
1376
  }
1117
- function Re(e, t, i, r, s, n) {
1377
+ function je(i, t, e, s, r, n) {
1118
1378
  return {
1119
- description: e,
1379
+ description: i,
1120
1380
  ...t,
1121
- console_errors: i,
1122
- annotations: r ? [r] : [],
1123
- target_element: r?.targetSelector ? {
1124
- selector: r.targetSelector,
1125
- text: r.targetText ?? "",
1126
- name: r.targetName ?? ""
1381
+ console_errors: e,
1382
+ annotations: s ? [s] : [],
1383
+ target_element: s?.targetSelector ? {
1384
+ selector: s.targetSelector,
1385
+ text: s.targetText ?? "",
1386
+ name: s.targetName ?? ""
1127
1387
  } : void 0,
1128
- user_id: s?.id,
1129
- user_email: s?.email,
1130
- user_name: s?.name,
1388
+ user_id: r?.id,
1389
+ user_email: r?.email,
1390
+ user_name: r?.name,
1131
1391
  recording_events: n?.events,
1132
1392
  recording_duration: n?.duration
1133
1393
  };
1134
1394
  }
1135
- const Ae = {
1395
+ const Ue = {
1136
1396
  tab: "Feedback",
1137
1397
  toolbar: {
1138
1398
  markup: "Mark up",
@@ -1156,6 +1416,7 @@ const Ae = {
1156
1416
  success: {
1157
1417
  title: "Thanks!",
1158
1418
  message: "Your feedback has been received.",
1419
+ view_feedback: "View my feedback",
1159
1420
  close: "Close"
1160
1421
  },
1161
1422
  error: {
@@ -1177,8 +1438,14 @@ const Ae = {
1177
1438
  stop: "Stop",
1178
1439
  timer_label: "Recording",
1179
1440
  max_reached: "Maximum recording time reached"
1441
+ },
1442
+ clarify: {
1443
+ thinking: "Thinking...",
1444
+ placeholder: "Type your response...",
1445
+ send: "Send",
1446
+ skip: "Skip"
1180
1447
  }
1181
- }, Te = {
1448
+ }, ze = {
1182
1449
  tab: "反馈",
1183
1450
  toolbar: {
1184
1451
  markup: "标注",
@@ -1202,6 +1469,7 @@ const Ae = {
1202
1469
  success: {
1203
1470
  title: "感谢!",
1204
1471
  message: "您的反馈已收到。",
1472
+ view_feedback: "查看我的反馈",
1205
1473
  close: "关闭"
1206
1474
  },
1207
1475
  error: {
@@ -1223,57 +1491,333 @@ const Ae = {
1223
1491
  stop: "停止",
1224
1492
  timer_label: "录制中",
1225
1493
  max_reached: "已达到最大录制时长"
1494
+ },
1495
+ clarify: {
1496
+ thinking: "思考中...",
1497
+ placeholder: "输入你的回复...",
1498
+ send: "发送",
1499
+ skip: "跳过"
1500
+ }
1501
+ }, Be = {
1502
+ tab: "フィードバック",
1503
+ toolbar: {
1504
+ markup: "マークアップ",
1505
+ record: "録画",
1506
+ hint: "要素をクリックして注釈 · ドラッグで描画",
1507
+ hintRecord: "画面を録画中",
1508
+ exit: "終了"
1509
+ },
1510
+ popup: {
1511
+ about: "概要",
1512
+ placeholder: "問題や提案を入力してください...",
1513
+ submit: "送信",
1514
+ cancel: "キャンセル",
1515
+ quickOptions: [
1516
+ { emoji: "🐛", label: "不具合があります" },
1517
+ { emoji: "💡", label: "もっと使いやすくしてほしい" },
1518
+ { emoji: "🤔", label: "ここがわかりにくい" },
1519
+ { emoji: "✨", label: "アイデアがあります" }
1520
+ ]
1521
+ },
1522
+ success: {
1523
+ title: "ありがとうございます!",
1524
+ message: "フィードバックを受け付けました。",
1525
+ view_feedback: "フィードバックを確認",
1526
+ close: "閉じる"
1527
+ },
1528
+ error: {
1529
+ submit: "送信に失敗しました。もう一度お試しください。"
1530
+ },
1531
+ pet: {
1532
+ bubble: "お困りですか?"
1533
+ },
1534
+ frustration: {
1535
+ prompt: "うまくいかないことがありますか?お知らせください。",
1536
+ action: "注釈",
1537
+ dismiss: "閉じる"
1538
+ },
1539
+ annotation: {
1540
+ drawing: "描画",
1541
+ element: "要素"
1542
+ },
1543
+ record: {
1544
+ stop: "停止",
1545
+ timer_label: "録画中",
1546
+ max_reached: "最大録画時間に達しました"
1547
+ },
1548
+ clarify: {
1549
+ thinking: "考え中...",
1550
+ placeholder: "回答を入力...",
1551
+ send: "送信",
1552
+ skip: "スキップ"
1553
+ }
1554
+ }, qe = {
1555
+ tab: "피드백",
1556
+ toolbar: {
1557
+ markup: "마크업",
1558
+ record: "녹화",
1559
+ hint: "요소를 클릭하여 주석 · 드래그하여 그리기",
1560
+ hintRecord: "화면을 녹화 중입니다",
1561
+ exit: "나가기"
1562
+ },
1563
+ popup: {
1564
+ about: "정보",
1565
+ placeholder: "문제 또는 제안 사항을 설명해 주세요...",
1566
+ submit: "제출",
1567
+ cancel: "취소",
1568
+ quickOptions: [
1569
+ { emoji: "🐛", label: "오류가 있어요" },
1570
+ { emoji: "💡", label: "이 기능을 개선해 주세요" },
1571
+ { emoji: "🤔", label: "이 부분을 모르겠어요" },
1572
+ { emoji: "✨", label: "아이디어가 있어요" }
1573
+ ]
1574
+ },
1575
+ success: {
1576
+ title: "감사합니다!",
1577
+ message: "피드백이 접수되었습니다.",
1578
+ view_feedback: "내 피드백 보기",
1579
+ close: "닫기"
1580
+ },
1581
+ error: {
1582
+ submit: "제출에 실패했습니다. 다시 시도해 주세요."
1583
+ },
1584
+ pet: {
1585
+ bubble: "도움이 필요하신가요?"
1586
+ },
1587
+ frustration: {
1588
+ prompt: "문제가 있으신가요? 알려 주세요.",
1589
+ action: "주석",
1590
+ dismiss: "닫기"
1591
+ },
1592
+ annotation: {
1593
+ drawing: "그리기",
1594
+ element: "요소"
1595
+ },
1596
+ record: {
1597
+ stop: "중지",
1598
+ timer_label: "녹화 중",
1599
+ max_reached: "최대 녹화 시간에 도달했습니다"
1600
+ },
1601
+ clarify: {
1602
+ thinking: "생각 중...",
1603
+ placeholder: "답변을 입력하세요...",
1604
+ send: "보내기",
1605
+ skip: "건너뛰기"
1606
+ }
1607
+ }, We = {
1608
+ tab: "Comentarios",
1609
+ toolbar: {
1610
+ markup: "Anotar",
1611
+ record: "Grabar",
1612
+ hint: "Haz clic en cualquier elemento para anotar · arrastra para dibujar",
1613
+ hintRecord: "Grabando tu pantalla",
1614
+ exit: "Salir"
1615
+ },
1616
+ popup: {
1617
+ about: "Acerca de",
1618
+ placeholder: "Describe el problema o sugerencia...",
1619
+ submit: "Enviar",
1620
+ cancel: "Cancelar",
1621
+ quickOptions: [
1622
+ { emoji: "🐛", label: "Algo no funciona" },
1623
+ { emoji: "💡", label: "Me gustaría que funcionara diferente" },
1624
+ { emoji: "🤔", label: "No entiendo esto" },
1625
+ { emoji: "✨", label: "Tengo una idea" }
1626
+ ]
1627
+ },
1628
+ success: {
1629
+ title: "¡Gracias!",
1630
+ message: "Tu comentario ha sido recibido.",
1631
+ view_feedback: "Ver mis comentarios",
1632
+ close: "Cerrar"
1633
+ },
1634
+ error: {
1635
+ submit: "Error al enviar. Por favor, inténtalo de nuevo."
1636
+ },
1637
+ pet: {
1638
+ bubble: "¿Necesitas ayuda?"
1639
+ },
1640
+ frustration: {
1641
+ prompt: "¿Algo no funciona? Cuéntanos.",
1642
+ action: "Anotar",
1643
+ dismiss: "Cerrar"
1644
+ },
1645
+ annotation: {
1646
+ drawing: "Dibujo",
1647
+ element: "elemento"
1648
+ },
1649
+ record: {
1650
+ stop: "Detener",
1651
+ timer_label: "Grabando",
1652
+ max_reached: "Se alcanzó el tiempo máximo de grabación"
1653
+ },
1654
+ clarify: {
1655
+ thinking: "Pensando...",
1656
+ placeholder: "Escribe tu respuesta...",
1657
+ send: "Enviar",
1658
+ skip: "Omitir"
1659
+ }
1660
+ }, Ne = {
1661
+ tab: "Avis",
1662
+ toolbar: {
1663
+ markup: "Annoter",
1664
+ record: "Enregistrer",
1665
+ hint: "Cliquez sur un élément pour l'annoter · glissez pour dessiner",
1666
+ hintRecord: "Enregistrement de l'écran en cours",
1667
+ exit: "Quitter"
1668
+ },
1669
+ popup: {
1670
+ about: "À propos",
1671
+ placeholder: "Décrivez le problème ou votre suggestion...",
1672
+ submit: "Envoyer",
1673
+ cancel: "Annuler",
1674
+ quickOptions: [
1675
+ { emoji: "🐛", label: "Quelque chose ne fonctionne pas" },
1676
+ { emoji: "💡", label: "J'aimerais que cela fonctionne autrement" },
1677
+ { emoji: "🤔", label: "Je ne comprends pas ceci" },
1678
+ { emoji: "✨", label: "J'ai une idée" }
1679
+ ]
1680
+ },
1681
+ success: {
1682
+ title: "Merci !",
1683
+ message: "Votre avis a bien été reçu.",
1684
+ view_feedback: "Voir mes avis",
1685
+ close: "Fermer"
1686
+ },
1687
+ error: {
1688
+ submit: "Échec de l'envoi. Veuillez réessayer."
1689
+ },
1690
+ pet: {
1691
+ bubble: "Besoin d'aide ?"
1692
+ },
1693
+ frustration: {
1694
+ prompt: "Un problème ? Dites-le-nous.",
1695
+ action: "Annoter",
1696
+ dismiss: "Fermer"
1697
+ },
1698
+ annotation: {
1699
+ drawing: "Dessin",
1700
+ element: "élément"
1701
+ },
1702
+ record: {
1703
+ stop: "Arrêter",
1704
+ timer_label: "Enregistrement",
1705
+ max_reached: "Durée maximale d'enregistrement atteinte"
1706
+ },
1707
+ clarify: {
1708
+ thinking: "Réflexion...",
1709
+ placeholder: "Tapez votre réponse...",
1710
+ send: "Envoyer",
1711
+ skip: "Passer"
1226
1712
  }
1227
- }, w = {
1228
- en: Ae,
1229
- "zh-CN": Te
1713
+ }, Ve = {
1714
+ tab: "Feedback",
1715
+ toolbar: {
1716
+ markup: "Markieren",
1717
+ record: "Aufnehmen",
1718
+ hint: "Klicken Sie auf ein Element zum Kommentieren · ziehen Sie zum Zeichnen",
1719
+ hintRecord: "Bildschirmaufnahme läuft",
1720
+ exit: "Beenden"
1721
+ },
1722
+ popup: {
1723
+ about: "Info",
1724
+ placeholder: "Beschreiben Sie das Problem oder Ihren Vorschlag...",
1725
+ submit: "Absenden",
1726
+ cancel: "Abbrechen",
1727
+ quickOptions: [
1728
+ { emoji: "🐛", label: "Etwas funktioniert nicht" },
1729
+ { emoji: "💡", label: "Ich wünsche mir das anders" },
1730
+ { emoji: "🤔", label: "Das verstehe ich nicht" },
1731
+ { emoji: "✨", label: "Ich habe eine Idee" }
1732
+ ]
1733
+ },
1734
+ success: {
1735
+ title: "Vielen Dank!",
1736
+ message: "Ihr Feedback wurde empfangen.",
1737
+ view_feedback: "Mein Feedback ansehen",
1738
+ close: "Schließen"
1739
+ },
1740
+ error: {
1741
+ submit: "Senden fehlgeschlagen. Bitte versuchen Sie es erneut."
1742
+ },
1743
+ pet: {
1744
+ bubble: "Brauchen Sie Hilfe?"
1745
+ },
1746
+ frustration: {
1747
+ prompt: "Etwas funktioniert nicht? Sagen Sie es uns.",
1748
+ action: "Kommentieren",
1749
+ dismiss: "Schließen"
1750
+ },
1751
+ annotation: {
1752
+ drawing: "Zeichnung",
1753
+ element: "Element"
1754
+ },
1755
+ record: {
1756
+ stop: "Stopp",
1757
+ timer_label: "Aufnahme",
1758
+ max_reached: "Maximale Aufnahmezeit erreicht"
1759
+ },
1760
+ clarify: {
1761
+ thinking: "Einen Moment...",
1762
+ placeholder: "Antwort eingeben...",
1763
+ send: "Senden",
1764
+ skip: "Überspringen"
1765
+ }
1766
+ }, k = {
1767
+ en: Ue,
1768
+ "zh-CN": ze,
1769
+ ja: Be,
1770
+ ko: qe,
1771
+ es: We,
1772
+ fr: Ne,
1773
+ de: Ve
1230
1774
  };
1231
- function $e(e) {
1232
- if (w[e]) return w[e];
1233
- const t = e.split("-")[0];
1234
- return w[t] ? w[t] : w.en;
1775
+ function Ye(i) {
1776
+ if (k[i]) return k[i];
1777
+ const t = i.split("-")[0];
1778
+ return k[t] ? k[t] : k.en;
1235
1779
  }
1236
- const Pe = 60, De = "https://cdn.jsdelivr.net/npm/rrweb@2/dist/rrweb.min.js";
1237
- let v = null;
1238
- function _e() {
1239
- return v || (v = Ie().catch(() => He()), v);
1780
+ const Xe = 60, Ge = "https://cdn.jsdelivr.net/npm/rrweb@2.1.0/dist/rrweb.min.js", Ke = "sha384-6qZKf9GE/E2uhA8IdLwXsQiLN/jVx8mhA0i04rQ1aHLrs2URo3ivHlSbaccG59zt";
1781
+ let E = null;
1782
+ function Je() {
1783
+ return E || (E = Qe().catch(() => Ze()), E);
1240
1784
  }
1241
- async function Ie() {
1785
+ async function Qe() {
1242
1786
  return (await import("rrweb")).record;
1243
1787
  }
1244
- function He() {
1245
- return new Promise((e, t) => {
1246
- const i = globalThis;
1247
- if (i.rrweb?.record) {
1248
- e(i.rrweb.record);
1788
+ function Ze() {
1789
+ return new Promise((i, t) => {
1790
+ const e = globalThis;
1791
+ if (e.rrweb?.record) {
1792
+ i(e.rrweb.record);
1249
1793
  return;
1250
1794
  }
1251
- const r = document.createElement("script");
1252
- r.src = De, r.onload = () => {
1253
- const s = globalThis;
1254
- s.rrweb?.record ? e(s.rrweb.record) : t(new Error("rrweb global not found after script load"));
1255
- }, r.onerror = () => t(new Error("Failed to load rrweb from CDN")), document.head.appendChild(r);
1795
+ const s = document.createElement("script");
1796
+ s.src = Ge, s.integrity = Ke, s.crossOrigin = "anonymous", s.onload = () => {
1797
+ const r = globalThis;
1798
+ r.rrweb?.record ? i(r.rrweb.record) : t(new Error("rrweb global not found after script load"));
1799
+ }, s.onerror = () => t(new Error("Failed to load rrweb from CDN")), document.head.appendChild(s);
1256
1800
  });
1257
1801
  }
1258
- class Fe {
1259
- constructor(t, i) {
1260
- this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.shadow = t, this.onMaxReached = i;
1802
+ class ti {
1803
+ constructor(t, e) {
1804
+ this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.shadow = t, this.onMaxReached = e;
1261
1805
  }
1262
1806
  async start() {
1263
- const t = await _e();
1807
+ const t = await Je();
1264
1808
  this.startedAt = Date.now(), this.stopped = !1, this.stopFn = t({
1265
- emit: (i) => {
1266
- this.stopped || this.events.push(i);
1809
+ emit: (e) => {
1810
+ this.stopped || this.events.push(e);
1267
1811
  }
1268
- }), this.clickHandler = (i) => {
1269
- this.showClickRipple(i.clientX, i.clientY), t.addCustomEvent?.("mtb-click", {
1270
- x: i.clientX,
1271
- y: i.clientY,
1272
- target: i.target instanceof HTMLElement ? i.target.tagName : ""
1812
+ }), this.clickHandler = (e) => {
1813
+ this.showClickRipple(e.clientX, e.clientY), t.addCustomEvent?.("mtb-click", {
1814
+ x: e.clientX,
1815
+ y: e.clientY,
1816
+ target: e.target instanceof HTMLElement ? e.target.tagName : ""
1273
1817
  });
1274
1818
  }, document.addEventListener("click", this.clickHandler, !0), this.timer = setTimeout(() => {
1275
1819
  this.onMaxReached?.();
1276
- }, Pe * 1e3);
1820
+ }, Xe * 1e3);
1277
1821
  }
1278
1822
  stop() {
1279
1823
  return this.stopped = !0, this.stopFn?.(), this.stopFn = null, this.cleanupTimer(), this.cleanupClickHandler(), {
@@ -1293,44 +1837,70 @@ class Fe {
1293
1837
  cleanupClickHandler() {
1294
1838
  this.clickHandler && (document.removeEventListener("click", this.clickHandler, !0), this.clickHandler = null);
1295
1839
  }
1296
- showClickRipple(t, i) {
1297
- const r = this.shadow.el("div", "mtb-click-ripple");
1298
- r.style.left = `${t}px`, r.style.top = `${i}px`, this.shadow.append(r), r.addEventListener("animationend", () => r.remove());
1840
+ showClickRipple(t, e) {
1841
+ const s = this.shadow.el("div", "mtb-click-ripple");
1842
+ s.style.left = `${t}px`, s.style.top = `${e}px`, this.shadow.append(s), s.addEventListener("animationend", () => s.remove());
1299
1843
  }
1300
1844
  }
1301
- class Oe {
1302
- constructor(t, i, r, s) {
1303
- this.intervalId = null, this.getDuration = r, this.el = t.el("div", "mtb-record-bar"), this.el.innerHTML = `
1845
+ class ei {
1846
+ constructor(t, e, s, r) {
1847
+ this.intervalId = null, this.getDuration = s, this.el = t.el("div", "mtb-record-bar"), this.el.innerHTML = `
1304
1848
  <span class="mtb-record-dot"></span>
1305
1849
  <span class="mtb-record-timer">00:00</span>
1306
- <button class="mtb-record-stop" type="button">${i.record.stop}</button>
1307
- `, t.append(this.el), this.timerEl = this.el.querySelector(".mtb-record-timer"), this.el.querySelector(".mtb-record-stop").addEventListener("click", s), this.intervalId = setInterval(() => this.updateTimer(), 1e3);
1850
+ <button class="mtb-record-stop" type="button">${e.record.stop}</button>
1851
+ `, t.append(this.el), this.timerEl = this.el.querySelector(".mtb-record-timer"), this.el.querySelector(".mtb-record-stop").addEventListener("click", r), this.intervalId = setInterval(() => this.updateTimer(), 1e3);
1308
1852
  }
1309
1853
  updateTimer() {
1310
- const t = this.getDuration(), i = String(Math.floor(t / 60)).padStart(2, "0"), r = String(t % 60).padStart(2, "0");
1311
- this.timerEl.textContent = `${i}:${r}`;
1854
+ const t = this.getDuration(), e = String(Math.floor(t / 60)).padStart(2, "0"), s = String(t % 60).padStart(2, "0");
1855
+ this.timerEl.textContent = `${e}:${s}`;
1312
1856
  }
1313
1857
  destroy() {
1314
1858
  this.intervalId && (clearInterval(this.intervalId), this.intervalId = null), this.el.remove();
1315
1859
  }
1316
1860
  }
1317
- class q {
1861
+ class ii {
1862
+ constructor() {
1863
+ this.session = null, this.bar = null, this.result = null;
1864
+ }
1865
+ async start(t, e, s) {
1866
+ this.session = new ti(t, s), this.bar = new ei(
1867
+ t,
1868
+ e,
1869
+ () => this.session?.getDuration() ?? 0,
1870
+ s
1871
+ ), await this.session.start();
1872
+ }
1873
+ stop() {
1874
+ return this.session ? (this.result = this.session.stop(), this.teardownUI(), this.result) : null;
1875
+ }
1876
+ getRecording() {
1877
+ return this.result;
1878
+ }
1879
+ destroy() {
1880
+ this.teardownUI(), this.result = null;
1881
+ }
1882
+ teardownUI() {
1883
+ this.session?.destroy(), this.session = null, this.bar?.destroy(), this.bar = null;
1884
+ }
1885
+ }
1886
+ class N {
1318
1887
  constructor(t) {
1319
- this.tab = null, this.pet = null, this.toolbar = null, this.session = null, this.popup = null, this.success = null, this.frustrationPrompt = null, this.frustrationDetector = null, this.mode = "idle", this.currentAnnotation = null, this.recordSession = null, this.recordBar = null, this.currentRecording = null, this.config = t, this.messages = $e(t.locale ?? "en"), this.apiClient = new Me(t.projectKey, t.apiUrl), this.consoleCollector = new xe(), this.consoleCollector.start(), this.buildUI(), t.frustrationDetection !== !1 && (this.frustrationDetector = new A(() => this.handleFrustration()), this.frustrationDetector.start());
1888
+ this.tab = null, this.pet = null, this.toolbar = null, this.session = null, this.popup = null, this.clarify = null, this.success = null, this.frustrationPrompt = null, this.frustrationDetector = null, this.mode = "idle", this.currentAnnotation = null, this.recordingManager = null, this.config = t, this.messages = Ye(t.locale ?? "en"), this.apiClient = new Oe(t.projectKey, t.apiUrl, void 0, t.userToken, t.userTokenFn), this.consoleCollector = new Ee(), this.consoleCollector.start(), this.buildUI(), t.frustrationDetection !== !1 && (this.frustrationDetector = new P(() => this.handleFrustration()), this.frustrationDetector.start());
1320
1889
  }
1321
1890
  buildUI() {
1322
- this.shadow = new it(this.config.theme ?? "auto"), (this.config.entryMode ?? "button") === "pet" ? this.pet = new st(this.shadow, this.messages, () => this.handleTabClick()) : this.tab = new rt(
1891
+ this.shadow = new rt(this.config.theme ?? "auto"), (this.config.entryMode ?? "button") === "pet" ? this.pet = new ot(this.shadow, this.messages, () => this.handleTabClick()) : this.tab = new nt(
1323
1892
  this.shadow,
1324
1893
  this.messages,
1325
1894
  this.config.position ?? "right",
1326
- () => this.handleTabClick()
1895
+ () => this.handleTabClick(),
1896
+ this.config.tabText
1327
1897
  );
1328
1898
  }
1329
1899
  handleTabClick() {
1330
1900
  this.mode === "idle" ? (this.dismissFrustrationPrompt(), this.enterAnnotationMode()) : this.exitAll();
1331
1901
  }
1332
1902
  handleFrustration() {
1333
- this.mode !== "idle" || this.frustrationPrompt || (this.frustrationPrompt = new ot(this.shadow, this.messages, {
1903
+ this.mode !== "idle" || this.frustrationPrompt || (this.frustrationPrompt = new lt(this.shadow, this.messages, {
1334
1904
  onTell: () => {
1335
1905
  this.dismissFrustrationPrompt(), this.enterAnnotationMode();
1336
1906
  },
@@ -1341,93 +1911,95 @@ class q {
1341
1911
  this.frustrationPrompt?.destroy(), this.frustrationPrompt = null;
1342
1912
  }
1343
1913
  enterAnnotationMode() {
1344
- this.mode = "annotating", this.tab?.setActive(!0), this.pet?.setActive(!0), this.toolbar = new at(
1914
+ this.mode = "annotating", this.tab?.setActive(!0), this.pet?.setActive(!0), this.toolbar = new ct(
1345
1915
  this.shadow,
1346
1916
  this.messages,
1347
1917
  () => this.exitAll(),
1348
1918
  (t) => this.handleToolbarModeChange(t)
1349
- ), this.session = new P(this.shadow, this.messages, (t, i) => {
1350
- this.currentAnnotation = t, this.showPopup(t.x, t.y, i);
1919
+ ), this.session = new H(this.shadow, this.messages, (t, e) => {
1920
+ this.currentAnnotation = t, this.showPopup(t.x, t.y, e);
1351
1921
  });
1352
1922
  }
1353
1923
  handleToolbarModeChange(t) {
1354
- t === "record" ? this.enterRecordingMode() : (this.exitRecordingMode(), this.session || (this.session = new P(this.shadow, this.messages, (i, r) => {
1355
- this.currentAnnotation = i, this.showPopup(i.x, i.y, r);
1924
+ t === "record" ? (this.mode = "recording", this.session?.destroy(), this.session = null, this.recordingManager = new ii(), this.recordingManager.start(this.shadow, this.messages, () => {
1925
+ this.recordingManager && (this.recordingManager.stop(), this.showPopup(window.innerWidth / 2, window.innerHeight / 2, this.messages.record.timer_label));
1926
+ }).catch(() => {
1927
+ this.mode === "recording" && (this.toolbar?.setMode("markup"), this.handleToolbarModeChange("markup"));
1928
+ })) : (this.recordingManager?.destroy(), this.recordingManager = null, this.session || (this.session = new H(this.shadow, this.messages, (e, s) => {
1929
+ this.currentAnnotation = e, this.showPopup(e.x, e.y, s);
1356
1930
  })), this.mode = "annotating");
1357
1931
  }
1358
- async enterRecordingMode() {
1359
- this.mode = "recording", this.session?.destroy(), this.session = null, this.recordSession = new Fe(this.shadow, () => this.stopRecording()), this.recordBar = new Oe(
1360
- this.shadow,
1361
- this.messages,
1362
- () => this.recordSession?.getDuration() ?? 0,
1363
- () => this.stopRecording()
1364
- ), await this.recordSession.start();
1365
- }
1366
- stopRecording() {
1367
- this.recordSession && (this.currentRecording = this.recordSession.stop(), this.exitRecordingMode(), this.showPopup(
1368
- window.innerWidth / 2,
1369
- window.innerHeight / 2,
1370
- this.messages.record.timer_label
1371
- ));
1372
- }
1373
- exitRecordingMode() {
1374
- this.recordSession?.destroy(), this.recordSession = null, this.recordBar?.destroy(), this.recordBar = null;
1375
- }
1376
- showPopup(t, i, r) {
1377
- this.mode = "popup", this.session?.dismissInteraction(), this.popup = new mt(this.shadow, {
1378
- targetName: r,
1932
+ showPopup(t, e, s) {
1933
+ this.mode = "popup", this.session?.dismissInteraction(), this.popup = new gt(this.shadow, {
1934
+ targetName: s,
1379
1935
  x: t,
1380
- y: i,
1936
+ y: e,
1381
1937
  messages: this.messages,
1382
- onSubmit: (s) => this.handleSubmit(s),
1938
+ onSubmit: (r) => this.handleSubmit(r),
1383
1939
  onClose: () => this.exitAll()
1384
1940
  });
1385
1941
  }
1386
1942
  async handleSubmit(t) {
1387
1943
  if (!this.popup) return;
1388
1944
  this.popup.setLoading(!0);
1389
- const i = this.currentAnnotation, r = this.currentRecording ?? void 0, [s, n] = await Promise.all([
1390
- de(i ? [i] : []),
1391
- Promise.resolve(Se())
1392
- ]), o = Re(
1945
+ const e = this.currentAnnotation, s = this.recordingManager?.getRecording() ?? void 0, [r, n] = await Promise.all([
1946
+ be(e ? [e] : []),
1947
+ Promise.resolve(_e())
1948
+ ]), o = je(
1393
1949
  t,
1394
1950
  n,
1395
1951
  this.consoleCollector.getErrors(),
1396
- i,
1952
+ e,
1397
1953
  this.config.user,
1398
- r
1954
+ s
1399
1955
  );
1400
1956
  try {
1401
- await this.apiClient.submitFeedback(o, s), this.popup?.destroy(), this.popup = null, this.session?.destroy(), this.session = null, this.currentRecording = null, this.showSuccess();
1957
+ const a = await this.apiClient.submitFeedback(o, r);
1958
+ this.popup?.destroy(), this.popup = null, this.session?.destroy(), this.session = null, this.recordingManager?.destroy(), this.recordingManager = null, this.showClarify(a.id, a.project_id);
1402
1959
  } catch {
1403
1960
  this.popup?.setLoading(!1), this.popup?.setError(this.messages.error.submit);
1404
1961
  }
1405
1962
  }
1406
- showSuccess() {
1407
- this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1), this.success = new gt(this.shadow, this.messages, () => {
1408
- this.success?.destroy(), this.success = null;
1963
+ showClarify(t, e) {
1964
+ this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1), this.clarify = new wt(this.shadow, {
1965
+ feedbackId: t,
1966
+ apiClient: this.apiClient,
1967
+ messages: this.messages,
1968
+ onDone: () => {
1969
+ this.clarify?.destroy(), this.clarify = null, this.showSuccess(e);
1970
+ }
1409
1971
  });
1410
1972
  }
1973
+ showSuccess(t) {
1974
+ this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1);
1975
+ const s = `${this.config.apiUrl ? this.config.apiUrl.replace(/\/api\/v1\/?$/, "") : "https://makethisbetter.dev"}/board/projects/${t}/feedbacks`, r = !!(this.config.userToken || this.config.userTokenFn);
1976
+ this.success = new vt(this.shadow, this.messages, () => {
1977
+ this.success?.destroy(), this.success = null;
1978
+ }, r ? async () => {
1979
+ const n = await this.apiClient.resolveUserToken();
1980
+ n && window.open(`${s}?identity=${encodeURIComponent(n)}`, "_blank");
1981
+ } : void 0);
1982
+ }
1411
1983
  exitAll() {
1412
- this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1), this.toolbar?.destroy(), this.toolbar = null, this.session?.destroy(), this.session = null, this.popup?.destroy(), this.popup = null, this.currentAnnotation = null, this.currentRecording = null, this.exitRecordingMode();
1984
+ this.mode = "idle", this.tab?.setActive(!1), this.pet?.setActive(!1), this.toolbar?.destroy(), this.toolbar = null, this.session?.destroy(), this.session = null, this.popup?.destroy(), this.popup = null, this.clarify?.destroy(), this.clarify = null, this.currentAnnotation = null, this.recordingManager?.destroy(), this.recordingManager = null;
1413
1985
  }
1414
1986
  destroy() {
1415
- this.exitAll(), this.consoleCollector.stop(), this.frustrationDetector?.stop(), this.dismissFrustrationPrompt(), this.success?.destroy(), this.tab?.destroy(), this.pet?.destroy(), this.exitRecordingMode(), this.shadow.destroy();
1987
+ this.exitAll(), this.consoleCollector.stop(), this.frustrationDetector?.stop(), this.dismissFrustrationPrompt(), this.clarify?.destroy(), this.success?.destroy(), this.tab?.destroy(), this.pet?.destroy(), this.recordingManager?.destroy(), this.shadow.destroy();
1416
1988
  }
1417
1989
  }
1418
1990
  let f = null;
1419
- const Ue = {
1420
- init(e) {
1991
+ const si = {
1992
+ init(i) {
1421
1993
  f && (f.destroy(), f = null), document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", () => {
1422
- f = new q(e);
1423
- }) : f = new q(e);
1994
+ f = new N(i);
1995
+ }) : f = new N(i);
1424
1996
  },
1425
1997
  destroy() {
1426
1998
  f?.destroy(), f = null;
1427
1999
  }
1428
2000
  };
1429
- typeof window < "u" && (window.MakeThisBetter = Ue);
2001
+ typeof window < "u" && (window.MakeThisBetter = si);
1430
2002
  export {
1431
- Ue as MakeThisBetter
2003
+ si as MakeThisBetter
1432
2004
  };
1433
2005
  //# sourceMappingURL=makethisbetter.esm.js.map