makethisbetter 1.28.0 → 1.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/i18n/de.d.ts +2 -0
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/en.d.ts +2 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/es.d.ts +2 -0
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/fr.d.ts +2 -0
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/ja.d.ts +2 -0
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ko.d.ts +2 -0
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/zh-CN.d.ts +2 -0
- package/dist/i18n/zh-CN.d.ts.map +1 -1
- package/dist/makethisbetter.cjs +16 -27
- package/dist/makethisbetter.cjs.map +1 -1
- package/dist/makethisbetter.esm.js +380 -388
- package/dist/makethisbetter.esm.js.map +1 -1
- package/dist/makethisbetter.js +24 -35
- package/dist/makethisbetter.js.map +1 -1
- package/dist/makethisbetter.standalone.js +1206 -1214
- package/dist/makethisbetter.standalone.js.map +1 -1
- package/dist/popup/chat-popup.d.ts +6 -2
- package/dist/popup/chat-popup.d.ts.map +1 -1
- package/dist/widget/controller.d.ts.map +1 -1
- package/dist/widget/submission-lifecycle.d.ts +3 -5
- package/dist/widget/submission-lifecycle.d.ts.map +1 -1
- package/dist/widget/tab.d.ts +1 -0
- package/dist/widget/tab.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/i18n/de.ts +2 -0
- package/src/i18n/en.ts +2 -0
- package/src/i18n/es.ts +2 -0
- package/src/i18n/fr.ts +2 -0
- package/src/i18n/ja.ts +2 -0
- package/src/i18n/ko.ts +2 -0
- package/src/i18n/zh-CN.ts +2 -0
- package/src/popup/chat-popup.ts +59 -18
- package/src/styles/widget.css +76 -64
- package/src/widget/controller.ts +12 -14
- package/src/widget/submission-lifecycle.ts +6 -22
- package/src/widget/tab.ts +6 -0
- package/dist/popup/failure.d.ts +0 -12
- package/dist/popup/failure.d.ts.map +0 -1
- package/dist/screenshot/html-to-image-fallback.test.d.ts +0 -2
- package/dist/screenshot/html-to-image-fallback.test.d.ts.map +0 -1
- package/src/popup/failure.ts +0 -57
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
const tr = `*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;line-height:1.5;color:#191a1c;-webkit-font-smoothing:antialiased}:host{--mtb-brand-primary: #059669;--mtb-brand-hover: #047857;--mtb-brand-active: #065f46;--mtb-brand-on-primary: #fff;--mtb-brand-rgb: 5, 150, 105;--mtb-brand-on-primary-rgb: 255, 255, 255;--mtb-brand-emphasis: #10b981;--mtb-brand-emphasis-rgb: 16, 185, 129;--mtb-brand-gradient-start: #10b981;--mtb-brand-gradient-end: #059669;--mtb-panel-bg: #fff;--mtb-panel-border: rgba(0, 0, 0, .1);--mtb-panel-divider: rgba(0, 0, 0, .06);--mtb-fg: #191a1c;--mtb-field-bg: #fff;--mtb-field-bg-subtle: #fafafa;--mtb-field-border: rgba(0, 0, 0, .12);--mtb-field-border-soft: rgba(0, 0, 0, .09);--mtb-placeholder-fg: rgba(0, 0, 0, .34);--mtb-action-bg: #fff;--mtb-action-border: rgba(0, 0, 0, .12);--mtb-action-fg: rgba(0, 0, 0, .55);--mtb-action-hover-bg: rgba(0, 0, 0, .04);--mtb-clarify-close-fg: rgba(0, 0, 0, .38);--mtb-clarify-close-hover-fg: rgba(0, 0, 0, .7);--mtb-dismiss-fg: rgba(0, 0, 0, .4);--mtb-dismiss-hover-fg: rgba(0, 0, 0, .7);--mtb-quick-hover-bg: rgba(var(--mtb-brand-emphasis-rgb), .06);--mtb-quick-hover-border: rgba(var(--mtb-brand-emphasis-rgb), .3);--mtb-quick-selected-bg: rgba(var(--mtb-brand-emphasis-rgb), .1);--mtb-quick-selected-border: rgba(var(--mtb-brand-emphasis-rgb), .5);--mtb-field-focus-border: var(--mtb-brand-emphasis);--mtb-chat-card-bg: #FFFFFF;--mtb-chat-card-shadow: 0 24px 64px rgba(0, 0, 0, .18);--mtb-chat-raised-bg: #F9FAFB;--mtb-chat-write-bg: #FFFFFF;--mtb-chat-title-fg: #111827;--mtb-chat-body-fg: #1f2937;--mtb-chat-muted-fg: #6b7280;--mtb-chat-placeholder-fg: #9ca3af;--mtb-chat-pill-fg: #374151;--mtb-chat-pill-shadow: 0 1px 3px rgba(0, 0, 0, .08), 0 0 0 1px rgba(0, 0, 0, .04);--mtb-chat-pill-hover-shadow: 0 3px 10px rgba(0, 0, 0, .12), 0 0 0 1px rgba(0, 0, 0, .05);--mtb-chat-close-hover-bg: #F3F4F6;--mtb-chat-close-hover-fg: #111827;--mtb-chat-composer-shadow: 0 -1px 6px rgba(0, 0, 0, .06);--mtb-chat-skip-fg: #9ca3af;--mtb-chat-skip-hover-fg: #4b5563;--mtb-chat-camera-lens: #fff;--mtb-chat-accent: var(--mtb-brand-primary);--mtb-chat-accent-fg: var(--mtb-brand-on-primary);--mtb-chat-accent-rgb: var(--mtb-brand-rgb);--mtb-chat-accent-fg-rgb: var(--mtb-brand-on-primary-rgb);--mtb-chat-link-fg: var(--mtb-brand-primary);--mtb-chat-send-shadow: 0 2px 8px rgba(var(--mtb-chat-accent-rgb), .35);--mtb-chat-success-icon-shadow: 0 4px 14px rgba(var(--mtb-chat-accent-rgb), .35);--mtb-chat-logo-start: #10b981;--mtb-chat-logo-end: #059669;--mtb-chat-logo-fg: #fff}:host([data-mtb-theme="dark"]){--mtb-panel-bg: #151719;--mtb-panel-border: rgba(255, 255, 255, .12);--mtb-panel-divider: rgba(255, 255, 255, .1);--mtb-fg: #f9fafb;--mtb-field-bg: #1f2327;--mtb-field-bg-subtle: #1f2327;--mtb-field-border: rgba(255, 255, 255, .12);--mtb-field-border-soft: rgba(255, 255, 255, .12);--mtb-placeholder-fg: rgba(255, 255, 255, .4);--mtb-action-bg: #1f2327;--mtb-action-border: rgba(255, 255, 255, .14);--mtb-action-fg: rgba(255, 255, 255, .7);--mtb-action-hover-bg: rgba(255, 255, 255, .06);--mtb-clarify-close-fg: rgba(255, 255, 255, .45);--mtb-clarify-close-hover-fg: rgba(255, 255, 255, .75);--mtb-dismiss-fg: rgba(255, 255, 255, .4);--mtb-dismiss-hover-fg: rgba(255, 255, 255, .7);--mtb-quick-hover-bg: rgba(var(--mtb-brand-emphasis-rgb), .12);--mtb-quick-hover-border: rgba(var(--mtb-brand-emphasis-rgb), .45);--mtb-quick-selected-bg: rgba(var(--mtb-brand-emphasis-rgb), .18);--mtb-quick-selected-border: var(--mtb-brand-primary);--mtb-field-focus-border: var(--mtb-brand-emphasis);--mtb-chat-card-bg: #17191C;--mtb-chat-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--mtb-chat-raised-bg: #202327;--mtb-chat-write-bg: #23272C;--mtb-chat-title-fg: #E8EAED;--mtb-chat-body-fg: #DCE0E4;--mtb-chat-muted-fg: #B0B6BD;--mtb-chat-placeholder-fg: #A3AAB2;--mtb-chat-pill-fg: #DDE1E5;--mtb-chat-pill-shadow: 0 1px 3px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .08);--mtb-chat-pill-hover-shadow: 0 4px 14px rgba(0, 0, 0, .6), 0 0 0 1px rgba(255, 255, 255, .14);--mtb-chat-close-hover-bg: rgba(255, 255, 255, .08);--mtb-chat-close-hover-fg: #FFFFFF;--mtb-chat-composer-shadow: 0 -1px 6px rgba(0, 0, 0, .45);--mtb-chat-skip-fg: #A3AAB2;--mtb-chat-skip-hover-fg: #E8EAED;--mtb-chat-camera-lens: #EAF7EE;--mtb-chat-accent: #4ADE80;--mtb-chat-accent-fg: #0D1210;--mtb-chat-accent-rgb: 74, 222, 128;--mtb-chat-accent-fg-rgb: 13, 18, 16;--mtb-chat-link-fg: #5BD98A;--mtb-chat-send-shadow: 0 1px 3px rgba(0, 0, 0, .5);--mtb-chat-success-icon-shadow: 0 2px 10px rgba(0, 0, 0, .5);--mtb-chat-logo-start: #1E9E4A;--mtb-chat-logo-end: #0B8AA0;--mtb-chat-logo-fg: #EAF7EE}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]){--mtb-panel-bg: #151719;--mtb-panel-border: rgba(255, 255, 255, .12);--mtb-panel-divider: rgba(255, 255, 255, .1);--mtb-fg: #f9fafb;--mtb-field-bg: #1f2327;--mtb-field-bg-subtle: #1f2327;--mtb-field-border: rgba(255, 255, 255, .12);--mtb-field-border-soft: rgba(255, 255, 255, .12);--mtb-placeholder-fg: rgba(255, 255, 255, .4);--mtb-action-bg: #1f2327;--mtb-action-border: rgba(255, 255, 255, .14);--mtb-action-fg: rgba(255, 255, 255, .7);--mtb-action-hover-bg: rgba(255, 255, 255, .06);--mtb-clarify-close-fg: rgba(255, 255, 255, .45);--mtb-clarify-close-hover-fg: rgba(255, 255, 255, .75);--mtb-dismiss-fg: rgba(255, 255, 255, .4);--mtb-dismiss-hover-fg: rgba(255, 255, 255, .7);--mtb-quick-hover-bg: rgba(var(--mtb-brand-emphasis-rgb), .12);--mtb-quick-hover-border: rgba(var(--mtb-brand-emphasis-rgb), .45);--mtb-quick-selected-bg: rgba(var(--mtb-brand-emphasis-rgb), .18);--mtb-quick-selected-border: var(--mtb-brand-primary);--mtb-field-focus-border: var(--mtb-brand-emphasis);--mtb-chat-card-bg: #17191C;--mtb-chat-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--mtb-chat-raised-bg: #202327;--mtb-chat-write-bg: #23272C;--mtb-chat-title-fg: #E8EAED;--mtb-chat-body-fg: #DCE0E4;--mtb-chat-muted-fg: #B0B6BD;--mtb-chat-placeholder-fg: #A3AAB2;--mtb-chat-pill-fg: #DDE1E5;--mtb-chat-pill-shadow: 0 1px 3px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .08);--mtb-chat-pill-hover-shadow: 0 4px 14px rgba(0, 0, 0, .6), 0 0 0 1px rgba(255, 255, 255, .14);--mtb-chat-close-hover-bg: rgba(255, 255, 255, .08);--mtb-chat-close-hover-fg: #FFFFFF;--mtb-chat-composer-shadow: 0 -1px 6px rgba(0, 0, 0, .45);--mtb-chat-skip-fg: #A3AAB2;--mtb-chat-skip-hover-fg: #E8EAED;--mtb-chat-camera-lens: #EAF7EE;--mtb-chat-accent: #4ADE80;--mtb-chat-accent-fg: #0D1210;--mtb-chat-accent-rgb: 74, 222, 128;--mtb-chat-accent-fg-rgb: 13, 18, 16;--mtb-chat-link-fg: #5BD98A;--mtb-chat-send-shadow: 0 1px 3px rgba(0, 0, 0, .5);--mtb-chat-success-icon-shadow: 0 2px 10px rgba(0, 0, 0, .5);--mtb-chat-logo-start: #1E9E4A;--mtb-chat-logo-end: #0B8AA0;--mtb-chat-logo-fg: #EAF7EE}}.mtb-tab{--mtb-tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='8'/%3E%3Ccircle cx='12' cy='12' r='2.4' fill='%23000' stroke='none'/%3E%3Cpath d='M12 1.8v3.4M12 18.8v3.4M1.8 12h3.4M18.8 12h3.4'/%3E%3C/svg%3E");--mtb-tab-bg: var(--mtb-brand-primary);--mtb-tab-hover-bg: var(--mtb-brand-hover);--mtb-tab-active-bg: var(--mtb-brand-active);--mtb-tab-shadow-color: var(--mtb-brand-rgb);--mtb-tab-fg: var(--mtb-brand-on-primary);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:var(--mtb-tab-bg);color:var(--mtb-tab-fg);border-radius:8px 0 0 8px;cursor:pointer;box-shadow:-2px 0 14px rgba(var(--mtb-tab-shadow-color),.35);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 rgba(var(--mtb-tab-shadow-color),.35)}.mtb-tab:hover{background:var(--mtb-tab-hover-bg);box-shadow:-3px 0 20px rgba(var(--mtb-tab-shadow-color),.45)}.mtb-tab.active{background:var(--mtb-tab-active-bg)}.mtb-hint-bar{position:fixed;top:18px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;height:38px;padding:0 16px;border-radius:13px;background:linear-gradient(120deg,var(--mtb-brand-gradient-start),var(--mtb-brand-gradient-end));color:var(--mtb-brand-on-primary);box-shadow:0 10px 26px #0f172a38;animation:mtbHintIn .2s ease;white-space:nowrap;transition:opacity .15s ease;pointer-events:none}.mtb-hint-bar--under-pointer{opacity:.3}.mtb-hint-bar.mtb-hint-bar--dismissed{display:none}@keyframes mtbHintIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}.mtb-toolbar{position:fixed;top:50%;right:8px;transform:translateY(-50%);z-index:2147483647;display:flex;flex-direction:column;align-items:center;gap:6px;width:38px;padding:6px 0;max-height:calc(100vh - 24px);border-radius:19px;background:linear-gradient(160deg,var(--mtb-brand-gradient-start),var(--mtb-brand-gradient-end));color:var(--mtb-brand-on-primary);box-shadow:0 8px 22px #0f172a33;animation:mtbEdgeBarIn .2s ease;white-space:nowrap;pointer-events:none}.mtb-toolbar.left{right:auto;left:8px;animation:mtbEdgeBarInLeft .2s ease}@keyframes mtbBarIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}@keyframes mtbEdgeBarIn{0%{transform:translate(12px,-50%);opacity:0}to{transform:translateY(-50%);opacity:1}}@keyframes mtbEdgeBarInLeft{0%{transform:translate(-12px,-50%);opacity:0}to{transform:translateY(-50%);opacity:1}}.mtb-toolbar-label{display:none}:host([data-mtb-toolbar]) .mtb-tab{display:none}.mtb-toolbar-modes{display:flex;align-items:center;gap:3px;background:rgba(var(--mtb-brand-on-primary-rgb),.16);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:var(--mtb-brand-on-primary);transition:all .12s}.mtb-toolbar-mode-btn.active{background:#fff;color:var(--mtb-brand-active)}.mtb-toolbar-hint{font-size:12px;color:var(--mtb-brand-on-primary);white-space:nowrap}.mtb-toolbar-sep{width:20px;height:1px;align-self:center;background:rgba(var(--mtb-brand-on-primary-rgb),.22)}.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:var(--mtb-brand-on-primary);cursor:pointer;background:rgba(var(--mtb-brand-on-primary-rgb),.16);border:none;font-family:inherit;transition:background .12s}.mtb-toolbar-modes{flex-direction:column;gap:6px;padding:0;background:none;border-radius:0}.mtb-toolbar-mode-btn,.mtb-exit-btn{pointer-events:auto;display:flex;align-items:center;justify-content:center;gap:0;width:30px;height:30px;padding:0;border-radius:50%;background:none;color:var(--mtb-brand-on-primary)}.mtb-toolbar-mode-btn{opacity:.72}.mtb-exit-btn{opacity:1}.mtb-toolbar-mode-btn:hover,.mtb-exit-btn:hover{background:rgba(var(--mtb-brand-on-primary-rgb),.16);color:var(--mtb-brand-on-primary);opacity:1}.mtb-toolbar-mode-btn.active,.mtb-toolbar-mode-btn.active:hover{background:var(--mtb-brand-on-primary);color:var(--mtb-brand-hover);opacity:1}.mtb-exit-btn{color:var(--mtb-brand-on-primary)}.mtb-toolbar-sep{width:16px;height:1px;margin:1px 0;align-self:center;background:rgba(var(--mtb-brand-on-primary-rgb),.28)}.mtb-exit-btn:hover{background:rgba(var(--mtb-brand-on-primary-rgb),.28)}.mtb-overlay{position:fixed;inset:0;z-index:2147483640;cursor:crosshair;touch-action:none}.mtb-dim{position:fixed;inset:0;z-index:2147483639;background:#00000014}.mtb-highlight{position:fixed;z-index:2147483641;pointer-events:none;border:2px solid var(--mtb-brand-emphasis);border-radius:6px;background:rgba(var(--mtb-brand-emphasis-rgb),.06);transition:all .08s ease}.mtb-highlight-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%,-100%);max-width:240px;overflow:hidden;text-overflow:ellipsis;background:var(--mtb-brand-active);color:var(--mtb-brand-on-primary);padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:0 4px 12px #0000002e;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-highlight-tooltip.below{transform:translate(-50%)}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--mtb-brand-active)}.mtb-highlight-tooltip.below:after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:var(--mtb-brand-active)}.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:var(--mtb-brand-primary);border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--mtb-brand-on-primary);font-weight:700;box-shadow:0 0 0 1px #0f172aad,0 2px 8px rgba(var(--mtb-brand-rgb),.45);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)}}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-draw-shot input:disabled{appearance:none;-webkit-appearance:none;border:none;border-radius:4px;background-color:var(--mtb-placeholder-fg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:center;background-size:contain;opacity:1}.mtb-draw-shot input:disabled{background-color:#0000004d}.mtb-btn-loading{pointer-events:none;opacity:.8}.mtb-btn-loading:after{content:"";display:inline-block;width:10px;height:10px;margin-left:6px;border:1.5px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:mtbSpin .7s linear infinite;vertical-align:middle}.mtb-chat{position:fixed;z-index:2147483645;display:flex;flex-direction:column;width:min(320px,calc(100vw - 56px));max-height:420px;background:var(--mtb-chat-card-bg);border-radius:16px;color:var(--mtb-chat-title-fg);box-shadow:var(--mtb-chat-card-shadow);overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-chat.mtb-chat-receipt{inset:auto 20px 20px auto;width:min(320px,calc(100vw - 40px));animation:none}.mtb-chat-header{display:flex;align-items:center;gap:7px;padding:11px 12px;background:var(--mtb-chat-raised-bg);flex-shrink:0}.mtb-chat-brand{display:flex;align-items:center;gap:7px;text-decoration:none;opacity:.9;transition:opacity .16s}.mtb-chat-brand:hover{opacity:1}.mtb-chat-brand:hover .mtb-chat-brand-name{text-decoration:underline;text-underline-offset:2px}.mtb-chat-logo{width:20px;height:20px;border-radius:6px;overflow:hidden;flex:none}.mtb-chat-logo svg{width:100%;height:100%;display:block}.mtb-chat-brand-name{font-size:12px;font-weight:600;color:var(--mtb-chat-title-fg)}.mtb-chat-header-row{display:flex;align-items:center;gap:7px;width:100%}.mtb-chat-header-gap{flex:1}.mtb-chat-close{width:28px;height:28px;border-radius:99px;display:flex;align-items:center;justify-content:center;background:none;border:none;padding:0;color:var(--mtb-chat-muted-fg);cursor:pointer;flex:none;transition:background .16s,color .16s}.mtb-chat-close:hover{background:var(--mtb-chat-close-hover-bg);color:var(--mtb-chat-close-hover-fg)}.mtb-chat-messages{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;min-height:0;background:var(--mtb-chat-card-bg)}.mtb-chat-messages:empty{display:none}.mtb-chat-bubble{font-size:13px;max-width:85%;word-break:break-word}.mtb-chat-bubble-user{align-self:flex-end;background:var(--mtb-chat-accent);color:var(--mtb-chat-accent-fg);line-height:1.45;padding:8px 11px;border-radius:12px 12px 4px}.mtb-chat-bubble-ai{background:var(--mtb-chat-raised-bg);color:var(--mtb-chat-body-fg);line-height:1.5;padding:9px 12px;border-radius:12px 12px 12px 4px}.mtb-chat-ai-row{display:flex;align-items:flex-end;gap:7px}.mtb-chat-avatar{width:22px;height:22px;border-radius:7px;overflow:hidden;flex:none}.mtb-chat-avatar svg{width:100%;height:100%;display:block}.mtb-chat-dots{display:flex;align-items:center;gap:4px;padding:10px 12px;background:var(--mtb-chat-raised-bg);border-radius:12px 12px 12px 4px}.mtb-chat-dots span{width:5px;height:5px;background:var(--mtb-chat-accent);border-radius:99px;animation:mtbChatDot 1.1s infinite}.mtb-chat-dots span:nth-child(2){animation-delay:.15s}.mtb-chat-dots span:nth-child(3){animation-delay:.3s}@keyframes mtbChatDot{0%,60%,to{transform:translateY(0);opacity:.45}30%{transform:translateY(-4px);opacity:1}}.mtb-chat-suggestions{display:flex;flex-wrap:wrap;gap:6px;padding-left:29px}.mtb-chat-sg{background:var(--mtb-chat-write-bg);border:none;border-radius:99px;padding:5px 10px;font-size:11px;font-weight:500;font-family:inherit;color:var(--mtb-chat-pill-fg);cursor:pointer;box-shadow:var(--mtb-chat-pill-shadow);transition:box-shadow .16s,transform .16s}.mtb-chat-sg:hover{box-shadow:var(--mtb-chat-pill-hover-shadow);transform:translateY(-1px)}.mtb-chat-quick-replies{display:flex;flex-wrap:wrap;gap:6px;padding:12px;background:var(--mtb-chat-card-bg)}.mtb-chat-qr{display:flex;align-items:center;gap:5px;background:var(--mtb-chat-write-bg);border:none;border-radius:99px;padding:7px 12px;font-size:12px;font-weight:500;font-family:inherit;color:var(--mtb-chat-pill-fg);cursor:pointer;box-shadow:var(--mtb-chat-pill-shadow);transition:box-shadow .16s,transform .16s}.mtb-chat-qr:hover{box-shadow:var(--mtb-chat-pill-hover-shadow);transform:translateY(-1px)}.mtb-chat-qr:disabled{opacity:.5;pointer-events:none;cursor:default;transform:none!important;box-shadow:var(--mtb-chat-pill-shadow)!important}.mtb-chat-composer{display:flex;flex-direction:column;gap:8px;padding:10px;background:var(--mtb-chat-raised-bg);box-shadow:var(--mtb-chat-composer-shadow);flex-shrink:0}.mtb-chat-composer-disabled{pointer-events:none}.mtb-chat-composer-disabled .mtb-chat-input{opacity:.3}.mtb-chat-input{box-sizing:border-box;width:100%;min-height:64px;max-height:132px;padding:10px 12px;background:var(--mtb-chat-write-bg);border:none;border-radius:10px;font-size:13px;line-height:1.5;font-family:inherit;color:var(--mtb-chat-title-fg);outline:none;resize:none}.mtb-chat-input::placeholder{color:var(--mtb-chat-placeholder-fg)}.mtb-chat-input:disabled{opacity:.5;cursor:default}.mtb-chat-actions{display:flex;align-items:center;gap:10px}.mtb-chat-actions-gap{flex:1}.mtb-chat-screenshot,.mtb-chat-attachment{display:flex;align-items:center;gap:6px;background:none;border:none;padding:0;font-family:inherit;color:var(--mtb-chat-accent);cursor:pointer;transition:opacity .16s}.mtb-chat-screenshot svg,.mtb-chat-attachment svg{display:flex;flex:none}.mtb-chat-icon-lens{fill:var(--mtb-chat-camera-lens)}.mtb-chat-screenshot:hover{opacity:.75}.mtb-chat-attachment{cursor:default}.mtb-chat-capture-label{font-size:11px;color:var(--mtb-chat-muted-fg)}.mtb-chat-screenshot[aria-pressed=false],.mtb-chat-screenshot-off{opacity:.4;color:var(--mtb-chat-muted-fg)}.mtb-chat-screenshot:disabled{opacity:.3;pointer-events:none;cursor:default}.mtb-chat-skip{height:26px;border:none;border-radius:6px;background:none;display:flex;align-items:center;padding:0 4px;font-size:11px;font-weight:500;font-family:inherit;color:var(--mtb-chat-skip-fg);cursor:pointer;flex:none;transition:color .16s}.mtb-chat-skip:hover{color:var(--mtb-chat-skip-hover-fg)}.mtb-chat-send{position:relative;height:34px;padding:0 14px;border:none;border-radius:10px;background:var(--mtb-chat-accent);font-size:12px;font-weight:600;font-family:inherit;color:var(--mtb-chat-accent-fg);display:flex;align-items:center;justify-content:center;flex:none;cursor:pointer;box-shadow:var(--mtb-chat-send-shadow)}.mtb-chat-send:disabled{opacity:.3;box-shadow:none;cursor:default}.mtb-chat-error-row{display:flex;align-items:center;justify-content:center;gap:8px;padding:4px 0}.mtb-chat-error-text{font-size:11px;color:var(--mtb-danger, #ef4444)}.mtb-chat-error-retry{font-size:11px;font-weight:600;font-family:inherit;color:var(--mtb-chat-pill-fg);background:var(--mtb-chat-write-bg);border:none;border-radius:999px;padding:4px 11px;box-shadow:var(--mtb-chat-pill-shadow);cursor:pointer}.mtb-chat-error-retry:hover{box-shadow:var(--mtb-chat-pill-hover-shadow)}.mtb-chat-success{padding:30px 20px 26px;display:flex;flex-direction:column;align-items:center;gap:10px;background:var(--mtb-chat-card-bg);animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1) both}.mtb-chat-success-simple{padding-top:34px;padding-bottom:22px}.mtb-chat-success-icon{width:40px;height:40px;border-radius:99px;background:var(--mtb-chat-accent);color:var(--mtb-chat-accent-fg);display:flex;align-items:center;justify-content:center;box-shadow:var(--mtb-chat-success-icon-shadow)}.mtb-chat-success-title{font-size:15px;font-weight:600;color:var(--mtb-chat-title-fg);margin-top:2px;text-align:center}.mtb-chat-success-link{display:inline-flex;align-items:center;font-size:12px;font-weight:500;color:var(--mtb-chat-link-fg);text-decoration:none;margin-top:4px;cursor:pointer}.mtb-chat-success-link-pending{color:var(--mtb-chat-muted-fg);cursor:default;pointer-events:none}.mtb-chat-email-card{align-self:stretch;margin-top:10px;background:var(--mtb-chat-raised-bg);border-radius:10px;padding:10px;display:flex;flex-direction:column;gap:7px}.mtb-chat-email-row{display:flex;align-items:center;gap:7px}.mtb-chat-email-field{flex:1;background:var(--mtb-chat-write-bg);border-radius:8px;box-sizing:border-box;min-height:40px;display:flex;align-items:center;padding:0 10px;min-width:0}.mtb-chat-email-input{flex:1;min-width:0;background:none;border:none;outline:none;font-size:12px;font-family:inherit;color:var(--mtb-chat-title-fg)}.mtb-chat-email-input::placeholder{color:var(--mtb-chat-placeholder-fg)}.mtb-chat-email-submit{height:30px;padding:0 10px;border:none;border-radius:8px;background:var(--mtb-chat-accent);font-size:11px;font-weight:600;font-family:inherit;color:var(--mtb-chat-accent-fg);display:flex;align-items:center;justify-content:center;flex:none;cursor:pointer}.mtb-chat-email-submit:disabled{opacity:.3;cursor:default}.mtb-chat-email-note{font-size:12px;color:var(--mtb-chat-muted-fg);text-align:center}.mtb-chat-email-error{font-size:11px;color:var(--mtb-danger, #ef4444);text-align:center}.mtb-failure{position:fixed;z-index:2147483645;width:332px;background:var(--mtb-panel-bg);border:1px solid var(--mtb-panel-border);border-radius:16px;color:var(--mtb-fg);box-shadow:0 24px 64px #0000003d;padding:24px 22px;text-align:center;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-failure-icon{width:46px;height:46px;border-radius:50%;background:#dc262617;display:flex;align-items:center;justify-content:center;margin:0 auto 12px}.mtb-failure-title{font-size:15px;font-weight:600;margin-bottom:14px;letter-spacing:-.01em;line-height:1.45;color:var(--mtb-fg)}.mtb-failure-title:last-child{margin-bottom:0}.mtb-failure-actions{display:flex;align-items:center;justify-content:center}.mtb-failure-close{position:absolute;top:12px;right:12px;background:none;border:none;cursor:pointer;padding:3px;color:var(--mtb-clarify-close-fg);display:flex;transition:color .12s}.mtb-failure-close:hover{color:var(--mtb-clarify-close-hover-fg)}.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(var(--mtb-brand-rgb),.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:var(--mtb-panel-bg);border:1px solid var(--mtb-panel-border);border-radius:12px;color:var(--mtb-fg);box-shadow:0 8px 30px #0000001f;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.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:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-frustration-tell:hover{background:var(--mtb-brand-hover)}.mtb-frustration-tell:active{background:var(--mtb-brand-active)}.mtb-frustration-dismiss{height:28px;padding:0 8px;border:none;border-radius:7px;background:transparent;color:var(--mtb-dismiss-fg);cursor:pointer;font-family:inherit;font-size:12px;transition:color .12s}.mtb-frustration-dismiss:hover{color:var(--mtb-dismiss-hover-fg)}.mtb-record-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:12px;height:42px;padding:0 8px 0 14px;border-radius:12px;background:#0f172aeb;box-shadow:0 8px 24px #00000040;animation:mtbBarIn .2s ease}.mtb-record-dot{width:8px;height:8px;border-radius:50%;background:#dc2626;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:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-record-stop:hover{background:var(--mtb-brand-hover)}.mtb-record-stop:active{background:var(--mtb-brand-active)}.mtb-click-ripple{position:fixed;z-index:2147483644;width:24px;height:24px;border-radius:50%;border:2px solid var(--mtb-brand-emphasis);background:rgba(var(--mtb-brand-emphasis-rgb),.25);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}}@keyframes mtbDot{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}.mtb-clarify-retry{flex:1;height:30px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:none;border-radius:8px;background:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-clarify-retry:not(:disabled):hover{background:var(--mtb-brand-hover)}.mtb-clarify-retry:not(:disabled):active{background:var(--mtb-brand-active)}.mtb-clarify-retry:disabled{background:#00000026;cursor:not-allowed}@keyframes mtbSpin{to{transform:rotate(360deg)}}.mtb-dim-clickable{z-index:2147483643;pointer-events:auto;cursor:default;background:#0000001f}.mtb-draw-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:8px;height:46px;padding:0 8px 0 12px;border-radius:13px;background:#fff;border:1px solid rgba(0,0,0,.08);box-shadow:0 10px 30px #0f172a38;animation:mtbBarIn .2s ease;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-draw-input{width:220px;height:32px;padding:0 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:13px;color:#191a1c;outline:none;background:#fafafa;transition:border-color .12s,box-shadow .12s,background .12s}.mtb-draw-input:focus{border-color:var(--mtb-brand-emphasis);box-shadow:0 0 0 3px rgba(var(--mtb-brand-emphasis-rgb),.15);background:#fff}.mtb-draw-input::placeholder{color:#00000057}.mtb-draw-icon-btn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:8px;background:transparent;color:#374151;cursor:pointer;transition:background .12s,color .12s}.mtb-draw-icon-btn:hover:not(:disabled){background:#0000000f}.mtb-draw-icon-btn:disabled{color:#00000038;cursor:default}.mtb-draw-shot{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:#0000008c;white-space:nowrap;cursor:default;user-select:none}.mtb-draw-shot input{width:14px;height:14px;margin:0;accent-color:var(--mtb-brand-primary);cursor:default}.mtb-draw-sep{width:1px;height:22px;background:#0000001a}.mtb-draw-cancel{height:32px;padding:0 12px;border:1px solid rgba(0,0,0,.12);border-radius:8px;background:#fff;color:#0000008c;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:550;transition:background .12s}.mtb-draw-cancel:hover{background:#0000000a}.mtb-draw-submit{height:32px;padding:0 14px;border:none;border-radius:8px;background:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-draw-submit:hover:not(:disabled){background:var(--mtb-brand-hover)}.mtb-draw-submit:active:not(:disabled){background:var(--mtb-brand-active)}.mtb-draw-submit:disabled{opacity:.6;cursor:default}.mtb-record-preview{margin-bottom:12px}.mtb-record-preview-stage{position:relative;width:100%;height:132px;border-radius:10px;overflow:hidden;background:#0f172a;display:flex;align-items:center;justify-content:center}.mtb-record-preview-stage.playing{align-items:flex-start;justify-content:flex-start}.mtb-record-preview-play{width:44px;height:44px;border-radius:50%;border:none;background:#ffffffeb;color:var(--mtb-brand-primary);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .12s,background .12s}.mtb-record-preview-play:hover:not(:disabled){transform:scale(1.06);background:#fff}.mtb-record-preview-play:disabled{cursor:default;opacity:.6}.mtb-record-preview-badge{position:absolute;right:8px;bottom:8px;padding:2px 7px;border-radius:6px;background:#0009;color:#fff;font-size:11px;font-variant-numeric:tabular-nums;font-family:JetBrains Mono,SF Mono,monospace}.mtb-record-preview-fallback{color:#ffffffd9;font-size:12px}.mtb-record-preview-name{display:block;margin-top:5px;font-size:11px;color:#0000006b}@media (pointer: coarse){.mtb-tab:after{content:"";position:absolute;inset:-6px 0 -6px -12px}.mtb-tab.left:after{inset:-6px -12px -6px 0}.mtb-toolbar{min-height:56px;border-radius:16px}.mtb-toolbar-mode-btn,.mtb-exit-btn{min-height:44px}.mtb-chat-input,.mtb-chat-email-input,.mtb-draw-input{font-size:16px}}@media (max-width: 480px){.mtb-tab{width:36px;height:40px;padding:0;font-size:0;writing-mode:horizontal-tb;border-radius:12px 0 0 12px;right:env(safe-area-inset-right,0px)}.mtb-tab.left{left:env(safe-area-inset-left,0px);border-radius:0 12px 12px 0}.mtb-tab:before{content:"";width:18px;height:18px;background:currentColor;-webkit-mask:var(--mtb-tab-icon) center / contain no-repeat;mask:var(--mtb-tab-icon) center / contain no-repeat}.mtb-toolbar{inset:0 0 auto;width:100%;max-width:none;max-height:none;transform:none;flex-direction:row;align-items:center;border-radius:0;gap:8px;justify-content:center;padding:env(safe-area-inset-top,0px) 8px 0;height:calc(44px + env(safe-area-inset-top,0px));min-height:calc(44px + env(safe-area-inset-top,0px));border-bottom:1px solid rgba(60,60,67,.16);background:#f8f8f8f5;box-shadow:0 1px 3px #00000014;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);animation:none}.mtb-toolbar-modes{flex-direction:row;gap:0;padding:2px;background:#7676801f;border-radius:8px}.mtb-toolbar-sep{display:none}.mtb-hint-bar{top:calc(44px + env(safe-area-inset-top,0px));right:0;bottom:0;left:0;transform:none;justify-content:center;height:auto;padding:0 24px;border-radius:0;background:#0000001a;box-shadow:none;animation:none;white-space:normal;text-align:center;transition:none}.mtb-hint-bar .mtb-toolbar-hint{max-width:280px;color:#fffffff5;font-size:17px;font-weight:600;line-height:1.4;letter-spacing:0;white-space:normal;text-shadow:0 1px 3px rgba(0,0,0,.45)}.mtb-toolbar-mode-btn,.mtb-exit-btn{position:relative;width:auto;height:32px;min-height:32px;gap:6px;border-radius:6px;padding-right:8px;padding-left:8px;color:#3c3c43d1;transition:none}.mtb-toolbar-mode-btn:hover{background:transparent;color:#3c3c43d1}.mtb-toolbar-mode-btn.active,.mtb-toolbar-mode-btn.active:hover{background:var(--mtb-brand-on-primary);color:var(--mtb-brand-hover);box-shadow:0 1px 3px #0000001f}.mtb-toolbar-mode-btn:after,.mtb-exit-btn:after{content:"";position:absolute;inset:-6px 0}.mtb-exit-btn{width:32px;padding:0;border-radius:50%;background:#7676801f}.mtb-exit-btn:hover{background:#7676801f;color:#3c3c43d1}.mtb-toolbar-label{display:inline}.mtb-exit-btn .mtb-toolbar-label{display:none}.mtb-draw-bar{left:0;right:0;bottom:0;transform:none;height:auto;padding:10px 12px calc(10px + env(safe-area-inset-bottom,0px));border-radius:16px 16px 0 0}.mtb-frustration-prompt{left:0;right:0;bottom:0;flex-direction:column;align-items:stretch;gap:12px;padding:16px 16px calc(16px + env(safe-area-inset-bottom,0px));border-radius:16px 16px 0 0;border-width:1px 0 0;animation:none}.mtb-frustration-actions{display:flex;gap:8px}.mtb-frustration-tell,.mtb-frustration-dismiss{flex:1;min-height:44px}.mtb-chat{position:fixed;left:0!important;right:0;bottom:0;top:auto!important;width:100%;max-width:none;max-height:85vh;border-radius:20px 20px 0 0;box-shadow:0 -18px 60px #0003;animation:none}.mtb-chat-handle{width:36px;height:4px;border-radius:99px;background:#0000001f;margin:0 auto;flex-shrink:0}.mtb-chat-header{flex-direction:column;align-items:center;gap:8px;border-radius:20px 20px 0 0;padding:10px 16px 12px}.mtb-chat-header-row{width:100%;display:flex;align-items:center}.mtb-chat-messages,.mtb-chat-quick-replies{padding:14px 16px 12px}.mtb-chat-qr{padding:8px 13px}.mtb-chat-suggestions{padding-left:45px}.mtb-chat-sg{padding:8px 13px;font-size:12px}.mtb-chat-composer{padding:10px 12px calc(10px + env(safe-area-inset-bottom,12px))}.mtb-chat-success{padding:30px 20px}.mtb-chat-success-simple{padding-top:36px;padding-bottom:calc(44px + env(safe-area-inset-bottom,0px))}.mtb-chat-email-card{margin-top:12px;padding:12px;gap:8px}}:host([data-mtb-theme="dark"]) .mtb-chat-handle{background:#fff3}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-chat-handle{background:#fff3}}@media (max-width: 480px){:host([data-mtb-theme="dark"]) .mtb-chat{box-shadow:0 -18px 60px #0000008c}}@media (max-width: 480px) and (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-chat{box-shadow:0 -18px 60px #0000008c}}.mtb-chat-handle{display:none}@media (max-width: 480px){.mtb-chat-handle{display:block}}`, k = "mtb-widget-host";
|
|
1
|
+
const ti = `*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:host{all:initial;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;font-size:14px;line-height:1.5;color:#191a1c;-webkit-font-smoothing:antialiased}:host{--mtb-brand-primary: #059669;--mtb-brand-hover: #047857;--mtb-brand-active: #065f46;--mtb-brand-on-primary: #fff;--mtb-brand-rgb: 5, 150, 105;--mtb-brand-on-primary-rgb: 255, 255, 255;--mtb-brand-emphasis: #10b981;--mtb-brand-emphasis-rgb: 16, 185, 129;--mtb-brand-gradient-start: #10b981;--mtb-brand-gradient-end: #059669;--mtb-panel-bg: #fff;--mtb-panel-border: rgba(0, 0, 0, .1);--mtb-panel-divider: rgba(0, 0, 0, .06);--mtb-fg: #191a1c;--mtb-field-bg: #fff;--mtb-field-bg-subtle: #fafafa;--mtb-field-border: rgba(0, 0, 0, .12);--mtb-field-border-soft: rgba(0, 0, 0, .09);--mtb-placeholder-fg: rgba(0, 0, 0, .34);--mtb-action-bg: #fff;--mtb-action-border: rgba(0, 0, 0, .12);--mtb-action-fg: rgba(0, 0, 0, .55);--mtb-action-hover-bg: rgba(0, 0, 0, .04);--mtb-clarify-close-fg: rgba(0, 0, 0, .38);--mtb-clarify-close-hover-fg: rgba(0, 0, 0, .7);--mtb-dismiss-fg: rgba(0, 0, 0, .4);--mtb-dismiss-hover-fg: rgba(0, 0, 0, .7);--mtb-quick-hover-bg: rgba(var(--mtb-brand-emphasis-rgb), .06);--mtb-quick-hover-border: rgba(var(--mtb-brand-emphasis-rgb), .3);--mtb-quick-selected-bg: rgba(var(--mtb-brand-emphasis-rgb), .1);--mtb-quick-selected-border: rgba(var(--mtb-brand-emphasis-rgb), .5);--mtb-field-focus-border: var(--mtb-brand-emphasis);--mtb-chat-card-bg: #FFFFFF;--mtb-chat-card-shadow: 0 24px 64px rgba(0, 0, 0, .18);--mtb-chat-raised-bg: #F9FAFB;--mtb-chat-write-bg: #FFFFFF;--mtb-chat-title-fg: #111827;--mtb-chat-body-fg: #1f2937;--mtb-chat-muted-fg: #6b7280;--mtb-chat-placeholder-fg: #9ca3af;--mtb-chat-pill-fg: #374151;--mtb-chat-pill-shadow: 0 1px 3px rgba(0, 0, 0, .08), 0 0 0 1px rgba(0, 0, 0, .04);--mtb-chat-pill-hover-shadow: 0 3px 10px rgba(0, 0, 0, .12), 0 0 0 1px rgba(0, 0, 0, .05);--mtb-chat-close-hover-bg: #F3F4F6;--mtb-chat-close-hover-fg: #111827;--mtb-chat-composer-shadow: 0 -1px 6px rgba(0, 0, 0, .06);--mtb-chat-skip-fg: #9ca3af;--mtb-chat-skip-hover-fg: #4b5563;--mtb-chat-camera-lens: #fff;--mtb-chat-accent: var(--mtb-brand-primary);--mtb-chat-accent-hover: var(--mtb-brand-hover);--mtb-chat-accent-fg: var(--mtb-brand-on-primary);--mtb-chat-accent-rgb: var(--mtb-brand-rgb);--mtb-chat-accent-fg-rgb: var(--mtb-brand-on-primary-rgb);--mtb-chat-link-fg: var(--mtb-brand-primary);--mtb-chat-send-shadow: 0 2px 8px rgba(var(--mtb-chat-accent-rgb), .35);--mtb-chat-success-icon-shadow: 0 4px 14px rgba(var(--mtb-chat-accent-rgb), .35);--mtb-chat-danger: #EF4444;--mtb-chat-logo-start: #10b981;--mtb-chat-logo-end: #059669;--mtb-chat-logo-fg: #fff}:host([data-mtb-theme="dark"]){--mtb-panel-bg: #151719;--mtb-panel-border: rgba(255, 255, 255, .12);--mtb-panel-divider: rgba(255, 255, 255, .1);--mtb-fg: #f9fafb;--mtb-field-bg: #1f2327;--mtb-field-bg-subtle: #1f2327;--mtb-field-border: rgba(255, 255, 255, .12);--mtb-field-border-soft: rgba(255, 255, 255, .12);--mtb-placeholder-fg: rgba(255, 255, 255, .4);--mtb-action-bg: #1f2327;--mtb-action-border: rgba(255, 255, 255, .14);--mtb-action-fg: rgba(255, 255, 255, .7);--mtb-action-hover-bg: rgba(255, 255, 255, .06);--mtb-clarify-close-fg: rgba(255, 255, 255, .45);--mtb-clarify-close-hover-fg: rgba(255, 255, 255, .75);--mtb-dismiss-fg: rgba(255, 255, 255, .4);--mtb-dismiss-hover-fg: rgba(255, 255, 255, .7);--mtb-quick-hover-bg: rgba(var(--mtb-brand-emphasis-rgb), .12);--mtb-quick-hover-border: rgba(var(--mtb-brand-emphasis-rgb), .45);--mtb-quick-selected-bg: rgba(var(--mtb-brand-emphasis-rgb), .18);--mtb-quick-selected-border: var(--mtb-brand-primary);--mtb-field-focus-border: var(--mtb-brand-emphasis);--mtb-chat-card-bg: #17191C;--mtb-chat-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--mtb-chat-raised-bg: #202327;--mtb-chat-write-bg: #23272C;--mtb-chat-title-fg: #E8EAED;--mtb-chat-body-fg: #DCE0E4;--mtb-chat-muted-fg: #B0B6BD;--mtb-chat-placeholder-fg: #A3AAB2;--mtb-chat-pill-fg: #DDE1E5;--mtb-chat-pill-shadow: 0 1px 3px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .08);--mtb-chat-pill-hover-shadow: 0 4px 14px rgba(0, 0, 0, .6), 0 0 0 1px rgba(255, 255, 255, .14);--mtb-chat-close-hover-bg: rgba(255, 255, 255, .08);--mtb-chat-close-hover-fg: #FFFFFF;--mtb-chat-composer-shadow: 0 -1px 6px rgba(0, 0, 0, .45);--mtb-chat-skip-fg: #A3AAB2;--mtb-chat-skip-hover-fg: #E8EAED;--mtb-chat-camera-lens: #EAF7EE;--mtb-chat-accent: #4ADE80;--mtb-chat-accent-hover: #34D399;--mtb-chat-accent-fg: #0D1210;--mtb-chat-accent-rgb: 74, 222, 128;--mtb-chat-accent-fg-rgb: 13, 18, 16;--mtb-chat-link-fg: #5BD98A;--mtb-chat-send-shadow: 0 1px 3px rgba(0, 0, 0, .5);--mtb-chat-success-icon-shadow: 0 2px 10px rgba(0, 0, 0, .5);--mtb-chat-danger: #F87171;--mtb-chat-logo-start: #1E9E4A;--mtb-chat-logo-end: #0B8AA0;--mtb-chat-logo-fg: #EAF7EE}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]){--mtb-panel-bg: #151719;--mtb-panel-border: rgba(255, 255, 255, .12);--mtb-panel-divider: rgba(255, 255, 255, .1);--mtb-fg: #f9fafb;--mtb-field-bg: #1f2327;--mtb-field-bg-subtle: #1f2327;--mtb-field-border: rgba(255, 255, 255, .12);--mtb-field-border-soft: rgba(255, 255, 255, .12);--mtb-placeholder-fg: rgba(255, 255, 255, .4);--mtb-action-bg: #1f2327;--mtb-action-border: rgba(255, 255, 255, .14);--mtb-action-fg: rgba(255, 255, 255, .7);--mtb-action-hover-bg: rgba(255, 255, 255, .06);--mtb-clarify-close-fg: rgba(255, 255, 255, .45);--mtb-clarify-close-hover-fg: rgba(255, 255, 255, .75);--mtb-dismiss-fg: rgba(255, 255, 255, .4);--mtb-dismiss-hover-fg: rgba(255, 255, 255, .7);--mtb-quick-hover-bg: rgba(var(--mtb-brand-emphasis-rgb), .12);--mtb-quick-hover-border: rgba(var(--mtb-brand-emphasis-rgb), .45);--mtb-quick-selected-bg: rgba(var(--mtb-brand-emphasis-rgb), .18);--mtb-quick-selected-border: var(--mtb-brand-primary);--mtb-field-focus-border: var(--mtb-brand-emphasis);--mtb-chat-card-bg: #17191C;--mtb-chat-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--mtb-chat-raised-bg: #202327;--mtb-chat-write-bg: #23272C;--mtb-chat-title-fg: #E8EAED;--mtb-chat-body-fg: #DCE0E4;--mtb-chat-muted-fg: #B0B6BD;--mtb-chat-placeholder-fg: #A3AAB2;--mtb-chat-pill-fg: #DDE1E5;--mtb-chat-pill-shadow: 0 1px 3px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .08);--mtb-chat-pill-hover-shadow: 0 4px 14px rgba(0, 0, 0, .6), 0 0 0 1px rgba(255, 255, 255, .14);--mtb-chat-close-hover-bg: rgba(255, 255, 255, .08);--mtb-chat-close-hover-fg: #FFFFFF;--mtb-chat-composer-shadow: 0 -1px 6px rgba(0, 0, 0, .45);--mtb-chat-skip-fg: #A3AAB2;--mtb-chat-skip-hover-fg: #E8EAED;--mtb-chat-camera-lens: #EAF7EE;--mtb-chat-accent: #4ADE80;--mtb-chat-accent-hover: #34D399;--mtb-chat-accent-fg: #0D1210;--mtb-chat-accent-rgb: 74, 222, 128;--mtb-chat-accent-fg-rgb: 13, 18, 16;--mtb-chat-link-fg: #5BD98A;--mtb-chat-send-shadow: 0 1px 3px rgba(0, 0, 0, .5);--mtb-chat-success-icon-shadow: 0 2px 10px rgba(0, 0, 0, .5);--mtb-chat-danger: #F87171;--mtb-chat-logo-start: #1E9E4A;--mtb-chat-logo-end: #0B8AA0;--mtb-chat-logo-fg: #EAF7EE}}.mtb-tab{--mtb-tab-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='8'/%3E%3Ccircle cx='12' cy='12' r='2.4' fill='%23000' stroke='none'/%3E%3Cpath d='M12 1.8v3.4M12 18.8v3.4M1.8 12h3.4M18.8 12h3.4'/%3E%3C/svg%3E");--mtb-tab-bg: var(--mtb-brand-primary);--mtb-tab-hover-bg: var(--mtb-brand-hover);--mtb-tab-active-bg: var(--mtb-brand-active);--mtb-tab-shadow-color: var(--mtb-brand-rgb);--mtb-tab-fg: var(--mtb-brand-on-primary);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:var(--mtb-tab-bg);color:var(--mtb-tab-fg);border-radius:8px 0 0 8px;cursor:pointer;box-shadow:-2px 0 14px rgba(var(--mtb-tab-shadow-color),.35);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 rgba(var(--mtb-tab-shadow-color),.35)}.mtb-tab:hover{background:var(--mtb-tab-hover-bg);box-shadow:-3px 0 20px rgba(var(--mtb-tab-shadow-color),.45)}.mtb-tab.active{background:var(--mtb-tab-active-bg)}.mtb-hint-bar{position:fixed;top:18px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;height:38px;padding:0 16px;border-radius:13px;background:linear-gradient(120deg,var(--mtb-brand-gradient-start),var(--mtb-brand-gradient-end));color:var(--mtb-brand-on-primary);box-shadow:0 10px 26px #0f172a38;animation:mtbHintIn .2s ease;white-space:nowrap;transition:opacity .15s ease;pointer-events:none}.mtb-hint-bar--under-pointer{opacity:.3}.mtb-hint-bar.mtb-hint-bar--dismissed{display:none}@keyframes mtbHintIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}.mtb-toolbar{position:fixed;top:50%;right:8px;transform:translateY(-50%);z-index:2147483647;display:flex;flex-direction:column;align-items:center;gap:6px;width:38px;padding:6px 0;max-height:calc(100vh - 24px);border-radius:19px;background:linear-gradient(160deg,var(--mtb-brand-gradient-start),var(--mtb-brand-gradient-end));color:var(--mtb-brand-on-primary);box-shadow:0 8px 22px #0f172a33;animation:mtbEdgeBarIn .2s ease;white-space:nowrap;pointer-events:none}.mtb-toolbar.left{right:auto;left:8px;animation:mtbEdgeBarInLeft .2s ease}@keyframes mtbBarIn{0%{transform:translate(-50%,12px);opacity:0}to{transform:translate(-50%);opacity:1}}@keyframes mtbEdgeBarIn{0%{transform:translate(12px,-50%);opacity:0}to{transform:translateY(-50%);opacity:1}}@keyframes mtbEdgeBarInLeft{0%{transform:translate(-12px,-50%);opacity:0}to{transform:translateY(-50%);opacity:1}}.mtb-toolbar-label{display:none}:host([data-mtb-toolbar]) .mtb-tab{display:none}.mtb-toolbar-modes{display:flex;align-items:center;gap:3px;background:rgba(var(--mtb-brand-on-primary-rgb),.16);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:var(--mtb-brand-on-primary);transition:all .12s}.mtb-toolbar-mode-btn.active{background:#fff;color:var(--mtb-brand-active)}.mtb-toolbar-hint{font-size:12px;color:var(--mtb-brand-on-primary);white-space:nowrap}.mtb-toolbar-sep{width:20px;height:1px;align-self:center;background:rgba(var(--mtb-brand-on-primary-rgb),.22)}.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:var(--mtb-brand-on-primary);cursor:pointer;background:rgba(var(--mtb-brand-on-primary-rgb),.16);border:none;font-family:inherit;transition:background .12s}.mtb-toolbar-modes{flex-direction:column;gap:6px;padding:0;background:none;border-radius:0}.mtb-toolbar-mode-btn,.mtb-exit-btn{pointer-events:auto;display:flex;align-items:center;justify-content:center;gap:0;width:30px;height:30px;padding:0;border-radius:50%;background:none;color:var(--mtb-brand-on-primary)}.mtb-toolbar-mode-btn{opacity:.72}.mtb-exit-btn{opacity:1}.mtb-toolbar-mode-btn:hover,.mtb-exit-btn:hover{background:rgba(var(--mtb-brand-on-primary-rgb),.16);color:var(--mtb-brand-on-primary);opacity:1}.mtb-toolbar-mode-btn.active,.mtb-toolbar-mode-btn.active:hover{background:var(--mtb-brand-on-primary);color:var(--mtb-brand-hover);opacity:1}.mtb-exit-btn{color:var(--mtb-brand-on-primary)}.mtb-toolbar-sep{width:16px;height:1px;margin:1px 0;align-self:center;background:rgba(var(--mtb-brand-on-primary-rgb),.28)}.mtb-exit-btn:hover{background:rgba(var(--mtb-brand-on-primary-rgb),.28)}.mtb-overlay{position:fixed;inset:0;z-index:2147483640;cursor:crosshair;touch-action:none}.mtb-dim{position:fixed;inset:0;z-index:2147483639;background:#00000014}.mtb-highlight{position:fixed;z-index:2147483641;pointer-events:none;border:2px solid var(--mtb-brand-emphasis);border-radius:6px;background:rgba(var(--mtb-brand-emphasis-rgb),.06);transition:all .08s ease}.mtb-highlight-tooltip{position:fixed;z-index:2147483642;pointer-events:none;transform:translate(-50%,-100%);max-width:240px;overflow:hidden;text-overflow:ellipsis;background:var(--mtb-brand-active);color:var(--mtb-brand-on-primary);padding:4px 10px;border-radius:6px;font-size:11px;font-weight:500;white-space:nowrap;box-shadow:0 4px 12px #0000002e;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-highlight-tooltip.below{transform:translate(-50%)}.mtb-highlight-tooltip:after{content:"";position:absolute;top:100%;left:50%;transform:translate(-50%);border:4px solid transparent;border-top-color:var(--mtb-brand-active)}.mtb-highlight-tooltip.below:after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:var(--mtb-brand-active)}.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:var(--mtb-brand-primary);border:2px solid #fff;display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--mtb-brand-on-primary);font-weight:700;box-shadow:0 0 0 1px #0f172aad,0 2px 8px rgba(var(--mtb-brand-rgb),.45);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)}}@keyframes mtbSlideUp{0%{transform:translateY(14px) scale(.97);opacity:0}to{transform:translateY(0) scale(1);opacity:1}}.mtb-draw-shot input:disabled{appearance:none;-webkit-appearance:none;border:none;border-radius:4px;background-color:var(--mtb-placeholder-fg);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:center;background-size:contain;opacity:1}.mtb-draw-shot input:disabled{background-color:#0000004d}.mtb-btn-loading{pointer-events:none;opacity:.8}.mtb-btn-loading:after{content:"";display:inline-block;width:10px;height:10px;margin-left:6px;border:1.5px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:mtbSpin .7s linear infinite;vertical-align:middle}.mtb-chat{position:fixed;z-index:2147483645;display:flex;flex-direction:column;width:min(320px,calc(100vw - 56px));max-height:420px;background:var(--mtb-chat-card-bg);border-radius:16px;color:var(--mtb-chat-title-fg);box-shadow:var(--mtb-chat-card-shadow);overflow:hidden;animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-chat.mtb-chat-receipt{inset:auto 20px 20px auto;width:min(320px,calc(100vw - 40px));animation:none}.mtb-chat-header{display:flex;align-items:center;gap:7px;padding:11px 12px;background:var(--mtb-chat-raised-bg);flex-shrink:0}.mtb-chat-brand{display:flex;align-items:center;gap:7px;text-decoration:none;opacity:.9;transition:opacity .16s}.mtb-chat-brand:hover{opacity:1}.mtb-chat-brand:hover .mtb-chat-brand-name{text-decoration:underline;text-underline-offset:2px}.mtb-chat-logo{width:20px;height:20px;border-radius:6px;overflow:hidden;flex:none}.mtb-chat-logo svg{width:100%;height:100%;display:block}.mtb-chat-brand-name{font-size:12px;font-weight:600;color:var(--mtb-chat-title-fg)}.mtb-chat-header-row{display:flex;align-items:center;gap:7px;width:100%}.mtb-chat-header-gap{flex:1}.mtb-chat-close{width:28px;height:28px;border-radius:99px;display:flex;align-items:center;justify-content:center;background:none;border:none;padding:0;color:var(--mtb-chat-muted-fg);cursor:pointer;flex:none;transition:background .16s,color .16s}.mtb-chat-close:hover{background:var(--mtb-chat-close-hover-bg);color:var(--mtb-chat-close-hover-fg)}.mtb-chat-messages{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;min-height:0;background:var(--mtb-chat-card-bg)}.mtb-chat-messages:empty{display:none}.mtb-chat-bubble{font-size:13px;max-width:85%;word-break:break-word}.mtb-chat-bubble-user{align-self:flex-end;background:var(--mtb-chat-accent);color:var(--mtb-chat-accent-fg);line-height:1.45;padding:8px 11px;border-radius:12px 12px 4px}.mtb-chat-bubble-ai{background:var(--mtb-chat-raised-bg);color:var(--mtb-chat-body-fg);line-height:1.5;padding:9px 12px;border-radius:12px 12px 12px 4px}.mtb-chat-ai-row{display:flex;align-items:flex-end;gap:7px}.mtb-chat-avatar{width:22px;height:22px;border-radius:7px;overflow:hidden;flex:none}.mtb-chat-avatar svg{width:100%;height:100%;display:block}.mtb-chat-dots{display:flex;align-items:center;gap:4px;padding:10px 12px;background:var(--mtb-chat-raised-bg);border-radius:12px 12px 12px 4px}.mtb-chat-dots span{width:5px;height:5px;background:var(--mtb-chat-accent);border-radius:99px;animation:mtbChatDot 1.1s infinite}.mtb-chat-dots span:nth-child(2){animation-delay:.15s}.mtb-chat-dots span:nth-child(3){animation-delay:.3s}@keyframes mtbChatDot{0%,60%,to{transform:translateY(0);opacity:.45}30%{transform:translateY(-4px);opacity:1}}.mtb-chat-suggestions{display:flex;flex-wrap:wrap;gap:6px;padding-left:29px}.mtb-chat-sg{background:var(--mtb-chat-write-bg);border:none;border-radius:99px;padding:5px 10px;font-size:11px;font-weight:500;font-family:inherit;color:var(--mtb-chat-pill-fg);cursor:pointer;box-shadow:var(--mtb-chat-pill-shadow);transition:box-shadow .16s,transform .16s}.mtb-chat-sg:hover{box-shadow:var(--mtb-chat-pill-hover-shadow);transform:translateY(-1px)}.mtb-chat-quick-replies{display:flex;flex-wrap:wrap;gap:6px;padding:12px;background:var(--mtb-chat-card-bg)}.mtb-chat-qr{display:flex;align-items:center;gap:5px;background:var(--mtb-chat-write-bg);border:none;border-radius:99px;padding:7px 12px;font-size:12px;font-weight:500;font-family:inherit;color:var(--mtb-chat-pill-fg);cursor:pointer;box-shadow:var(--mtb-chat-pill-shadow);transition:box-shadow .16s,transform .16s}.mtb-chat-qr:hover{box-shadow:var(--mtb-chat-pill-hover-shadow);transform:translateY(-1px)}.mtb-chat-qr:disabled{opacity:.5;pointer-events:none;cursor:default;transform:none!important;box-shadow:var(--mtb-chat-pill-shadow)!important}.mtb-chat-composer{display:flex;flex-direction:column;gap:8px;padding:10px;background:var(--mtb-chat-raised-bg);box-shadow:var(--mtb-chat-composer-shadow);flex-shrink:0}.mtb-chat-composer-disabled{pointer-events:none}.mtb-chat-composer-disabled .mtb-chat-input{opacity:.3}.mtb-chat-input{box-sizing:border-box;width:100%;min-height:64px;max-height:132px;padding:10px 12px;background:var(--mtb-chat-write-bg);border:none;border-radius:10px;font-size:13px;line-height:1.5;font-family:inherit;color:var(--mtb-chat-title-fg);outline:none;resize:none}.mtb-chat-input::placeholder{color:var(--mtb-chat-placeholder-fg)}.mtb-chat-input:disabled{opacity:.5;cursor:default}.mtb-chat-actions{display:flex;align-items:center;gap:10px}.mtb-chat-actions-gap{flex:1}.mtb-chat-screenshot,.mtb-chat-attachment{display:flex;align-items:center;gap:6px;background:none;border:none;padding:0;font-family:inherit;color:var(--mtb-chat-accent);cursor:pointer;transition:opacity .16s}.mtb-chat-screenshot svg,.mtb-chat-attachment svg{display:flex;flex:none}.mtb-chat-icon-lens{fill:var(--mtb-chat-camera-lens)}.mtb-chat-screenshot:hover{opacity:.75}.mtb-chat-attachment{cursor:default}.mtb-chat-capture-label{font-size:11px;color:var(--mtb-chat-muted-fg)}.mtb-chat-screenshot[aria-pressed=false],.mtb-chat-screenshot-off{opacity:.4;color:var(--mtb-chat-muted-fg)}.mtb-chat-screenshot:disabled{opacity:.3;pointer-events:none;cursor:default}.mtb-chat-skip{height:26px;border:none;border-radius:6px;background:none;display:flex;align-items:center;padding:0 4px;font-size:11px;font-weight:500;font-family:inherit;color:var(--mtb-chat-skip-fg);cursor:pointer;flex:none;transition:color .16s}.mtb-chat-skip:hover{color:var(--mtb-chat-skip-hover-fg)}.mtb-chat-send{position:relative;height:34px;padding:0 14px;border:none;border-radius:10px;background:var(--mtb-chat-accent);font-size:12px;font-weight:600;font-family:inherit;color:var(--mtb-chat-accent-fg);display:flex;align-items:center;justify-content:center;flex:none;cursor:pointer;box-shadow:var(--mtb-chat-send-shadow)}.mtb-chat-send:disabled{opacity:.3;box-shadow:none;cursor:default}.mtb-chat-error-row{display:flex;align-items:center;justify-content:center;gap:8px;padding:4px 0}.mtb-chat-error-text{font-size:11px;color:var(--mtb-danger, #ef4444)}.mtb-chat-error-retry{font-size:11px;font-weight:600;font-family:inherit;color:var(--mtb-chat-pill-fg);background:var(--mtb-chat-write-bg);border:none;border-radius:999px;padding:4px 11px;box-shadow:var(--mtb-chat-pill-shadow);cursor:pointer}.mtb-chat-error-retry:hover{box-shadow:var(--mtb-chat-pill-hover-shadow)}.mtb-chat-success{padding:30px 20px 26px;display:flex;flex-direction:column;align-items:center;gap:10px;background:var(--mtb-chat-card-bg);animation:mtbSlideUp .28s cubic-bezier(.34,1.56,.64,1) both}.mtb-chat-success-simple{padding-top:34px;padding-bottom:22px}.mtb-chat-success-icon{width:40px;height:40px;border-radius:99px;background:var(--mtb-chat-accent);color:var(--mtb-chat-accent-fg);display:flex;align-items:center;justify-content:center;box-shadow:var(--mtb-chat-success-icon-shadow)}.mtb-chat-success-title{font-size:15px;font-weight:600;color:var(--mtb-chat-title-fg);margin-top:2px;text-align:center}.mtb-chat-finalize-failure .mtb-chat-failure-icon{background:#ef44441a;color:var(--mtb-chat-danger, #ef4444);box-shadow:none;font-size:20px;font-weight:700}.mtb-chat-finalize-failure{padding:26px 24px;gap:8px}.mtb-chat-finalize-message{color:var(--mtb-chat-muted-fg);font-size:12px;line-height:1.5;text-align:center}.mtb-chat-finalize-retry{margin-top:12px;width:100%;height:34px;border:none;border-radius:10px;background:var(--mtb-chat-accent);box-shadow:var(--mtb-chat-send-shadow);color:var(--mtb-chat-accent-fg);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600}.mtb-chat-finalize-retry:hover:not(:disabled){background:var(--mtb-chat-accent-hover)}.mtb-chat-finalize-retry:disabled{cursor:wait;opacity:.8}.mtb-chat-finalize-spinner{width:14px;height:14px;display:inline-block;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:mtbSpin .7s linear infinite}.mtb-chat-finalize-close{margin-top:8px;padding:0;border:0;background:transparent;color:var(--mtb-chat-muted-fg);cursor:pointer;font-family:inherit;font-size:12px;font-weight:500}.mtb-chat-finalize-close:hover{color:var(--mtb-chat-title-fg)}.mtb-chat-success-link{display:inline-flex;align-items:center;font-size:12px;font-weight:500;color:var(--mtb-chat-link-fg);text-decoration:none;margin-top:4px;cursor:pointer}.mtb-chat-success-link-pending{color:var(--mtb-chat-muted-fg);cursor:default;pointer-events:none}.mtb-chat-email-card{align-self:stretch;margin-top:10px;background:var(--mtb-chat-raised-bg);border-radius:10px;padding:10px;display:flex;flex-direction:column;gap:7px}.mtb-chat-email-row{display:flex;align-items:center;gap:7px}.mtb-chat-email-field{flex:1;background:var(--mtb-chat-write-bg);border-radius:8px;box-sizing:border-box;min-height:40px;display:flex;align-items:center;padding:0 10px;min-width:0}.mtb-chat-email-input{flex:1;min-width:0;background:none;border:none;outline:none;font-size:12px;font-family:inherit;color:var(--mtb-chat-title-fg)}.mtb-chat-email-input::placeholder{color:var(--mtb-chat-placeholder-fg)}.mtb-chat-email-submit{height:30px;padding:0 10px;border:none;border-radius:8px;background:var(--mtb-chat-accent);font-size:11px;font-weight:600;font-family:inherit;color:var(--mtb-chat-accent-fg);display:flex;align-items:center;justify-content:center;flex:none;cursor:pointer}.mtb-chat-email-submit:disabled{opacity:.3;cursor:default}.mtb-chat-email-note{font-size:12px;color:var(--mtb-chat-muted-fg);text-align:center}.mtb-chat-email-error{font-size:11px;color:var(--mtb-danger, #ef4444);text-align:center}.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(var(--mtb-brand-rgb),.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:var(--mtb-panel-bg);border:1px solid var(--mtb-panel-border);border-radius:12px;color:var(--mtb-fg);box-shadow:0 8px 30px #0000001f;animation:mtbSlideUp .35s cubic-bezier(.34,1.56,.64,1);font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.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:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-frustration-tell:hover{background:var(--mtb-brand-hover)}.mtb-frustration-tell:active{background:var(--mtb-brand-active)}.mtb-frustration-dismiss{height:28px;padding:0 8px;border:none;border-radius:7px;background:transparent;color:var(--mtb-dismiss-fg);cursor:pointer;font-family:inherit;font-size:12px;transition:color .12s}.mtb-frustration-dismiss:hover{color:var(--mtb-dismiss-hover-fg)}.mtb-record-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:12px;height:42px;padding:0 8px 0 14px;border-radius:12px;background:#0f172aeb;box-shadow:0 8px 24px #00000040;animation:mtbBarIn .2s ease}.mtb-record-dot{width:8px;height:8px;border-radius:50%;background:#dc2626;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:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-record-stop:hover{background:var(--mtb-brand-hover)}.mtb-record-stop:active{background:var(--mtb-brand-active)}.mtb-click-ripple{position:fixed;z-index:2147483644;width:24px;height:24px;border-radius:50%;border:2px solid var(--mtb-brand-emphasis);background:rgba(var(--mtb-brand-emphasis-rgb),.25);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}}@keyframes mtbDot{0%,80%,to{opacity:.3;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}.mtb-clarify-retry{flex:1;height:30px;display:inline-flex;align-items:center;justify-content:center;gap:5px;border:none;border-radius:8px;background:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12px;font-weight:600;transition:background .12s}.mtb-clarify-retry:not(:disabled):hover{background:var(--mtb-brand-hover)}.mtb-clarify-retry:not(:disabled):active{background:var(--mtb-brand-active)}.mtb-clarify-retry:disabled{background:#00000026;cursor:not-allowed}@keyframes mtbSpin{to{transform:rotate(360deg)}}.mtb-dim-clickable{z-index:2147483643;pointer-events:auto;cursor:default;background:#0000001f}.mtb-draw-bar{position:fixed;bottom:48px;left:50%;transform:translate(-50%);z-index:2147483647;display:flex;align-items:center;gap:8px;height:46px;padding:0 8px 0 12px;border-radius:13px;background:#fff;border:1px solid rgba(0,0,0,.08);box-shadow:0 10px 30px #0f172a38;animation:mtbBarIn .2s ease;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif}.mtb-draw-input{width:220px;height:32px;padding:0 10px;border:1px solid rgba(0,0,0,.12);border-radius:8px;font-family:inherit;font-size:13px;color:#191a1c;outline:none;background:#fafafa;transition:border-color .12s,box-shadow .12s,background .12s}.mtb-draw-input:focus{border-color:var(--mtb-brand-emphasis);box-shadow:0 0 0 3px rgba(var(--mtb-brand-emphasis-rgb),.15);background:#fff}.mtb-draw-input::placeholder{color:#00000057}.mtb-draw-icon-btn{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:none;border-radius:8px;background:transparent;color:#374151;cursor:pointer;transition:background .12s,color .12s}.mtb-draw-icon-btn:hover:not(:disabled){background:#0000000f}.mtb-draw-icon-btn:disabled{color:#00000038;cursor:default}.mtb-draw-shot{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:#0000008c;white-space:nowrap;cursor:default;user-select:none}.mtb-draw-shot input{width:14px;height:14px;margin:0;accent-color:var(--mtb-brand-primary);cursor:default}.mtb-draw-sep{width:1px;height:22px;background:#0000001a}.mtb-draw-cancel{height:32px;padding:0 12px;border:1px solid rgba(0,0,0,.12);border-radius:8px;background:#fff;color:#0000008c;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:550;transition:background .12s}.mtb-draw-cancel:hover{background:#0000000a}.mtb-draw-submit{height:32px;padding:0 14px;border:none;border-radius:8px;background:var(--mtb-brand-primary);color:var(--mtb-brand-on-primary);cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:600;transition:background .12s}.mtb-draw-submit:hover:not(:disabled){background:var(--mtb-brand-hover)}.mtb-draw-submit:active:not(:disabled){background:var(--mtb-brand-active)}.mtb-draw-submit:disabled{opacity:.6;cursor:default}.mtb-record-preview{margin-bottom:12px}.mtb-record-preview-stage{position:relative;width:100%;height:132px;border-radius:10px;overflow:hidden;background:#0f172a;display:flex;align-items:center;justify-content:center}.mtb-record-preview-stage.playing{align-items:flex-start;justify-content:flex-start}.mtb-record-preview-play{width:44px;height:44px;border-radius:50%;border:none;background:#ffffffeb;color:var(--mtb-brand-primary);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:transform .12s,background .12s}.mtb-record-preview-play:hover:not(:disabled){transform:scale(1.06);background:#fff}.mtb-record-preview-play:disabled{cursor:default;opacity:.6}.mtb-record-preview-badge{position:absolute;right:8px;bottom:8px;padding:2px 7px;border-radius:6px;background:#0009;color:#fff;font-size:11px;font-variant-numeric:tabular-nums;font-family:JetBrains Mono,SF Mono,monospace}.mtb-record-preview-fallback{color:#ffffffd9;font-size:12px}.mtb-record-preview-name{display:block;margin-top:5px;font-size:11px;color:#0000006b}@media (pointer: coarse){.mtb-tab:after{content:"";position:absolute;inset:-6px 0 -6px -12px}.mtb-tab.left:after{inset:-6px -12px -6px 0}.mtb-toolbar{min-height:56px;border-radius:16px}.mtb-toolbar-mode-btn,.mtb-exit-btn{min-height:44px}.mtb-chat-input,.mtb-chat-email-input,.mtb-draw-input{font-size:16px}}@media (max-width: 480px){.mtb-tab{width:36px;height:40px;padding:0;font-size:0;writing-mode:horizontal-tb;border-radius:12px 0 0 12px;right:env(safe-area-inset-right,0px)}.mtb-tab.left{left:env(safe-area-inset-left,0px);border-radius:0 12px 12px 0}.mtb-tab:before{content:"";width:18px;height:18px;background:currentColor;-webkit-mask:var(--mtb-tab-icon) center / contain no-repeat;mask:var(--mtb-tab-icon) center / contain no-repeat}.mtb-toolbar{inset:0 0 auto;width:100%;max-width:none;max-height:none;transform:none;flex-direction:row;align-items:center;border-radius:0;gap:8px;justify-content:center;padding:env(safe-area-inset-top,0px) 8px 0;height:calc(44px + env(safe-area-inset-top,0px));min-height:calc(44px + env(safe-area-inset-top,0px));border-bottom:1px solid rgba(60,60,67,.16);background:#f8f8f8f5;box-shadow:0 1px 3px #00000014;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);animation:none}.mtb-toolbar-modes{flex-direction:row;gap:0;padding:2px;background:#7676801f;border-radius:8px}.mtb-toolbar-sep{display:none}.mtb-hint-bar{top:calc(44px + env(safe-area-inset-top,0px));right:0;bottom:0;left:0;transform:none;justify-content:center;height:auto;padding:0 24px;border-radius:0;background:#0000001a;box-shadow:none;animation:none;white-space:normal;text-align:center;transition:none}.mtb-hint-bar .mtb-toolbar-hint{max-width:280px;color:#fffffff5;font-size:17px;font-weight:600;line-height:1.4;letter-spacing:0;white-space:normal;text-shadow:0 1px 3px rgba(0,0,0,.45)}.mtb-toolbar-mode-btn,.mtb-exit-btn{position:relative;width:auto;height:32px;min-height:32px;gap:6px;border-radius:6px;padding-right:8px;padding-left:8px;color:#3c3c43d1;transition:none}.mtb-toolbar-mode-btn:hover{background:transparent;color:#3c3c43d1}.mtb-toolbar-mode-btn.active,.mtb-toolbar-mode-btn.active:hover{background:var(--mtb-brand-on-primary);color:var(--mtb-brand-hover);box-shadow:0 1px 3px #0000001f}.mtb-toolbar-mode-btn:after,.mtb-exit-btn:after{content:"";position:absolute;inset:-6px 0}.mtb-exit-btn{width:32px;padding:0;border-radius:50%;background:#7676801f}.mtb-exit-btn:hover{background:#7676801f;color:#3c3c43d1}.mtb-toolbar-label{display:inline}.mtb-exit-btn .mtb-toolbar-label{display:none}.mtb-draw-bar{left:0;right:0;bottom:0;transform:none;height:auto;padding:10px 12px calc(10px + env(safe-area-inset-bottom,0px));border-radius:16px 16px 0 0}.mtb-frustration-prompt{left:0;right:0;bottom:0;flex-direction:column;align-items:stretch;gap:12px;padding:16px 16px calc(16px + env(safe-area-inset-bottom,0px));border-radius:16px 16px 0 0;border-width:1px 0 0;animation:none}.mtb-frustration-actions{display:flex;gap:8px}.mtb-frustration-tell,.mtb-frustration-dismiss{flex:1;min-height:44px}.mtb-chat{position:fixed;left:0!important;right:0;bottom:0;top:auto!important;width:100%;max-width:none;max-height:85vh;border-radius:20px 20px 0 0;box-shadow:0 -18px 60px #0003;animation:none}.mtb-chat-handle{width:36px;height:4px;border-radius:99px;background:#0000001f;margin:0 auto;flex-shrink:0}.mtb-chat-header{flex-direction:column;align-items:center;gap:8px;border-radius:20px 20px 0 0;padding:10px 16px 12px}.mtb-chat-header-row{width:100%;display:flex;align-items:center}.mtb-chat-messages,.mtb-chat-quick-replies{padding:14px 16px 12px}.mtb-chat-qr{padding:8px 13px}.mtb-chat-suggestions{padding-left:45px}.mtb-chat-sg{padding:8px 13px;font-size:12px}.mtb-chat-composer{padding:10px 12px calc(10px + env(safe-area-inset-bottom,12px))}.mtb-chat-success{padding:30px 20px}.mtb-chat-success-simple{padding-top:36px;padding-bottom:calc(44px + env(safe-area-inset-bottom,0px))}.mtb-chat-email-card{margin-top:12px;padding:12px;gap:8px}}:host([data-mtb-theme="dark"]) .mtb-chat-handle{background:#fff3}@media (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-chat-handle{background:#fff3}}@media (max-width: 480px){:host([data-mtb-theme="dark"]) .mtb-chat{box-shadow:0 -18px 60px #0000008c}}@media (max-width: 480px) and (prefers-color-scheme: dark){:host([data-mtb-theme="auto"]) .mtb-chat{box-shadow:0 -18px 60px #0000008c}}.mtb-chat-handle{display:none}@media (max-width: 480px){.mtb-chat-handle{display:block}}`, k = "mtb-widget-host";
|
|
2
2
|
function _(e) {
|
|
3
3
|
const t = document.getElementById(k);
|
|
4
4
|
return t ? t === e || t.contains(e) : !1;
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
return document.elementsFromPoint?.(e, t).find((
|
|
6
|
+
function Q(e, t) {
|
|
7
|
+
return document.elementsFromPoint?.(e, t).find((i) => i.id !== k) ?? null;
|
|
8
8
|
}
|
|
9
9
|
function d(e) {
|
|
10
10
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function Dt(e) {
|
|
13
13
|
return e.isComposing || e.keyCode === 229;
|
|
14
14
|
}
|
|
15
|
-
const
|
|
15
|
+
const ei = /^(script|style|noscript|template)$/i;
|
|
16
16
|
function ge(e, t = 80) {
|
|
17
|
-
let
|
|
18
|
-
for (const
|
|
19
|
-
if (
|
|
20
|
-
|
|
17
|
+
let i = "";
|
|
18
|
+
for (const r of Array.from(e.childNodes)) {
|
|
19
|
+
if (i.length >= t) break;
|
|
20
|
+
r.nodeType === 3 ? i += r.nodeValue ?? "" : r instanceof Element && !ei.test(r.tagName) && (i += ge(r, t - i.length));
|
|
21
21
|
}
|
|
22
|
-
return
|
|
22
|
+
return i;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function Mt(e) {
|
|
25
25
|
if (e instanceof HTMLElement) {
|
|
26
26
|
const t = e.getAttribute("aria-label");
|
|
27
27
|
if (t) return t;
|
|
28
|
-
const
|
|
29
|
-
if (r) return r;
|
|
30
|
-
const i = ge(e).trim().slice(0, 40);
|
|
28
|
+
const i = e.getAttribute("title");
|
|
31
29
|
if (i) return i;
|
|
30
|
+
const r = ge(e).trim().slice(0, 40);
|
|
31
|
+
if (r) return r;
|
|
32
32
|
const n = e.placeholder;
|
|
33
33
|
if (n) return n;
|
|
34
34
|
const s = e.alt;
|
|
35
35
|
if (s) return s;
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
36
|
+
const a = e.getAttribute("data-mark");
|
|
37
|
+
if (a) return a;
|
|
38
38
|
}
|
|
39
39
|
return e.tagName.toLowerCase();
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function we(e) {
|
|
42
42
|
const t = [];
|
|
43
|
-
let
|
|
44
|
-
for (;
|
|
45
|
-
let
|
|
46
|
-
if (
|
|
47
|
-
|
|
43
|
+
let i = e;
|
|
44
|
+
for (; i && i !== document.body && t.length < 5; ) {
|
|
45
|
+
let r = i.tagName.toLowerCase();
|
|
46
|
+
if (i.id) {
|
|
47
|
+
r = `#${i.id}`, t.unshift(r);
|
|
48
48
|
break;
|
|
49
49
|
}
|
|
50
|
-
const n = Array.from(
|
|
51
|
-
n && (
|
|
52
|
-
const s =
|
|
50
|
+
const n = Array.from(i.classList).filter((a) => !a.startsWith("mtb-")).slice(0, 2).join(".");
|
|
51
|
+
n && (r += `.${n}`);
|
|
52
|
+
const s = i.parentElement;
|
|
53
53
|
if (s) {
|
|
54
|
-
const
|
|
55
|
-
(
|
|
54
|
+
const a = Array.from(s.children).filter(
|
|
55
|
+
(o) => o.tagName === i.tagName
|
|
56
56
|
);
|
|
57
|
-
if (
|
|
58
|
-
const
|
|
59
|
-
|
|
57
|
+
if (a.length > 1) {
|
|
58
|
+
const o = a.indexOf(i) + 1;
|
|
59
|
+
r += `:nth-of-type(${o})`;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
t.unshift(
|
|
62
|
+
t.unshift(r), i = i.parentElement;
|
|
63
63
|
}
|
|
64
64
|
return t.join(" > ");
|
|
65
65
|
}
|
|
66
|
-
const
|
|
67
|
-
constructor(t = "auto",
|
|
66
|
+
const j = class j {
|
|
67
|
+
constructor(t = "auto", i) {
|
|
68
68
|
this.stopHostInteraction = (s) => {
|
|
69
69
|
s.stopPropagation();
|
|
70
70
|
};
|
|
71
|
-
const
|
|
72
|
-
if (this.ownsHost = !
|
|
73
|
-
const s = [1, 3, 5].map((
|
|
74
|
-
this.host.style.setProperty("--mtb-brand-primary",
|
|
71
|
+
const r = document.getElementById(k);
|
|
72
|
+
if (this.ownsHost = !r, this.host = r ?? document.createElement("div"), this.root = this.host.shadowRoot ?? this.host.attachShadow({ mode: "open" }), this.root.replaceChildren(), this.originalInlineStyle = this.host.getAttribute("style"), this.originalTheme = this.host.getAttribute("data-mtb-theme"), this.host.id = k, this.host.style.cssText = "position:fixed;top:0;left:0;width:0;height:0;overflow:visible;z-index:2147483646;", i) {
|
|
73
|
+
const s = [1, 3, 5].map((o) => parseInt(i.primary.slice(o, o + 2), 16)), a = [1, 3, 5].map((o) => parseInt(i.onPrimary.slice(o, o + 2), 16));
|
|
74
|
+
this.host.style.setProperty("--mtb-brand-primary", i.primary.toLowerCase()), this.host.style.setProperty("--mtb-brand-hover", i.hover.toLowerCase()), this.host.style.setProperty("--mtb-brand-active", i.active.toLowerCase()), this.host.style.setProperty("--mtb-brand-on-primary", i.onPrimary.toLowerCase()), this.host.style.setProperty("--mtb-brand-rgb", s.join(", ")), this.host.style.setProperty("--mtb-brand-on-primary-rgb", a.join(", ")), this.host.style.setProperty("--mtb-brand-emphasis", i.primary.toLowerCase()), this.host.style.setProperty("--mtb-brand-emphasis-rgb", s.join(", ")), this.host.style.setProperty("--mtb-brand-gradient-start", i.primary.toLowerCase()), this.host.style.setProperty("--mtb-brand-gradient-end", i.hover.toLowerCase());
|
|
75
75
|
}
|
|
76
76
|
this.host.setAttribute("data-mtb-theme", t), this.ownsHost && document.body.appendChild(this.host);
|
|
77
|
-
for (const s of
|
|
77
|
+
for (const s of j.HOST_INTERACTION_EVENTS)
|
|
78
78
|
this.root.addEventListener(s, this.stopHostInteraction);
|
|
79
79
|
const n = document.createElement("style");
|
|
80
|
-
n.textContent =
|
|
80
|
+
n.textContent = ti, this.root.appendChild(n);
|
|
81
81
|
}
|
|
82
|
-
el(t,
|
|
83
|
-
const
|
|
84
|
-
return
|
|
82
|
+
el(t, i) {
|
|
83
|
+
const r = document.createElement(t);
|
|
84
|
+
return i && (r.className = i), r;
|
|
85
85
|
}
|
|
86
86
|
append(...t) {
|
|
87
|
-
for (const
|
|
87
|
+
for (const i of t) this.root.appendChild(i);
|
|
88
88
|
}
|
|
89
89
|
remove(...t) {
|
|
90
|
-
for (const
|
|
91
|
-
|
|
90
|
+
for (const i of t)
|
|
91
|
+
i.parentNode === this.root && this.root.removeChild(i);
|
|
92
92
|
}
|
|
93
93
|
destroy() {
|
|
94
|
-
for (const t of
|
|
94
|
+
for (const t of j.HOST_INTERACTION_EVENTS)
|
|
95
95
|
this.root.removeEventListener(t, this.stopHostInteraction);
|
|
96
96
|
if (!this.ownsHost) {
|
|
97
97
|
this.root.replaceChildren(), this.host.removeAttribute("data-mtb-toolbar"), this.originalInlineStyle === null ? this.host.removeAttribute("style") : this.host.setAttribute("style", this.originalInlineStyle), this.originalTheme === null ? this.host.removeAttribute("data-mtb-theme") : this.host.setAttribute("data-mtb-theme", this.originalTheme);
|
|
@@ -100,7 +100,7 @@ const q = class q {
|
|
|
100
100
|
this.host.remove();
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
|
|
103
|
+
j.HOST_INTERACTION_EVENTS = [
|
|
104
104
|
"pointerdown",
|
|
105
105
|
"pointerup",
|
|
106
106
|
"pointercancel",
|
|
@@ -111,10 +111,12 @@ q.HOST_INTERACTION_EVENTS = [
|
|
|
111
111
|
"touchcancel",
|
|
112
112
|
"click"
|
|
113
113
|
];
|
|
114
|
-
let
|
|
115
|
-
class
|
|
116
|
-
constructor(t,
|
|
117
|
-
this.active = !1, this.
|
|
114
|
+
let Tt = j;
|
|
115
|
+
class ii {
|
|
116
|
+
constructor(t, i, r, n, s) {
|
|
117
|
+
this.active = !1, this.preserveHostFocus = (a) => {
|
|
118
|
+
a.preventDefault();
|
|
119
|
+
}, this.onClick = n, this.customText = s, this.el = t.el("button", "mtb-tab"), r === "left" && this.el.classList.add("left"), this.idleLabel = s ?? i.tab, this.activeLabel = i.toolbar.exit, this.setLabel(this.idleLabel), this.el.addEventListener("mousedown", this.preserveHostFocus), this.el.addEventListener("click", n), t.append(this.el);
|
|
118
120
|
}
|
|
119
121
|
setLabel(t) {
|
|
120
122
|
this.el.textContent = t, this.el.setAttribute("aria-label", t);
|
|
@@ -126,30 +128,30 @@ class rr {
|
|
|
126
128
|
this.active = t, this.el.classList.toggle("active", t), this.setLabel(t ? this.activeLabel : this.idleLabel);
|
|
127
129
|
}
|
|
128
130
|
destroy() {
|
|
129
|
-
this.el.removeEventListener("click", this.onClick), this.el.remove();
|
|
131
|
+
this.el.removeEventListener("mousedown", this.preserveHostFocus), this.el.removeEventListener("click", this.onClick), this.el.remove();
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
|
-
const
|
|
133
|
-
class
|
|
134
|
-
constructor(t,
|
|
134
|
+
const ri = 8e3;
|
|
135
|
+
class ni {
|
|
136
|
+
constructor(t, i, r) {
|
|
135
137
|
this.autoHideTimer = null, this.el = t.el("div", "mtb-frustration-prompt"), this.el.innerHTML = `
|
|
136
138
|
<div class="mtb-frustration-icon">⚠️</div>
|
|
137
|
-
<span class="mtb-frustration-text">${d(
|
|
139
|
+
<span class="mtb-frustration-text">${d(i.frustration.prompt)}</span>
|
|
138
140
|
<div class="mtb-frustration-actions">
|
|
139
|
-
<button class="mtb-frustration-tell">${d(
|
|
140
|
-
<button class="mtb-frustration-dismiss">${d(
|
|
141
|
+
<button class="mtb-frustration-tell">${d(i.frustration.action)}</button>
|
|
142
|
+
<button class="mtb-frustration-dismiss">${d(i.frustration.dismiss)}</button>
|
|
141
143
|
</div>
|
|
142
|
-
`, this.el.querySelector(".mtb-frustration-tell").addEventListener("click",
|
|
144
|
+
`, this.el.querySelector(".mtb-frustration-tell").addEventListener("click", r.onTell), this.el.querySelector(".mtb-frustration-dismiss").addEventListener("click", r.onDismiss), t.append(this.el), this.autoHideTimer = setTimeout(r.onAutoHide, ri);
|
|
143
145
|
}
|
|
144
146
|
destroy() {
|
|
145
147
|
this.autoHideTimer && (clearTimeout(this.autoHideTimer), this.autoHideTimer = null), this.el.remove();
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
|
-
const
|
|
150
|
+
const si = 400;
|
|
149
151
|
class Ut {
|
|
150
|
-
constructor(t,
|
|
151
|
-
this.bornAt = Date.now(), this.bornAt =
|
|
152
|
-
|
|
152
|
+
constructor(t, i, r = () => Date.now()) {
|
|
153
|
+
this.bornAt = Date.now(), this.bornAt = r(), this.onClick = () => {
|
|
154
|
+
r() - this.bornAt < si || i();
|
|
153
155
|
}, this.el = t.el("div", "mtb-dim mtb-dim-clickable"), this.el.addEventListener("click", this.onClick), t.append(this.el);
|
|
154
156
|
}
|
|
155
157
|
destroy() {
|
|
@@ -159,17 +161,17 @@ class Ut {
|
|
|
159
161
|
function L() {
|
|
160
162
|
return window.matchMedia?.("(pointer: coarse)").matches ?? !1;
|
|
161
163
|
}
|
|
162
|
-
class
|
|
164
|
+
class ai {
|
|
163
165
|
constructor() {
|
|
164
166
|
this.applied = !1, this.previousPadding = "", this.previousTransition = "";
|
|
165
167
|
}
|
|
166
168
|
reserve(t) {
|
|
167
169
|
if (this.applied || t <= 0) return;
|
|
168
170
|
this.applied = !0;
|
|
169
|
-
const
|
|
170
|
-
this.previousPadding =
|
|
171
|
-
const
|
|
172
|
-
|
|
171
|
+
const i = document.body.style;
|
|
172
|
+
this.previousPadding = i.paddingTop, this.previousTransition = i.transition;
|
|
173
|
+
const r = parseFloat(getComputedStyle(document.body).paddingTop) || 0;
|
|
174
|
+
i.transition = "none", i.paddingTop = `${r + t}px`;
|
|
173
175
|
}
|
|
174
176
|
release() {
|
|
175
177
|
if (!this.applied) return;
|
|
@@ -181,7 +183,7 @@ class or {
|
|
|
181
183
|
return this.applied;
|
|
182
184
|
}
|
|
183
185
|
}
|
|
184
|
-
const
|
|
186
|
+
const jt = ["wheel", "touchmove"], oi = /* @__PURE__ */ new Set([
|
|
185
187
|
"ArrowUp",
|
|
186
188
|
"ArrowDown",
|
|
187
189
|
"ArrowLeft",
|
|
@@ -192,51 +194,51 @@ const zt = ["wheel", "touchmove"], ar = /* @__PURE__ */ new Set([
|
|
|
192
194
|
"End",
|
|
193
195
|
" "
|
|
194
196
|
]);
|
|
195
|
-
function
|
|
197
|
+
function li(e) {
|
|
196
198
|
for (const t of e.composedPath()) {
|
|
197
199
|
if (!(t instanceof Element)) continue;
|
|
198
|
-
const
|
|
199
|
-
if (/auto|scroll/.test(`${
|
|
200
|
+
const i = getComputedStyle(t);
|
|
201
|
+
if (/auto|scroll/.test(`${i.overflowY} ${i.overflowX}`) && (t.scrollHeight > t.clientHeight || t.scrollWidth > t.clientWidth))
|
|
200
202
|
return !0;
|
|
201
203
|
}
|
|
202
204
|
return !1;
|
|
203
205
|
}
|
|
204
|
-
function
|
|
205
|
-
const
|
|
206
|
-
return !!(
|
|
207
|
-
}
|
|
208
|
-
function
|
|
209
|
-
const e = (
|
|
210
|
-
|
|
211
|
-
}, t = (
|
|
212
|
-
if (!(
|
|
213
|
-
const
|
|
214
|
-
|
|
206
|
+
function ci(e, t) {
|
|
207
|
+
const i = e.tagName;
|
|
208
|
+
return !!(i === "INPUT" || i === "TEXTAREA" || i === "SELECT" || e instanceof HTMLElement && e.isContentEditable || t === " " && (i === "BUTTON" || i === "SUMMARY"));
|
|
209
|
+
}
|
|
210
|
+
function hi() {
|
|
211
|
+
const e = (i) => {
|
|
212
|
+
li(i) || i.cancelable && i.preventDefault();
|
|
213
|
+
}, t = (i) => {
|
|
214
|
+
if (!(i instanceof KeyboardEvent) || !oi.has(i.key)) return;
|
|
215
|
+
const r = i.composedPath()[0];
|
|
216
|
+
r instanceof Element && ci(r, i.key) || i.cancelable && i.preventDefault();
|
|
215
217
|
};
|
|
216
|
-
for (const
|
|
217
|
-
window.addEventListener(
|
|
218
|
+
for (const i of jt)
|
|
219
|
+
window.addEventListener(i, e, { capture: !0, passive: !1 });
|
|
218
220
|
return window.addEventListener("keydown", t, { capture: !0 }), {
|
|
219
221
|
release() {
|
|
220
|
-
for (const
|
|
221
|
-
window.removeEventListener(
|
|
222
|
+
for (const i of jt)
|
|
223
|
+
window.removeEventListener(i, e, { capture: !0 });
|
|
222
224
|
window.removeEventListener("keydown", t, { capture: !0 });
|
|
223
225
|
}
|
|
224
226
|
};
|
|
225
227
|
}
|
|
226
|
-
const
|
|
227
|
-
class
|
|
228
|
-
constructor(t,
|
|
229
|
-
this.currentMode = "markup", this.handlePointerMove = (
|
|
230
|
-
if (
|
|
231
|
-
const l = this.hintBarEl.getBoundingClientRect(), c =
|
|
228
|
+
const di = 44;
|
|
229
|
+
class ui {
|
|
230
|
+
constructor(t, i, r, n, s = "right", a = !0) {
|
|
231
|
+
this.currentMode = "markup", this.handlePointerMove = (o) => {
|
|
232
|
+
if (o.pointerType !== "mouse") return;
|
|
233
|
+
const l = this.hintBarEl.getBoundingClientRect(), c = o.clientX >= l.left && o.clientX <= l.right && o.clientY >= l.top && o.clientY <= l.bottom;
|
|
232
234
|
this.hintBarEl.classList.toggle("mtb-hint-bar--under-pointer", c);
|
|
233
235
|
}, this.touchHintDismissListening = !1, this.dismissTouchHint = () => {
|
|
234
236
|
this.hintBarEl.classList.add("mtb-hint-bar--dismissed"), this.stopTouchHintDismissListening();
|
|
235
|
-
}, this.messages =
|
|
237
|
+
}, this.messages = i, this.touch = L(), this.hintBarEl = t.el("div", "mtb-hint-bar"), this.hintBarEl.innerHTML = `<span class="mtb-toolbar-hint">${d(this.idleHint())}</span>`, this.touch && !a && this.hintBarEl.classList.add("mtb-hint-bar--dismissed"), this.el = t.el("div", "mtb-toolbar"), s === "left" && this.el.classList.add("left"), this.el.innerHTML = this.buildHTML(i), t.append(this.hintBarEl, this.el), this.host = t.host, this.host.setAttribute("data-mtb-toolbar", ""), this.hintTextEl = this.hintBarEl.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", () => {
|
|
236
238
|
this.setMode("markup"), n?.("markup");
|
|
237
239
|
}), this.recordBtn.addEventListener("click", () => {
|
|
238
240
|
this.setMode("record"), n?.("record");
|
|
239
|
-
}), this.el.querySelector(".mtb-exit-btn").addEventListener("click",
|
|
241
|
+
}), this.el.querySelector(".mtb-exit-btn").addEventListener("click", r), document.addEventListener("pointermove", this.handlePointerMove), this.touch && a && (document.addEventListener("pointerdown", this.dismissTouchHint, !0), this.touchHintDismissListening = !0);
|
|
240
242
|
}
|
|
241
243
|
stopTouchHintDismissListening() {
|
|
242
244
|
this.touchHintDismissListening && (this.touchHintDismissListening = !1, document.removeEventListener("pointerdown", this.dismissTouchHint, !0));
|
|
@@ -277,16 +279,16 @@ class ur {
|
|
|
277
279
|
* the bar covers the page again, which is the defect this exists to fix.
|
|
278
280
|
*/
|
|
279
281
|
height() {
|
|
280
|
-
return this.el.getBoundingClientRect().height ||
|
|
282
|
+
return this.el.getBoundingClientRect().height || di;
|
|
281
283
|
}
|
|
282
284
|
destroy() {
|
|
283
285
|
document.removeEventListener("pointermove", this.handlePointerMove), this.stopTouchHintDismissListening(), this.host.removeAttribute("data-mtb-toolbar"), this.hintBarEl.remove(), this.el.remove();
|
|
284
286
|
}
|
|
285
287
|
}
|
|
286
|
-
class
|
|
287
|
-
constructor(t,
|
|
288
|
-
this.handlers =
|
|
289
|
-
const n =
|
|
288
|
+
class mi {
|
|
289
|
+
constructor(t, i) {
|
|
290
|
+
this.handlers = i, this.overlayEl = t.el("div", "mtb-overlay"), this.onPointerDown = (r) => {
|
|
291
|
+
const n = r;
|
|
290
292
|
if (n.isPrimary) {
|
|
291
293
|
try {
|
|
292
294
|
this.overlayEl.setPointerCapture(n.pointerId);
|
|
@@ -294,14 +296,14 @@ class mr {
|
|
|
294
296
|
}
|
|
295
297
|
this.handlers.onPointerDown(n);
|
|
296
298
|
}
|
|
297
|
-
}, this.onPointerMove = (
|
|
298
|
-
const n =
|
|
299
|
+
}, this.onPointerMove = (r) => {
|
|
300
|
+
const n = r;
|
|
299
301
|
n.isPrimary && this.handlers.onPointerMove(n);
|
|
300
|
-
}, this.onPointerUp = (
|
|
301
|
-
const n =
|
|
302
|
+
}, this.onPointerUp = (r) => {
|
|
303
|
+
const n = r;
|
|
302
304
|
n.isPrimary && (this.releaseCapture(n.pointerId), this.handlers.onPointerUp(n));
|
|
303
|
-
}, this.onPointerCancel = (
|
|
304
|
-
const n =
|
|
305
|
+
}, this.onPointerCancel = (r) => {
|
|
306
|
+
const n = r;
|
|
305
307
|
n.isPrimary && (this.releaseCapture(n.pointerId), this.handlers.onPointerCancel(n));
|
|
306
308
|
}, this.overlayEl.addEventListener("pointerdown", this.onPointerDown), this.overlayEl.addEventListener("pointermove", this.onPointerMove), this.overlayEl.addEventListener("pointerup", this.onPointerUp), this.overlayEl.addEventListener("pointercancel", this.onPointerCancel), t.append(this.overlayEl), this.dimEl = t.el("div", "mtb-dim"), t.append(this.dimEl);
|
|
307
309
|
}
|
|
@@ -315,18 +317,18 @@ class mr {
|
|
|
315
317
|
this.overlayEl.removeEventListener("pointerdown", this.onPointerDown), this.overlayEl.removeEventListener("pointermove", this.onPointerMove), this.overlayEl.removeEventListener("pointerup", this.onPointerUp), this.overlayEl.removeEventListener("pointercancel", this.onPointerCancel), this.overlayEl.remove(), this.dimEl.remove();
|
|
316
318
|
}
|
|
317
319
|
}
|
|
318
|
-
class
|
|
320
|
+
class bi {
|
|
319
321
|
constructor(t) {
|
|
320
322
|
this.highlightEl = t.el("div", "mtb-highlight"), this.tooltipEl = t.el("div", "mtb-highlight-tooltip"), this.hide(), t.append(this.highlightEl, this.tooltipEl);
|
|
321
323
|
}
|
|
322
324
|
highlight(t) {
|
|
323
|
-
const
|
|
324
|
-
this.highlightEl.style.top = `${
|
|
325
|
+
const i = t.getBoundingClientRect();
|
|
326
|
+
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", this.showTooltip(t, i);
|
|
325
327
|
}
|
|
326
|
-
showTooltip(t,
|
|
327
|
-
this.tooltipEl.textContent =
|
|
328
|
-
const
|
|
329
|
-
this.tooltipEl.classList.toggle("below",
|
|
328
|
+
showTooltip(t, i) {
|
|
329
|
+
this.tooltipEl.textContent = Mt(t);
|
|
330
|
+
const r = i.top < 30;
|
|
331
|
+
this.tooltipEl.classList.toggle("below", r), this.tooltipEl.style.left = `${i.left + i.width / 2}px`, this.tooltipEl.style.top = r ? `${i.bottom + 8}px` : `${i.top - 8}px`, this.tooltipEl.style.display = "block";
|
|
330
332
|
}
|
|
331
333
|
select() {
|
|
332
334
|
this.highlightEl.classList.add("selected"), this.tooltipEl.style.display = "none";
|
|
@@ -338,56 +340,56 @@ class br {
|
|
|
338
340
|
this.highlightEl.remove(), this.tooltipEl.remove();
|
|
339
341
|
}
|
|
340
342
|
}
|
|
341
|
-
function
|
|
343
|
+
function pi(e, t, i) {
|
|
342
344
|
return {
|
|
343
345
|
left: e.left,
|
|
344
346
|
top: e.top,
|
|
345
347
|
scaleX: t / e.width,
|
|
346
|
-
scaleY:
|
|
348
|
+
scaleY: i / e.height
|
|
347
349
|
};
|
|
348
350
|
}
|
|
349
|
-
function
|
|
351
|
+
function it(e, t) {
|
|
350
352
|
return (t - e.left) * e.scaleX;
|
|
351
353
|
}
|
|
352
354
|
function rt(e, t) {
|
|
353
355
|
return (t - e.top) * e.scaleY;
|
|
354
356
|
}
|
|
355
|
-
function
|
|
357
|
+
function fi(e, t) {
|
|
356
358
|
return {
|
|
357
|
-
left:
|
|
359
|
+
left: it(e, t.left),
|
|
358
360
|
top: rt(e, t.top),
|
|
359
361
|
width: t.width * e.scaleX,
|
|
360
362
|
height: t.height * e.scaleY
|
|
361
363
|
};
|
|
362
364
|
}
|
|
363
|
-
function
|
|
365
|
+
function gi() {
|
|
364
366
|
return { left: 0, top: 0, width: window.innerWidth, height: window.innerHeight };
|
|
365
367
|
}
|
|
366
|
-
function
|
|
368
|
+
function wi(e, t) {
|
|
367
369
|
return { x: e.x - t.x, y: e.y - t.y };
|
|
368
370
|
}
|
|
369
|
-
function
|
|
370
|
-
let t = 0,
|
|
371
|
-
for (;
|
|
372
|
-
|
|
373
|
-
return { x: t, y:
|
|
371
|
+
function Y(e) {
|
|
372
|
+
let t = 0, i = 0, r = e;
|
|
373
|
+
for (; r && r !== document.body; )
|
|
374
|
+
r instanceof HTMLElement && (t += r.scrollLeft, i += r.scrollTop), r = ye(r);
|
|
375
|
+
return { x: t, y: i };
|
|
374
376
|
}
|
|
375
|
-
function
|
|
377
|
+
function ye(e) {
|
|
376
378
|
if (e.parentElement) return e.parentElement;
|
|
377
379
|
const t = e.getRootNode();
|
|
378
380
|
return t instanceof ShadowRoot ? t.host : null;
|
|
379
381
|
}
|
|
380
|
-
function
|
|
381
|
-
const t =
|
|
382
|
+
function qt(e) {
|
|
383
|
+
const t = Y(e);
|
|
382
384
|
return { x: t.x + window.scrollX, y: t.y + window.scrollY };
|
|
383
385
|
}
|
|
384
|
-
class
|
|
386
|
+
class yi {
|
|
385
387
|
constructor(t) {
|
|
386
388
|
this.pins = [], this.shadow = t;
|
|
387
389
|
}
|
|
388
|
-
addPin(t,
|
|
389
|
-
const
|
|
390
|
-
|
|
390
|
+
addPin(t, i) {
|
|
391
|
+
const r = this.shadow.el("div", "mtb-pin");
|
|
392
|
+
r.style.top = `${i}px`, r.style.left = `${t}px`, this.shadow.append(r), this.pins.push(r);
|
|
391
393
|
}
|
|
392
394
|
clearAll() {
|
|
393
395
|
for (const t of this.pins) t.remove();
|
|
@@ -404,15 +406,15 @@ const ve = "#059669", D = {
|
|
|
404
406
|
linejoin: "round",
|
|
405
407
|
filter: "drop-shadow(0 0 1px rgba(255, 255, 255, 0.95)) drop-shadow(0 1px 2px rgba(15, 23, 42, 0.72))"
|
|
406
408
|
};
|
|
407
|
-
class
|
|
409
|
+
class vi {
|
|
408
410
|
constructor(t) {
|
|
409
|
-
this.currentPath = null, this.currentPoints = [], this.currentAnchor =
|
|
411
|
+
this.currentPath = null, this.currentPoints = [], this.currentAnchor = xi(), this.isDrawing = !1, this.committed = [], this.redoStack = [], this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"), this.svg.setAttribute("class", "mtb-draw-svg"), t.append(this.svg);
|
|
410
412
|
}
|
|
411
|
-
startDraw(t,
|
|
412
|
-
this.isDrawing = !0, this.currentPoints = [[t,
|
|
413
|
+
startDraw(t, i) {
|
|
414
|
+
this.isDrawing = !0, this.currentPoints = [[t, i]], this.currentAnchor = ki(t, i), this.currentPath = this.createPath(), this.svg.appendChild(this.currentPath);
|
|
413
415
|
}
|
|
414
|
-
continueDraw(t,
|
|
415
|
-
!this.isDrawing || !this.currentPath || (this.currentPoints.push([t,
|
|
416
|
+
continueDraw(t, i) {
|
|
417
|
+
!this.isDrawing || !this.currentPath || (this.currentPoints.push([t, i]), this.currentPath.setAttribute("d", gt(this.currentPoints)));
|
|
416
418
|
}
|
|
417
419
|
/**
|
|
418
420
|
* How far the pointer has wandered from where it went down, in pixels.
|
|
@@ -425,17 +427,17 @@ class vr {
|
|
|
425
427
|
getCurrentSpan() {
|
|
426
428
|
const [t] = this.currentPoints;
|
|
427
429
|
if (!t) return 0;
|
|
428
|
-
let
|
|
429
|
-
for (const [
|
|
430
|
-
|
|
431
|
-
return
|
|
430
|
+
let i = 0;
|
|
431
|
+
for (const [r, n] of this.currentPoints)
|
|
432
|
+
i = Math.max(i, Math.hypot(r - t[0], n - t[1]));
|
|
433
|
+
return i;
|
|
432
434
|
}
|
|
433
435
|
// Commits the in-progress stroke to the undo stack and clears the redo stack.
|
|
434
436
|
// Callers decide whether the stroke has enough points before committing.
|
|
435
437
|
commitStroke() {
|
|
436
438
|
return !this.isDrawing || !this.currentPath ? !1 : (this.isDrawing = !1, this.committed.push({
|
|
437
439
|
path: this.currentPath,
|
|
438
|
-
d:
|
|
440
|
+
d: gt(this.currentPoints),
|
|
439
441
|
points: this.currentPoints,
|
|
440
442
|
anchor: this.currentAnchor
|
|
441
443
|
}), this.redoStack = [], this.currentPath = null, this.currentPoints = [], !0);
|
|
@@ -450,8 +452,8 @@ class vr {
|
|
|
450
452
|
redo() {
|
|
451
453
|
const t = this.redoStack.pop();
|
|
452
454
|
if (!t) return !1;
|
|
453
|
-
const
|
|
454
|
-
return
|
|
455
|
+
const i = this.createPath();
|
|
456
|
+
return i.setAttribute("d", t.d), this.svg.appendChild(i), this.committed.push({ path: i, d: t.d, points: t.points, anchor: t.anchor }), !0;
|
|
455
457
|
}
|
|
456
458
|
canUndo() {
|
|
457
459
|
return this.committed.length > 0;
|
|
@@ -465,15 +467,15 @@ class vr {
|
|
|
465
467
|
getAnnotation() {
|
|
466
468
|
const [t] = this.committed;
|
|
467
469
|
if (!t) return null;
|
|
468
|
-
const
|
|
470
|
+
const i = this.committed.map((s) => Ei(s.points, {
|
|
469
471
|
x: s.anchor.offset.x - t.anchor.offset.x,
|
|
470
472
|
y: s.anchor.offset.y - t.anchor.offset.y
|
|
471
|
-
})), [
|
|
473
|
+
})), [r, n] = Si(i.flat());
|
|
472
474
|
return {
|
|
473
475
|
type: "draw",
|
|
474
|
-
x:
|
|
476
|
+
x: r,
|
|
475
477
|
y: n,
|
|
476
|
-
drawPath:
|
|
478
|
+
drawPath: i.map(gt).join(" "),
|
|
477
479
|
captureOffsetX: t.anchor.offset.x,
|
|
478
480
|
captureOffsetY: t.anchor.offset.y
|
|
479
481
|
};
|
|
@@ -505,59 +507,59 @@ class vr {
|
|
|
505
507
|
return t.setAttribute("fill", "none"), t.setAttribute("stroke", D.color), t.setAttribute("stroke-width", D.width), t.setAttribute("stroke-linecap", D.linecap), t.setAttribute("stroke-linejoin", D.linejoin), t.setAttribute("style", `filter:${D.filter}`), t;
|
|
506
508
|
}
|
|
507
509
|
}
|
|
508
|
-
function
|
|
510
|
+
function gt(e) {
|
|
509
511
|
if (e.length === 0) return "";
|
|
510
|
-
const [t,
|
|
511
|
-
let
|
|
512
|
+
const [t, i] = e[0];
|
|
513
|
+
let r = `M ${t} ${i}`;
|
|
512
514
|
for (let n = 1; n < e.length; n++) {
|
|
513
|
-
const [s,
|
|
514
|
-
|
|
515
|
+
const [s, a] = e[n];
|
|
516
|
+
r += ` L ${s} ${a}`;
|
|
515
517
|
}
|
|
516
|
-
return
|
|
518
|
+
return r;
|
|
517
519
|
}
|
|
518
|
-
function
|
|
520
|
+
function xi() {
|
|
519
521
|
return { offset: { x: 0, y: 0 }, pageScroll: { x: 0, y: 0 } };
|
|
520
522
|
}
|
|
521
|
-
function
|
|
522
|
-
const
|
|
523
|
+
function ki(e, t) {
|
|
524
|
+
const i = { x: window.scrollX, y: window.scrollY }, r = Y(Q(e, t));
|
|
523
525
|
return {
|
|
524
|
-
offset: { x:
|
|
525
|
-
pageScroll:
|
|
526
|
+
offset: { x: r.x + i.x, y: r.y + i.y },
|
|
527
|
+
pageScroll: i
|
|
526
528
|
};
|
|
527
529
|
}
|
|
528
|
-
function
|
|
529
|
-
return t.x === 0 && t.y === 0 ? e : e.map(([
|
|
530
|
+
function Ei(e, t) {
|
|
531
|
+
return t.x === 0 && t.y === 0 ? e : e.map(([i, r]) => [i + t.x, r + t.y]);
|
|
530
532
|
}
|
|
531
|
-
function
|
|
532
|
-
const t = e.map((s) => s[0]),
|
|
533
|
-
return [
|
|
533
|
+
function Si(e) {
|
|
534
|
+
const t = e.map((s) => s[0]), i = e.map((s) => s[1]), r = (Math.min(...t) + Math.max(...t)) / 2, n = (Math.min(...i) + Math.max(...i)) / 2;
|
|
535
|
+
return [r, n];
|
|
534
536
|
}
|
|
535
|
-
const
|
|
536
|
-
function
|
|
537
|
-
return e.closest(
|
|
537
|
+
const ut = "rr-block", W = "rr-mask", Ci = `.${ut}, .${W}`;
|
|
538
|
+
function mt(e) {
|
|
539
|
+
return e.closest(Ci) !== null;
|
|
538
540
|
}
|
|
539
|
-
function
|
|
541
|
+
function It(e) {
|
|
540
542
|
const t = e.getAttribute("role")?.trim().split(/\s+/)[0];
|
|
541
543
|
return t && /^[a-z][a-z0-9-]*$/i.test(t) ? t : e.tagName.toLowerCase();
|
|
542
544
|
}
|
|
543
545
|
function xe(e) {
|
|
544
546
|
return e.tagName.toLowerCase();
|
|
545
547
|
}
|
|
546
|
-
const
|
|
547
|
-
function
|
|
548
|
-
return
|
|
549
|
-
name:
|
|
548
|
+
const Ti = 10;
|
|
549
|
+
function Wt(e) {
|
|
550
|
+
return mt(e) ? {
|
|
551
|
+
name: It(e),
|
|
550
552
|
text: "",
|
|
551
553
|
selector: xe(e)
|
|
552
554
|
} : {
|
|
553
|
-
name:
|
|
555
|
+
name: Mt(e),
|
|
554
556
|
text: e.textContent?.trim().slice(0, 200) ?? "",
|
|
555
|
-
selector:
|
|
557
|
+
selector: we(e)
|
|
556
558
|
};
|
|
557
559
|
}
|
|
558
|
-
class
|
|
559
|
-
constructor(t,
|
|
560
|
-
this.messages =
|
|
560
|
+
class _i {
|
|
561
|
+
constructor(t, i, r) {
|
|
562
|
+
this.messages = i, this.handlers = r, this.interactionActive = !0, this.pendingHighlightFrame = null, this.lastMoveX = 0, this.lastMoveY = 0, this.touch = L(), this.highlighter = new bi(t), this.pinMarker = new yi(t), this.drawLayer = new vi(t), this.overlay = new mi(t, {
|
|
561
563
|
onPointerDown: (n) => this.handlePointerDown(n),
|
|
562
564
|
onPointerMove: (n) => this.handlePointerMove(n),
|
|
563
565
|
onPointerUp: (n) => this.handlePointerUp(n),
|
|
@@ -583,7 +585,7 @@ class _r {
|
|
|
583
585
|
}
|
|
584
586
|
updateHighlight() {
|
|
585
587
|
if (!this.interactionActive || this.drawLayer.isCurrentlyDrawing() || this.drawSessionActive()) return;
|
|
586
|
-
const t =
|
|
588
|
+
const t = Q(this.lastMoveX, this.lastMoveY);
|
|
587
589
|
t ? this.highlighter.highlight(t) : this.highlighter.hide();
|
|
588
590
|
}
|
|
589
591
|
cancelPendingHighlight() {
|
|
@@ -596,23 +598,23 @@ class _r {
|
|
|
596
598
|
// draw note bar; a tap on an element becomes a pin. Stray taps while a
|
|
597
599
|
// drawing already exists are ignored so they don't hijack the draw flow.
|
|
598
600
|
finishStroke(t) {
|
|
599
|
-
if (this.drawLayer.getCurrentSpan() >=
|
|
601
|
+
if (this.drawLayer.getCurrentSpan() >= Ti) {
|
|
600
602
|
this.drawLayer.commitStroke(), this.highlighter.hide(), this.handlers.onDrawStroke();
|
|
601
603
|
return;
|
|
602
604
|
}
|
|
603
605
|
if (this.drawLayer.cancelCurrentDraw(), this.touch || this.drawLayer.hasStrokes() || !t) return;
|
|
604
|
-
const
|
|
606
|
+
const i = Q(t.clientX, t.clientY), r = i ? Wt(i) : null, n = r?.name ?? this.messages.annotation.element, s = i?.getBoundingClientRect(), a = qt(i), o = {
|
|
605
607
|
type: "pin",
|
|
606
608
|
x: t.clientX,
|
|
607
609
|
y: t.clientY,
|
|
608
|
-
targetSelector:
|
|
609
|
-
targetText:
|
|
610
|
+
targetSelector: r?.selector,
|
|
611
|
+
targetText: r?.text ?? "",
|
|
610
612
|
targetName: n,
|
|
611
613
|
targetRect: s ? { top: s.top, left: s.left, width: s.width, height: s.height, bottom: s.bottom } : void 0,
|
|
612
|
-
captureOffsetX:
|
|
613
|
-
captureOffsetY:
|
|
614
|
+
captureOffsetX: a.x,
|
|
615
|
+
captureOffsetY: a.y
|
|
614
616
|
};
|
|
615
|
-
this.pinMarker.addPin(t.clientX, t.clientY), this.highlighter.select(), this.handlers.onPin(
|
|
617
|
+
this.pinMarker.addPin(t.clientX, t.clientY), this.highlighter.select(), this.handlers.onPin(o, n);
|
|
616
618
|
}
|
|
617
619
|
undoDraw() {
|
|
618
620
|
this.drawLayer.undo();
|
|
@@ -642,20 +644,20 @@ class _r {
|
|
|
642
644
|
getDrawAnnotation() {
|
|
643
645
|
const t = this.drawLayer.getAnnotation();
|
|
644
646
|
if (!t) return null;
|
|
645
|
-
const
|
|
646
|
-
if (!
|
|
647
|
-
const n =
|
|
647
|
+
const i = this.drawLayer.viewportDrift(), r = Q(t.x - i.x, t.y - i.y);
|
|
648
|
+
if (!r) return t;
|
|
649
|
+
const n = r.getBoundingClientRect(), s = qt(r), a = s.x - (t.captureOffsetX ?? 0), o = s.y - (t.captureOffsetY ?? 0), l = Wt(r);
|
|
648
650
|
return {
|
|
649
651
|
...t,
|
|
650
652
|
targetSelector: l.selector,
|
|
651
653
|
targetText: l.text,
|
|
652
654
|
targetName: l.name,
|
|
653
655
|
targetRect: {
|
|
654
|
-
top: n.top +
|
|
655
|
-
left: n.left +
|
|
656
|
+
top: n.top + o,
|
|
657
|
+
left: n.left + a,
|
|
656
658
|
width: n.width,
|
|
657
659
|
height: n.height,
|
|
658
|
-
bottom: n.bottom +
|
|
660
|
+
bottom: n.bottom + o
|
|
659
661
|
}
|
|
660
662
|
};
|
|
661
663
|
}
|
|
@@ -672,8 +674,8 @@ class _r {
|
|
|
672
674
|
this.dismissInteraction(), this.highlighter.destroy(), this.pinMarker.destroy(), this.drawLayer.destroy();
|
|
673
675
|
}
|
|
674
676
|
}
|
|
675
|
-
const
|
|
676
|
-
class
|
|
677
|
+
const Ai = 140;
|
|
678
|
+
class Li {
|
|
677
679
|
constructor() {
|
|
678
680
|
this.onChange = null, this.timer = null, this.lastReading = null, this.handler = () => {
|
|
679
681
|
this.timer !== null && clearTimeout(this.timer), this.timer = setTimeout(() => {
|
|
@@ -684,35 +686,35 @@ class Lr {
|
|
|
684
686
|
return;
|
|
685
687
|
}
|
|
686
688
|
this.lastReading = t, this.handler();
|
|
687
|
-
},
|
|
689
|
+
}, Ai);
|
|
688
690
|
};
|
|
689
691
|
}
|
|
690
692
|
current() {
|
|
691
693
|
const t = window.visualViewport;
|
|
692
694
|
if (!t || t.height <= 0) return 0;
|
|
693
|
-
const
|
|
694
|
-
return Math.min(Math.max(0,
|
|
695
|
+
const i = Math.round(window.innerHeight - (t.height + t.offsetTop));
|
|
696
|
+
return Math.min(Math.max(0, i), window.innerHeight);
|
|
695
697
|
}
|
|
696
698
|
observe(t) {
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
+
const i = window.visualViewport;
|
|
700
|
+
i && (this.onChange = t, i.addEventListener("resize", this.handler), i.addEventListener("scroll", this.handler));
|
|
699
701
|
}
|
|
700
702
|
stop() {
|
|
701
703
|
const t = window.visualViewport;
|
|
702
704
|
this.onChange = null, this.lastReading = null, this.timer !== null && (clearTimeout(this.timer), this.timer = null), t && (t.removeEventListener("resize", this.handler), t.removeEventListener("scroll", this.handler));
|
|
703
705
|
}
|
|
704
706
|
}
|
|
705
|
-
const
|
|
706
|
-
function
|
|
707
|
-
return window.innerWidth <=
|
|
707
|
+
const Pi = 480;
|
|
708
|
+
function Ri() {
|
|
709
|
+
return window.innerWidth <= Pi;
|
|
708
710
|
}
|
|
709
711
|
class ke {
|
|
710
712
|
constructor(t) {
|
|
711
|
-
this.el = t, this.inset = new
|
|
713
|
+
this.el = t, this.inset = new Li();
|
|
712
714
|
}
|
|
713
715
|
/** Returns true when this took over layout, i.e. the caller should not position. */
|
|
714
716
|
apply() {
|
|
715
|
-
return
|
|
717
|
+
return Ri() ? (this.el.style.left = "", this.el.style.top = "", this.el.style.maxHeight = "", this.lift(this.inset.current()), this.inset.observe((t) => this.lift(t)), !0) : !1;
|
|
716
718
|
}
|
|
717
719
|
release() {
|
|
718
720
|
this.inset.stop();
|
|
@@ -727,14 +729,14 @@ class ke {
|
|
|
727
729
|
* question about this panel's height, which is known right here.
|
|
728
730
|
*/
|
|
729
731
|
lift(t) {
|
|
730
|
-
const
|
|
731
|
-
this.el.style.bottom =
|
|
732
|
+
const i = Math.max(0, window.innerHeight - this.el.offsetHeight), r = Math.min(t, i);
|
|
733
|
+
this.el.style.bottom = r > 0 ? `${r}px` : "";
|
|
732
734
|
}
|
|
733
735
|
}
|
|
734
|
-
class
|
|
735
|
-
constructor(t,
|
|
736
|
-
this.onSubmit =
|
|
737
|
-
|
|
736
|
+
class Di {
|
|
737
|
+
constructor(t, i) {
|
|
738
|
+
this.onSubmit = i.onSubmit, this.submitLabel = i.messages.draw.submit, this.messages = i.messages, this.el = t.el("div", "mtb-draw-bar"), this.el.innerHTML = this.buildHTML(i.messages), t.append(this.el), this.sheet = new ke(this.el), this.sheet.apply(), this.input = this.el.querySelector(".mtb-draw-input"), this.undoBtn = this.el.querySelector(".mtb-draw-undo"), this.redoBtn = this.el.querySelector(".mtb-draw-redo"), this.submitBtn = this.el.querySelector(".mtb-draw-submit"), this.undoBtn.addEventListener("click", i.onUndo), this.redoBtn.addEventListener("click", i.onRedo), this.el.querySelector(".mtb-draw-cancel").addEventListener("click", i.onCancel), this.submitBtn.addEventListener("click", () => this.submit()), i.onActivity && this.input.addEventListener("input", i.onActivity), this.input.addEventListener("keydown", (r) => {
|
|
739
|
+
Dt(r) || r.key === "Enter" && !r.shiftKey && (r.preventDefault(), this.submit());
|
|
738
740
|
}), this.input.focus({ preventScroll: !0 });
|
|
739
741
|
}
|
|
740
742
|
buildHTML(t) {
|
|
@@ -757,8 +759,8 @@ class Dr {
|
|
|
757
759
|
setLoading(t) {
|
|
758
760
|
t ? (this.submitBtn.disabled = !0, this.submitBtn.classList.add("mtb-btn-loading"), this.submitBtn.textContent = this.messages.popup.sending, this.input.disabled = !0) : (this.submitBtn.disabled = !1, this.submitBtn.classList.remove("mtb-btn-loading"), this.submitBtn.textContent = this.submitLabel, this.input.disabled = !1);
|
|
759
761
|
}
|
|
760
|
-
setUndoRedo(t,
|
|
761
|
-
this.undoBtn.disabled = !t, this.redoBtn.disabled = !
|
|
762
|
+
setUndoRedo(t, i) {
|
|
763
|
+
this.undoBtn.disabled = !t, this.redoBtn.disabled = !i;
|
|
762
764
|
}
|
|
763
765
|
submit() {
|
|
764
766
|
this.onSubmit(this.input.value.trim());
|
|
@@ -767,20 +769,20 @@ class Dr {
|
|
|
767
769
|
this.sheet.release(), this.el.remove();
|
|
768
770
|
}
|
|
769
771
|
}
|
|
770
|
-
const
|
|
771
|
-
function
|
|
772
|
-
const t = window.innerWidth,
|
|
772
|
+
const nt = 12, _t = 32;
|
|
773
|
+
function Mi(e) {
|
|
774
|
+
const t = window.innerWidth, i = window.innerHeight;
|
|
773
775
|
return {
|
|
774
776
|
vw: t,
|
|
775
|
-
vh:
|
|
776
|
-
minLeft:
|
|
777
|
-
maxRight: t -
|
|
777
|
+
vh: i,
|
|
778
|
+
minLeft: nt + (e === "left" ? _t : 0),
|
|
779
|
+
maxRight: t - nt - (e === "right" ? _t : 0)
|
|
778
780
|
};
|
|
779
781
|
}
|
|
780
|
-
function
|
|
781
|
-
return Math.min(e, t.vw - 2 *
|
|
782
|
+
function Ii(e, t) {
|
|
783
|
+
return Math.min(e, t.vw - 2 * nt - _t);
|
|
782
784
|
}
|
|
783
|
-
const
|
|
785
|
+
const Fi = [
|
|
784
786
|
"button:not([disabled])",
|
|
785
787
|
"input:not([disabled])",
|
|
786
788
|
"textarea:not([disabled])",
|
|
@@ -789,26 +791,26 @@ const Fr = [
|
|
|
789
791
|
'[tabindex]:not([tabindex="-1"])'
|
|
790
792
|
].join(", ");
|
|
791
793
|
function Ee(e) {
|
|
792
|
-
const t = document.activeElement instanceof HTMLElement ? document.activeElement : null,
|
|
793
|
-
if (
|
|
794
|
-
const n = Array.from(e.querySelectorAll(
|
|
794
|
+
const t = document.activeElement instanceof HTMLElement ? document.activeElement : null, i = (r) => {
|
|
795
|
+
if (r.key !== "Tab") return;
|
|
796
|
+
const n = Array.from(e.querySelectorAll(Fi)).filter((c) => !c.hidden);
|
|
795
797
|
if (n.length === 0) return;
|
|
796
|
-
const s = n[0],
|
|
797
|
-
|
|
798
|
+
const s = n[0], a = n[n.length - 1], l = e.getRootNode().activeElement ?? document.activeElement;
|
|
799
|
+
r.shiftKey ? (l === s || !e.contains(l)) && (r.preventDefault(), a.focus({ preventScroll: !0 })) : (l === a || !e.contains(l)) && (r.preventDefault(), s.focus({ preventScroll: !0 }));
|
|
798
800
|
};
|
|
799
|
-
return e.addEventListener("keydown",
|
|
801
|
+
return e.addEventListener("keydown", i), {
|
|
800
802
|
release() {
|
|
801
|
-
e.removeEventListener("keydown",
|
|
803
|
+
e.removeEventListener("keydown", i);
|
|
802
804
|
},
|
|
803
805
|
restoreFocus() {
|
|
804
806
|
t?.isConnected && t.focus({ preventScroll: !0 });
|
|
805
807
|
}
|
|
806
808
|
};
|
|
807
809
|
}
|
|
808
|
-
const
|
|
809
|
-
class
|
|
810
|
-
constructor(t,
|
|
811
|
-
this.state = "idle", this.autoCloseTimer = null, this.session = null, this.clarifyAbort = null, this.streamingBubbleEl = null, this.opts =
|
|
810
|
+
const Hi = 320, Vt = 5e3, Bi = "https://makethisbetter.dev", K = '<svg viewBox="0 0 512 512" fill="none"><defs><linearGradient id="mtb-bg" x1=".3" y1="0" x2=".7" y2="1"><stop offset="0%" stop-color="var(--mtb-chat-logo-start, #10b981)"/><stop offset="100%" stop-color="var(--mtb-chat-logo-end, #059669)"/></linearGradient></defs><rect width="512" height="512" rx="96" fill="url(#mtb-bg)"/><g transform="translate(89,89) scale(13.9)" stroke="var(--mtb-chat-logo-fg, #fff)" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2v6h-6"/><path d="M21 13a9 9 0 1 1-3-7.7L21 8"/><circle cx="12" cy="12" r="2.2" fill="var(--mtb-chat-logo-fg, #fff)" stroke="none"/></g></svg>', Ni = '<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8.9 8l3.3-3.3-.9-.9L8 7.1 4.7 3.8l-.9.9L7.1 8l-3.3 3.3.9.9L8 8.9l3.3 3.3.9-.9z"/></svg>', Oi = '<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><path d="M6.2 2.6h3.6l.9 1.4H14a1 1 0 011 1v7.4a1 1 0 01-1 1H2a1 1 0 01-1-1V5a1 1 0 011-1h3.3l.9-1.4z"/><circle cx="8" cy="9" r="2.5" class="mtb-chat-icon-lens"/></svg>', zi = '<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><circle cx="8" cy="8" r="6.6"/><polygon points="6.4,5.2 11,8 6.4,10.8" class="mtb-chat-icon-lens"/></svg>', $i = '<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M8.1 14.6L3.8 10.3l1.5-1.5 2.8 2.8 6.6-6.6 1.5 1.5z"/></svg>';
|
|
811
|
+
class wt {
|
|
812
|
+
constructor(t, i) {
|
|
813
|
+
this.state = "idle", this.autoCloseTimer = null, this.session = null, this.clarifyAbort = null, this.streamingBubbleEl = null, this.opts = i, this.i18n = i.messages, this.el = t.el("div", "mtb-chat"), this.el.setAttribute("role", "dialog"), this.el.setAttribute("aria-modal", "true"), this.el.setAttribute("aria-label", i.targetName), this.el.innerHTML = this.buildHTML(), t.append(this.el), this.focusTrap = Ee(this.el), this.sheet = new ke(this.el), this.sheet.apply() || this.positionCard(i.x, i.y, i.targetRect, i.position ?? "right"), this.messagesEl = this.el.querySelector(".mtb-chat-messages"), this.composerEl = this.el.querySelector(".mtb-chat-composer"), this.actionsEl = this.el.querySelector(".mtb-chat-actions"), this.inputEl = this.el.querySelector(".mtb-chat-input"), this.sendBtn = this.el.querySelector(".mtb-chat-send"), this.quickRepliesEl = this.el.querySelector(".mtb-chat-quick-replies"), this.bindEvents(), this.handleEscape = this.handleEscape.bind(this), window.addEventListener("keydown", this.handleEscape), this.inputEl.focus({ preventScroll: !0 });
|
|
812
814
|
}
|
|
813
815
|
handleEscape(t) {
|
|
814
816
|
if (t.key === "Escape" && (t.preventDefault(), t.stopPropagation(), this.state !== "sending")) {
|
|
@@ -820,21 +822,21 @@ class gt {
|
|
|
820
822
|
}
|
|
821
823
|
}
|
|
822
824
|
buildHTML() {
|
|
823
|
-
const t = this.i18n,
|
|
825
|
+
const t = this.i18n, i = this.opts, r = t.popup.quickOptions.map((s) => `<button class="mtb-chat-qr" type="button" data-quick="${d(s.label)}" data-value="${d(s.value ?? s.label)}">${d(s.emoji)} ${d(s.label)}</button>`).join(""), n = i.recordingSeconds != null ? `<span class="mtb-chat-attachment" title="${d(t.popup.recording_locked_hint)}">${zi}<span class="mtb-chat-capture-label">${Math.round(i.recordingSeconds)}s</span></span>` : i.onScreenshotToggle ? `<button class="mtb-chat-screenshot" type="button" title="${d(t.popup.screenshot_hint)}" aria-pressed="${i.screenshotEnabled !== !1}">${Oi}<span class="mtb-chat-capture-label">${d(t.popup.screenshot_short)}</span></button>` : "";
|
|
824
826
|
return `
|
|
825
827
|
<div class="mtb-chat-header">
|
|
826
828
|
<div class="mtb-chat-handle"></div>
|
|
827
829
|
<div class="mtb-chat-header-row">
|
|
828
|
-
<a class="mtb-chat-brand" href="${
|
|
829
|
-
<span class="mtb-chat-logo">${
|
|
830
|
+
<a class="mtb-chat-brand" href="${Bi}" target="_blank" rel="noopener">
|
|
831
|
+
<span class="mtb-chat-logo">${K}</span>
|
|
830
832
|
<span class="mtb-chat-brand-name">Make This Better</span>
|
|
831
833
|
</a>
|
|
832
834
|
<span class="mtb-chat-header-gap"></span>
|
|
833
|
-
<button class="mtb-chat-close" type="button" aria-label="${d(t.popup.close)}">${
|
|
835
|
+
<button class="mtb-chat-close" type="button" aria-label="${d(t.popup.close)}">${Ni}</button>
|
|
834
836
|
</div>
|
|
835
837
|
</div>
|
|
836
838
|
<div class="mtb-chat-messages"></div>
|
|
837
|
-
<div class="mtb-chat-quick-replies">${
|
|
839
|
+
<div class="mtb-chat-quick-replies">${r}</div>
|
|
838
840
|
<div class="mtb-chat-composer">
|
|
839
841
|
<textarea class="mtb-chat-input" rows="1" placeholder="${d(t.popup.placeholder)}"></textarea>
|
|
840
842
|
<div class="mtb-chat-actions">
|
|
@@ -848,27 +850,27 @@ class gt {
|
|
|
848
850
|
bindEvents() {
|
|
849
851
|
this.el.querySelector(".mtb-chat-close").addEventListener("click", () => {
|
|
850
852
|
this.opts.onCancel();
|
|
851
|
-
}), this.quickRepliesEl.querySelectorAll(".mtb-chat-qr").forEach((
|
|
852
|
-
|
|
853
|
-
const
|
|
854
|
-
this.inputEl.value =
|
|
853
|
+
}), this.quickRepliesEl.querySelectorAll(".mtb-chat-qr").forEach((i) => {
|
|
854
|
+
i.addEventListener("click", () => {
|
|
855
|
+
const r = i.dataset.value ?? i.dataset.quick ?? "";
|
|
856
|
+
this.inputEl.value = r, this.sendMessage(r);
|
|
855
857
|
});
|
|
856
858
|
}), this.inputEl.addEventListener("input", () => {
|
|
857
859
|
this.sendBtn.disabled = !this.inputEl.value.trim(), this.opts.onActivity?.();
|
|
858
|
-
}), this.inputEl.addEventListener("keydown", (
|
|
859
|
-
if (!
|
|
860
|
-
|
|
861
|
-
const
|
|
862
|
-
|
|
860
|
+
}), this.inputEl.addEventListener("keydown", (i) => {
|
|
861
|
+
if (!Dt(i) && i.key === "Enter" && !i.shiftKey) {
|
|
862
|
+
i.preventDefault();
|
|
863
|
+
const r = this.inputEl.value.trim();
|
|
864
|
+
r ? this.sendMessage(r) : this.state === "clarifying" && this.skipAndSend();
|
|
863
865
|
}
|
|
864
866
|
}), this.sendBtn.addEventListener("click", () => {
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
+
const i = this.inputEl.value.trim();
|
|
868
|
+
i && this.sendMessage(i);
|
|
867
869
|
});
|
|
868
870
|
const t = this.el.querySelector(".mtb-chat-screenshot");
|
|
869
871
|
t && this.opts.onScreenshotToggle && t.addEventListener("click", () => {
|
|
870
|
-
const
|
|
871
|
-
t.setAttribute("aria-pressed", String(!
|
|
872
|
+
const i = t.getAttribute("aria-pressed") === "true";
|
|
873
|
+
t.setAttribute("aria-pressed", String(!i)), t.classList.toggle("mtb-chat-screenshot-off", i), this.opts.onScreenshotToggle(!i);
|
|
872
874
|
});
|
|
873
875
|
}
|
|
874
876
|
async sendMessage(t) {
|
|
@@ -878,56 +880,49 @@ class gt {
|
|
|
878
880
|
return;
|
|
879
881
|
}
|
|
880
882
|
this.state = "sending", this.appendUserBubble(t), this.quickRepliesEl.style.display = "none", this.hideCapture(), this.showThinking(), this.setComposerDisabled(!0);
|
|
881
|
-
let
|
|
883
|
+
let i;
|
|
882
884
|
try {
|
|
883
|
-
|
|
885
|
+
i = await this.opts.onSubmit(t);
|
|
884
886
|
} catch {
|
|
885
|
-
|
|
887
|
+
i = null;
|
|
886
888
|
}
|
|
887
|
-
if (!
|
|
889
|
+
if (!i) {
|
|
888
890
|
this.removeThinking(), this.setComposerDisabled(!1), this.showRetryableError(this.i18n.error.submit, () => {
|
|
889
891
|
this.clearError(), this.sendMessage(t);
|
|
890
892
|
}), this.state = "idle";
|
|
891
893
|
return;
|
|
892
894
|
}
|
|
893
|
-
if (this.session =
|
|
895
|
+
if (this.session = i, !i.ai_clarify_available) {
|
|
894
896
|
this.removeThinking(), this.showDone();
|
|
895
897
|
return;
|
|
896
898
|
}
|
|
897
|
-
let
|
|
898
|
-
const n = [];
|
|
899
|
+
let r = null, n = !1;
|
|
899
900
|
this.clarifyAbort = new AbortController();
|
|
900
901
|
try {
|
|
901
|
-
|
|
902
|
-
n.
|
|
902
|
+
r = await this.opts.onClarify(i.id, i.token, (a) => {
|
|
903
|
+
n || (this.removeThinking(), this.startStreamingBubble(), n = !0), this.appendStreamDelta(a);
|
|
903
904
|
}, this.clarifyAbort.signal);
|
|
904
905
|
} catch {
|
|
905
|
-
this.removeThinking(), this.showDone();
|
|
906
|
+
n ? this.endStreamingBubble() : this.removeThinking(), this.showDone();
|
|
906
907
|
return;
|
|
907
908
|
}
|
|
908
|
-
if (this.removeThinking(),
|
|
909
|
+
if (n ? this.endStreamingBubble() : this.removeThinking(), r.done || !r.messages.length) {
|
|
909
910
|
this.showDone();
|
|
910
911
|
return;
|
|
911
912
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
for (const o of n)
|
|
915
|
-
this.appendStreamDelta(o), await new Promise((a) => setTimeout(a, 15));
|
|
916
|
-
this.endStreamingBubble();
|
|
917
|
-
}
|
|
918
|
-
const s = i.messages.find((o) => o.role === "assistant");
|
|
919
|
-
!n.length && s && this.appendAiBubble(s.content), this.renderSuggestions(i.suggestions), this.state = "clarifying", this.setComposerDisabled(!1), this.inputEl.value = "", this.inputEl.placeholder = this.i18n.clarify.placeholder, this.sendBtn.textContent = this.i18n.clarify.submit ?? this.i18n.clarify.send, this.sendBtn.disabled = !0, this.showSkip(), this.inputEl.focus({ preventScroll: !0 }), this.opts.onConversationOpen?.();
|
|
913
|
+
const s = r.messages.find((a) => a.role === "assistant");
|
|
914
|
+
!n && s && this.appendAiBubble(s.content), this.renderSuggestions(r.suggestions), this.state = "clarifying", this.setComposerDisabled(!1), this.inputEl.value = "", this.inputEl.placeholder = this.i18n.clarify.placeholder, this.sendBtn.textContent = this.i18n.clarify.submit ?? this.i18n.clarify.send, this.sendBtn.disabled = !0, this.showSkip(), this.inputEl.focus({ preventScroll: !0 }), this.opts.onConversationOpen?.();
|
|
920
915
|
}
|
|
921
916
|
handleAnswer(t) {
|
|
922
|
-
const
|
|
923
|
-
|
|
917
|
+
const i = this.session;
|
|
918
|
+
i && (this.state = "done", this.appendUserBubble(t), this.clearSuggestions(), this.hideSkip(), this.setComposerDisabled(!0), this.renderSuccess(), Promise.resolve(this.opts.onAnswer(i.id, i.token, t)).catch(() => {
|
|
924
919
|
}).then(() => this.finalizeInBackground()));
|
|
925
920
|
}
|
|
926
921
|
/**
|
|
927
922
|
* The receipt goes up the moment the reporter is done rather than waiting on
|
|
928
923
|
* the finalize round trip; the hand-off it returns is patched into the card
|
|
929
|
-
* when it lands
|
|
930
|
-
*
|
|
924
|
+
* when it lands. A failed finalize replaces this receipt with an in-card
|
|
925
|
+
* retry state so the reporter stays in the conversation they used.
|
|
931
926
|
*/
|
|
932
927
|
showDone() {
|
|
933
928
|
this.state = "done", this.hideSkip(), this.setComposerDisabled(!0), this.renderSuccess(), this.finalizeInBackground();
|
|
@@ -940,14 +935,33 @@ class gt {
|
|
|
940
935
|
renderSuccess() {
|
|
941
936
|
const t = this.i18n.success;
|
|
942
937
|
this.messagesEl.remove(), this.quickRepliesEl.remove(), this.composerEl.remove();
|
|
938
|
+
const i = this.el.querySelector(".mtb-chat-success") ?? document.createElement("div");
|
|
939
|
+
i.className = "mtb-chat-success mtb-chat-success-simple", i.replaceChildren();
|
|
943
940
|
const r = document.createElement("div");
|
|
944
|
-
r.className = "mtb-chat-success
|
|
945
|
-
const i = document.createElement("div");
|
|
946
|
-
i.className = "mtb-chat-success-icon", i.innerHTML = Ur, r.appendChild(i);
|
|
941
|
+
r.className = "mtb-chat-success-icon", r.innerHTML = $i, i.appendChild(r);
|
|
947
942
|
const n = document.createElement("div");
|
|
948
|
-
n.className = "mtb-chat-success-title", n.textContent = this.session?.ai_clarify_available === !1 ? t.title_no_ai : t.title,
|
|
943
|
+
n.className = "mtb-chat-success-title", n.textContent = this.session?.ai_clarify_available === !1 ? t.title_no_ai : t.title, i.appendChild(n);
|
|
949
944
|
const s = document.createElement("a");
|
|
950
|
-
s.className = "mtb-chat-success-link mtb-chat-success-link-pending", s.href = "#", s.textContent = t.track_feedback, s.addEventListener("click", (
|
|
945
|
+
s.className = "mtb-chat-success-link mtb-chat-success-link-pending", s.href = "#", s.textContent = t.track_feedback, s.addEventListener("click", (a) => a.preventDefault()), i.appendChild(s), i.parentElement || this.el.appendChild(i), this.attachHandoff();
|
|
946
|
+
}
|
|
947
|
+
/** Keep a failed background finalize in the conversation the reporter used. */
|
|
948
|
+
showFinalizeFailure(t) {
|
|
949
|
+
this.autoCloseTimer && (clearTimeout(this.autoCloseTimer), this.autoCloseTimer = null);
|
|
950
|
+
let i = this.el.querySelector(".mtb-chat-success");
|
|
951
|
+
i || (this.messagesEl.remove(), this.quickRepliesEl.remove(), this.composerEl.remove(), i = document.createElement("div"), this.el.appendChild(i)), i.className = "mtb-chat-success mtb-chat-finalize-failure", i.innerHTML = `
|
|
952
|
+
<div class="mtb-chat-success-icon mtb-chat-failure-icon">!</div>
|
|
953
|
+
<div class="mtb-chat-success-title">${d(this.i18n.error.finalize_title)}</div>
|
|
954
|
+
<div class="mtb-chat-finalize-message">${d(this.i18n.error.finalize_message)}</div>
|
|
955
|
+
${t ? `<button class="mtb-chat-finalize-retry" type="button">${d(this.i18n.clarify.retry)}</button>` : ""}
|
|
956
|
+
<button class="mtb-chat-finalize-close" type="button">${d(this.i18n.success.close)}</button>
|
|
957
|
+
`, t && i.querySelector(".mtb-chat-finalize-retry").addEventListener("click", () => {
|
|
958
|
+
const r = i.querySelector(".mtb-chat-finalize-retry");
|
|
959
|
+
r.disabled = !0, r.innerHTML = '<span class="mtb-chat-finalize-spinner" aria-label="Retrying"></span>', t();
|
|
960
|
+
}), i.querySelector(".mtb-chat-finalize-close").addEventListener("click", () => this.opts.onCancel());
|
|
961
|
+
}
|
|
962
|
+
/** Restore the receipt after a retry reaches the final endpoint. */
|
|
963
|
+
showFinalizeSuccess() {
|
|
964
|
+
this.state = "done", this.renderSuccess();
|
|
951
965
|
}
|
|
952
966
|
/**
|
|
953
967
|
* The board link and the email form are both built from the hand-off that
|
|
@@ -959,53 +973,53 @@ class gt {
|
|
|
959
973
|
const t = this.el.querySelector(".mtb-chat-success");
|
|
960
974
|
if (!t) return;
|
|
961
975
|
this.i18n.success;
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
s.preventDefault(),
|
|
976
|
+
const i = this.opts.resolveBoardLink?.(), r = t.querySelector(".mtb-chat-success-link-pending");
|
|
977
|
+
i && r && (r.classList.remove("mtb-chat-success-link-pending"), r.addEventListener("click", (s) => {
|
|
978
|
+
s.preventDefault(), i();
|
|
965
979
|
}));
|
|
966
980
|
const n = this.opts.resolveEmailCapture?.();
|
|
967
|
-
n && !t.querySelector(".mtb-chat-email-card") ? (this.autoCloseTimer && (clearTimeout(this.autoCloseTimer), this.autoCloseTimer = null), t.classList.remove("mtb-chat-success-simple"), t.appendChild(this.buildEmailCard(n))) : !n && !this.autoCloseTimer && !t.querySelector(".mtb-chat-email-card") && (this.autoCloseTimer = setTimeout(() => this.destroy(),
|
|
981
|
+
n && !t.querySelector(".mtb-chat-email-card") ? (this.autoCloseTimer && (clearTimeout(this.autoCloseTimer), this.autoCloseTimer = null), t.classList.remove("mtb-chat-success-simple"), t.appendChild(this.buildEmailCard(n))) : !n && !this.autoCloseTimer && !t.querySelector(".mtb-chat-email-card") && (this.autoCloseTimer = setTimeout(() => this.destroy(), Vt));
|
|
968
982
|
}
|
|
969
983
|
finalizeInBackground() {
|
|
970
984
|
Promise.resolve(this.opts.onFinalize()).then(() => this.attachHandoff()).catch(() => {
|
|
971
985
|
});
|
|
972
986
|
}
|
|
973
987
|
buildEmailCard(t) {
|
|
974
|
-
const
|
|
975
|
-
|
|
988
|
+
const i = this.i18n.success, r = document.createElement("div");
|
|
989
|
+
r.className = "mtb-chat-email-card";
|
|
976
990
|
const n = document.createElement("div");
|
|
977
991
|
n.className = "mtb-chat-email-row";
|
|
978
992
|
const s = document.createElement("div");
|
|
979
993
|
s.className = "mtb-chat-email-field";
|
|
980
|
-
const
|
|
981
|
-
|
|
982
|
-
const
|
|
983
|
-
|
|
994
|
+
const a = document.createElement("input");
|
|
995
|
+
a.className = "mtb-chat-email-input", a.type = "email", a.placeholder = i.email_cta, s.appendChild(a);
|
|
996
|
+
const o = document.createElement("button");
|
|
997
|
+
o.className = "mtb-chat-email-submit", o.type = "button", o.textContent = i.notify, o.disabled = !0;
|
|
984
998
|
const l = async () => {
|
|
985
|
-
const c =
|
|
999
|
+
const c = a.value.trim();
|
|
986
1000
|
if (!c) return;
|
|
987
|
-
if (
|
|
1001
|
+
if (o.disabled = !0, a.disabled = !0, await t.onSubmit(c)) {
|
|
988
1002
|
const m = document.createElement("div");
|
|
989
|
-
m.className = "mtb-chat-email-note", m.textContent =
|
|
1003
|
+
m.className = "mtb-chat-email-note", m.textContent = i.email_saved, r.replaceChildren(m), this.autoCloseTimer = setTimeout(() => this.destroy(), Vt);
|
|
990
1004
|
return;
|
|
991
1005
|
}
|
|
992
|
-
|
|
993
|
-
const u =
|
|
994
|
-
u.className = "mtb-chat-email-error", u.textContent =
|
|
1006
|
+
a.disabled = !1, o.disabled = !1;
|
|
1007
|
+
const u = r.querySelector(".mtb-chat-email-error") ?? document.createElement("div");
|
|
1008
|
+
u.className = "mtb-chat-email-error", u.textContent = i.email_error, r.appendChild(u);
|
|
995
1009
|
};
|
|
996
|
-
return
|
|
997
|
-
|
|
998
|
-
}),
|
|
999
|
-
c.key === "Enter" &&
|
|
1000
|
-
}),
|
|
1010
|
+
return a.addEventListener("input", () => {
|
|
1011
|
+
o.disabled = !a.value.trim();
|
|
1012
|
+
}), a.addEventListener("keydown", (c) => {
|
|
1013
|
+
c.key === "Enter" && a.value.trim() && l();
|
|
1014
|
+
}), o.addEventListener("click", () => void l()), n.appendChild(s), n.appendChild(o), r.appendChild(n), r;
|
|
1001
1015
|
}
|
|
1002
1016
|
appendUserBubble(t) {
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1017
|
+
const i = document.createElement("div");
|
|
1018
|
+
i.className = "mtb-chat-bubble mtb-chat-bubble-user", i.textContent = t, this.messagesEl.appendChild(i), this.messagesEl.scrollTop = this.messagesEl.scrollHeight, this.inputEl.value = "", this.sendBtn.disabled = !0;
|
|
1005
1019
|
}
|
|
1006
1020
|
startStreamingBubble() {
|
|
1007
1021
|
const t = document.createElement("div");
|
|
1008
|
-
t.className = "mtb-chat-ai-row", t.innerHTML = `<div class="mtb-chat-avatar">${
|
|
1022
|
+
t.className = "mtb-chat-ai-row", t.innerHTML = `<div class="mtb-chat-avatar">${K}</div><div class="mtb-chat-bubble mtb-chat-bubble-ai"></div>`, this.messagesEl.appendChild(t), this.streamingBubbleEl = t.querySelector(".mtb-chat-bubble-ai");
|
|
1009
1023
|
}
|
|
1010
1024
|
appendStreamDelta(t) {
|
|
1011
1025
|
this.streamingBubbleEl && (this.streamingBubbleEl.textContent = (this.streamingBubbleEl.textContent ?? "") + t, this.messagesEl.scrollTop = this.messagesEl.scrollHeight);
|
|
@@ -1014,20 +1028,20 @@ class gt {
|
|
|
1014
1028
|
this.streamingBubbleEl = null;
|
|
1015
1029
|
}
|
|
1016
1030
|
appendAiBubble(t) {
|
|
1017
|
-
const
|
|
1018
|
-
|
|
1031
|
+
const i = document.createElement("div");
|
|
1032
|
+
i.className = "mtb-chat-ai-row", i.innerHTML = `<div class="mtb-chat-avatar">${K}</div><div class="mtb-chat-bubble mtb-chat-bubble-ai"></div>`, i.querySelector(".mtb-chat-bubble-ai").textContent = t, this.messagesEl.appendChild(i), this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
1019
1033
|
}
|
|
1020
1034
|
renderSuggestions(t) {
|
|
1021
1035
|
if (this.clearSuggestions(), !t?.length) return;
|
|
1022
|
-
const
|
|
1023
|
-
|
|
1024
|
-
for (const
|
|
1036
|
+
const i = document.createElement("div");
|
|
1037
|
+
i.className = "mtb-chat-suggestions";
|
|
1038
|
+
for (const r of t) {
|
|
1025
1039
|
const n = document.createElement("button");
|
|
1026
|
-
n.className = "mtb-chat-sg", n.type = "button", n.textContent =
|
|
1027
|
-
this.inputEl.value =
|
|
1028
|
-
}),
|
|
1040
|
+
n.className = "mtb-chat-sg", n.type = "button", n.textContent = r, n.addEventListener("click", () => {
|
|
1041
|
+
this.inputEl.value = r, this.sendBtn.disabled = !1, this.inputEl.focus({ preventScroll: !0 });
|
|
1042
|
+
}), i.appendChild(n);
|
|
1029
1043
|
}
|
|
1030
|
-
this.messagesEl.appendChild(
|
|
1044
|
+
this.messagesEl.appendChild(i), this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
1031
1045
|
}
|
|
1032
1046
|
clearSuggestions() {
|
|
1033
1047
|
this.messagesEl.querySelector(".mtb-chat-suggestions")?.remove();
|
|
@@ -1035,19 +1049,19 @@ class gt {
|
|
|
1035
1049
|
showThinking() {
|
|
1036
1050
|
if (this.messagesEl.querySelector(".mtb-chat-thinking")) return;
|
|
1037
1051
|
const t = document.createElement("div");
|
|
1038
|
-
t.className = "mtb-chat-ai-row mtb-chat-thinking", t.innerHTML = `<div class="mtb-chat-avatar">${
|
|
1052
|
+
t.className = "mtb-chat-ai-row mtb-chat-thinking", t.innerHTML = `<div class="mtb-chat-avatar">${K}</div><div class="mtb-chat-dots"><span></span><span></span><span></span></div>`, this.messagesEl.appendChild(t), this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
1039
1053
|
}
|
|
1040
1054
|
removeThinking() {
|
|
1041
1055
|
this.messagesEl.querySelector(".mtb-chat-thinking")?.remove();
|
|
1042
1056
|
}
|
|
1043
|
-
showRetryableError(t,
|
|
1057
|
+
showRetryableError(t, i) {
|
|
1044
1058
|
this.clearError();
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1059
|
+
const r = document.createElement("div");
|
|
1060
|
+
r.className = "mtb-chat-error-row";
|
|
1047
1061
|
const n = document.createElement("span");
|
|
1048
1062
|
n.className = "mtb-chat-error-text", n.textContent = t;
|
|
1049
1063
|
const s = document.createElement("button");
|
|
1050
|
-
s.className = "mtb-chat-error-retry", s.type = "button", s.textContent = this.i18n.clarify.retry, s.addEventListener("click",
|
|
1064
|
+
s.className = "mtb-chat-error-retry", s.type = "button", s.textContent = this.i18n.clarify.retry, s.addEventListener("click", i), r.appendChild(n), r.appendChild(s), this.messagesEl.appendChild(r), this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
|
|
1051
1065
|
}
|
|
1052
1066
|
clearError() {
|
|
1053
1067
|
this.messagesEl.querySelectorAll(".mtb-chat-error-row").forEach((t) => t.remove());
|
|
@@ -1069,11 +1083,11 @@ class gt {
|
|
|
1069
1083
|
setComposerDisabled(t) {
|
|
1070
1084
|
this.inputEl.disabled = t, this.sendBtn.disabled = t, this.composerEl.classList.toggle("mtb-chat-composer-disabled", t);
|
|
1071
1085
|
}
|
|
1072
|
-
positionCard(t,
|
|
1073
|
-
const s =
|
|
1074
|
-
let
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1086
|
+
positionCard(t, i, r, n) {
|
|
1087
|
+
const s = Mi(n), { vw: a, vh: o, minLeft: l, maxRight: c } = s, h = nt, u = 8, m = Ii(Hi, s), y = (this.el.offsetHeight || 280) + 80;
|
|
1088
|
+
let w, b;
|
|
1089
|
+
const ft = r && r.width < a * 0.6 && r.height < o * 0.6;
|
|
1090
|
+
r && ft ? (w = r.left, b = r.bottom + u, b + y > o - h && (b = r.top - y - u), b < h && (b = Math.min(r.bottom + u, o - y - h))) : (w = t + 12, b = i + 12), w + m > c && (w = c - m), w < l && (w = l), b < h && (b = h), b + y > o - h && (b = o - y - h), b < h && (b = h), this.el.style.left = `${w}px`, this.el.style.top = `${b}px`, this.el.style.maxHeight = `${o - b - h}px`;
|
|
1077
1091
|
}
|
|
1078
1092
|
submit(t) {
|
|
1079
1093
|
this.sendMessage(t);
|
|
@@ -1086,35 +1100,35 @@ class gt {
|
|
|
1086
1100
|
this.clarifyAbort?.abort(), this.autoCloseTimer && clearTimeout(this.autoCloseTimer), window.removeEventListener("keydown", this.handleEscape), this.sheet.release(), this.focusTrap.release(), this.el.remove(), this.focusTrap.restoreFocus();
|
|
1087
1101
|
}
|
|
1088
1102
|
}
|
|
1089
|
-
const
|
|
1090
|
-
class
|
|
1091
|
-
constructor(t,
|
|
1092
|
-
const s =
|
|
1093
|
-
this.el = t.el("div", "mtb-chat mtb-chat-receipt"), this.el.setAttribute("role", "dialog"), this.el.setAttribute("aria-modal", "true"), this.el.setAttribute("aria-label",
|
|
1094
|
-
const
|
|
1095
|
-
|
|
1103
|
+
const Ui = 5e3, ji = '<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M8.1 14.6L3.8 10.3l1.5-1.5 2.8 2.8 6.6-6.6 1.5 1.5z"/></svg>';
|
|
1104
|
+
class qi {
|
|
1105
|
+
constructor(t, i, r, n) {
|
|
1106
|
+
const s = i.success, a = n?.skipFollowup ? s.title_no_ai : s.title;
|
|
1107
|
+
this.el = t.el("div", "mtb-chat mtb-chat-receipt"), this.el.setAttribute("role", "dialog"), this.el.setAttribute("aria-modal", "true"), this.el.setAttribute("aria-label", a);
|
|
1108
|
+
const o = document.createElement("div");
|
|
1109
|
+
o.className = "mtb-chat-success mtb-chat-success-simple";
|
|
1096
1110
|
const l = document.createElement("div");
|
|
1097
|
-
l.className = "mtb-chat-success-icon", l.innerHTML =
|
|
1111
|
+
l.className = "mtb-chat-success-icon", l.innerHTML = ji, o.appendChild(l);
|
|
1098
1112
|
const c = document.createElement("div");
|
|
1099
|
-
if (c.className = "mtb-chat-success-title", c.textContent =
|
|
1113
|
+
if (c.className = "mtb-chat-success-title", c.textContent = a, o.appendChild(c), n?.onViewFeedback) {
|
|
1100
1114
|
const h = document.createElement("a");
|
|
1101
1115
|
h.className = "mtb-chat-success-link", h.href = "#", h.textContent = s.track_feedback, h.addEventListener("click", (u) => {
|
|
1102
1116
|
u.preventDefault(), n.onViewFeedback();
|
|
1103
|
-
}),
|
|
1117
|
+
}), o.appendChild(h);
|
|
1104
1118
|
}
|
|
1105
|
-
this.el.appendChild(
|
|
1119
|
+
this.el.appendChild(o), t.append(this.el), this.focusTrap = Ee(this.el), this.autoCloseTimer = setTimeout(r, Ui);
|
|
1106
1120
|
}
|
|
1107
1121
|
destroy() {
|
|
1108
1122
|
clearTimeout(this.autoCloseTimer), this.focusTrap.release(), this.el.remove(), this.focusTrap.restoreFocus();
|
|
1109
1123
|
}
|
|
1110
1124
|
}
|
|
1111
|
-
const g = "[Filtered]",
|
|
1125
|
+
const g = "[Filtered]", Wi = /-----BEGIN ((?:[A-Z0-9]+ )*PRIVATE KEY)-----[\s\S]*?-----END \1-----/g, Vi = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, Yi = [
|
|
1112
1126
|
/\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\b/g,
|
|
1113
1127
|
/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g,
|
|
1114
1128
|
/\bgh[pousr]_[A-Za-z0-9]{30,}\b/g,
|
|
1115
1129
|
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
1116
1130
|
/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/g
|
|
1117
|
-
],
|
|
1131
|
+
], Xi = /\b(?:\d[ -]?){12,18}\d\b/g, Ki = /\bhttps?:\/\/[^\s<>"']+/gi, Gi = /* @__PURE__ */ new Set(["type", "autocomplete", "name", "id", "aria_label", "placeholder"]), Ji = /* @__PURE__ */ new Set(["value", "content"]), Zi = /* @__PURE__ */ new Set(["password", "hidden", "file"]), Qi = /* @__PURE__ */ new Set([
|
|
1118
1132
|
"current_password",
|
|
1119
1133
|
"new_password",
|
|
1120
1134
|
"one_time_code",
|
|
@@ -1123,14 +1137,14 @@ const g = "[Filtered]", Wr = /-----BEGIN ((?:[A-Z0-9]+ )*PRIVATE KEY)-----[\s\S]
|
|
|
1123
1137
|
"cc_exp",
|
|
1124
1138
|
"cc_exp_month",
|
|
1125
1139
|
"cc_exp_year"
|
|
1126
|
-
]),
|
|
1140
|
+
]), tr = /(?:^|_)(?:password|passwd|passcode|card_(?:number|no)(?:_[0-9]+)?|credit_card|cc_(?:number|num|csc|cvv|cvc|exp|expiry)|cvv|cvc|csc|security_code|one_time_(?:code|password)|otp(?:_code)?|verification_code|auth(?:entication)?_token|access_token|refresh_token|id_token|token|api_key|client_secret|secret|authorization|cookie|set_cookie|credential|private_key|hidden_value|file_name|filename)(?:$|_(?:value|field|input|confirmation|confirm|header|data|pem)$)/;
|
|
1127
1141
|
function R(e) {
|
|
1128
|
-
let t = e.replace(
|
|
1129
|
-
for (const
|
|
1130
|
-
t = t.replace(
|
|
1131
|
-
return t = t.replace(
|
|
1142
|
+
let t = e.replace(Wi, g).replace(Vi, g);
|
|
1143
|
+
for (const i of Yi)
|
|
1144
|
+
t = t.replace(i, g);
|
|
1145
|
+
return t = t.replace(Xi, (i) => er(i) ? g : i), t.replace(Ki, (i) => V(i) || g);
|
|
1132
1146
|
}
|
|
1133
|
-
function
|
|
1147
|
+
function V(e) {
|
|
1134
1148
|
try {
|
|
1135
1149
|
const t = new URL(e);
|
|
1136
1150
|
return `${t.origin}${t.pathname}`;
|
|
@@ -1138,43 +1152,43 @@ function Y(e) {
|
|
|
1138
1152
|
return "";
|
|
1139
1153
|
}
|
|
1140
1154
|
}
|
|
1141
|
-
function
|
|
1155
|
+
function st(e, t) {
|
|
1142
1156
|
if (t && Se(t) && e != null) return g;
|
|
1143
1157
|
if (typeof e == "string") return R(e);
|
|
1144
|
-
if (Array.isArray(e)) return e.map((
|
|
1158
|
+
if (Array.isArray(e)) return e.map((i) => st(i));
|
|
1145
1159
|
if (e && typeof e == "object") {
|
|
1146
|
-
const
|
|
1160
|
+
const i = Ce(e);
|
|
1147
1161
|
return Object.fromEntries(
|
|
1148
1162
|
Object.entries(e).map(([n, s]) => {
|
|
1149
|
-
const
|
|
1150
|
-
return [R(n),
|
|
1163
|
+
const a = i && Ji.has(N(n)) && s != null ? g : st(s, n);
|
|
1164
|
+
return [R(n), a];
|
|
1151
1165
|
})
|
|
1152
1166
|
);
|
|
1153
1167
|
}
|
|
1154
1168
|
return e;
|
|
1155
1169
|
}
|
|
1156
1170
|
function Se(e) {
|
|
1157
|
-
return
|
|
1171
|
+
return tr.test(N(e));
|
|
1158
1172
|
}
|
|
1159
1173
|
function Ce(e) {
|
|
1160
|
-
return Object.entries(e).some(([t,
|
|
1161
|
-
if (typeof
|
|
1162
|
-
const
|
|
1163
|
-
return
|
|
1174
|
+
return Object.entries(e).some(([t, i]) => {
|
|
1175
|
+
if (typeof i != "string") return !1;
|
|
1176
|
+
const r = N(t);
|
|
1177
|
+
return Gi.has(r) ? r === "type" ? Zi.has(N(i)) : r === "autocomplete" ? i.split(/\s+/).some((n) => Qi.has(N(n))) : Se(i) : !1;
|
|
1164
1178
|
});
|
|
1165
1179
|
}
|
|
1166
|
-
function
|
|
1180
|
+
function N(e) {
|
|
1167
1181
|
return e.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
1168
1182
|
}
|
|
1169
|
-
function
|
|
1183
|
+
function er(e) {
|
|
1170
1184
|
const t = e.replace(/\D/g, "");
|
|
1171
1185
|
if (t.length < 13 || t.length > 19) return !1;
|
|
1172
|
-
let
|
|
1186
|
+
let i = 0, r = !1;
|
|
1173
1187
|
for (let n = t.length - 1; n >= 0; n -= 1) {
|
|
1174
1188
|
let s = Number(t[n]);
|
|
1175
|
-
|
|
1189
|
+
r && (s *= 2, s > 9 && (s -= 9)), i += s, r = !r;
|
|
1176
1190
|
}
|
|
1177
|
-
return
|
|
1191
|
+
return i % 10 === 0;
|
|
1178
1192
|
}
|
|
1179
1193
|
function Te(e) {
|
|
1180
1194
|
return Ce({
|
|
@@ -1186,82 +1200,82 @@ function Te(e) {
|
|
|
1186
1200
|
placeholder: e.getAttribute("placeholder")
|
|
1187
1201
|
});
|
|
1188
1202
|
}
|
|
1189
|
-
function
|
|
1203
|
+
function at(e, t) {
|
|
1190
1204
|
return e && (Te(t) ? g : R(e));
|
|
1191
1205
|
}
|
|
1192
|
-
const
|
|
1206
|
+
const ir = 512;
|
|
1193
1207
|
function _e() {
|
|
1194
1208
|
return /* @__PURE__ */ new WeakMap();
|
|
1195
1209
|
}
|
|
1196
1210
|
function Ae(e, t) {
|
|
1197
|
-
let
|
|
1198
|
-
for (;
|
|
1199
|
-
const
|
|
1200
|
-
if (
|
|
1201
|
-
if (
|
|
1202
|
-
|
|
1211
|
+
let i = e.parentElement;
|
|
1212
|
+
for (; i && i !== document.body && i !== document.documentElement; ) {
|
|
1213
|
+
const r = Le(i, t);
|
|
1214
|
+
if (r === "sensitive") return !0;
|
|
1215
|
+
if (r === "contains-sensitive-child" || r === "too-large") return !1;
|
|
1216
|
+
i = i.parentElement;
|
|
1203
1217
|
}
|
|
1204
1218
|
return !1;
|
|
1205
1219
|
}
|
|
1206
1220
|
function Le(e, t) {
|
|
1207
|
-
const
|
|
1208
|
-
if (
|
|
1209
|
-
const
|
|
1221
|
+
const i = t.get(e);
|
|
1222
|
+
if (i) return i;
|
|
1223
|
+
const r = e.textContent ?? "";
|
|
1210
1224
|
let n = "none";
|
|
1211
|
-
return
|
|
1212
|
-
const
|
|
1213
|
-
return
|
|
1225
|
+
return r.length > ir ? n = "too-large" : R(r) !== r && (n = Array.from(e.children).some((a) => {
|
|
1226
|
+
const o = Le(a, t);
|
|
1227
|
+
return o === "sensitive" || o === "contains-sensitive-child";
|
|
1214
1228
|
}) ? "contains-sensitive-child" : "sensitive"), t.set(e, n), n;
|
|
1215
1229
|
}
|
|
1216
|
-
function
|
|
1230
|
+
function rr(e) {
|
|
1217
1231
|
return new Promise((t) => {
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1232
|
+
const i = new Image();
|
|
1233
|
+
i.onload = () => t(i), i.onerror = () => t(null), i.src = e;
|
|
1220
1234
|
});
|
|
1221
1235
|
}
|
|
1222
1236
|
function Pe(e) {
|
|
1223
1237
|
const t = [];
|
|
1224
|
-
let
|
|
1225
|
-
const
|
|
1226
|
-
for (const n of
|
|
1227
|
-
const [s,
|
|
1228
|
-
Number.isNaN(s) || Number.isNaN(
|
|
1238
|
+
let i = null;
|
|
1239
|
+
const r = e.match(/[ML]\s*[-\d.]+\s+[-\d.]+/g) ?? [];
|
|
1240
|
+
for (const n of r) {
|
|
1241
|
+
const [s, a] = n.slice(1).trim().split(/\s+/).map(Number);
|
|
1242
|
+
Number.isNaN(s) || Number.isNaN(a) || (n[0] === "M" ? (i = [[s, a]], t.push(i)) : i && i.push([s, a]));
|
|
1229
1243
|
}
|
|
1230
1244
|
return t;
|
|
1231
1245
|
}
|
|
1232
|
-
function
|
|
1246
|
+
function nr(e, t, i) {
|
|
1233
1247
|
return Pe(e).map(
|
|
1234
|
-
(
|
|
1248
|
+
(r) => r.map(([n, s], a) => `${a === 0 ? "M" : "L"} ${n + t} ${s + i}`).join(" ")
|
|
1235
1249
|
).join(" ");
|
|
1236
1250
|
}
|
|
1237
1251
|
let M = null;
|
|
1238
1252
|
function Re() {
|
|
1239
|
-
return M || (M = Promise.resolve().then(() =>
|
|
1253
|
+
return M || (M = Promise.resolve().then(() => Ps).catch((e) => {
|
|
1240
1254
|
throw M = null, e;
|
|
1241
1255
|
}), M);
|
|
1242
1256
|
}
|
|
1243
|
-
let yt,
|
|
1244
|
-
function
|
|
1245
|
-
return yt !== void 0 ? Promise.resolve(yt) : (
|
|
1246
|
-
|
|
1247
|
-
})),
|
|
1257
|
+
let yt, vt = null;
|
|
1258
|
+
function Ft() {
|
|
1259
|
+
return yt !== void 0 ? Promise.resolve(yt) : (vt ?? (vt = Re().then(({ getFontEmbedCSS: e }) => e(document.body)).then((e) => (yt = e, e)).catch(() => {
|
|
1260
|
+
vt = null;
|
|
1261
|
+
})), vt);
|
|
1248
1262
|
}
|
|
1249
|
-
const
|
|
1250
|
-
async function
|
|
1263
|
+
const sr = 200, ar = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
1264
|
+
async function or(e, t) {
|
|
1251
1265
|
try {
|
|
1252
1266
|
if (t?.aborted) return null;
|
|
1253
|
-
const [{ toJpeg:
|
|
1267
|
+
const [{ toJpeg: i }, r] = await Promise.all([Re(), Ft()]), n = document.body.getBoundingClientRect(), s = gi(), a = { x: window.scrollX, y: window.scrollY }, o = mr(document.body), l = await i(document.body, {
|
|
1254
1268
|
quality: 0.85,
|
|
1255
|
-
imagePlaceholder:
|
|
1269
|
+
imagePlaceholder: ar,
|
|
1256
1270
|
resourceUrlResolver: e,
|
|
1257
1271
|
fetchRequestInit: t ? { signal: t } : void 0,
|
|
1258
1272
|
width: s.width,
|
|
1259
1273
|
height: s.height,
|
|
1260
|
-
pixelRatio:
|
|
1274
|
+
pixelRatio: fr(s),
|
|
1261
1275
|
backgroundColor: "#ffffff",
|
|
1262
1276
|
skipFonts: !1,
|
|
1263
1277
|
skipAutoScale: !1,
|
|
1264
|
-
fontEmbedCSS:
|
|
1278
|
+
fontEmbedCSS: r,
|
|
1265
1279
|
style: {
|
|
1266
1280
|
// The clone lays out from the document top; shifting it by the body's
|
|
1267
1281
|
// current viewport offset puts the scrolled-to region at the canvas
|
|
@@ -1273,46 +1287,46 @@ async function ai(e, t) {
|
|
|
1273
1287
|
if (c instanceof HTMLElement && c.id === k) return !1;
|
|
1274
1288
|
if (!(c instanceof Element)) return !0;
|
|
1275
1289
|
const h = c.getBoundingClientRect();
|
|
1276
|
-
return h.width === 0 && h.height === 0 ? !0 : h.top + window.scrollY -
|
|
1290
|
+
return h.width === 0 && h.height === 0 ? !0 : h.top + window.scrollY - a.y <= s.height + sr;
|
|
1277
1291
|
}
|
|
1278
1292
|
});
|
|
1279
|
-
return t?.aborted ? null : { dataUrl: l, metrics: s, redactions:
|
|
1293
|
+
return t?.aborted ? null : { dataUrl: l, metrics: s, redactions: o, pageScroll: a };
|
|
1280
1294
|
} catch {
|
|
1281
1295
|
return null;
|
|
1282
1296
|
}
|
|
1283
1297
|
}
|
|
1284
|
-
async function
|
|
1298
|
+
async function lr(e, t = [], i) {
|
|
1285
1299
|
try {
|
|
1286
|
-
const
|
|
1287
|
-
(n) =>
|
|
1300
|
+
const r = t.map(
|
|
1301
|
+
(n) => cr(n, e.pageScroll)
|
|
1288
1302
|
);
|
|
1289
|
-
return await
|
|
1303
|
+
return await ur(e.dataUrl, r, e.metrics, e.redactions, i);
|
|
1290
1304
|
} catch {
|
|
1291
1305
|
return null;
|
|
1292
1306
|
}
|
|
1293
1307
|
}
|
|
1294
|
-
function
|
|
1295
|
-
const
|
|
1296
|
-
return
|
|
1308
|
+
function cr(e, t) {
|
|
1309
|
+
const i = hr(e, t);
|
|
1310
|
+
return i.x === 0 && i.y === 0 ? e : {
|
|
1297
1311
|
...e,
|
|
1298
|
-
x: e.x +
|
|
1299
|
-
y: e.y +
|
|
1312
|
+
x: e.x + i.x,
|
|
1313
|
+
y: e.y + i.y,
|
|
1300
1314
|
targetRect: e.targetRect && {
|
|
1301
1315
|
...e.targetRect,
|
|
1302
|
-
top: e.targetRect.top +
|
|
1303
|
-
left: e.targetRect.left +
|
|
1304
|
-
bottom: e.targetRect.bottom +
|
|
1316
|
+
top: e.targetRect.top + i.y,
|
|
1317
|
+
left: e.targetRect.left + i.x,
|
|
1318
|
+
bottom: e.targetRect.bottom + i.y
|
|
1305
1319
|
},
|
|
1306
|
-
drawPath: e.drawPath &&
|
|
1320
|
+
drawPath: e.drawPath && nr(e.drawPath, i.x, i.y)
|
|
1307
1321
|
};
|
|
1308
1322
|
}
|
|
1309
|
-
function
|
|
1310
|
-
return e.captureOffsetX !== void 0 && e.captureOffsetY !== void 0 ?
|
|
1323
|
+
function hr(e, t) {
|
|
1324
|
+
return e.captureOffsetX !== void 0 && e.captureOffsetY !== void 0 ? wi(
|
|
1311
1325
|
{ x: e.captureOffsetX, y: e.captureOffsetY },
|
|
1312
1326
|
t
|
|
1313
|
-
) :
|
|
1327
|
+
) : Y(dr(e));
|
|
1314
1328
|
}
|
|
1315
|
-
function
|
|
1329
|
+
function dr(e) {
|
|
1316
1330
|
if (e.targetSelector)
|
|
1317
1331
|
try {
|
|
1318
1332
|
const t = document.querySelector(e.targetSelector);
|
|
@@ -1321,106 +1335,106 @@ function di(e) {
|
|
|
1321
1335
|
}
|
|
1322
1336
|
return document.elementsFromPoint?.(e.x, e.y)[0] ?? null;
|
|
1323
1337
|
}
|
|
1324
|
-
async function
|
|
1325
|
-
const s = document.createElement("canvas"),
|
|
1326
|
-
if (!o) return null;
|
|
1327
|
-
const a = await ii(e);
|
|
1338
|
+
async function ur(e, t, i, r, n) {
|
|
1339
|
+
const s = document.createElement("canvas"), a = s.getContext("2d");
|
|
1328
1340
|
if (!a) return null;
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
o.
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1341
|
+
const o = await rr(e);
|
|
1342
|
+
if (!o) return null;
|
|
1343
|
+
s.width = o.naturalWidth || window.innerWidth, s.height = o.naturalHeight || window.innerHeight, a.drawImage(o, 0, 0);
|
|
1344
|
+
const l = pi(i, s.width, s.height);
|
|
1345
|
+
a.fillStyle = "#e5e7eb";
|
|
1346
|
+
for (const c of r) {
|
|
1347
|
+
const h = fi(l, c);
|
|
1348
|
+
a.fillRect(h.left, h.top, h.width, h.height);
|
|
1335
1349
|
}
|
|
1336
1350
|
for (const c of t)
|
|
1337
|
-
c.type === "draw" && c.drawPath ?
|
|
1338
|
-
|
|
1339
|
-
|
|
1351
|
+
c.type === "draw" && c.drawPath ? pr(a, c.drawPath, l, n?.primary) : c.type === "pin" && gr(
|
|
1352
|
+
a,
|
|
1353
|
+
it(l, c.x),
|
|
1340
1354
|
rt(l, c.y),
|
|
1341
1355
|
n
|
|
1342
1356
|
);
|
|
1343
|
-
return
|
|
1357
|
+
return wr(s);
|
|
1344
1358
|
}
|
|
1345
|
-
function
|
|
1359
|
+
function mr(e) {
|
|
1346
1360
|
const t = [];
|
|
1347
|
-
for (const s of
|
|
1348
|
-
|
|
1361
|
+
for (const s of br(e, `.${ut}`))
|
|
1362
|
+
xt(t, s.getBoundingClientRect(), Yt(s));
|
|
1349
1363
|
for (const s of e.querySelectorAll("input, textarea, select")) {
|
|
1350
|
-
if (
|
|
1351
|
-
const
|
|
1352
|
-
!
|
|
1364
|
+
if (Xt(s)) continue;
|
|
1365
|
+
const a = s instanceof HTMLInputElement || s instanceof HTMLTextAreaElement || s instanceof HTMLSelectElement ? s.value : "", o = s.closest(`.${W}`) !== null, l = Te(s) || at(a, s) !== a;
|
|
1366
|
+
!o && !l || xt(t, s.getBoundingClientRect(), Yt(s), Gt);
|
|
1353
1367
|
}
|
|
1354
|
-
const
|
|
1355
|
-
let n =
|
|
1368
|
+
const i = document.createTreeWalker(e, NodeFilter.SHOW_TEXT), r = _e();
|
|
1369
|
+
let n = i.nextNode();
|
|
1356
1370
|
for (; n; ) {
|
|
1357
|
-
const s = n.parentElement,
|
|
1358
|
-
if (s && !
|
|
1359
|
-
const c =
|
|
1371
|
+
const s = n.parentElement, a = n.textContent ?? "", o = s?.closest(`.${W}`) !== null, l = R(a) !== a || Ae(n, r);
|
|
1372
|
+
if (s && !Xt(s) && (o || l)) {
|
|
1373
|
+
const c = Y(s), h = document.createRange();
|
|
1360
1374
|
h.selectNodeContents(n);
|
|
1361
1375
|
for (const u of Array.from(h.getClientRects()))
|
|
1362
|
-
|
|
1376
|
+
xt(t, u, c, Gt);
|
|
1363
1377
|
}
|
|
1364
|
-
n =
|
|
1378
|
+
n = i.nextNode();
|
|
1365
1379
|
}
|
|
1366
1380
|
return t;
|
|
1367
1381
|
}
|
|
1368
|
-
function
|
|
1369
|
-
return
|
|
1382
|
+
function Yt(e) {
|
|
1383
|
+
return Y(ye(e));
|
|
1370
1384
|
}
|
|
1371
|
-
function
|
|
1372
|
-
const
|
|
1373
|
-
return e.matches(t) ? [e, ...
|
|
1385
|
+
function br(e, t) {
|
|
1386
|
+
const i = Array.from(e.querySelectorAll(t));
|
|
1387
|
+
return e.matches(t) ? [e, ...i] : i;
|
|
1374
1388
|
}
|
|
1375
|
-
function
|
|
1376
|
-
return e.closest(`#${k}`) !== null || e.closest(`.${
|
|
1389
|
+
function Xt(e) {
|
|
1390
|
+
return e.closest(`#${k}`) !== null || e.closest(`.${ut}`) !== null;
|
|
1377
1391
|
}
|
|
1378
|
-
function
|
|
1392
|
+
function xt(e, t, i, r = 0) {
|
|
1379
1393
|
if (![t.left, t.top, t.width, t.height].every(Number.isFinite))
|
|
1380
1394
|
throw new Error("Invalid privacy redaction geometry");
|
|
1381
1395
|
t.width <= 0 || t.height <= 0 || e.push({
|
|
1382
|
-
left: t.left +
|
|
1383
|
-
top: t.top +
|
|
1384
|
-
width: t.width +
|
|
1385
|
-
height: t.height +
|
|
1396
|
+
left: t.left + i.x - r,
|
|
1397
|
+
top: t.top + i.y - r,
|
|
1398
|
+
width: t.width + r * 2,
|
|
1399
|
+
height: t.height + r * 2
|
|
1386
1400
|
});
|
|
1387
1401
|
}
|
|
1388
|
-
function
|
|
1402
|
+
function pr(e, t, i, r = ve) {
|
|
1389
1403
|
e.save(), e.lineCap = "round", e.lineJoin = "round";
|
|
1390
1404
|
for (const n of Pe(t))
|
|
1391
1405
|
if (n.length !== 0) {
|
|
1392
1406
|
e.beginPath(), e.moveTo(
|
|
1393
|
-
|
|
1394
|
-
rt(
|
|
1407
|
+
it(i, n[0][0]),
|
|
1408
|
+
rt(i, n[0][1])
|
|
1395
1409
|
);
|
|
1396
1410
|
for (let s = 1; s < n.length; s++)
|
|
1397
1411
|
e.lineTo(
|
|
1398
|
-
|
|
1399
|
-
rt(
|
|
1412
|
+
it(i, n[s][0]),
|
|
1413
|
+
rt(i, n[s][1])
|
|
1400
1414
|
);
|
|
1401
|
-
e.shadowColor = "transparent", e.strokeStyle = "rgba(15, 23, 42, 0.72)", e.lineWidth = 7, e.stroke(), e.strokeStyle = "#ffffff", e.lineWidth = 5.5, e.stroke(), e.strokeStyle =
|
|
1415
|
+
e.shadowColor = "transparent", e.strokeStyle = "rgba(15, 23, 42, 0.72)", e.lineWidth = 7, e.stroke(), e.strokeStyle = "#ffffff", e.lineWidth = 5.5, e.stroke(), e.strokeStyle = r, e.lineWidth = 3.5, e.stroke();
|
|
1402
1416
|
}
|
|
1403
1417
|
e.restore();
|
|
1404
1418
|
}
|
|
1405
|
-
const
|
|
1406
|
-
function
|
|
1419
|
+
const Kt = 16e6, Gt = 2;
|
|
1420
|
+
function fr(e) {
|
|
1407
1421
|
const t = e.width * e.height;
|
|
1408
|
-
return !Number.isFinite(t) || t <=
|
|
1422
|
+
return !Number.isFinite(t) || t <= Kt ? 1 : Math.sqrt(Kt / t);
|
|
1409
1423
|
}
|
|
1410
|
-
function
|
|
1411
|
-
const n =
|
|
1412
|
-
e.save(), e.shadowColor = "rgba(15, 23, 42, 0.68)", e.shadowOffsetY = 2, e.shadowBlur = 8, e.fillStyle = n, e.beginPath(), e.arc(t,
|
|
1424
|
+
function gr(e, t, i, r) {
|
|
1425
|
+
const n = r?.primary ?? ve;
|
|
1426
|
+
e.save(), e.shadowColor = "rgba(15, 23, 42, 0.68)", e.shadowOffsetY = 2, e.shadowBlur = 8, e.fillStyle = n, e.beginPath(), e.arc(t, i, 11, 0, Math.PI * 2), e.fill(), e.shadowColor = "transparent", e.lineWidth = 2, e.strokeStyle = "#ffffff", e.stroke(), e.restore();
|
|
1413
1427
|
}
|
|
1414
|
-
function
|
|
1428
|
+
function wr(e) {
|
|
1415
1429
|
return new Promise((t) => {
|
|
1416
1430
|
try {
|
|
1417
|
-
e.toBlob((
|
|
1431
|
+
e.toBlob((i) => t(i), "image/jpeg", 0.85);
|
|
1418
1432
|
} catch {
|
|
1419
1433
|
t(null);
|
|
1420
1434
|
}
|
|
1421
1435
|
});
|
|
1422
1436
|
}
|
|
1423
|
-
class
|
|
1437
|
+
class yr {
|
|
1424
1438
|
constructor() {
|
|
1425
1439
|
this.listeners = /* @__PURE__ */ new Set(), this.originalOnError = null, this.installedOnError = null, this.rejectionHandler = null, this.hooked = !1;
|
|
1426
1440
|
}
|
|
@@ -1430,33 +1444,33 @@ class wi {
|
|
|
1430
1444
|
};
|
|
1431
1445
|
}
|
|
1432
1446
|
hook() {
|
|
1433
|
-
this.hooked || (this.hooked = !0, this.originalOnError = window.onerror, this.installedOnError = (t,
|
|
1434
|
-
const
|
|
1435
|
-
this.emit({ name:
|
|
1447
|
+
this.hooked || (this.hooked = !0, this.originalOnError = window.onerror, this.installedOnError = (t, i, r, n, s) => (this.emit({ name: vr(s), message: String(t), source: i, line: r, col: n, error: s }), this.originalOnError ? this.originalOnError.call(window, t, i, r, n, s) : !1), window.onerror = this.installedOnError, this.rejectionHandler = (t) => {
|
|
1448
|
+
const i = t.reason instanceof Error ? t.reason.message : String(t.reason), r = t.reason instanceof Error ? t.reason.name : "UnhandledRejection";
|
|
1449
|
+
this.emit({ name: r, message: `Unhandled rejection: ${i}` });
|
|
1436
1450
|
}, window.addEventListener("unhandledrejection", this.rejectionHandler));
|
|
1437
1451
|
}
|
|
1438
1452
|
unhook() {
|
|
1439
1453
|
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));
|
|
1440
1454
|
}
|
|
1441
1455
|
emit(t) {
|
|
1442
|
-
for (const
|
|
1456
|
+
for (const i of this.listeners) i(t);
|
|
1443
1457
|
}
|
|
1444
1458
|
}
|
|
1445
|
-
const
|
|
1446
|
-
function
|
|
1459
|
+
const Ht = new yr();
|
|
1460
|
+
function vr(e) {
|
|
1447
1461
|
return !e || typeof e != "object" || !("name" in e) ? void 0 : String(e.name) || void 0;
|
|
1448
1462
|
}
|
|
1449
1463
|
function De(e) {
|
|
1450
|
-
const t =
|
|
1451
|
-
return
|
|
1464
|
+
const t = xr(e.name) || kr(e.message), i = Er(e);
|
|
1465
|
+
return i ? `${t} (${i})` : t;
|
|
1452
1466
|
}
|
|
1453
|
-
function
|
|
1467
|
+
function xr(e) {
|
|
1454
1468
|
return e && /^[A-Za-z][A-Za-z0-9]*(?:Error|Exception|Rejection)$/.test(e) ? e : "";
|
|
1455
1469
|
}
|
|
1456
|
-
function
|
|
1470
|
+
function kr(e) {
|
|
1457
1471
|
return e.match(/^([A-Za-z][A-Za-z0-9]*(?:Error|Exception))\b/)?.[1] ?? "Error";
|
|
1458
1472
|
}
|
|
1459
|
-
function
|
|
1473
|
+
function Er(e) {
|
|
1460
1474
|
if (!e.source) return "";
|
|
1461
1475
|
try {
|
|
1462
1476
|
const t = new URL(e.source, window.location.href).pathname;
|
|
@@ -1465,19 +1479,19 @@ function Ei(e) {
|
|
|
1465
1479
|
return "";
|
|
1466
1480
|
}
|
|
1467
1481
|
}
|
|
1468
|
-
const
|
|
1469
|
-
class
|
|
1482
|
+
const Sr = 20;
|
|
1483
|
+
class Cr {
|
|
1470
1484
|
constructor() {
|
|
1471
1485
|
this.errors = [], this.unsubscribe = null;
|
|
1472
1486
|
}
|
|
1473
1487
|
start() {
|
|
1474
|
-
this.unsubscribe || (this.unsubscribe =
|
|
1488
|
+
this.unsubscribe || (this.unsubscribe = Ht.subscribe((t) => this.record(t)));
|
|
1475
1489
|
}
|
|
1476
1490
|
record(t) {
|
|
1477
1491
|
this.addError(De(t));
|
|
1478
1492
|
}
|
|
1479
1493
|
addError(t) {
|
|
1480
|
-
this.errors.length >=
|
|
1494
|
+
this.errors.length >= Sr || this.errors.includes(t) || this.errors.push(t);
|
|
1481
1495
|
}
|
|
1482
1496
|
getErrors() {
|
|
1483
1497
|
return [...this.errors];
|
|
@@ -1486,52 +1500,52 @@ class Ci {
|
|
|
1486
1500
|
this.unsubscribe?.(), this.unsubscribe = null;
|
|
1487
1501
|
}
|
|
1488
1502
|
}
|
|
1489
|
-
const
|
|
1490
|
-
let
|
|
1503
|
+
const tt = /* @__PURE__ */ new Set();
|
|
1504
|
+
let O = null, z = null, $ = null, ot = null, U = null, lt = null;
|
|
1491
1505
|
function Me(e) {
|
|
1492
|
-
|
|
1506
|
+
tt.add(e), Tr();
|
|
1493
1507
|
let t = !1;
|
|
1494
1508
|
return () => {
|
|
1495
|
-
t || (t = !0,
|
|
1509
|
+
t || (t = !0, tt.delete(e), tt.size === 0 && _r());
|
|
1496
1510
|
};
|
|
1497
1511
|
}
|
|
1498
|
-
function
|
|
1499
|
-
const
|
|
1500
|
-
|
|
1501
|
-
for (const
|
|
1512
|
+
function kt(e, t) {
|
|
1513
|
+
const i = { type: e, fromUrl: t, toUrl: location.href };
|
|
1514
|
+
lt = i.toUrl;
|
|
1515
|
+
for (const r of [...tt])
|
|
1502
1516
|
try {
|
|
1503
|
-
i
|
|
1517
|
+
r(i);
|
|
1504
1518
|
} catch {
|
|
1505
1519
|
}
|
|
1506
1520
|
}
|
|
1507
|
-
function
|
|
1508
|
-
if (
|
|
1509
|
-
|
|
1510
|
-
const e =
|
|
1511
|
-
|
|
1521
|
+
function Tr() {
|
|
1522
|
+
if ($) return;
|
|
1523
|
+
lt = location.href, U = () => kt("pop", lt ?? location.href), window.addEventListener("popstate", U), O = history.pushState, z = history.replaceState;
|
|
1524
|
+
const e = O, t = z;
|
|
1525
|
+
$ = function(i, r, n) {
|
|
1512
1526
|
const s = location.href;
|
|
1513
|
-
e.call(history,
|
|
1514
|
-
}, ot = function(
|
|
1527
|
+
e.call(history, i, r, n), kt("push", s);
|
|
1528
|
+
}, ot = function(i, r, n) {
|
|
1515
1529
|
const s = location.href;
|
|
1516
|
-
t.call(history,
|
|
1517
|
-
}, history.pushState =
|
|
1530
|
+
t.call(history, i, r, n), kt("replace", s);
|
|
1531
|
+
}, history.pushState = $, history.replaceState = ot;
|
|
1518
1532
|
}
|
|
1519
|
-
function
|
|
1520
|
-
|
|
1533
|
+
function _r() {
|
|
1534
|
+
U && (window.removeEventListener("popstate", U), U = null), O && history.pushState === $ && (history.pushState = O), z && history.replaceState === ot && (history.replaceState = z), O = null, z = null, $ = null, ot = null, lt = null;
|
|
1521
1535
|
}
|
|
1522
|
-
const
|
|
1523
|
-
function
|
|
1524
|
-
return
|
|
1536
|
+
const Ar = 20;
|
|
1537
|
+
function Lr(e) {
|
|
1538
|
+
return mt(e) ? It(e) : Mt(e);
|
|
1525
1539
|
}
|
|
1526
|
-
function
|
|
1527
|
-
return
|
|
1540
|
+
function Pr(e) {
|
|
1541
|
+
return mt(e) ? xe(e) : we(e);
|
|
1528
1542
|
}
|
|
1529
|
-
class
|
|
1543
|
+
class Rr {
|
|
1530
1544
|
constructor() {
|
|
1531
1545
|
this.breadcrumbs = [], this.active = !1, this.unsubscribeErrors = null, this.unsubscribeNavigation = null, this.lastUrl = "", this.boundClickHandler = (t) => this.handleClick(t), this.boundChangeHandler = (t) => this.handleChange(t);
|
|
1532
1546
|
}
|
|
1533
1547
|
start() {
|
|
1534
|
-
this.active || (this.active = !0, this.lastUrl = location.href, document.addEventListener("click", this.boundClickHandler, { capture: !0, passive: !0 }), document.addEventListener("change", this.boundChangeHandler, { capture: !0, passive: !0 }), this.unsubscribeErrors =
|
|
1548
|
+
this.active || (this.active = !0, this.lastUrl = location.href, document.addEventListener("click", this.boundClickHandler, { capture: !0, passive: !0 }), document.addEventListener("change", this.boundChangeHandler, { capture: !0, passive: !0 }), this.unsubscribeErrors = Ht.subscribe((t) => this.recordError(t)), this.unsubscribeNavigation = Me(() => this.handleNavigation()));
|
|
1535
1549
|
}
|
|
1536
1550
|
stop() {
|
|
1537
1551
|
this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), document.removeEventListener("change", this.boundChangeHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.unsubscribeNavigation?.(), this.unsubscribeNavigation = null);
|
|
@@ -1540,27 +1554,27 @@ class Ri {
|
|
|
1540
1554
|
return [...this.breadcrumbs];
|
|
1541
1555
|
}
|
|
1542
1556
|
add(t) {
|
|
1543
|
-
this.breadcrumbs.push(t), this.breadcrumbs.length >
|
|
1557
|
+
this.breadcrumbs.push(t), this.breadcrumbs.length > Ar && this.breadcrumbs.shift();
|
|
1544
1558
|
}
|
|
1545
1559
|
handleClick(t) {
|
|
1546
|
-
const
|
|
1547
|
-
if (
|
|
1560
|
+
const i = t.target;
|
|
1561
|
+
if (i && !_(i))
|
|
1548
1562
|
try {
|
|
1549
1563
|
this.add({
|
|
1550
1564
|
type: "ui",
|
|
1551
1565
|
category: "ui.click",
|
|
1552
1566
|
timestamp: Date.now(),
|
|
1553
|
-
message:
|
|
1554
|
-
data: { selector:
|
|
1567
|
+
message: Lr(i),
|
|
1568
|
+
data: { selector: Pr(i) }
|
|
1555
1569
|
});
|
|
1556
1570
|
} catch {
|
|
1557
1571
|
}
|
|
1558
1572
|
}
|
|
1559
1573
|
handleChange(t) {
|
|
1560
|
-
const
|
|
1561
|
-
if (
|
|
1574
|
+
const i = t.target;
|
|
1575
|
+
if (i && !_(i))
|
|
1562
1576
|
try {
|
|
1563
|
-
const
|
|
1577
|
+
const r = i, n = mt(i) ? It(i) : r.name || r.placeholder || i.getAttribute("aria-label") || i.tagName;
|
|
1564
1578
|
this.add({
|
|
1565
1579
|
type: "ui",
|
|
1566
1580
|
category: "ui.input",
|
|
@@ -1572,64 +1586,64 @@ class Ri {
|
|
|
1572
1586
|
}
|
|
1573
1587
|
}
|
|
1574
1588
|
recordError(t) {
|
|
1575
|
-
const
|
|
1589
|
+
const i = De(t);
|
|
1576
1590
|
this.add({
|
|
1577
1591
|
type: "console",
|
|
1578
1592
|
category: "console.error",
|
|
1579
1593
|
timestamp: Date.now(),
|
|
1580
|
-
message:
|
|
1581
|
-
data: { message:
|
|
1594
|
+
message: i,
|
|
1595
|
+
data: { message: i }
|
|
1582
1596
|
});
|
|
1583
1597
|
}
|
|
1584
1598
|
handleNavigation() {
|
|
1585
1599
|
if (!this.active) return;
|
|
1586
|
-
const t = this.lastUrl,
|
|
1587
|
-
if (t ===
|
|
1588
|
-
this.lastUrl =
|
|
1589
|
-
const
|
|
1600
|
+
const t = this.lastUrl, i = location.href;
|
|
1601
|
+
if (t === i) return;
|
|
1602
|
+
this.lastUrl = i;
|
|
1603
|
+
const r = V(t), n = V(i);
|
|
1590
1604
|
this.add({
|
|
1591
1605
|
type: "navigation",
|
|
1592
1606
|
category: "navigation",
|
|
1593
1607
|
timestamp: Date.now(),
|
|
1594
|
-
message: `${
|
|
1595
|
-
data: { from:
|
|
1608
|
+
message: `${r} → ${n}`,
|
|
1609
|
+
data: { from: r, to: n }
|
|
1596
1610
|
});
|
|
1597
1611
|
}
|
|
1598
1612
|
}
|
|
1599
1613
|
const Ie = "mtb_frustration_state";
|
|
1600
|
-
let
|
|
1601
|
-
function
|
|
1614
|
+
let At = null;
|
|
1615
|
+
function ct() {
|
|
1602
1616
|
try {
|
|
1603
1617
|
const e = window.sessionStorage.getItem(Ie);
|
|
1604
|
-
return
|
|
1618
|
+
return et(e ? JSON.parse(e) : At);
|
|
1605
1619
|
} catch {
|
|
1606
|
-
return
|
|
1620
|
+
return et(At);
|
|
1607
1621
|
}
|
|
1608
1622
|
}
|
|
1609
1623
|
function Fe(e) {
|
|
1610
|
-
const t =
|
|
1611
|
-
|
|
1624
|
+
const t = et(e);
|
|
1625
|
+
At = t;
|
|
1612
1626
|
try {
|
|
1613
1627
|
window.sessionStorage.setItem(Ie, JSON.stringify(t));
|
|
1614
1628
|
} catch {
|
|
1615
1629
|
}
|
|
1616
1630
|
}
|
|
1617
|
-
function
|
|
1618
|
-
return
|
|
1631
|
+
function Dr() {
|
|
1632
|
+
return ct().dismissedByUser;
|
|
1619
1633
|
}
|
|
1620
|
-
function
|
|
1621
|
-
Fe({ ...
|
|
1634
|
+
function Mr() {
|
|
1635
|
+
Fe({ ...ct(), dismissedByUser: !0 });
|
|
1622
1636
|
}
|
|
1623
|
-
function
|
|
1637
|
+
function et(e) {
|
|
1624
1638
|
const t = e ?? {};
|
|
1625
1639
|
return {
|
|
1626
|
-
navTimestamps: Array.isArray(t.navTimestamps) ? t.navTimestamps.filter((
|
|
1640
|
+
navTimestamps: Array.isArray(t.navTimestamps) ? t.navTimestamps.filter((i) => typeof i == "number") : [],
|
|
1627
1641
|
cooldownUntil: typeof t.cooldownUntil == "number" ? t.cooldownUntil : 0,
|
|
1628
|
-
errorPageUrls: Array.isArray(t.errorPageUrls) ? t.errorPageUrls.filter((
|
|
1642
|
+
errorPageUrls: Array.isArray(t.errorPageUrls) ? t.errorPageUrls.filter((i) => typeof i == "string").slice(-20) : [],
|
|
1629
1643
|
dismissedByUser: t.dismissedByUser === !0
|
|
1630
1644
|
};
|
|
1631
1645
|
}
|
|
1632
|
-
const
|
|
1646
|
+
const Ir = 4, Fr = 1500, Hr = 3, Br = 5e3, Et = 500, Nr = 2, Or = 3e4, zr = 2e3, $r = 1e3, Ur = 300, jr = /* @__PURE__ */ new Set([
|
|
1633
1647
|
"A",
|
|
1634
1648
|
"BUTTON",
|
|
1635
1649
|
"INPUT",
|
|
@@ -1638,7 +1652,7 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1638
1652
|
"LABEL",
|
|
1639
1653
|
"SUMMARY",
|
|
1640
1654
|
"DETAILS"
|
|
1641
|
-
]),
|
|
1655
|
+
]), qr = /* @__PURE__ */ new Set([
|
|
1642
1656
|
"button",
|
|
1643
1657
|
"link",
|
|
1644
1658
|
"checkbox",
|
|
@@ -1652,24 +1666,24 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1652
1666
|
"listbox",
|
|
1653
1667
|
"slider",
|
|
1654
1668
|
"spinbutton"
|
|
1655
|
-
]),
|
|
1669
|
+
]), Wr = /* @__PURE__ */ new Set(["A", "BUTTON", "SUMMARY"]), Vr = /* @__PURE__ */ new Set(["button", "link", "tab", "menuitem"]), Jt = [
|
|
1656
1670
|
/\bnot found\b/,
|
|
1657
1671
|
/\bserver error\b/,
|
|
1658
1672
|
/^\s*(?:http\s*)?[45]\d{2}\s*$/,
|
|
1659
1673
|
/\b(?:error|http|status)\s*[:-]?\s*[45]\d{2}\b/,
|
|
1660
1674
|
/\b[45]\d{2}\s*[:-]?\s*error\b/
|
|
1661
|
-
],
|
|
1675
|
+
], q = class q {
|
|
1662
1676
|
constructor(t) {
|
|
1663
|
-
this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.lastInteraction = null, this.cooldownUntil = 0, this.navTimestamps = [], this.unsubscribeNavigation = null, this.boundPageLeaveHandler = null, this.boundTurboNavigationHandler = null, this.lastNavigationAt = -1, this.boundSubmitHandler = null, this.boundInvalidHandler = null, this.recentSubmitForms = /* @__PURE__ */ new WeakSet(), this.recentFailedForms = /* @__PURE__ */ new WeakSet(), this.formFailureTimestamps = /* @__PURE__ */ new WeakMap(), this.errorPageUrls = /* @__PURE__ */ new Set(), this.domObserver = null, this.pendingDomChecks = 0, this.lastMutationAt = -1, this.pendingTimers = /* @__PURE__ */ new Set(), this.onFrustration = t, this.boundClickHandler = (
|
|
1677
|
+
this.clickHistory = [], this.unsubscribeErrors = null, this.active = !1, this.lastInteraction = null, this.cooldownUntil = 0, this.navTimestamps = [], this.unsubscribeNavigation = null, this.boundPageLeaveHandler = null, this.boundTurboNavigationHandler = null, this.lastNavigationAt = -1, this.boundSubmitHandler = null, this.boundInvalidHandler = null, this.recentSubmitForms = /* @__PURE__ */ new WeakSet(), this.recentFailedForms = /* @__PURE__ */ new WeakSet(), this.formFailureTimestamps = /* @__PURE__ */ new WeakMap(), this.errorPageUrls = /* @__PURE__ */ new Set(), this.domObserver = null, this.pendingDomChecks = 0, this.lastMutationAt = -1, this.pendingTimers = /* @__PURE__ */ new Set(), this.onFrustration = t, this.boundClickHandler = (i) => this.handleClick(i);
|
|
1664
1678
|
}
|
|
1665
1679
|
start() {
|
|
1666
|
-
this.active || (this.active = !0, this.restoreState(), document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors =
|
|
1680
|
+
this.active || (this.active = !0, this.restoreState(), document.addEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors = Ht.subscribe(() => {
|
|
1667
1681
|
const t = Date.now();
|
|
1668
|
-
if (!this.lastInteraction || t - this.lastInteraction.time >
|
|
1669
|
-
const
|
|
1682
|
+
if (!this.lastInteraction || t - this.lastInteraction.time > zr) return;
|
|
1683
|
+
const i = this.lastInteraction;
|
|
1670
1684
|
this.lastInteraction = null, this.emitIfReady({
|
|
1671
1685
|
signal: "dead_click",
|
|
1672
|
-
target:
|
|
1686
|
+
target: G(i.target),
|
|
1673
1687
|
detail: "Uncaught error after interaction",
|
|
1674
1688
|
timestamp: t
|
|
1675
1689
|
});
|
|
@@ -1678,11 +1692,11 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1678
1692
|
stop() {
|
|
1679
1693
|
this.active && (this.active = !1, document.removeEventListener("click", this.boundClickHandler, !0), this.unsubscribeErrors?.(), this.unsubscribeErrors = null, this.clickHistory = [], this.lastInteraction = null, this.stopNavigationTracking(), this.stopFormTracking(), this.errorPageUrls.clear(), this.clearPendingTimers(), this.pendingDomChecks = 0, this.disconnectDomObserver());
|
|
1680
1694
|
}
|
|
1681
|
-
schedule(t,
|
|
1682
|
-
const
|
|
1683
|
-
this.pendingTimers.delete(
|
|
1684
|
-
},
|
|
1685
|
-
this.pendingTimers.add(
|
|
1695
|
+
schedule(t, i) {
|
|
1696
|
+
const r = setTimeout(() => {
|
|
1697
|
+
this.pendingTimers.delete(r), t();
|
|
1698
|
+
}, i);
|
|
1699
|
+
this.pendingTimers.add(r);
|
|
1686
1700
|
}
|
|
1687
1701
|
clearPendingTimers() {
|
|
1688
1702
|
for (const t of this.pendingTimers) clearTimeout(t);
|
|
@@ -1702,11 +1716,11 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1702
1716
|
// `rapid_navigation` can never reach its 3-in-5s threshold), no cooldown, and no
|
|
1703
1717
|
// memory of which error pages it already reported.
|
|
1704
1718
|
restoreState() {
|
|
1705
|
-
const t =
|
|
1719
|
+
const t = ct();
|
|
1706
1720
|
this.navTimestamps = t.navTimestamps, this.cooldownUntil = t.cooldownUntil, this.errorPageUrls = new Set(t.errorPageUrls);
|
|
1707
1721
|
}
|
|
1708
1722
|
persistState() {
|
|
1709
|
-
const t =
|
|
1723
|
+
const t = ct();
|
|
1710
1724
|
Fe({
|
|
1711
1725
|
...t,
|
|
1712
1726
|
navTimestamps: this.navTimestamps,
|
|
@@ -1721,77 +1735,77 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1721
1735
|
this.boundSubmitHandler && (document.removeEventListener("submit", this.boundSubmitHandler, !0), this.boundSubmitHandler = null), this.boundInvalidHandler && (document.removeEventListener("invalid", this.boundInvalidHandler, !0), this.boundInvalidHandler = null), this.recentSubmitForms = /* @__PURE__ */ new WeakSet(), this.recentFailedForms = /* @__PURE__ */ new WeakSet();
|
|
1722
1736
|
}
|
|
1723
1737
|
handleClick(t) {
|
|
1724
|
-
const
|
|
1725
|
-
if (!
|
|
1726
|
-
this.trackFormSubmitIntent(
|
|
1727
|
-
const
|
|
1728
|
-
this.lastInteraction = { target:
|
|
1729
|
-
const s = n -
|
|
1730
|
-
if (this.clickHistory = this.clickHistory.filter((
|
|
1738
|
+
const i = t.target;
|
|
1739
|
+
if (!i || _(i)) return;
|
|
1740
|
+
this.trackFormSubmitIntent(i), this.trackNativeNavigationIntent(t, i);
|
|
1741
|
+
const r = this.interactionTarget(i), n = Date.now();
|
|
1742
|
+
this.lastInteraction = { target: r, time: n }, this.clickHistory.push({ target: r, time: n });
|
|
1743
|
+
const s = n - Fr;
|
|
1744
|
+
if (this.clickHistory = this.clickHistory.filter((o) => o.time > s), this.clickHistory.filter((o) => o.target === r).length >= Ir) {
|
|
1731
1745
|
this.clickHistory = [], this.emitHighPriority({
|
|
1732
1746
|
signal: "rage_click",
|
|
1733
|
-
target:
|
|
1747
|
+
target: G(r),
|
|
1734
1748
|
timestamp: n
|
|
1735
1749
|
});
|
|
1736
1750
|
return;
|
|
1737
1751
|
}
|
|
1738
|
-
this.checkDeadClickDom(
|
|
1752
|
+
this.checkDeadClickDom(r, n);
|
|
1739
1753
|
}
|
|
1740
1754
|
handleNavigation(t) {
|
|
1741
|
-
const
|
|
1755
|
+
const i = Date.now();
|
|
1742
1756
|
if (this.noteNavigationStarted(), t.type !== "replace" && t.fromUrl !== t.toUrl && t.type === "pop") {
|
|
1743
|
-
this.navTimestamps.push(
|
|
1744
|
-
const n =
|
|
1745
|
-
this.navTimestamps = this.navTimestamps.filter((s) => s > n), this.navTimestamps.length >=
|
|
1757
|
+
this.navTimestamps.push(i);
|
|
1758
|
+
const n = i - Br;
|
|
1759
|
+
this.navTimestamps = this.navTimestamps.filter((s) => s > n), this.navTimestamps.length >= Hr && (this.navTimestamps = [], this.emitIfReady({
|
|
1746
1760
|
signal: "rapid_navigation",
|
|
1747
|
-
timestamp:
|
|
1761
|
+
timestamp: i
|
|
1748
1762
|
}));
|
|
1749
1763
|
}
|
|
1750
1764
|
this.persistState(), this.schedule(() => {
|
|
1751
1765
|
this.active && this.checkErrorPage();
|
|
1752
|
-
},
|
|
1766
|
+
}, Ur);
|
|
1753
1767
|
}
|
|
1754
1768
|
handleFormSubmit(t) {
|
|
1755
|
-
const
|
|
1756
|
-
|
|
1757
|
-
this.active &&
|
|
1758
|
-
},
|
|
1769
|
+
const i = t.target;
|
|
1770
|
+
i instanceof HTMLFormElement && (_(i) || (this.rememberSubmitAttempt(i), this.schedule(() => {
|
|
1771
|
+
this.active && i.querySelector('[aria-invalid="true"], .is-invalid') && this.recordFormFailure(i);
|
|
1772
|
+
}, Et)));
|
|
1759
1773
|
}
|
|
1760
1774
|
trackFormSubmitIntent(t) {
|
|
1761
|
-
const
|
|
1762
|
-
(
|
|
1775
|
+
const i = t.closest("button, input");
|
|
1776
|
+
(i instanceof HTMLButtonElement || i instanceof HTMLInputElement) && (i.type !== "submit" && i.type !== "image" || !i.form || _(i.form) || this.rememberSubmitAttempt(i.form));
|
|
1763
1777
|
}
|
|
1764
|
-
trackNativeNavigationIntent(t,
|
|
1765
|
-
|
|
1778
|
+
trackNativeNavigationIntent(t, i) {
|
|
1779
|
+
i.closest("a[href]") && queueMicrotask(() => {
|
|
1766
1780
|
this.active && !t.defaultPrevented && this.noteNavigationStarted();
|
|
1767
1781
|
});
|
|
1768
1782
|
}
|
|
1769
1783
|
rememberSubmitAttempt(t) {
|
|
1770
1784
|
this.recentSubmitForms.add(t), this.schedule(() => {
|
|
1771
1785
|
this.recentSubmitForms.delete(t);
|
|
1772
|
-
},
|
|
1786
|
+
}, Et);
|
|
1773
1787
|
}
|
|
1774
1788
|
recordFormFailure(t) {
|
|
1775
1789
|
if (this.recentFailedForms.has(t)) return;
|
|
1776
|
-
this.recentFailedForms.add(t), this.schedule(() => this.recentFailedForms.delete(t),
|
|
1777
|
-
const
|
|
1778
|
-
n.push(
|
|
1790
|
+
this.recentFailedForms.add(t), this.schedule(() => this.recentFailedForms.delete(t), Et);
|
|
1791
|
+
const i = Date.now(), r = i - Or, n = (this.formFailureTimestamps.get(t) ?? []).filter((s) => s > r);
|
|
1792
|
+
n.push(i), this.formFailureTimestamps.set(t, n), !(n.length < Nr) && (this.formFailureTimestamps.set(t, []), this.emitIfReady({
|
|
1779
1793
|
signal: "form_failure",
|
|
1780
|
-
target:
|
|
1781
|
-
timestamp:
|
|
1794
|
+
target: G(t),
|
|
1795
|
+
timestamp: i
|
|
1782
1796
|
}));
|
|
1783
1797
|
}
|
|
1784
1798
|
handleFormInvalid(t) {
|
|
1785
|
-
const
|
|
1786
|
-
if (!
|
|
1787
|
-
const
|
|
1788
|
-
!
|
|
1799
|
+
const i = t.target;
|
|
1800
|
+
if (!i || _(i)) return;
|
|
1801
|
+
const r = i.closest("form");
|
|
1802
|
+
!r || !this.recentSubmitForms.has(r) || this.recordFormFailure(r);
|
|
1789
1803
|
}
|
|
1790
1804
|
checkErrorPage() {
|
|
1791
1805
|
const t = location.href;
|
|
1792
1806
|
if (this.errorPageUrls.has(t)) return;
|
|
1793
|
-
const
|
|
1794
|
-
if (
|
|
1807
|
+
const i = document.title.toLowerCase();
|
|
1808
|
+
if (Jt.some((n) => n.test(i))) {
|
|
1795
1809
|
this.errorPageUrls.add(t), this.emitHighPriority({
|
|
1796
1810
|
signal: "error_page",
|
|
1797
1811
|
detail: document.title,
|
|
@@ -1799,12 +1813,12 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1799
1813
|
});
|
|
1800
1814
|
return;
|
|
1801
1815
|
}
|
|
1802
|
-
const
|
|
1816
|
+
const r = document.querySelectorAll(
|
|
1803
1817
|
'h1, h2, [class*="error"], [class*="not-found"], [id*="error"], [id*="not-found"]'
|
|
1804
1818
|
);
|
|
1805
|
-
for (const n of
|
|
1819
|
+
for (const n of r) {
|
|
1806
1820
|
const s = n.textContent ?? "";
|
|
1807
|
-
if (s.length < 200 &&
|
|
1821
|
+
if (s.length < 200 && Jt.some((a) => a.test(s.toLowerCase()))) {
|
|
1808
1822
|
this.errorPageUrls.add(t), this.emitHighPriority({
|
|
1809
1823
|
signal: "error_page",
|
|
1810
1824
|
detail: s.trim().slice(0, 60),
|
|
@@ -1817,16 +1831,16 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1817
1831
|
// One shared observer for all in-flight dead-click checks, connected only
|
|
1818
1832
|
// while at least one check is pending — a full-page observer per click was
|
|
1819
1833
|
// too heavy on mutation-busy pages.
|
|
1820
|
-
checkDeadClickDom(t,
|
|
1834
|
+
checkDeadClickDom(t, i) {
|
|
1821
1835
|
this.looksInteractive(t) && (this.pendingDomChecks++, this.ensureDomObserver(), this.schedule(() => {
|
|
1822
1836
|
this.pendingDomChecks--;
|
|
1823
|
-
const
|
|
1824
|
-
this.pendingDomChecks === 0 && this.disconnectDomObserver(), !
|
|
1837
|
+
const r = this.lastMutationAt >= i, n = this.lastNavigationAt >= i;
|
|
1838
|
+
this.pendingDomChecks === 0 && this.disconnectDomObserver(), !r && !n && this.active && this.emitIfReady({
|
|
1825
1839
|
signal: "dead_click_dom",
|
|
1826
|
-
target:
|
|
1827
|
-
timestamp:
|
|
1840
|
+
target: G(t),
|
|
1841
|
+
timestamp: i
|
|
1828
1842
|
});
|
|
1829
|
-
},
|
|
1843
|
+
}, $r));
|
|
1830
1844
|
}
|
|
1831
1845
|
ensureDomObserver() {
|
|
1832
1846
|
this.domObserver || (this.domObserver = new MutationObserver(() => {
|
|
@@ -1842,9 +1856,9 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1842
1856
|
this.domObserver?.disconnect(), this.domObserver = null;
|
|
1843
1857
|
}
|
|
1844
1858
|
looksInteractive(t) {
|
|
1845
|
-
if (
|
|
1846
|
-
const
|
|
1847
|
-
if (
|
|
1859
|
+
if (Wr.has(t.tagName) || t.hasAttribute("onclick")) return !0;
|
|
1860
|
+
const i = t.getAttribute("role");
|
|
1861
|
+
if (i && Vr.has(i) || window.getComputedStyle(t).cursor === "pointer") return !0;
|
|
1848
1862
|
if (t.classList)
|
|
1849
1863
|
for (const n of t.classList) {
|
|
1850
1864
|
const s = n.toLowerCase();
|
|
@@ -1853,59 +1867,59 @@ const Ii = 4, Fi = 1500, Hi = 3, Bi = 5e3, kt = 500, Ni = 2, Oi = 3e4, $i = 2e3,
|
|
|
1853
1867
|
return !1;
|
|
1854
1868
|
}
|
|
1855
1869
|
interactionTarget(t) {
|
|
1856
|
-
let r = t;
|
|
1857
|
-
for (; r && r !== document.body; ) {
|
|
1858
|
-
if (this.isIntrinsicInteractive(r)) return r;
|
|
1859
|
-
r = r.parentElement;
|
|
1860
|
-
}
|
|
1861
1870
|
let i = t;
|
|
1862
|
-
for (
|
|
1863
|
-
i
|
|
1864
|
-
|
|
1871
|
+
for (; i && i !== document.body; ) {
|
|
1872
|
+
if (this.isIntrinsicInteractive(i)) return i;
|
|
1873
|
+
i = i.parentElement;
|
|
1874
|
+
}
|
|
1875
|
+
let r = t;
|
|
1876
|
+
for (i = t.parentElement; i && i !== document.body && this.looksInteractive(i); )
|
|
1877
|
+
r = i, i = i.parentElement;
|
|
1878
|
+
return r;
|
|
1865
1879
|
}
|
|
1866
1880
|
isIntrinsicInteractive(t) {
|
|
1867
|
-
if (
|
|
1868
|
-
const
|
|
1869
|
-
return
|
|
1881
|
+
if (jr.has(t.tagName)) return !0;
|
|
1882
|
+
const i = t.getAttribute("role");
|
|
1883
|
+
return i && qr.has(i) || t.hasAttribute("onclick") || t.hasAttribute("tabindex") ? !0 : t.contentEditable === "true";
|
|
1870
1884
|
}
|
|
1871
1885
|
emitIfReady(t) {
|
|
1872
|
-
const
|
|
1873
|
-
|
|
1886
|
+
const i = Date.now();
|
|
1887
|
+
i < this.cooldownUntil || (this.cooldownUntil = i + q.COOLDOWN_MS, this.persistState(), this.onFrustration(t));
|
|
1874
1888
|
}
|
|
1875
1889
|
emitHighPriority(t) {
|
|
1876
|
-
this.cooldownUntil = Date.now() +
|
|
1890
|
+
this.cooldownUntil = Date.now() + q.COOLDOWN_MS, this.persistState(), this.onFrustration(t);
|
|
1877
1891
|
}
|
|
1878
1892
|
};
|
|
1879
|
-
|
|
1880
|
-
let
|
|
1881
|
-
function
|
|
1882
|
-
const t = e.tagName.toLowerCase(),
|
|
1883
|
-
return `<${t}${
|
|
1893
|
+
q.COOLDOWN_MS = 6e4;
|
|
1894
|
+
let Lt = q;
|
|
1895
|
+
function G(e) {
|
|
1896
|
+
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(".") : "", n = e.textContent?.trim().slice(0, 30) ?? "";
|
|
1897
|
+
return `<${t}${i}${r}>${n ? ` "${n}"` : ""}`;
|
|
1884
1898
|
}
|
|
1885
|
-
class
|
|
1899
|
+
class Yr extends Error {
|
|
1886
1900
|
constructor(t) {
|
|
1887
1901
|
super(`HTTP ${t}`), this.name = "ApiError", this.status = t;
|
|
1888
1902
|
}
|
|
1889
1903
|
}
|
|
1890
|
-
const
|
|
1891
|
-
class
|
|
1904
|
+
const Xr = 25e3, Kr = "https://makethisbetter.dev/api/v1", Gr = "sensitive-data-v1";
|
|
1905
|
+
class Jr {
|
|
1892
1906
|
constructor(t) {
|
|
1893
|
-
this.projectKey = t.projectKey, this.apiUrl = (t.apiUrl ??
|
|
1907
|
+
this.projectKey = t.projectKey, this.apiUrl = (t.apiUrl ?? Kr).replace(/\/$/, ""), this.retryDelayMs = t.retryDelayMs ?? 1e3, this.userToken = t.userToken, this.userTokenFn = t.userTokenFn;
|
|
1894
1908
|
}
|
|
1895
1909
|
async resolveUserToken() {
|
|
1896
1910
|
return this.userTokenFn ? this.userTokenFn() : this.userToken;
|
|
1897
1911
|
}
|
|
1898
|
-
async resolveScreenshotResourceUrl(t,
|
|
1912
|
+
async resolveScreenshotResourceUrl(t, i, r, n, s) {
|
|
1899
1913
|
if (!(n && !n.startsWith("image/")))
|
|
1900
1914
|
try {
|
|
1901
|
-
const
|
|
1902
|
-
if (!["http:", "https:"].includes(
|
|
1903
|
-
const
|
|
1915
|
+
const a = new URL(r, window.location.href);
|
|
1916
|
+
if (!["http:", "https:"].includes(a.protocol) || a.origin === window.location.origin) return;
|
|
1917
|
+
const o = await this.submissionHeaders(i, "application/json"), c = await (await this.fetchWithRetry(
|
|
1904
1918
|
`${this.apiUrl}/widget/feedback_submission_sessions/${t}/image_proxy_url`,
|
|
1905
1919
|
{
|
|
1906
1920
|
method: "POST",
|
|
1907
|
-
headers:
|
|
1908
|
-
body: JSON.stringify({ image_proxy_url: { source:
|
|
1921
|
+
headers: o,
|
|
1922
|
+
body: JSON.stringify({ image_proxy_url: { source: a.href } }),
|
|
1909
1923
|
signal: s
|
|
1910
1924
|
}
|
|
1911
1925
|
)).json();
|
|
@@ -1915,50 +1929,50 @@ class Ji {
|
|
|
1915
1929
|
}
|
|
1916
1930
|
}
|
|
1917
1931
|
async authHeaders(t) {
|
|
1918
|
-
const
|
|
1919
|
-
return
|
|
1932
|
+
const i = { "X-Project-Key": this.projectKey }, r = await this.resolveUserToken();
|
|
1933
|
+
return r && (i["X-User-Token"] = r), t && (i["Content-Type"] = t), i;
|
|
1920
1934
|
}
|
|
1921
|
-
async submissionHeaders(t,
|
|
1922
|
-
const
|
|
1923
|
-
return
|
|
1935
|
+
async submissionHeaders(t, i) {
|
|
1936
|
+
const r = await this.authHeaders(i);
|
|
1937
|
+
return r["X-Submission-Token"] = t, r;
|
|
1924
1938
|
}
|
|
1925
|
-
async createSubmissionSession(t,
|
|
1926
|
-
const
|
|
1939
|
+
async createSubmissionSession(t, i) {
|
|
1940
|
+
const r = tn(), n = new FormData();
|
|
1927
1941
|
if (n.append("feedback[description]", t.description), n.append("feedback[page_url]", t.page_url), n.append("feedback[user_agent]", t.user_agent), n.append("feedback[browser]", t.browser), n.append("feedback[os]", t.os), n.append("feedback[screen_width]", String(t.screen_width)), n.append("feedback[screen_height]", String(t.screen_height)), n.append("feedback[console_errors]", JSON.stringify(t.console_errors)), n.append("feedback[annotations]", JSON.stringify(t.annotations)), t.target_element && n.append("feedback[target_element]", JSON.stringify(t.target_element)), t.user_id && n.append("feedback[user_id]", t.user_id), t.reporter_external_id && n.append("feedback[reporter_external_id]", t.reporter_external_id), t.reporter_email && n.append("feedback[reporter_email]", t.reporter_email), t.user_email && n.append("feedback[user_email]", t.user_email), t.user_name && n.append("feedback[user_name]", t.user_name), t.breadcrumbs && t.breadcrumbs.length > 0 && n.append("feedback[breadcrumbs]", JSON.stringify(t.breadcrumbs)), t.recording_events && t.recording_events.length > 0) {
|
|
1928
1942
|
const l = JSON.stringify(t.recording_events), c = new Blob([l], { type: "application/json" });
|
|
1929
1943
|
n.append("feedback[recording]", c, "interaction-replay.json"), n.append("feedback[recording_duration]", String(t.recording_duration ?? 0));
|
|
1930
1944
|
}
|
|
1931
|
-
if (
|
|
1932
|
-
const l =
|
|
1933
|
-
n.append("feedback[screenshot]",
|
|
1945
|
+
if (i) {
|
|
1946
|
+
const l = i.type === "image/jpeg" ? "jpg" : "png";
|
|
1947
|
+
n.append("feedback[screenshot]", i, `screenshot.${l}`);
|
|
1934
1948
|
}
|
|
1935
1949
|
const s = await this.authHeaders();
|
|
1936
|
-
return s["X-Submission-Token"] =
|
|
1950
|
+
return s["X-Submission-Token"] = r, s["X-MTB-Capture-Policy"] = Gr, s["X-Idempotency-Key"] = Qr(), { ...(await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions`, {
|
|
1937
1951
|
method: "POST",
|
|
1938
1952
|
headers: s,
|
|
1939
1953
|
body: n
|
|
1940
|
-
})).json()).submission_session, token:
|
|
1954
|
+
})).json()).submission_session, token: r };
|
|
1941
1955
|
}
|
|
1942
1956
|
async createIdentityToken(t) {
|
|
1943
|
-
const
|
|
1957
|
+
const i = await this.authHeaders("application/json");
|
|
1944
1958
|
try {
|
|
1945
1959
|
return await (await this.fetchWithRetry(`${this.apiUrl}/widget/identity_tokens`, {
|
|
1946
1960
|
method: "POST",
|
|
1947
|
-
headers:
|
|
1961
|
+
headers: i,
|
|
1948
1962
|
body: JSON.stringify({ reporter_external_id: t })
|
|
1949
1963
|
})).json();
|
|
1950
1964
|
} catch {
|
|
1951
1965
|
return null;
|
|
1952
1966
|
}
|
|
1953
1967
|
}
|
|
1954
|
-
async updateReporter(t,
|
|
1968
|
+
async updateReporter(t, i, r) {
|
|
1955
1969
|
const n = await this.authHeaders("application/json");
|
|
1956
|
-
n["X-Identity-Token"] =
|
|
1970
|
+
n["X-Identity-Token"] = r;
|
|
1957
1971
|
try {
|
|
1958
1972
|
return await this.fetchWithRetry(`${this.apiUrl}/widget/feedbacks/${t}/reporter`, {
|
|
1959
1973
|
method: "PATCH",
|
|
1960
1974
|
headers: n,
|
|
1961
|
-
body: JSON.stringify({ reporter: { email:
|
|
1975
|
+
body: JSON.stringify({ reporter: { email: i } })
|
|
1962
1976
|
}), !0;
|
|
1963
1977
|
} catch {
|
|
1964
1978
|
return !1;
|
|
@@ -1967,90 +1981,90 @@ class Ji {
|
|
|
1967
1981
|
// Records the reporter's answer to the AI follow-up question. Must run
|
|
1968
1982
|
// before finalize: finalizing deactivates the session and the server then
|
|
1969
1983
|
// rejects the answer as terminal.
|
|
1970
|
-
async answerClarification(t,
|
|
1971
|
-
return this.requestClarification(t,
|
|
1984
|
+
async answerClarification(t, i, r) {
|
|
1985
|
+
return this.requestClarification(t, i, { message: R(r) });
|
|
1972
1986
|
}
|
|
1973
|
-
async requestClarification(t,
|
|
1974
|
-
const n = await this.submissionHeaders(
|
|
1987
|
+
async requestClarification(t, i, r) {
|
|
1988
|
+
const n = await this.submissionHeaders(i, "application/json");
|
|
1975
1989
|
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
1976
1990
|
method: "POST",
|
|
1977
1991
|
headers: n,
|
|
1978
|
-
body: JSON.stringify(
|
|
1992
|
+
body: JSON.stringify(r)
|
|
1979
1993
|
})).json()).clarification;
|
|
1980
1994
|
}
|
|
1981
1995
|
// Streams a clarification turn over SSE. Calls onDelta for each token and
|
|
1982
1996
|
// resolves with the committed result.
|
|
1983
|
-
async streamClarification(t,
|
|
1984
|
-
const s = await this.submissionHeaders(
|
|
1997
|
+
async streamClarification(t, i, r, n) {
|
|
1998
|
+
const s = await this.submissionHeaders(i, "application/json");
|
|
1985
1999
|
s.Accept = "text/event-stream";
|
|
1986
|
-
const
|
|
2000
|
+
const a = await fetch(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/clarification`, {
|
|
1987
2001
|
method: "POST",
|
|
1988
2002
|
headers: s,
|
|
1989
2003
|
body: JSON.stringify({}),
|
|
1990
2004
|
signal: n
|
|
1991
|
-
}),
|
|
1992
|
-
if (!
|
|
2005
|
+
}), o = a.headers.get("Content-Type") ?? "";
|
|
2006
|
+
if (!a.ok || !a.body || !o.includes("text/event-stream"))
|
|
1993
2007
|
throw new Error("clarify stream unavailable");
|
|
1994
|
-
return
|
|
2008
|
+
return Zr(a.body, r);
|
|
1995
2009
|
}
|
|
1996
2010
|
// No X-Idempotency-Key here, unlike createSubmissionSession: the session id in
|
|
1997
2011
|
// the path already is one. The server finalizes under a row lock and returns
|
|
1998
2012
|
// the feedback it already created if the session is finalized, so the retry
|
|
1999
2013
|
// fetchWithRetry makes after a 5xx cannot produce a second Feedback.
|
|
2000
|
-
async finalizeSubmissionSession(t,
|
|
2001
|
-
const
|
|
2014
|
+
async finalizeSubmissionSession(t, i) {
|
|
2015
|
+
const r = await this.submissionHeaders(i), n = new AbortController(), s = setTimeout(() => n.abort(), Xr);
|
|
2002
2016
|
try {
|
|
2003
2017
|
return (await (await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/feedback`, {
|
|
2004
2018
|
method: "POST",
|
|
2005
|
-
headers:
|
|
2019
|
+
headers: r,
|
|
2006
2020
|
signal: n.signal
|
|
2007
2021
|
})).json()).feedback;
|
|
2008
2022
|
} finally {
|
|
2009
2023
|
clearTimeout(s);
|
|
2010
2024
|
}
|
|
2011
2025
|
}
|
|
2012
|
-
async uploadScreenshot(t,
|
|
2013
|
-
const s = await this.submissionHeaders(
|
|
2026
|
+
async uploadScreenshot(t, i, r, n) {
|
|
2027
|
+
const s = await this.submissionHeaders(i);
|
|
2014
2028
|
delete s["Content-Type"];
|
|
2015
|
-
const
|
|
2016
|
-
|
|
2029
|
+
const a = new FormData();
|
|
2030
|
+
a.append("screenshot", r, "screenshot.jpg"), await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}/screenshot`, {
|
|
2017
2031
|
method: "PUT",
|
|
2018
2032
|
headers: s,
|
|
2019
|
-
body:
|
|
2033
|
+
body: a,
|
|
2020
2034
|
signal: n
|
|
2021
2035
|
});
|
|
2022
2036
|
}
|
|
2023
|
-
async abandonSubmissionSession(t,
|
|
2024
|
-
const
|
|
2037
|
+
async abandonSubmissionSession(t, i) {
|
|
2038
|
+
const r = await this.submissionHeaders(i);
|
|
2025
2039
|
await this.fetchWithRetry(`${this.apiUrl}/widget/feedback_submission_sessions/${t}`, {
|
|
2026
2040
|
method: "DELETE",
|
|
2027
|
-
headers:
|
|
2041
|
+
headers: r
|
|
2028
2042
|
});
|
|
2029
2043
|
}
|
|
2030
|
-
async fetchWithRetry(t,
|
|
2044
|
+
async fetchWithRetry(t, i, r = 1) {
|
|
2031
2045
|
let n;
|
|
2032
2046
|
try {
|
|
2033
|
-
n = await fetch(t,
|
|
2047
|
+
n = await fetch(t, i);
|
|
2034
2048
|
} catch (s) {
|
|
2035
|
-
if (
|
|
2036
|
-
return await
|
|
2049
|
+
if (r > 0 && !i.signal?.aborted)
|
|
2050
|
+
return await Zt(this.retryDelayMs), this.fetchWithRetry(t, i, r - 1);
|
|
2037
2051
|
throw s;
|
|
2038
2052
|
}
|
|
2039
2053
|
if (n.ok) return n;
|
|
2040
|
-
if (n.status >= 500 &&
|
|
2041
|
-
return await
|
|
2042
|
-
throw new
|
|
2054
|
+
if (n.status >= 500 && r > 0)
|
|
2055
|
+
return await Zt(this.retryDelayMs), this.fetchWithRetry(t, i, r - 1);
|
|
2056
|
+
throw new Yr(n.status);
|
|
2043
2057
|
}
|
|
2044
2058
|
}
|
|
2045
|
-
function
|
|
2059
|
+
function Zt(e) {
|
|
2046
2060
|
return e <= 0 ? Promise.resolve() : new Promise((t) => setTimeout(t, e));
|
|
2047
2061
|
}
|
|
2048
|
-
async function
|
|
2049
|
-
const
|
|
2062
|
+
async function Zr(e, t) {
|
|
2063
|
+
const i = e.getReader(), r = new TextDecoder();
|
|
2050
2064
|
let n = "", s = null;
|
|
2051
|
-
const
|
|
2052
|
-
const l =
|
|
2053
|
-
`).find((m) => m.startsWith("event:")), c =
|
|
2065
|
+
const a = (o) => {
|
|
2066
|
+
const l = o.split(`
|
|
2067
|
+
`).find((m) => m.startsWith("event:")), c = o.split(`
|
|
2054
2068
|
`).find((m) => m.startsWith("data:"));
|
|
2055
2069
|
if (!c) return;
|
|
2056
2070
|
const h = l?.slice(6).trim(), u = JSON.parse(c.slice(5).trim());
|
|
@@ -2062,9 +2076,9 @@ async function Zi(e, t) {
|
|
|
2062
2076
|
});
|
|
2063
2077
|
};
|
|
2064
2078
|
for (; ; ) {
|
|
2065
|
-
const { done:
|
|
2066
|
-
if (
|
|
2067
|
-
n +=
|
|
2079
|
+
const { done: o, value: l } = await i.read();
|
|
2080
|
+
if (o) break;
|
|
2081
|
+
n += r.decode(l, { stream: !0 });
|
|
2068
2082
|
let c;
|
|
2069
2083
|
for (; (c = n.indexOf(`
|
|
2070
2084
|
|
|
@@ -2072,20 +2086,20 @@ async function Zi(e, t) {
|
|
|
2072
2086
|
const h = n.slice(0, c);
|
|
2073
2087
|
n = n.slice(c + 2);
|
|
2074
2088
|
try {
|
|
2075
|
-
|
|
2089
|
+
a(h);
|
|
2076
2090
|
} catch {
|
|
2077
2091
|
}
|
|
2078
2092
|
}
|
|
2079
2093
|
}
|
|
2080
|
-
if (n +=
|
|
2094
|
+
if (n += r.decode(), n.trim())
|
|
2081
2095
|
try {
|
|
2082
|
-
|
|
2096
|
+
a(n);
|
|
2083
2097
|
} catch {
|
|
2084
2098
|
}
|
|
2085
2099
|
if (!s) throw new Error("clarify stream ended before done");
|
|
2086
2100
|
return s;
|
|
2087
2101
|
}
|
|
2088
|
-
function
|
|
2102
|
+
function Qr() {
|
|
2089
2103
|
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
2090
2104
|
}
|
|
2091
2105
|
function tn() {
|
|
@@ -2094,19 +2108,19 @@ function tn() {
|
|
|
2094
2108
|
const e = crypto.getRandomValues(new Uint8Array(32));
|
|
2095
2109
|
return Array.from(e, (t) => t.toString(16).padStart(2, "0")).join("");
|
|
2096
2110
|
}
|
|
2097
|
-
const
|
|
2098
|
-
let
|
|
2099
|
-
function
|
|
2111
|
+
const Qt = "mtb_anon_id", He = "mtb_reporter_email", Be = "mtb_board_url";
|
|
2112
|
+
let te = null, Ne = null, Oe = null;
|
|
2113
|
+
function ze() {
|
|
2100
2114
|
try {
|
|
2101
|
-
const e = window.localStorage.getItem(
|
|
2115
|
+
const e = window.localStorage.getItem(Qt);
|
|
2102
2116
|
if (e?.startsWith("anon_")) return e;
|
|
2103
|
-
const t =
|
|
2104
|
-
return window.localStorage.setItem(
|
|
2117
|
+
const t = ee();
|
|
2118
|
+
return window.localStorage.setItem(Qt, t), t;
|
|
2105
2119
|
} catch {
|
|
2106
|
-
return
|
|
2120
|
+
return te ?? (te = ee()), te;
|
|
2107
2121
|
}
|
|
2108
2122
|
}
|
|
2109
|
-
function
|
|
2123
|
+
function $e() {
|
|
2110
2124
|
try {
|
|
2111
2125
|
return window.localStorage.getItem(He) ?? void 0;
|
|
2112
2126
|
} catch {
|
|
@@ -2134,7 +2148,7 @@ function I(e) {
|
|
|
2134
2148
|
} catch {
|
|
2135
2149
|
}
|
|
2136
2150
|
}
|
|
2137
|
-
function
|
|
2151
|
+
function ee() {
|
|
2138
2152
|
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? `anon_${crypto.randomUUID()}` : `anon_${`${Date.now().toString(16)}-${Math.random().toString(16).slice(2, 10)}`}`;
|
|
2139
2153
|
}
|
|
2140
2154
|
const nn = {
|
|
@@ -2178,7 +2192,9 @@ const nn = {
|
|
|
2178
2192
|
notify: "Notify"
|
|
2179
2193
|
},
|
|
2180
2194
|
error: {
|
|
2181
|
-
submit: "Failed to submit. Please try again."
|
|
2195
|
+
submit: "Failed to submit. Please try again.",
|
|
2196
|
+
finalize_title: "We couldn't send this yet.",
|
|
2197
|
+
finalize_message: "Your feedback is still saved. Please try again."
|
|
2182
2198
|
},
|
|
2183
2199
|
pet: {
|
|
2184
2200
|
bubble: "Need help?"
|
|
@@ -2264,7 +2280,9 @@ const nn = {
|
|
|
2264
2280
|
notify: "通知我"
|
|
2265
2281
|
},
|
|
2266
2282
|
error: {
|
|
2267
|
-
submit: "提交失败,请重试。"
|
|
2283
|
+
submit: "提交失败,请重试。",
|
|
2284
|
+
finalize_title: "暂时无法发送。",
|
|
2285
|
+
finalize_message: "你的反馈仍已保存,请重试。"
|
|
2268
2286
|
},
|
|
2269
2287
|
pet: {
|
|
2270
2288
|
bubble: "需要帮助吗?"
|
|
@@ -2309,7 +2327,7 @@ const nn = {
|
|
|
2309
2327
|
error: "追问加载失败,可以直接发送反馈。",
|
|
2310
2328
|
expired: "这条反馈在发送前已过期。请关闭组件后重新提交。"
|
|
2311
2329
|
}
|
|
2312
|
-
},
|
|
2330
|
+
}, an = {
|
|
2313
2331
|
tab: "フィードバック",
|
|
2314
2332
|
toolbar: {
|
|
2315
2333
|
markup: "マークアップ",
|
|
@@ -2350,7 +2368,9 @@ const nn = {
|
|
|
2350
2368
|
notify: "通知"
|
|
2351
2369
|
},
|
|
2352
2370
|
error: {
|
|
2353
|
-
submit: "送信に失敗しました。もう一度お試しください。"
|
|
2371
|
+
submit: "送信に失敗しました。もう一度お試しください。",
|
|
2372
|
+
finalize_title: "まだ送信できませんでした。",
|
|
2373
|
+
finalize_message: "フィードバックは保存されています。もう一度お試しください。"
|
|
2354
2374
|
},
|
|
2355
2375
|
pet: {
|
|
2356
2376
|
bubble: "お困りですか?"
|
|
@@ -2395,7 +2415,7 @@ const nn = {
|
|
|
2395
2415
|
error: "質問を読み込めませんでした。そのままフィードバックを送信できます。",
|
|
2396
2416
|
expired: "このフィードバックは送信される前に有効期限が切れました。ウィジェットを閉じて、もう一度送信してください。"
|
|
2397
2417
|
}
|
|
2398
|
-
},
|
|
2418
|
+
}, on = {
|
|
2399
2419
|
tab: "피드백",
|
|
2400
2420
|
toolbar: {
|
|
2401
2421
|
markup: "마크업",
|
|
@@ -2436,7 +2456,9 @@ const nn = {
|
|
|
2436
2456
|
notify: "알림"
|
|
2437
2457
|
},
|
|
2438
2458
|
error: {
|
|
2439
|
-
submit: "제출에 실패했습니다. 다시 시도해 주세요."
|
|
2459
|
+
submit: "제출에 실패했습니다. 다시 시도해 주세요.",
|
|
2460
|
+
finalize_title: "아직 전송하지 못했습니다.",
|
|
2461
|
+
finalize_message: "피드백은 저장되어 있습니다. 다시 시도해 주세요."
|
|
2440
2462
|
},
|
|
2441
2463
|
pet: {
|
|
2442
2464
|
bubble: "도움이 필요하신가요?"
|
|
@@ -2522,7 +2544,9 @@ const nn = {
|
|
|
2522
2544
|
notify: "Avisarme"
|
|
2523
2545
|
},
|
|
2524
2546
|
error: {
|
|
2525
|
-
submit: "Error al enviar. Por favor, inténtalo de nuevo."
|
|
2547
|
+
submit: "Error al enviar. Por favor, inténtalo de nuevo.",
|
|
2548
|
+
finalize_title: "Aún no pudimos enviarlo.",
|
|
2549
|
+
finalize_message: "Tu comentario sigue guardado. Inténtalo de nuevo."
|
|
2526
2550
|
},
|
|
2527
2551
|
pet: {
|
|
2528
2552
|
bubble: "¿Necesitas ayuda?"
|
|
@@ -2608,7 +2632,9 @@ const nn = {
|
|
|
2608
2632
|
notify: "Avertir"
|
|
2609
2633
|
},
|
|
2610
2634
|
error: {
|
|
2611
|
-
submit: "Échec de l'envoi. Veuillez réessayer."
|
|
2635
|
+
submit: "Échec de l'envoi. Veuillez réessayer.",
|
|
2636
|
+
finalize_title: "Nous n'avons pas encore pu l'envoyer.",
|
|
2637
|
+
finalize_message: "Votre retour est toujours enregistré. Veuillez réessayer."
|
|
2612
2638
|
},
|
|
2613
2639
|
pet: {
|
|
2614
2640
|
bubble: "Besoin d'aide ?"
|
|
@@ -2694,7 +2720,9 @@ const nn = {
|
|
|
2694
2720
|
notify: "Melden"
|
|
2695
2721
|
},
|
|
2696
2722
|
error: {
|
|
2697
|
-
submit: "Senden fehlgeschlagen. Bitte versuchen Sie es erneut."
|
|
2723
|
+
submit: "Senden fehlgeschlagen. Bitte versuchen Sie es erneut.",
|
|
2724
|
+
finalize_title: "Wir konnten dies noch nicht senden.",
|
|
2725
|
+
finalize_message: "Ihr Feedback ist weiterhin gespeichert. Bitte versuchen Sie es erneut."
|
|
2698
2726
|
},
|
|
2699
2727
|
pet: {
|
|
2700
2728
|
bubble: "Brauchen Sie Hilfe?"
|
|
@@ -2742,13 +2770,13 @@ const nn = {
|
|
|
2742
2770
|
}, F = {
|
|
2743
2771
|
en: nn,
|
|
2744
2772
|
"zh-CN": sn,
|
|
2745
|
-
ja:
|
|
2746
|
-
ko:
|
|
2773
|
+
ja: an,
|
|
2774
|
+
ko: on,
|
|
2747
2775
|
es: ln,
|
|
2748
2776
|
fr: cn,
|
|
2749
2777
|
de: hn
|
|
2750
2778
|
};
|
|
2751
|
-
function
|
|
2779
|
+
function ie(e) {
|
|
2752
2780
|
if (F[e]) return F[e];
|
|
2753
2781
|
const t = e.split("-")[0];
|
|
2754
2782
|
return F[t] ? F[t] : F.en;
|
|
@@ -2781,65 +2809,65 @@ const dn = 60, re = ["value", "content"], un = Object.fromEntries([
|
|
|
2781
2809
|
].map((e) => [e, !0])), mn = "https://cdn.jsdelivr.net/npm/@rrweb/record@2.1.0/umd/record.min.js", bn = "sha384-MrD66HBNSykaP2N95+6hQCFlF5oH2tvL3TD/zyvHNkP/sAFWZx98DX9MEDy8MdVT";
|
|
2782
2810
|
let H = null;
|
|
2783
2811
|
function pn() {
|
|
2784
|
-
return H || (H = gn().catch(() =>
|
|
2812
|
+
return H || (H = gn().catch(() => wn()).catch((t) => {
|
|
2785
2813
|
throw H = null, t;
|
|
2786
2814
|
}), H);
|
|
2787
2815
|
}
|
|
2788
2816
|
function fn(e, t) {
|
|
2789
|
-
const
|
|
2790
|
-
return
|
|
2817
|
+
const i = st(e);
|
|
2818
|
+
return Pt(i, t, _e()), i;
|
|
2791
2819
|
}
|
|
2792
|
-
function
|
|
2820
|
+
function Pt(e, t, i) {
|
|
2793
2821
|
if (Array.isArray(e)) {
|
|
2794
|
-
e.forEach((
|
|
2822
|
+
e.forEach((o) => Pt(o, t, i));
|
|
2795
2823
|
return;
|
|
2796
2824
|
}
|
|
2797
|
-
if (!
|
|
2798
|
-
const
|
|
2799
|
-
if (
|
|
2800
|
-
if (typeof e.text == "string" && (e.text =
|
|
2801
|
-
for (const
|
|
2802
|
-
const l =
|
|
2803
|
-
typeof l == "string" && (
|
|
2825
|
+
if (!ne(e)) return;
|
|
2826
|
+
const r = ne(e.attributes) ? e.attributes : null, n = r && re.some((o) => typeof r[o] == "string"), a = (typeof e.text == "string" || typeof e.textContent == "string" || typeof e.value == "string" || n) && typeof e.id == "number" ? t.mirror.getNode(e.id) : null;
|
|
2827
|
+
if (a instanceof Element) {
|
|
2828
|
+
if (typeof e.text == "string" && (e.text = at(e.text, a)), r)
|
|
2829
|
+
for (const o of re) {
|
|
2830
|
+
const l = r[o];
|
|
2831
|
+
typeof l == "string" && (r[o] = at(l, a));
|
|
2804
2832
|
}
|
|
2805
|
-
} else
|
|
2806
|
-
Object.values(e).forEach((
|
|
2833
|
+
} else a?.nodeType === Node.TEXT_NODE && Ae(a, i) && (typeof e.textContent == "string" && (e.textContent = g), typeof e.value == "string" && (e.value = g));
|
|
2834
|
+
Object.values(e).forEach((o) => Pt(o, t, i));
|
|
2807
2835
|
}
|
|
2808
|
-
function
|
|
2836
|
+
function ne(e) {
|
|
2809
2837
|
return !!e && typeof e == "object" && !Array.isArray(e);
|
|
2810
2838
|
}
|
|
2811
2839
|
async function gn() {
|
|
2812
2840
|
return (await import("@rrweb/record")).record;
|
|
2813
2841
|
}
|
|
2814
|
-
function
|
|
2842
|
+
function se() {
|
|
2815
2843
|
const e = globalThis;
|
|
2816
2844
|
return e.rrwebRecord?.record ?? e.rrweb?.record;
|
|
2817
2845
|
}
|
|
2818
|
-
function
|
|
2846
|
+
function wn() {
|
|
2819
2847
|
return new Promise((e, t) => {
|
|
2820
|
-
const
|
|
2821
|
-
if (
|
|
2822
|
-
e(
|
|
2848
|
+
const i = se();
|
|
2849
|
+
if (i) {
|
|
2850
|
+
e(i);
|
|
2823
2851
|
return;
|
|
2824
2852
|
}
|
|
2825
|
-
const
|
|
2826
|
-
|
|
2827
|
-
const n =
|
|
2853
|
+
const r = document.createElement("script");
|
|
2854
|
+
r.src = mn, r.integrity = bn, r.crossOrigin = "anonymous", r.onload = () => {
|
|
2855
|
+
const n = se();
|
|
2828
2856
|
n ? e(n) : t(new Error("rrweb record global not found after script load"));
|
|
2829
|
-
},
|
|
2857
|
+
}, r.onerror = () => t(new Error("Failed to load rrweb from CDN")), document.head.appendChild(r);
|
|
2830
2858
|
});
|
|
2831
2859
|
}
|
|
2832
|
-
class
|
|
2833
|
-
constructor(t,
|
|
2834
|
-
this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.destroyed = !1, this.shadow = t, this.onMaxReached =
|
|
2860
|
+
class yn {
|
|
2861
|
+
constructor(t, i) {
|
|
2862
|
+
this.events = [], this.stopFn = null, this.startedAt = 0, this.timer = null, this.clickHandler = null, this.stopped = !1, this.destroyed = !1, this.shadow = t, this.onMaxReached = i;
|
|
2835
2863
|
}
|
|
2836
2864
|
async start() {
|
|
2837
2865
|
const t = await pn();
|
|
2838
2866
|
this.destroyed || (this.startedAt = Date.now(), this.stopped = !1, this.stopFn = t({
|
|
2839
|
-
emit: (
|
|
2867
|
+
emit: (i) => {
|
|
2840
2868
|
if (!this.stopped)
|
|
2841
2869
|
try {
|
|
2842
|
-
this.events.push(fn(
|
|
2870
|
+
this.events.push(fn(i, t));
|
|
2843
2871
|
} catch {
|
|
2844
2872
|
}
|
|
2845
2873
|
},
|
|
@@ -2848,15 +2876,15 @@ class wn {
|
|
|
2848
2876
|
// ordinary values are returned unchanged.
|
|
2849
2877
|
maskAllInputs: !1,
|
|
2850
2878
|
maskInputOptions: un,
|
|
2851
|
-
maskInputFn: (
|
|
2879
|
+
maskInputFn: (i, r) => r.closest(`.${W}`) ? g : at(i, r),
|
|
2852
2880
|
maskTextFn: () => g,
|
|
2853
|
-
blockClass:
|
|
2854
|
-
maskTextClass:
|
|
2855
|
-
}), this.clickHandler = (
|
|
2856
|
-
this.showClickRipple(
|
|
2857
|
-
x:
|
|
2858
|
-
y:
|
|
2859
|
-
target:
|
|
2881
|
+
blockClass: ut,
|
|
2882
|
+
maskTextClass: W
|
|
2883
|
+
}), this.clickHandler = (i) => {
|
|
2884
|
+
this.showClickRipple(i.clientX, i.clientY), t.addCustomEvent?.("mtb-click", {
|
|
2885
|
+
x: i.clientX,
|
|
2886
|
+
y: i.clientY,
|
|
2887
|
+
target: i.target instanceof HTMLElement ? i.target.tagName : ""
|
|
2860
2888
|
});
|
|
2861
2889
|
}, document.addEventListener("click", this.clickHandler, !0), this.timer = setTimeout(() => {
|
|
2862
2890
|
this.onMaxReached?.();
|
|
@@ -2880,22 +2908,22 @@ class wn {
|
|
|
2880
2908
|
cleanupClickHandler() {
|
|
2881
2909
|
this.clickHandler && (document.removeEventListener("click", this.clickHandler, !0), this.clickHandler = null);
|
|
2882
2910
|
}
|
|
2883
|
-
showClickRipple(t,
|
|
2884
|
-
const
|
|
2885
|
-
|
|
2911
|
+
showClickRipple(t, i) {
|
|
2912
|
+
const r = this.shadow.el("div", "mtb-click-ripple");
|
|
2913
|
+
r.style.left = `${t}px`, r.style.top = `${i}px`, this.shadow.append(r), r.addEventListener("animationend", () => r.remove());
|
|
2886
2914
|
}
|
|
2887
2915
|
}
|
|
2888
2916
|
class vn {
|
|
2889
|
-
constructor(t,
|
|
2890
|
-
this.intervalId = null, this.getDuration =
|
|
2917
|
+
constructor(t, i, r, n) {
|
|
2918
|
+
this.intervalId = null, this.getDuration = r, this.el = t.el("div", "mtb-record-bar"), this.el.innerHTML = `
|
|
2891
2919
|
<span class="mtb-record-dot"></span>
|
|
2892
2920
|
<span class="mtb-record-timer">00:00</span>
|
|
2893
|
-
<button class="mtb-record-stop" type="button">${d(
|
|
2921
|
+
<button class="mtb-record-stop" type="button">${d(i.record.stop)}</button>
|
|
2894
2922
|
`, t.append(this.el), this.timerEl = this.el.querySelector(".mtb-record-timer"), this.el.querySelector(".mtb-record-stop").addEventListener("click", n), this.intervalId = setInterval(() => this.updateTimer(), 1e3);
|
|
2895
2923
|
}
|
|
2896
2924
|
updateTimer() {
|
|
2897
|
-
const t = this.getDuration(),
|
|
2898
|
-
this.timerEl.textContent = `${
|
|
2925
|
+
const t = this.getDuration(), i = String(Math.floor(t / 60)).padStart(2, "0"), r = String(t % 60).padStart(2, "0");
|
|
2926
|
+
this.timerEl.textContent = `${i}:${r}`;
|
|
2899
2927
|
}
|
|
2900
2928
|
destroy() {
|
|
2901
2929
|
this.intervalId && (clearInterval(this.intervalId), this.intervalId = null), this.el.remove();
|
|
@@ -2905,12 +2933,12 @@ class xn {
|
|
|
2905
2933
|
constructor() {
|
|
2906
2934
|
this.session = null, this.bar = null, this.result = null;
|
|
2907
2935
|
}
|
|
2908
|
-
async start(t,
|
|
2909
|
-
this.session = new
|
|
2936
|
+
async start(t, i, r) {
|
|
2937
|
+
this.session = new yn(t, r), this.bar = new vn(
|
|
2910
2938
|
t,
|
|
2911
|
-
|
|
2939
|
+
i,
|
|
2912
2940
|
() => this.session?.getDuration() ?? 0,
|
|
2913
|
-
|
|
2941
|
+
r
|
|
2914
2942
|
), await this.session.start();
|
|
2915
2943
|
}
|
|
2916
2944
|
stop() {
|
|
@@ -2926,67 +2954,40 @@ class xn {
|
|
|
2926
2954
|
this.session?.destroy(), this.session = null, this.bar?.destroy(), this.bar = null;
|
|
2927
2955
|
}
|
|
2928
2956
|
}
|
|
2929
|
-
|
|
2930
|
-
constructor(t, r, i) {
|
|
2931
|
-
this.el = t.el("div", "mtb-failure"), this.el.style.right = "20px", this.el.style.bottom = "20px", this.el.setAttribute("role", "alert");
|
|
2932
|
-
const n = i.onRetry ? `<div class="mtb-failure-actions">
|
|
2933
|
-
<button class="mtb-clarify-retry mtb-failure-retry" type="button">${d(r.clarify.retry)}</button>
|
|
2934
|
-
</div>` : "";
|
|
2935
|
-
this.el.innerHTML = `
|
|
2936
|
-
<button class="mtb-failure-close" type="button" title="${d(r.success.close)}" aria-label="${d(r.success.close)}">
|
|
2937
|
-
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2938
|
-
<path d="M18 6L6 18M6 6l12 12"/>
|
|
2939
|
-
</svg>
|
|
2940
|
-
</button>
|
|
2941
|
-
<div class="mtb-failure-icon">
|
|
2942
|
-
<svg width="23" height="23" viewBox="0 0 24 24" fill="none" stroke="#dc2626" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
|
|
2943
|
-
<path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
|
2944
|
-
<line x1="12" y1="9" x2="12" y2="13"/>
|
|
2945
|
-
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
|
2946
|
-
</svg>
|
|
2947
|
-
</div>
|
|
2948
|
-
<div class="mtb-failure-title">${d(r.error.submit)}</div>
|
|
2949
|
-
${n}
|
|
2950
|
-
`, t.append(this.el), i.onRetry && this.el.querySelector(".mtb-failure-retry").addEventListener("click", i.onRetry), this.el.querySelector(".mtb-failure-close").addEventListener("click", i.onClose);
|
|
2951
|
-
}
|
|
2952
|
-
destroy() {
|
|
2953
|
-
this.el.remove();
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2956
|
-
function En() {
|
|
2957
|
+
function kn() {
|
|
2957
2958
|
return {
|
|
2958
|
-
page_url:
|
|
2959
|
+
page_url: V(window.location.href),
|
|
2959
2960
|
user_agent: navigator.userAgent,
|
|
2960
|
-
browser:
|
|
2961
|
-
os:
|
|
2961
|
+
browser: En(),
|
|
2962
|
+
os: Sn(),
|
|
2962
2963
|
screen_width: window.screen.width,
|
|
2963
2964
|
screen_height: window.screen.height
|
|
2964
2965
|
};
|
|
2965
2966
|
}
|
|
2966
|
-
function
|
|
2967
|
+
function En() {
|
|
2967
2968
|
const e = navigator.userAgent;
|
|
2968
2969
|
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";
|
|
2969
2970
|
}
|
|
2970
|
-
function
|
|
2971
|
+
function Sn() {
|
|
2971
2972
|
const e = navigator.userAgent;
|
|
2972
2973
|
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";
|
|
2973
2974
|
}
|
|
2974
|
-
function
|
|
2975
|
-
const { description: t, pageContext:
|
|
2975
|
+
function Cn(e) {
|
|
2976
|
+
const { description: t, pageContext: i, consoleErrors: r, annotation: n, user: s, recording: a, anonId: o, anonEmail: l, breadcrumbs: c } = e;
|
|
2976
2977
|
return {
|
|
2977
|
-
...
|
|
2978
|
+
...st({
|
|
2978
2979
|
description: t,
|
|
2979
|
-
...
|
|
2980
|
-
page_url:
|
|
2981
|
-
console_errors:
|
|
2980
|
+
...i,
|
|
2981
|
+
page_url: V(i.page_url),
|
|
2982
|
+
console_errors: r,
|
|
2982
2983
|
annotations: n ? [n] : [],
|
|
2983
2984
|
target_element: n?.targetSelector ? {
|
|
2984
2985
|
selector: n.targetSelector,
|
|
2985
2986
|
text: n.targetText ?? "",
|
|
2986
2987
|
name: n.targetName ?? ""
|
|
2987
2988
|
} : void 0,
|
|
2988
|
-
recording_events:
|
|
2989
|
-
recording_duration:
|
|
2989
|
+
recording_events: a?.events,
|
|
2990
|
+
recording_duration: a?.duration,
|
|
2990
2991
|
breadcrumbs: c
|
|
2991
2992
|
}),
|
|
2992
2993
|
user_id: s?.id,
|
|
@@ -2995,14 +2996,14 @@ function Tn(e) {
|
|
|
2995
2996
|
// An identified user carries no anonymous identity: the host has vouched
|
|
2996
2997
|
// for who the reporter is, so attaching the stored anon id/email would tie
|
|
2997
2998
|
// that account to a stranger's earlier anonymous submissions.
|
|
2998
|
-
reporter_external_id: s ? void 0 :
|
|
2999
|
+
reporter_external_id: s ? void 0 : o,
|
|
2999
3000
|
reporter_email: s ? void 0 : l
|
|
3000
3001
|
};
|
|
3001
3002
|
}
|
|
3002
|
-
const
|
|
3003
|
-
class
|
|
3004
|
-
constructor(t,
|
|
3005
|
-
this.deps = t, this.host =
|
|
3003
|
+
const Tn = 300, _n = 5e3;
|
|
3004
|
+
class An {
|
|
3005
|
+
constructor(t, i) {
|
|
3006
|
+
this.deps = t, this.host = i, this.activeSubmission = null, this.pendingSubmissionRequest = null, this.submissionAttempt = 0, this.pendingScreenshotTask = null, this.screenshotAbortController = null, this.screenshotEnabled = !0;
|
|
3006
3007
|
}
|
|
3007
3008
|
/**
|
|
3008
3009
|
* What the note surface must render. Reading it back rather than assuming
|
|
@@ -3039,28 +3040,28 @@ class Ln {
|
|
|
3039
3040
|
// Load the screenshot dependency and font CSS ahead of submit. Bitmap capture
|
|
3040
3041
|
// starts alongside Session creation; only cross-origin fallback waits for it.
|
|
3041
3042
|
warmScreenshotDeps() {
|
|
3042
|
-
this.screenshotEnabled &&
|
|
3043
|
+
this.screenshotEnabled && Ft();
|
|
3043
3044
|
}
|
|
3044
|
-
start(t,
|
|
3045
|
-
const n = ++this.submissionAttempt, s = this.createSubmission(t,
|
|
3045
|
+
start(t, i, r) {
|
|
3046
|
+
const n = ++this.submissionAttempt, s = this.createSubmission(t, i, r, n);
|
|
3046
3047
|
return this.pendingSubmissionRequest = s, s;
|
|
3047
3048
|
}
|
|
3048
|
-
async createSubmission(t,
|
|
3049
|
-
if (await
|
|
3050
|
-
const s =
|
|
3049
|
+
async createSubmission(t, i, r, n) {
|
|
3050
|
+
if (await ae(), n !== this.submissionAttempt) return null;
|
|
3051
|
+
const s = kn(), a = Cn({
|
|
3051
3052
|
description: t,
|
|
3052
3053
|
pageContext: s,
|
|
3053
3054
|
consoleErrors: this.deps.consoleCollector.getErrors(),
|
|
3054
|
-
annotation:
|
|
3055
|
+
annotation: i,
|
|
3055
3056
|
user: this.deps.user(),
|
|
3056
|
-
recording:
|
|
3057
|
-
anonId:
|
|
3058
|
-
anonEmail:
|
|
3057
|
+
recording: r,
|
|
3058
|
+
anonId: ze(),
|
|
3059
|
+
anonEmail: $e(),
|
|
3059
3060
|
breadcrumbs: this.deps.breadcrumbCollector.getBreadcrumbs()
|
|
3060
3061
|
});
|
|
3061
|
-
let
|
|
3062
|
+
let o;
|
|
3062
3063
|
try {
|
|
3063
|
-
|
|
3064
|
+
o = this.deps.apiClient.createSubmissionSession(a, null);
|
|
3064
3065
|
} catch {
|
|
3065
3066
|
return null;
|
|
3066
3067
|
}
|
|
@@ -3070,23 +3071,23 @@ class Ln {
|
|
|
3070
3071
|
l = h, this.screenshotAbortController?.abort(), this.screenshotAbortController = h;
|
|
3071
3072
|
const m = (async () => {
|
|
3072
3073
|
try {
|
|
3073
|
-
const
|
|
3074
|
-
const $t = await
|
|
3074
|
+
const y = await or(async (ft, Qe) => {
|
|
3075
|
+
const $t = await o;
|
|
3075
3076
|
if (!(h.signal.aborted || n !== this.submissionAttempt))
|
|
3076
3077
|
return this.deps.apiClient.resolveScreenshotResourceUrl(
|
|
3077
3078
|
$t.id,
|
|
3078
3079
|
$t.token,
|
|
3079
|
-
|
|
3080
|
+
ft,
|
|
3080
3081
|
Qe,
|
|
3081
3082
|
h.signal
|
|
3082
3083
|
);
|
|
3083
3084
|
}, h.signal);
|
|
3084
|
-
if (h.signal.aborted || n !== this.submissionAttempt || !w) return;
|
|
3085
|
-
const y = await li(w, r ? [r] : [], this.deps.brandColors);
|
|
3086
3085
|
if (h.signal.aborted || n !== this.submissionAttempt || !y) return;
|
|
3087
|
-
const
|
|
3086
|
+
const w = await lr(y, i ? [i] : [], this.deps.brandColors);
|
|
3087
|
+
if (h.signal.aborted || n !== this.submissionAttempt || !w) return;
|
|
3088
|
+
const b = await o;
|
|
3088
3089
|
if (h.signal.aborted || n !== this.submissionAttempt) return;
|
|
3089
|
-
await this.deps.apiClient.uploadScreenshot(b.id, b.token,
|
|
3090
|
+
await this.deps.apiClient.uploadScreenshot(b.id, b.token, w, h.signal);
|
|
3090
3091
|
} catch {
|
|
3091
3092
|
}
|
|
3092
3093
|
})().finally(() => {
|
|
@@ -3096,7 +3097,7 @@ class Ln {
|
|
|
3096
3097
|
}
|
|
3097
3098
|
let c;
|
|
3098
3099
|
try {
|
|
3099
|
-
if (c = await
|
|
3100
|
+
if (c = await o, n !== this.submissionAttempt)
|
|
3100
3101
|
return l?.abort(), await this.deps.apiClient.abandonSubmissionSession(c.id, c.token).catch(() => {
|
|
3101
3102
|
}), null;
|
|
3102
3103
|
this.activeSubmission = c;
|
|
@@ -3108,46 +3109,40 @@ class Ln {
|
|
|
3108
3109
|
async finalize() {
|
|
3109
3110
|
const t = this.submissionAttempt;
|
|
3110
3111
|
this.resetScreenshotConsent();
|
|
3111
|
-
const
|
|
3112
|
+
const i = this.host.isBackground(), r = this.activeSubmission ?? await (this.pendingSubmissionRequest ?? Promise.resolve(null));
|
|
3112
3113
|
if (t !== this.submissionAttempt) return;
|
|
3113
|
-
if (!
|
|
3114
|
-
if (
|
|
3114
|
+
if (!r) {
|
|
3115
|
+
if (i) return this.showFinalizeFailure({ canRetry: !1 });
|
|
3115
3116
|
throw new Error("No active submission session");
|
|
3116
3117
|
}
|
|
3117
3118
|
if (await this.waitForScreenshot(), t !== this.submissionAttempt) return;
|
|
3118
|
-
const n =
|
|
3119
|
+
const n = i ? Promise.resolve() : new Promise((a) => setTimeout(a, Tn));
|
|
3119
3120
|
let s;
|
|
3120
3121
|
try {
|
|
3121
|
-
s = await this.deps.apiClient.finalizeSubmissionSession(
|
|
3122
|
-
} catch (
|
|
3123
|
-
if (
|
|
3124
|
-
throw
|
|
3122
|
+
s = await this.deps.apiClient.finalizeSubmissionSession(r.id, r.token);
|
|
3123
|
+
} catch (a) {
|
|
3124
|
+
if (i) return this.showFinalizeFailure({ canRetry: !0 });
|
|
3125
|
+
throw a;
|
|
3125
3126
|
}
|
|
3126
|
-
await Promise.all([n,
|
|
3127
|
+
await Promise.all([n, ae()]), !(t !== this.submissionAttempt || this.activeSubmission !== r) && (this.activeSubmission = null, this.pendingSubmissionRequest = null, this.host.onFinalized(s, r));
|
|
3127
3128
|
}
|
|
3128
3129
|
async waitForScreenshot() {
|
|
3129
3130
|
const t = this.pendingScreenshotTask;
|
|
3130
3131
|
if (!t) return;
|
|
3131
|
-
let
|
|
3132
|
-
const
|
|
3132
|
+
let i;
|
|
3133
|
+
const r = await Promise.race([
|
|
3133
3134
|
t.then(() => !0),
|
|
3134
3135
|
new Promise((n) => {
|
|
3135
|
-
|
|
3136
|
+
i = setTimeout(() => n(!1), _n);
|
|
3136
3137
|
})
|
|
3137
3138
|
]);
|
|
3138
|
-
|
|
3139
|
+
i !== void 0 && clearTimeout(i), r || (this.screenshotAbortController?.abort(), this.pendingScreenshotTask === t && (this.pendingScreenshotTask = null));
|
|
3139
3140
|
}
|
|
3140
3141
|
showFinalizeFailure(t) {
|
|
3141
|
-
this.host.
|
|
3142
|
-
onRetry: t.canRetry ? () => this.retryBackgroundFinalization() : void 0,
|
|
3143
|
-
onClose: () => this.dismissFinalizeFailure()
|
|
3144
|
-
});
|
|
3142
|
+
this.host.onFinalizeFailure(t.canRetry ? () => this.retryBackgroundFinalization() : void 0);
|
|
3145
3143
|
}
|
|
3146
3144
|
retryBackgroundFinalization() {
|
|
3147
|
-
this.
|
|
3148
|
-
}
|
|
3149
|
-
dismissFinalizeFailure() {
|
|
3150
|
-
this.failure?.destroy(), this.failure = null;
|
|
3145
|
+
this.host.onReenterBackground(), this.finalize().catch(() => this.showFinalizeFailure({ canRetry: !0 }));
|
|
3151
3146
|
}
|
|
3152
3147
|
/**
|
|
3153
3148
|
* Invalidate every in-flight attempt and abandon what already reached the
|
|
@@ -3160,10 +3155,10 @@ class Ln {
|
|
|
3160
3155
|
});
|
|
3161
3156
|
}
|
|
3162
3157
|
}
|
|
3163
|
-
function
|
|
3158
|
+
function ae() {
|
|
3164
3159
|
return new Promise((e) => requestAnimationFrame(() => setTimeout(e, 0)));
|
|
3165
3160
|
}
|
|
3166
|
-
function
|
|
3161
|
+
function bt(e) {
|
|
3167
3162
|
e.preventDefault(), e.stopPropagation();
|
|
3168
3163
|
}
|
|
3169
3164
|
class E {
|
|
@@ -3189,7 +3184,7 @@ class E {
|
|
|
3189
3184
|
handleDrawStroke() {
|
|
3190
3185
|
}
|
|
3191
3186
|
}
|
|
3192
|
-
class
|
|
3187
|
+
class J extends E {
|
|
3193
3188
|
constructor() {
|
|
3194
3189
|
super(...arguments), this.kind = "idle", this.launcherLit = !1, this.acceptsFrustrationPrompt = !0;
|
|
3195
3190
|
}
|
|
@@ -3218,16 +3213,16 @@ class S extends E {
|
|
|
3218
3213
|
// exit: the toolbar and session deliberately outlive this state — they span
|
|
3219
3214
|
// the whole flow and are released by the flow-ending paths, not per mode.
|
|
3220
3215
|
handleEscape(t) {
|
|
3221
|
-
|
|
3216
|
+
bt(t), this.host.exitAll();
|
|
3222
3217
|
}
|
|
3223
3218
|
handleToolbarModeChange(t) {
|
|
3224
|
-
t === "record" ? this.host.transitionTo(new
|
|
3219
|
+
t === "record" ? this.host.transitionTo(new Bt(this.host)) : this.host.transitionTo(new S(this.host));
|
|
3225
3220
|
}
|
|
3226
3221
|
handleDrawStroke() {
|
|
3227
|
-
this.host.transitionTo(new
|
|
3222
|
+
this.host.transitionTo(new Ln(this.host, L() ? "sheet" : "bar"));
|
|
3228
3223
|
}
|
|
3229
3224
|
}
|
|
3230
|
-
class
|
|
3225
|
+
class Bt extends E {
|
|
3231
3226
|
constructor() {
|
|
3232
3227
|
super(...arguments), this.kind = "recording";
|
|
3233
3228
|
}
|
|
@@ -3235,46 +3230,46 @@ class Ht extends E {
|
|
|
3235
3230
|
this.host.clearCurrentAnnotation(), this.host.teardownDrawBar(), this.host.destroySession(), this.host.startRecorder();
|
|
3236
3231
|
}
|
|
3237
3232
|
handleEscape(t) {
|
|
3238
|
-
|
|
3233
|
+
bt(t), this.host.stopRecordingIntoNote();
|
|
3239
3234
|
}
|
|
3240
3235
|
handleToolbarModeChange(t) {
|
|
3241
3236
|
t !== "record" && this.host.transitionTo(new S(this.host));
|
|
3242
3237
|
}
|
|
3243
3238
|
}
|
|
3244
|
-
class
|
|
3239
|
+
class Ln extends E {
|
|
3245
3240
|
// Which note surface collects the drawing's note: the inline bar on a
|
|
3246
3241
|
// desktop, the bottom sheet on touch.
|
|
3247
|
-
constructor(t,
|
|
3248
|
-
super(t), this.surface =
|
|
3242
|
+
constructor(t, i) {
|
|
3243
|
+
super(t), this.surface = i, this.kind = "drawing";
|
|
3249
3244
|
}
|
|
3250
3245
|
enter() {
|
|
3251
3246
|
this.surface === "sheet" ? this.host.mountDrawSheet() : (this.host.mountDrawBar(), this.host.refreshDrawBar());
|
|
3252
3247
|
}
|
|
3253
3248
|
handleEscape(t) {
|
|
3254
|
-
|
|
3249
|
+
bt(t), this.host.cancelDraw();
|
|
3255
3250
|
}
|
|
3256
3251
|
handleToolbarModeChange(t) {
|
|
3257
|
-
t === "record" ? this.host.transitionTo(new
|
|
3252
|
+
t === "record" ? this.host.transitionTo(new Bt(this.host)) : this.host.transitionTo(new S(this.host));
|
|
3258
3253
|
}
|
|
3259
3254
|
handleDrawStroke() {
|
|
3260
3255
|
this.surface === "bar" && this.host.refreshDrawBar();
|
|
3261
3256
|
}
|
|
3262
3257
|
}
|
|
3263
3258
|
class oe extends E {
|
|
3264
|
-
constructor(t,
|
|
3265
|
-
super(t), this.opts =
|
|
3259
|
+
constructor(t, i) {
|
|
3260
|
+
super(t), this.opts = i, this.kind = "popup";
|
|
3266
3261
|
}
|
|
3267
3262
|
enter() {
|
|
3268
3263
|
this.host.mountNotePopup(this.opts);
|
|
3269
3264
|
}
|
|
3270
3265
|
handleEscape(t) {
|
|
3271
|
-
|
|
3266
|
+
bt(t), this.host.exitAll();
|
|
3272
3267
|
}
|
|
3273
3268
|
handleToolbarModeChange(t) {
|
|
3274
|
-
t === "record" ? this.host.transitionTo(new
|
|
3269
|
+
t === "record" ? this.host.transitionTo(new Bt(this.host)) : (this.host.dismissNotePopup(), this.host.transitionTo(new S(this.host)));
|
|
3275
3270
|
}
|
|
3276
3271
|
}
|
|
3277
|
-
class
|
|
3272
|
+
class St extends E {
|
|
3278
3273
|
constructor() {
|
|
3279
3274
|
super(...arguments), this.kind = "clarifying";
|
|
3280
3275
|
}
|
|
@@ -3285,7 +3280,7 @@ class Et extends E {
|
|
|
3285
3280
|
this.host.revertToolbarDuringClarify();
|
|
3286
3281
|
}
|
|
3287
3282
|
}
|
|
3288
|
-
class
|
|
3283
|
+
class Z extends E {
|
|
3289
3284
|
constructor() {
|
|
3290
3285
|
super(...arguments), this.kind = "submitting", this.launcherLit = !1;
|
|
3291
3286
|
}
|
|
@@ -3297,9 +3292,9 @@ class ae extends E {
|
|
|
3297
3292
|
// Escape falls through unconsumed: nothing is on screen to dismiss, and the
|
|
3298
3293
|
// background finalize must not be cancellable by a stray keypress.
|
|
3299
3294
|
}
|
|
3300
|
-
const
|
|
3301
|
-
function
|
|
3302
|
-
return e === void 0 ? void 0 : typeof e != "object" || e === null || ![e.primary, e.hover, e.active, e.onPrimary].every((
|
|
3295
|
+
const Pn = /^#[0-9a-f]{6}$/i;
|
|
3296
|
+
function Rn(e) {
|
|
3297
|
+
return e === void 0 ? void 0 : typeof e != "object" || e === null || ![e.primary, e.hover, e.active, e.onPrimary].every((i) => typeof i == "string" && Pn.test(i)) ? le() : {
|
|
3303
3298
|
primary: e.primary.toLowerCase(),
|
|
3304
3299
|
hover: e.hover.toLowerCase(),
|
|
3305
3300
|
active: e.active.toLowerCase(),
|
|
@@ -3315,22 +3310,22 @@ function ce() {
|
|
|
3315
3310
|
const { hostname: e } = window.location;
|
|
3316
3311
|
return e === "localhost" || e === "127.0.0.1" || e === "[::1]" || e.endsWith(".localhost") || e.endsWith(".local") || e.endsWith(".test");
|
|
3317
3312
|
}
|
|
3318
|
-
class
|
|
3313
|
+
class Dn {
|
|
3319
3314
|
constructor(t) {
|
|
3320
|
-
this.tab = null, this.toolbar = null, this.session = null, this.drawBar = null, this.dim = null, this.pageOffset = new
|
|
3321
|
-
|
|
3315
|
+
this.tab = null, this.toolbar = null, this.session = null, this.drawBar = null, this.dim = null, this.pageOffset = new ai(), this.chatPopup = null, this.scrollLock = null, this.success = null, this.frustrationPrompt = null, this.frustrationDetector = null, this.state = new J(this), this.via = "pin", this.currentAnnotation = null, this.lastPopupPos = null, this.recordingManager = null, this.touchHintShown = !1, this.lastHandoff = {}, this.handleKeydown = (i) => {
|
|
3316
|
+
i.key === "Escape" && (Dt(i) || this.state.handleEscape(i));
|
|
3322
3317
|
}, this.stopRecordingIntoNote = () => {
|
|
3323
3318
|
this.recordingManager && (this.recordingManager.stop(), this.via = "record", this.transitionTo(new oe(this, {
|
|
3324
3319
|
x: window.innerWidth / 2,
|
|
3325
3320
|
y: window.innerHeight / 2,
|
|
3326
3321
|
targetName: this.messages.record.timer_label
|
|
3327
3322
|
})));
|
|
3328
|
-
}, this.config = t, t.projectKey || console.warn("[MakeThisBetter] projectKey is missing. Feedback submission will be rejected."), this.brandColors =
|
|
3323
|
+
}, this.config = t, t.projectKey || console.warn("[MakeThisBetter] projectKey is missing. Feedback submission will be rejected."), this.brandColors = Rn(t.brandColors), this.messages = ie(t.locale ?? document.documentElement.lang ?? "en"), this.apiClient = new Jr({
|
|
3329
3324
|
projectKey: t.projectKey,
|
|
3330
3325
|
apiUrl: t.apiUrl,
|
|
3331
3326
|
userToken: t.userToken,
|
|
3332
3327
|
userTokenFn: t.userTokenFn
|
|
3333
|
-
}), this.consoleCollector = new
|
|
3328
|
+
}), this.consoleCollector = new Cr(), this.consoleCollector.start(), this.breadcrumbCollector = new Rr(), this.breadcrumbCollector.start(), this.lifecycle = new An(
|
|
3334
3329
|
{
|
|
3335
3330
|
apiClient: this.apiClient,
|
|
3336
3331
|
consoleCollector: this.consoleCollector,
|
|
@@ -3342,31 +3337,29 @@ class Mn {
|
|
|
3342
3337
|
},
|
|
3343
3338
|
{
|
|
3344
3339
|
isBackground: () => this.state.kind === "submitting",
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
onReenterBackground: () => this.transitionTo(new ae(this)),
|
|
3349
|
-
onFinalized: (r, i) => this.handleFinalized(r, i)
|
|
3340
|
+
onFinalizeFailure: (i) => this.chatPopup?.showFinalizeFailure(i),
|
|
3341
|
+
onReenterBackground: () => this.transitionTo(new Z(this)),
|
|
3342
|
+
onFinalized: (i, r) => this.handleFinalized(i, r)
|
|
3350
3343
|
}
|
|
3351
3344
|
);
|
|
3352
3345
|
try {
|
|
3353
3346
|
this.buildUI();
|
|
3354
|
-
} catch (
|
|
3355
|
-
this.consoleCollector.stop(), this.breadcrumbCollector.stop(), console.warn("[MakeThisBetter] Widget failed to start:",
|
|
3347
|
+
} catch (i) {
|
|
3348
|
+
this.consoleCollector.stop(), this.breadcrumbCollector.stop(), console.warn("[MakeThisBetter] Widget failed to start:", i);
|
|
3356
3349
|
return;
|
|
3357
3350
|
}
|
|
3358
|
-
t.frustrationDetection !== !1 && (this.frustrationDetector = new
|
|
3351
|
+
t.frustrationDetection !== !1 && (this.frustrationDetector = new Lt(() => this.handleFrustration()), this.frustrationDetector.start()), document.addEventListener("keydown", this.handleKeydown, !0);
|
|
3359
3352
|
}
|
|
3360
3353
|
/**
|
|
3361
3354
|
* The single mutation point of the mode machine: the outgoing state exits,
|
|
3362
3355
|
* the incoming state enters, and the launcher reflects the new mode.
|
|
3363
3356
|
*/
|
|
3364
3357
|
transitionTo(t) {
|
|
3365
|
-
const
|
|
3366
|
-
this.state = t,
|
|
3358
|
+
const i = this.state;
|
|
3359
|
+
this.state = t, i.exit(), t.enter(), this.tab?.setActive(t.launcherLit);
|
|
3367
3360
|
}
|
|
3368
3361
|
buildUI() {
|
|
3369
|
-
if (this.shadow = new
|
|
3362
|
+
if (this.shadow = new Tt(this.config.theme ?? "auto", this.brandColors), this.config.entryMode === "api") {
|
|
3370
3363
|
ce() && console.warn(
|
|
3371
3364
|
'[MakeThisBetter] entryMode: "api" renders no launcher. Call MakeThisBetter.open() from your own UI.'
|
|
3372
3365
|
);
|
|
@@ -3381,7 +3374,7 @@ class Mn {
|
|
|
3381
3374
|
this.mountTab();
|
|
3382
3375
|
}
|
|
3383
3376
|
mountTab() {
|
|
3384
|
-
this.tab || !this.shadow || (this.tab = new
|
|
3377
|
+
this.tab || !this.shadow || (this.tab = new ii(
|
|
3385
3378
|
this.shadow,
|
|
3386
3379
|
this.messages,
|
|
3387
3380
|
this.config.position ?? "right",
|
|
@@ -3406,15 +3399,15 @@ class Mn {
|
|
|
3406
3399
|
// the language they were opened in rather than being re-rendered underneath a
|
|
3407
3400
|
// reporter who may be mid-sentence.
|
|
3408
3401
|
setLocale(t) {
|
|
3409
|
-
this.config.locale = t, this.messages =
|
|
3402
|
+
this.config.locale = t, this.messages = ie(t), this.tab?.setMessages(this.messages);
|
|
3410
3403
|
}
|
|
3411
3404
|
handleFrustration() {
|
|
3412
|
-
!this.state.acceptsFrustrationPrompt || this.frustrationPrompt ||
|
|
3405
|
+
!this.state.acceptsFrustrationPrompt || this.frustrationPrompt || Dr() || (this.frustrationPrompt = new ni(this.shadow, this.messages, {
|
|
3413
3406
|
onTell: () => {
|
|
3414
3407
|
this.dismissFrustrationPrompt(), this.state.handleOpen();
|
|
3415
3408
|
},
|
|
3416
3409
|
onDismiss: () => {
|
|
3417
|
-
|
|
3410
|
+
Mr(), this.dismissFrustrationPrompt();
|
|
3418
3411
|
},
|
|
3419
3412
|
// An unnoticed card is not a refusal, so it must not suppress later
|
|
3420
3413
|
// prompts. The detector's own 60s cooldown does the rate limiting.
|
|
@@ -3431,13 +3424,13 @@ class Mn {
|
|
|
3431
3424
|
return this.toolbar !== null;
|
|
3432
3425
|
}
|
|
3433
3426
|
mountAnnotationChrome() {
|
|
3434
|
-
|
|
3427
|
+
Ft();
|
|
3435
3428
|
const t = L();
|
|
3436
|
-
this.toolbar = new
|
|
3429
|
+
this.toolbar = new ui(
|
|
3437
3430
|
this.shadow,
|
|
3438
3431
|
this.messages,
|
|
3439
3432
|
() => this.exitAll(),
|
|
3440
|
-
(
|
|
3433
|
+
(i) => this.state.handleToolbarModeChange(i),
|
|
3441
3434
|
// The bar stands at whichever edge the tab does. Leaving it pinned right
|
|
3442
3435
|
// while a left-configured tab sat opposite would split the widget across
|
|
3443
3436
|
// both sides of the page.
|
|
@@ -3446,12 +3439,12 @@ class Mn {
|
|
|
3446
3439
|
), t && (this.touchHintShown = !0), this.ensureSession(), t && this.toolbar && this.pageOffset.reserve(this.toolbar.height());
|
|
3447
3440
|
}
|
|
3448
3441
|
ensureSession() {
|
|
3449
|
-
this.session || (this.session = new
|
|
3450
|
-
onPin: (t,
|
|
3442
|
+
this.session || (this.session = new _i(this.shadow, this.messages, {
|
|
3443
|
+
onPin: (t, i) => {
|
|
3451
3444
|
this.currentAnnotation = t, this.via = "pin", this.transitionTo(new oe(this, {
|
|
3452
3445
|
x: t.x,
|
|
3453
3446
|
y: t.y,
|
|
3454
|
-
targetName:
|
|
3447
|
+
targetName: i,
|
|
3455
3448
|
targetRect: t.targetRect
|
|
3456
3449
|
}));
|
|
3457
3450
|
},
|
|
@@ -3477,7 +3470,7 @@ class Mn {
|
|
|
3477
3470
|
this.recordingManager?.destroy(), this.recordingManager = null;
|
|
3478
3471
|
}
|
|
3479
3472
|
mountDrawBar() {
|
|
3480
|
-
this.engageScrollLock(), this.drawBar = new
|
|
3473
|
+
this.engageScrollLock(), this.drawBar = new Di(this.shadow, {
|
|
3481
3474
|
messages: this.messages,
|
|
3482
3475
|
onUndo: () => this.handleDrawUndoRedo("undo"),
|
|
3483
3476
|
onRedo: () => this.handleDrawUndoRedo("redo"),
|
|
@@ -3496,29 +3489,29 @@ class Mn {
|
|
|
3496
3489
|
mountDrawSheet() {
|
|
3497
3490
|
this.engageScrollLock();
|
|
3498
3491
|
let t = !1;
|
|
3499
|
-
this.chatPopup = new
|
|
3492
|
+
this.chatPopup = new wt(this.shadow, {
|
|
3500
3493
|
targetName: this.messages.annotation.drawing,
|
|
3501
3494
|
x: window.innerWidth / 2,
|
|
3502
3495
|
y: window.innerHeight / 2,
|
|
3503
3496
|
messages: this.messages,
|
|
3504
3497
|
position: this.config.position ?? "right",
|
|
3505
|
-
onSubmit: async (
|
|
3506
|
-
const
|
|
3507
|
-
if (!
|
|
3498
|
+
onSubmit: async (i) => {
|
|
3499
|
+
const r = this.session?.getDrawAnnotation();
|
|
3500
|
+
if (!r)
|
|
3508
3501
|
return this.cancelDraw(), null;
|
|
3509
|
-
t = !0, this.currentAnnotation =
|
|
3502
|
+
t = !0, this.currentAnnotation = r, this.via = "draw", this.session?.dismissInteraction(), this.teardownDrawBar();
|
|
3510
3503
|
const n = this.recordingManager?.getRecording() ?? void 0, s = await this.lifecycle.start(
|
|
3511
|
-
|
|
3512
|
-
|
|
3504
|
+
i || this.messages.annotation.drawing,
|
|
3505
|
+
r,
|
|
3513
3506
|
n
|
|
3514
3507
|
);
|
|
3515
3508
|
return s?.board_url && I(s.board_url), s;
|
|
3516
3509
|
},
|
|
3517
|
-
onClarify: async (
|
|
3518
|
-
onAnswer: (
|
|
3519
|
-
onFinalize: () => this.lifecycle.finalize(),
|
|
3510
|
+
onClarify: async (i, r, n, s) => this.apiClient.streamClarification(i, r, n, s),
|
|
3511
|
+
onAnswer: (i, r, n) => this.apiClient.answerClarification(i, r, n),
|
|
3512
|
+
onFinalize: () => (this.transitionTo(new Z(this)), this.lifecycle.finalize()),
|
|
3520
3513
|
onCancel: () => t ? this.exitAll() : this.cancelDraw(),
|
|
3521
|
-
onConversationOpen: () => this.transitionTo(new
|
|
3514
|
+
onConversationOpen: () => this.transitionTo(new St(this)),
|
|
3522
3515
|
onActivity: () => this.lifecycle.warmScreenshotDeps(),
|
|
3523
3516
|
resolveBoardLink: () => this.buildViewFeedbackHandler() ?? this.buildMyFeedbackHandler(),
|
|
3524
3517
|
resolveEmailCapture: () => this.buildEmailCapture()
|
|
@@ -3537,61 +3530,60 @@ class Mn {
|
|
|
3537
3530
|
this.drawBar?.destroy(), this.drawBar = null;
|
|
3538
3531
|
}
|
|
3539
3532
|
handleDrawSubmit(t) {
|
|
3540
|
-
const
|
|
3541
|
-
if (!
|
|
3533
|
+
const i = this.session?.getDrawAnnotation();
|
|
3534
|
+
if (!i) {
|
|
3542
3535
|
this.cancelDraw();
|
|
3543
3536
|
return;
|
|
3544
3537
|
}
|
|
3545
|
-
this.currentAnnotation =
|
|
3546
|
-
const
|
|
3547
|
-
this.teardownDrawBar(), this.releaseScrollLock(), this.dim?.destroy(), this.dim = null, this.mountChatAfterSubmit(
|
|
3538
|
+
this.currentAnnotation = i, this.via = "draw", this.session?.dismissInteraction();
|
|
3539
|
+
const r = t || this.messages.annotation.drawing, n = this.recordingManager?.getRecording() ?? void 0;
|
|
3540
|
+
this.teardownDrawBar(), this.releaseScrollLock(), this.dim?.destroy(), this.dim = null, this.mountChatAfterSubmit(r, i, n);
|
|
3548
3541
|
}
|
|
3549
|
-
mountChatAfterSubmit(t,
|
|
3550
|
-
this.dim = new Ut(this.shadow, () => this.exitAll()), this.engageScrollLock(), this.chatPopup = new
|
|
3551
|
-
targetName:
|
|
3542
|
+
mountChatAfterSubmit(t, i, r) {
|
|
3543
|
+
this.dim = new Ut(this.shadow, () => this.exitAll()), this.engageScrollLock(), this.chatPopup = new wt(this.shadow, {
|
|
3544
|
+
targetName: i?.targetName ?? this.messages.annotation.drawing,
|
|
3552
3545
|
x: this.lastPopupPos?.x ?? window.innerWidth / 2,
|
|
3553
3546
|
y: this.lastPopupPos?.y ?? window.innerHeight / 2,
|
|
3554
3547
|
messages: this.messages,
|
|
3555
3548
|
position: this.config.position ?? "right",
|
|
3556
3549
|
onSubmit: async () => {
|
|
3557
|
-
const n = await this.lifecycle.start(t,
|
|
3550
|
+
const n = await this.lifecycle.start(t, i, r);
|
|
3558
3551
|
return n?.board_url && I(n.board_url), n;
|
|
3559
3552
|
},
|
|
3560
|
-
onClarify: async (n, s,
|
|
3561
|
-
onAnswer: (n, s,
|
|
3562
|
-
onFinalize: () => this.lifecycle.finalize(),
|
|
3553
|
+
onClarify: async (n, s, a, o) => this.apiClient.streamClarification(n, s, a, o),
|
|
3554
|
+
onAnswer: (n, s, a) => this.apiClient.answerClarification(n, s, a),
|
|
3555
|
+
onFinalize: () => (this.transitionTo(new Z(this)), this.lifecycle.finalize()),
|
|
3563
3556
|
onCancel: () => this.exitAll(),
|
|
3564
|
-
onConversationOpen: () => this.transitionTo(new
|
|
3557
|
+
onConversationOpen: () => this.transitionTo(new St(this)),
|
|
3565
3558
|
resolveBoardLink: () => this.buildViewFeedbackHandler() ?? this.buildMyFeedbackHandler(),
|
|
3566
3559
|
resolveEmailCapture: () => this.buildEmailCapture()
|
|
3567
3560
|
}), this.chatPopup.submit(t);
|
|
3568
3561
|
}
|
|
3569
|
-
mountNotePopup({ x: t, y:
|
|
3570
|
-
this.lastPopupPos = { x: t, y:
|
|
3562
|
+
mountNotePopup({ x: t, y: i, targetName: r, targetRect: n }) {
|
|
3563
|
+
this.lastPopupPos = { x: t, y: i }, this.teardownDrawBar(), this.session?.dismissInteraction(), this.chatPopup?.destroy(), this.chatPopup = null, this.dim?.destroy(), this.dim = null, this.dim = new Ut(this.shadow, () => this.exitAll());
|
|
3571
3564
|
const s = this.recordingManager?.getRecording();
|
|
3572
3565
|
s && this.lifecycle.setScreenshotEnabled(!0);
|
|
3573
|
-
const
|
|
3574
|
-
this.chatPopup = new
|
|
3575
|
-
targetName:
|
|
3566
|
+
const a = this.currentAnnotation, o = this.recordingManager?.getRecording() ?? void 0;
|
|
3567
|
+
this.chatPopup = new wt(this.shadow, {
|
|
3568
|
+
targetName: r,
|
|
3576
3569
|
x: t,
|
|
3577
|
-
y:
|
|
3570
|
+
y: i,
|
|
3578
3571
|
targetRect: n,
|
|
3579
3572
|
messages: this.messages,
|
|
3580
3573
|
position: this.config.position ?? "right",
|
|
3581
3574
|
onSubmit: async (l) => {
|
|
3582
|
-
this.currentAnnotation =
|
|
3583
|
-
const c = await this.lifecycle.start(l, this.currentAnnotation,
|
|
3575
|
+
this.currentAnnotation = a ?? this.currentAnnotation;
|
|
3576
|
+
const c = await this.lifecycle.start(l, this.currentAnnotation, o);
|
|
3584
3577
|
return c?.board_url && I(c.board_url), c;
|
|
3585
3578
|
},
|
|
3586
3579
|
onClarify: async (l, c, h, u) => this.apiClient.streamClarification(l, c, h, u),
|
|
3587
3580
|
onAnswer: (l, c, h) => this.apiClient.answerClarification(l, c, h),
|
|
3588
3581
|
// The chat card turns into a receipt at this point: the pin, the scrim
|
|
3589
|
-
// and the scroll lock have nothing left to hold
|
|
3590
|
-
//
|
|
3591
|
-
|
|
3592
|
-
onFinalize: () => (this.teardownSubmittingUi(), this.transitionTo(new ae(this)), this.lifecycle.finalize()),
|
|
3582
|
+
// and the scroll lock have nothing left to hold. A finalization failure
|
|
3583
|
+
// remains in this card as a retryable receipt state.
|
|
3584
|
+
onFinalize: () => (this.teardownSubmittingUi(), this.transitionTo(new Z(this)), this.lifecycle.finalize()),
|
|
3593
3585
|
onCancel: () => this.exitAll(),
|
|
3594
|
-
onConversationOpen: () => this.transitionTo(new
|
|
3586
|
+
onConversationOpen: () => this.transitionTo(new St(this)),
|
|
3595
3587
|
onActivity: () => this.lifecycle.warmScreenshotDeps(),
|
|
3596
3588
|
resolveBoardLink: () => this.buildViewFeedbackHandler() ?? this.buildMyFeedbackHandler(),
|
|
3597
3589
|
resolveEmailCapture: () => this.buildEmailCapture(),
|
|
@@ -3611,7 +3603,7 @@ class Mn {
|
|
|
3611
3603
|
this.chatPopup?.destroy(), this.chatPopup = null, this.dim?.destroy(), this.dim = null, this.releaseScrollLock(), this.clearCurrentAnnotation(), this.destroySession();
|
|
3612
3604
|
}
|
|
3613
3605
|
engageScrollLock() {
|
|
3614
|
-
this.scrollLock || (this.scrollLock =
|
|
3606
|
+
this.scrollLock || (this.scrollLock = hi());
|
|
3615
3607
|
}
|
|
3616
3608
|
releaseScrollLock() {
|
|
3617
3609
|
this.scrollLock?.release(), this.scrollLock = null;
|
|
@@ -3619,7 +3611,7 @@ class Mn {
|
|
|
3619
3611
|
buildMyFeedbackHandler() {
|
|
3620
3612
|
if (!this.config.user && rn())
|
|
3621
3613
|
return async () => {
|
|
3622
|
-
const t = await this.apiClient.createIdentityToken(
|
|
3614
|
+
const t = await this.apiClient.createIdentityToken(ze());
|
|
3623
3615
|
!t?.identity_token || !t.board_url || (I(t.board_url), window.open(`${t.board_url}?identity=${encodeURIComponent(t.identity_token)}`, "_blank"));
|
|
3624
3616
|
};
|
|
3625
3617
|
}
|
|
@@ -3632,47 +3624,47 @@ class Mn {
|
|
|
3632
3624
|
releaseClarifyUi() {
|
|
3633
3625
|
this.teardownToolbar(), this.currentAnnotation = null;
|
|
3634
3626
|
}
|
|
3635
|
-
handleFinalized(t,
|
|
3627
|
+
handleFinalized(t, i) {
|
|
3636
3628
|
if (this.lastHandoff = {
|
|
3637
3629
|
feedbackId: t.id,
|
|
3638
3630
|
boardUrl: t.board_url,
|
|
3639
3631
|
identityToken: t.identity_token
|
|
3640
|
-
}, t.board_url && I(t.board_url), !(this.chatPopup && this.chatPopup.sessionId() !==
|
|
3632
|
+
}, t.board_url && I(t.board_url), !(this.chatPopup && this.chatPopup.sessionId() !== i.id) && !(!this.chatPopup && this.state.kind !== "submitting" && this.state.kind !== "clarifying")) {
|
|
3641
3633
|
if (this.chatPopup) {
|
|
3642
|
-
this.teardownSubmittingUi(), this.teardownToolbar(), this.lifecycle.resetScreenshotConsent(), this.transitionTo(new
|
|
3634
|
+
this.chatPopup.showFinalizeSuccess(), this.teardownSubmittingUi(), this.teardownToolbar(), this.lifecycle.resetScreenshotConsent(), this.transitionTo(new J(this));
|
|
3643
3635
|
return;
|
|
3644
3636
|
}
|
|
3645
|
-
this.teardownToolbar(), this.lifecycle.resetScreenshotConsent(), this.showSuccess({ skipFollowup:
|
|
3637
|
+
this.teardownToolbar(), this.lifecycle.resetScreenshotConsent(), this.showSuccess({ skipFollowup: i.ai_clarify_available === !1 });
|
|
3646
3638
|
}
|
|
3647
3639
|
}
|
|
3648
3640
|
showSuccess(t) {
|
|
3649
|
-
this.
|
|
3641
|
+
this.transitionTo(new J(this)), this.success = new qi(this.shadow, this.messages, () => {
|
|
3650
3642
|
this.success?.destroy(), this.success = null;
|
|
3651
3643
|
}, { ...t, onViewFeedback: this.buildViewFeedbackHandler() });
|
|
3652
3644
|
}
|
|
3653
3645
|
buildEmailCapture() {
|
|
3654
3646
|
if (this.config.user) return;
|
|
3655
|
-
const { feedbackId: t, identityToken:
|
|
3656
|
-
if (!(!t || !
|
|
3647
|
+
const { feedbackId: t, identityToken: i } = this.lastHandoff;
|
|
3648
|
+
if (!(!t || !i) && !$e())
|
|
3657
3649
|
return {
|
|
3658
|
-
onSubmit: async (
|
|
3659
|
-
const n = await this.apiClient.updateReporter(t,
|
|
3660
|
-
return n && en(
|
|
3650
|
+
onSubmit: async (r) => {
|
|
3651
|
+
const n = await this.apiClient.updateReporter(t, r, i);
|
|
3652
|
+
return n && en(r), n;
|
|
3661
3653
|
}
|
|
3662
3654
|
};
|
|
3663
3655
|
}
|
|
3664
3656
|
buildViewFeedbackHandler() {
|
|
3665
|
-
const { boardUrl: t, identityToken:
|
|
3657
|
+
const { boardUrl: t, identityToken: i } = this.lastHandoff;
|
|
3666
3658
|
if (t) {
|
|
3667
|
-
if (
|
|
3659
|
+
if (i)
|
|
3668
3660
|
return () => {
|
|
3669
|
-
window.open(`${t}?identity=${encodeURIComponent(
|
|
3661
|
+
window.open(`${t}?identity=${encodeURIComponent(i)}`, "_blank");
|
|
3670
3662
|
};
|
|
3671
3663
|
if (this.config.userToken || this.config.userTokenFn)
|
|
3672
3664
|
return async () => {
|
|
3673
3665
|
try {
|
|
3674
|
-
const
|
|
3675
|
-
|
|
3666
|
+
const r = await this.apiClient.resolveUserToken();
|
|
3667
|
+
r && window.open(`${t}?identity=${encodeURIComponent(r)}`, "_blank");
|
|
3676
3668
|
} catch {
|
|
3677
3669
|
}
|
|
3678
3670
|
};
|
|
@@ -3688,27 +3680,27 @@ class Mn {
|
|
|
3688
3680
|
this.pageOffset.release(), this.toolbar?.destroy(), this.toolbar = null;
|
|
3689
3681
|
}
|
|
3690
3682
|
exitAll() {
|
|
3691
|
-
this.lifecycle.abandon(), this.via = "pin", this.transitionTo(new
|
|
3683
|
+
this.lifecycle.abandon(), this.via = "pin", this.transitionTo(new J(this)), this.teardownToolbar(), this.teardownDrawBar(), this.releaseScrollLock(), this.session?.hideHighlight(), this.session?.destroy(), this.session = null, this.dim?.destroy(), this.dim = null, this.chatPopup?.destroy(), this.chatPopup = null, this.currentAnnotation = null, this.recordingManager?.destroy(), this.recordingManager = null;
|
|
3692
3684
|
}
|
|
3693
3685
|
destroy() {
|
|
3694
|
-
document.removeEventListener("keydown", this.handleKeydown, !0), this.exitAll(), this.consoleCollector.stop(), this.breadcrumbCollector.stop(), this.frustrationDetector?.stop(), this.dismissFrustrationPrompt(), this.success?.destroy(), this.
|
|
3686
|
+
document.removeEventListener("keydown", this.handleKeydown, !0), this.exitAll(), this.consoleCollector.stop(), this.breadcrumbCollector.stop(), this.frustrationDetector?.stop(), this.dismissFrustrationPrompt(), this.success?.destroy(), this.tab?.destroy(), this.recordingManager?.destroy(), this.shadow?.destroy();
|
|
3695
3687
|
}
|
|
3696
3688
|
}
|
|
3697
3689
|
let x = null, A = null, P = null;
|
|
3698
|
-
function
|
|
3690
|
+
function Mn() {
|
|
3699
3691
|
P && (document.removeEventListener("DOMContentLoaded", P), P = null);
|
|
3700
3692
|
}
|
|
3701
|
-
function
|
|
3702
|
-
|
|
3693
|
+
function B(e) {
|
|
3694
|
+
Mn(), x?.destroy(), x = e ? new Dn(e) : null;
|
|
3703
3695
|
}
|
|
3704
|
-
const
|
|
3696
|
+
const In = {
|
|
3705
3697
|
init(e) {
|
|
3706
|
-
typeof document > "u" || (
|
|
3707
|
-
P = null,
|
|
3708
|
-
}, document.addEventListener("DOMContentLoaded", P, { once: !0 })) :
|
|
3698
|
+
typeof document > "u" || (B(), A = e, document.readyState === "loading" ? (P = () => {
|
|
3699
|
+
P = null, B(e);
|
|
3700
|
+
}, document.addEventListener("DOMContentLoaded", P, { once: !0 })) : B(e));
|
|
3709
3701
|
},
|
|
3710
3702
|
destroy() {
|
|
3711
|
-
|
|
3703
|
+
B(), A = null;
|
|
3712
3704
|
},
|
|
3713
3705
|
setLocale(e) {
|
|
3714
3706
|
A && (A.locale = e), x?.setLocale(e);
|
|
@@ -3732,21 +3724,21 @@ const Fn = {
|
|
|
3732
3724
|
x?.hideLauncher();
|
|
3733
3725
|
}
|
|
3734
3726
|
};
|
|
3735
|
-
typeof window < "u" && (window.MakeThisBetter =
|
|
3727
|
+
typeof window < "u" && (window.MakeThisBetter = In, document.addEventListener("turbo:load", () => {
|
|
3736
3728
|
const e = document.getElementById(k);
|
|
3737
|
-
A && (!e || !e.shadowRoot) && (e?.remove(),
|
|
3729
|
+
A && (!e || !e.shadowRoot) && (e?.remove(), B(A));
|
|
3738
3730
|
}));
|
|
3739
|
-
function
|
|
3731
|
+
function Fn(e, t) {
|
|
3740
3732
|
if (e.match(/^[a-z]+:\/\//i))
|
|
3741
3733
|
return e;
|
|
3742
3734
|
if (e.match(/^\/\//))
|
|
3743
3735
|
return window.location.protocol + e;
|
|
3744
3736
|
if (e.match(/^[a-z]+:/i))
|
|
3745
3737
|
return e;
|
|
3746
|
-
const
|
|
3747
|
-
return
|
|
3738
|
+
const i = document.implementation.createHTMLDocument(), r = i.createElement("base"), n = i.createElement("a");
|
|
3739
|
+
return i.head.appendChild(r), i.body.appendChild(n), t && (r.href = t), n.href = e, n.href;
|
|
3748
3740
|
}
|
|
3749
|
-
const
|
|
3741
|
+
const Hn = /* @__PURE__ */ (() => {
|
|
3750
3742
|
let e = 0;
|
|
3751
3743
|
const t = () => (
|
|
3752
3744
|
// eslint-disable-next-line no-bitwise
|
|
@@ -3756,109 +3748,109 @@ const Bn = /* @__PURE__ */ (() => {
|
|
|
3756
3748
|
})();
|
|
3757
3749
|
function v(e) {
|
|
3758
3750
|
const t = [];
|
|
3759
|
-
for (let
|
|
3760
|
-
t.push(e[
|
|
3751
|
+
for (let i = 0, r = e.length; i < r; i++)
|
|
3752
|
+
t.push(e[i]);
|
|
3761
3753
|
return t;
|
|
3762
3754
|
}
|
|
3763
3755
|
let C = null;
|
|
3764
|
-
function
|
|
3756
|
+
function Ue(e = {}) {
|
|
3765
3757
|
return C || (e.includeStyleProperties ? (C = e.includeStyleProperties, C) : (C = v(window.getComputedStyle(document.documentElement)), C));
|
|
3766
3758
|
}
|
|
3767
|
-
function
|
|
3768
|
-
const
|
|
3769
|
-
return
|
|
3759
|
+
function ht(e, t) {
|
|
3760
|
+
const r = (e.ownerDocument.defaultView || window).getComputedStyle(e).getPropertyValue(t);
|
|
3761
|
+
return r ? parseFloat(r.replace("px", "")) : 0;
|
|
3770
3762
|
}
|
|
3771
|
-
function
|
|
3772
|
-
const t =
|
|
3773
|
-
return e.clientWidth + t +
|
|
3763
|
+
function Bn(e) {
|
|
3764
|
+
const t = ht(e, "border-left-width"), i = ht(e, "border-right-width");
|
|
3765
|
+
return e.clientWidth + t + i;
|
|
3774
3766
|
}
|
|
3775
|
-
function
|
|
3776
|
-
const t =
|
|
3777
|
-
return e.clientHeight + t +
|
|
3767
|
+
function Nn(e) {
|
|
3768
|
+
const t = ht(e, "border-top-width"), i = ht(e, "border-bottom-width");
|
|
3769
|
+
return e.clientHeight + t + i;
|
|
3778
3770
|
}
|
|
3779
|
-
function
|
|
3780
|
-
const
|
|
3781
|
-
return { width:
|
|
3771
|
+
function Nt(e, t = {}) {
|
|
3772
|
+
const i = t.width || Bn(e), r = t.height || Nn(e);
|
|
3773
|
+
return { width: i, height: r };
|
|
3782
3774
|
}
|
|
3783
|
-
function
|
|
3775
|
+
function On() {
|
|
3784
3776
|
let e, t;
|
|
3785
3777
|
try {
|
|
3786
3778
|
t = process;
|
|
3787
3779
|
} catch {
|
|
3788
3780
|
}
|
|
3789
|
-
const
|
|
3790
|
-
return
|
|
3781
|
+
const i = t && t.env ? t.env.devicePixelRatio : null;
|
|
3782
|
+
return i && (e = parseInt(i, 10), Number.isNaN(e) && (e = 1)), e || window.devicePixelRatio || 1;
|
|
3791
3783
|
}
|
|
3792
3784
|
const f = 16384;
|
|
3793
|
-
function
|
|
3785
|
+
function zn(e) {
|
|
3794
3786
|
(e.width > f || e.height > f) && (e.width > f && e.height > f ? e.width > e.height ? (e.height *= f / e.width, e.width = f) : (e.width *= f / e.height, e.height = f) : e.width > f ? (e.height *= f / e.width, e.width = f) : (e.width *= f / e.height, e.height = f));
|
|
3795
3787
|
}
|
|
3796
|
-
function
|
|
3797
|
-
return e.toBlob ? new Promise((
|
|
3798
|
-
e.toBlob(
|
|
3799
|
-
}) : new Promise((
|
|
3800
|
-
const
|
|
3801
|
-
for (let
|
|
3802
|
-
s[
|
|
3803
|
-
|
|
3788
|
+
function $n(e, t = {}) {
|
|
3789
|
+
return e.toBlob ? new Promise((i) => {
|
|
3790
|
+
e.toBlob(i, t.type ? t.type : "image/png", t.quality ? t.quality : 1);
|
|
3791
|
+
}) : new Promise((i) => {
|
|
3792
|
+
const r = window.atob(e.toDataURL(t.type ? t.type : void 0, t.quality ? t.quality : void 0).split(",")[1]), n = r.length, s = new Uint8Array(n);
|
|
3793
|
+
for (let a = 0; a < n; a += 1)
|
|
3794
|
+
s[a] = r.charCodeAt(a);
|
|
3795
|
+
i(new Blob([s], {
|
|
3804
3796
|
type: t.type ? t.type : "image/png"
|
|
3805
3797
|
}));
|
|
3806
3798
|
});
|
|
3807
3799
|
}
|
|
3808
|
-
function
|
|
3809
|
-
return new Promise((t,
|
|
3810
|
-
const
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
requestAnimationFrame(() => t(
|
|
3800
|
+
function dt(e) {
|
|
3801
|
+
return new Promise((t, i) => {
|
|
3802
|
+
const r = new Image();
|
|
3803
|
+
r.onload = () => {
|
|
3804
|
+
r.decode().then(() => {
|
|
3805
|
+
requestAnimationFrame(() => t(r));
|
|
3814
3806
|
});
|
|
3815
|
-
},
|
|
3807
|
+
}, r.onerror = i, r.crossOrigin = "anonymous", r.decoding = "async", r.src = e;
|
|
3816
3808
|
});
|
|
3817
3809
|
}
|
|
3818
|
-
async function
|
|
3810
|
+
async function Un(e) {
|
|
3819
3811
|
return Promise.resolve().then(() => new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then((t) => `data:image/svg+xml;charset=utf-8,${t}`);
|
|
3820
3812
|
}
|
|
3821
|
-
async function
|
|
3822
|
-
const
|
|
3823
|
-
return n.setAttribute("width", `${t}`), n.setAttribute("height", `${
|
|
3813
|
+
async function jn(e, t, i) {
|
|
3814
|
+
const r = "http://www.w3.org/2000/svg", n = document.createElementNS(r, "svg"), s = document.createElementNS(r, "foreignObject");
|
|
3815
|
+
return n.setAttribute("width", `${t}`), n.setAttribute("height", `${i}`), n.setAttribute("viewBox", `0 0 ${t} ${i}`), s.setAttribute("width", "100%"), s.setAttribute("height", "100%"), s.setAttribute("x", "0"), s.setAttribute("y", "0"), s.setAttribute("externalResourcesRequired", "true"), n.appendChild(s), s.appendChild(e), Un(n);
|
|
3824
3816
|
}
|
|
3825
3817
|
const p = (e, t) => {
|
|
3826
3818
|
if (e instanceof t)
|
|
3827
3819
|
return !0;
|
|
3828
|
-
const
|
|
3829
|
-
return
|
|
3820
|
+
const i = Object.getPrototypeOf(e);
|
|
3821
|
+
return i === null ? !1 : i.constructor.name === t.name || p(i, t);
|
|
3830
3822
|
};
|
|
3831
|
-
function
|
|
3823
|
+
function qn(e) {
|
|
3832
3824
|
const t = e.getPropertyValue("content");
|
|
3833
3825
|
return `${e.cssText} content: '${t.replace(/'|"/g, "")}';`;
|
|
3834
3826
|
}
|
|
3835
|
-
function
|
|
3836
|
-
return
|
|
3837
|
-
const
|
|
3838
|
-
return `${
|
|
3827
|
+
function Wn(e, t) {
|
|
3828
|
+
return Ue(t).map((i) => {
|
|
3829
|
+
const r = e.getPropertyValue(i), n = e.getPropertyPriority(i);
|
|
3830
|
+
return `${i}: ${r}${n ? " !important" : ""};`;
|
|
3839
3831
|
}).join(" ");
|
|
3840
3832
|
}
|
|
3841
|
-
function
|
|
3842
|
-
const n = `.${e}:${t}`, s =
|
|
3833
|
+
function Vn(e, t, i, r) {
|
|
3834
|
+
const n = `.${e}:${t}`, s = i.cssText ? qn(i) : Wn(i, r);
|
|
3843
3835
|
return document.createTextNode(`${n}{${s}}`);
|
|
3844
3836
|
}
|
|
3845
|
-
function he(e, t,
|
|
3846
|
-
const n = window.getComputedStyle(e,
|
|
3837
|
+
function he(e, t, i, r) {
|
|
3838
|
+
const n = window.getComputedStyle(e, i), s = n.getPropertyValue("content");
|
|
3847
3839
|
if (s === "" || s === "none")
|
|
3848
3840
|
return;
|
|
3849
|
-
const
|
|
3841
|
+
const a = Hn();
|
|
3850
3842
|
try {
|
|
3851
|
-
t.className = `${t.className} ${
|
|
3843
|
+
t.className = `${t.className} ${a}`;
|
|
3852
3844
|
} catch {
|
|
3853
3845
|
return;
|
|
3854
3846
|
}
|
|
3855
|
-
const
|
|
3856
|
-
|
|
3847
|
+
const o = document.createElement("style");
|
|
3848
|
+
o.appendChild(Vn(a, i, n, r)), t.appendChild(o);
|
|
3857
3849
|
}
|
|
3858
|
-
function
|
|
3859
|
-
he(e, t, ":before",
|
|
3850
|
+
function Yn(e, t, i) {
|
|
3851
|
+
he(e, t, ":before", i), he(e, t, ":after", i);
|
|
3860
3852
|
}
|
|
3861
|
-
const de = "application/font-woff", ue = "image/jpeg",
|
|
3853
|
+
const de = "application/font-woff", ue = "image/jpeg", Xn = {
|
|
3862
3854
|
woff: de,
|
|
3863
3855
|
woff2: de,
|
|
3864
3856
|
ttf: "application/font-truetype",
|
|
@@ -3871,234 +3863,234 @@ const de = "application/font-woff", ue = "image/jpeg", Kn = {
|
|
|
3871
3863
|
svg: "image/svg+xml",
|
|
3872
3864
|
webp: "image/webp"
|
|
3873
3865
|
};
|
|
3874
|
-
function
|
|
3866
|
+
function Kn(e) {
|
|
3875
3867
|
const t = /\.([^./]*?)$/g.exec(e);
|
|
3876
3868
|
return t ? t[1] : "";
|
|
3877
3869
|
}
|
|
3878
|
-
function
|
|
3879
|
-
const t =
|
|
3880
|
-
return
|
|
3870
|
+
function Ot(e) {
|
|
3871
|
+
const t = Kn(e).toLowerCase();
|
|
3872
|
+
return Xn[t] || "";
|
|
3881
3873
|
}
|
|
3882
|
-
function
|
|
3874
|
+
function Gn(e) {
|
|
3883
3875
|
return e.split(/,/)[1];
|
|
3884
3876
|
}
|
|
3885
|
-
function
|
|
3877
|
+
function Rt(e) {
|
|
3886
3878
|
return e.search(/^(data:)/) !== -1;
|
|
3887
3879
|
}
|
|
3888
|
-
function
|
|
3880
|
+
function Jn(e, t) {
|
|
3889
3881
|
return `data:${t};base64,${e}`;
|
|
3890
3882
|
}
|
|
3891
|
-
async function je(e, t,
|
|
3892
|
-
const
|
|
3893
|
-
if (!
|
|
3894
|
-
throw new Error(`Resource "${
|
|
3895
|
-
const n = await
|
|
3896
|
-
return new Promise((s,
|
|
3897
|
-
const
|
|
3898
|
-
|
|
3883
|
+
async function je(e, t, i) {
|
|
3884
|
+
const r = await fetch(e, t);
|
|
3885
|
+
if (!r.ok)
|
|
3886
|
+
throw new Error(`Resource "${r.url}" returned HTTP ${r.status}`);
|
|
3887
|
+
const n = await r.blob();
|
|
3888
|
+
return new Promise((s, a) => {
|
|
3889
|
+
const o = new FileReader();
|
|
3890
|
+
o.onerror = a, o.onloadend = () => {
|
|
3899
3891
|
try {
|
|
3900
|
-
s(
|
|
3892
|
+
s(i({ res: r, result: o.result }));
|
|
3901
3893
|
} catch (l) {
|
|
3902
|
-
|
|
3894
|
+
a(l);
|
|
3903
3895
|
}
|
|
3904
|
-
},
|
|
3896
|
+
}, o.readAsDataURL(n);
|
|
3905
3897
|
});
|
|
3906
3898
|
}
|
|
3907
|
-
const
|
|
3908
|
-
function
|
|
3909
|
-
let
|
|
3910
|
-
return
|
|
3899
|
+
const Ct = {};
|
|
3900
|
+
function Zn(e, t, i) {
|
|
3901
|
+
let r = e.replace(/\?.*/, "");
|
|
3902
|
+
return i && (r = e), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), t ? `[${t}]${r}` : r;
|
|
3911
3903
|
}
|
|
3912
|
-
async function
|
|
3913
|
-
const
|
|
3914
|
-
if (
|
|
3915
|
-
return
|
|
3916
|
-
|
|
3904
|
+
async function zt(e, t, i) {
|
|
3905
|
+
const r = Zn(e, t, i.includeQueryParams);
|
|
3906
|
+
if (Ct[r] != null)
|
|
3907
|
+
return Ct[r];
|
|
3908
|
+
i.cacheBust && (e += (/\?/.test(e) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
|
|
3917
3909
|
let n;
|
|
3918
3910
|
try {
|
|
3919
|
-
const s = (
|
|
3920
|
-
let
|
|
3911
|
+
const s = (o) => je(o, i.fetchRequestInit, ({ res: l, result: c }) => (t || (t = l.headers.get("Content-Type") || ""), Gn(c)));
|
|
3912
|
+
let a;
|
|
3921
3913
|
try {
|
|
3922
|
-
|
|
3923
|
-
} catch (
|
|
3924
|
-
const l = await
|
|
3914
|
+
a = await s(e);
|
|
3915
|
+
} catch (o) {
|
|
3916
|
+
const l = await i.resourceUrlResolver?.(e, t);
|
|
3925
3917
|
if (!l || l === e)
|
|
3926
|
-
throw
|
|
3927
|
-
|
|
3918
|
+
throw o;
|
|
3919
|
+
a = await s(l);
|
|
3928
3920
|
}
|
|
3929
|
-
n =
|
|
3921
|
+
n = Jn(a, t);
|
|
3930
3922
|
} catch (s) {
|
|
3931
|
-
n =
|
|
3932
|
-
let
|
|
3933
|
-
s && (
|
|
3923
|
+
n = i.imagePlaceholder || "";
|
|
3924
|
+
let a = `Failed to fetch resource: ${e}`;
|
|
3925
|
+
s && (a = typeof s == "string" ? s : s.message), a && console.warn(a);
|
|
3934
3926
|
}
|
|
3935
|
-
return
|
|
3927
|
+
return Ct[r] = n, n;
|
|
3936
3928
|
}
|
|
3937
|
-
async function
|
|
3929
|
+
async function Qn(e) {
|
|
3938
3930
|
const t = e.toDataURL();
|
|
3939
|
-
return t === "data:," ? e.cloneNode(!1) :
|
|
3931
|
+
return t === "data:," ? e.cloneNode(!1) : dt(t);
|
|
3940
3932
|
}
|
|
3941
|
-
async function
|
|
3933
|
+
async function ts(e, t) {
|
|
3942
3934
|
if (e.currentSrc) {
|
|
3943
|
-
const s = document.createElement("canvas"),
|
|
3944
|
-
s.width = e.clientWidth, s.height = e.clientHeight,
|
|
3945
|
-
const
|
|
3946
|
-
return
|
|
3935
|
+
const s = document.createElement("canvas"), a = s.getContext("2d");
|
|
3936
|
+
s.width = e.clientWidth, s.height = e.clientHeight, a?.drawImage(e, 0, 0, s.width, s.height);
|
|
3937
|
+
const o = s.toDataURL();
|
|
3938
|
+
return dt(o);
|
|
3947
3939
|
}
|
|
3948
|
-
const
|
|
3949
|
-
return
|
|
3940
|
+
const i = e.poster, r = Ot(i), n = await zt(i, r, t);
|
|
3941
|
+
return dt(n);
|
|
3950
3942
|
}
|
|
3951
|
-
async function
|
|
3952
|
-
var
|
|
3943
|
+
async function es(e, t) {
|
|
3944
|
+
var i;
|
|
3953
3945
|
try {
|
|
3954
|
-
if (!((
|
|
3955
|
-
return await
|
|
3946
|
+
if (!((i = e?.contentDocument) === null || i === void 0) && i.body)
|
|
3947
|
+
return await pt(e.contentDocument.body, t, !0);
|
|
3956
3948
|
} catch {
|
|
3957
3949
|
}
|
|
3958
3950
|
return e.cloneNode(!1);
|
|
3959
3951
|
}
|
|
3960
3952
|
async function is(e, t) {
|
|
3961
|
-
return p(e, HTMLCanvasElement) ?
|
|
3953
|
+
return p(e, HTMLCanvasElement) ? Qn(e) : p(e, HTMLVideoElement) ? ts(e, t) : p(e, HTMLIFrameElement) ? es(e, t) : e.cloneNode(qe(e));
|
|
3962
3954
|
}
|
|
3963
|
-
const
|
|
3964
|
-
async function
|
|
3965
|
-
var
|
|
3955
|
+
const rs = (e) => e.tagName != null && e.tagName.toUpperCase() === "SLOT", qe = (e) => e.tagName != null && e.tagName.toUpperCase() === "SVG";
|
|
3956
|
+
async function ns(e, t, i) {
|
|
3957
|
+
var r, n;
|
|
3966
3958
|
if (qe(t))
|
|
3967
3959
|
return t;
|
|
3968
3960
|
let s = [];
|
|
3969
|
-
return
|
|
3961
|
+
return rs(e) && e.assignedNodes ? s = v(e.assignedNodes()) : p(e, HTMLIFrameElement) && (!((r = e.contentDocument) === null || r === void 0) && r.body) ? s = v(e.contentDocument.body.childNodes) : s = v(((n = e.shadowRoot) !== null && n !== void 0 ? n : e).childNodes), s.length === 0 || p(e, HTMLVideoElement) || await s.reduce((a, o) => a.then(() => pt(o, i)).then((l) => {
|
|
3970
3962
|
l && t.appendChild(l);
|
|
3971
3963
|
}), Promise.resolve()), t;
|
|
3972
3964
|
}
|
|
3973
|
-
function
|
|
3974
|
-
const
|
|
3975
|
-
if (!
|
|
3965
|
+
function ss(e, t, i) {
|
|
3966
|
+
const r = t.style;
|
|
3967
|
+
if (!r)
|
|
3976
3968
|
return;
|
|
3977
3969
|
const n = window.getComputedStyle(e);
|
|
3978
|
-
n.cssText ? (
|
|
3979
|
-
let
|
|
3980
|
-
s === "font-size" &&
|
|
3970
|
+
n.cssText ? (r.cssText = n.cssText, r.transformOrigin = n.transformOrigin) : Ue(i).forEach((s) => {
|
|
3971
|
+
let a = n.getPropertyValue(s);
|
|
3972
|
+
s === "font-size" && a.endsWith("px") && (a = `${Math.floor(parseFloat(a.substring(0, a.length - 2))) - 0.1}px`), p(e, HTMLIFrameElement) && s === "display" && a === "inline" && (a = "block"), s === "d" && t.getAttribute("d") && (a = `path(${t.getAttribute("d")})`), r.setProperty(s, a, n.getPropertyPriority(s));
|
|
3981
3973
|
});
|
|
3982
3974
|
}
|
|
3983
3975
|
function as(e, t) {
|
|
3984
3976
|
p(e, HTMLTextAreaElement) && (t.innerHTML = e.value), p(e, HTMLInputElement) && t.setAttribute("value", e.value);
|
|
3985
3977
|
}
|
|
3986
|
-
function
|
|
3978
|
+
function os(e, t) {
|
|
3987
3979
|
if (p(e, HTMLSelectElement)) {
|
|
3988
|
-
const
|
|
3989
|
-
|
|
3980
|
+
const i = t, r = Array.from(i.children).find((n) => e.value === n.getAttribute("value"));
|
|
3981
|
+
r && r.setAttribute("selected", "");
|
|
3990
3982
|
}
|
|
3991
3983
|
}
|
|
3992
|
-
function
|
|
3993
|
-
return p(t, Element) && (
|
|
3984
|
+
function ls(e, t, i) {
|
|
3985
|
+
return p(t, Element) && (ss(e, t, i), Yn(e, t, i), as(e, t), os(e, t)), t;
|
|
3994
3986
|
}
|
|
3995
|
-
async function
|
|
3996
|
-
const
|
|
3997
|
-
if (
|
|
3987
|
+
async function cs(e, t) {
|
|
3988
|
+
const i = e.querySelectorAll ? e.querySelectorAll("use") : [];
|
|
3989
|
+
if (i.length === 0)
|
|
3998
3990
|
return e;
|
|
3999
|
-
const
|
|
4000
|
-
for (let s = 0; s <
|
|
4001
|
-
const
|
|
4002
|
-
if (
|
|
4003
|
-
const l = e.querySelector(
|
|
4004
|
-
!l && c && !
|
|
3991
|
+
const r = {};
|
|
3992
|
+
for (let s = 0; s < i.length; s++) {
|
|
3993
|
+
const o = i[s].getAttribute("xlink:href");
|
|
3994
|
+
if (o) {
|
|
3995
|
+
const l = e.querySelector(o), c = document.querySelector(o);
|
|
3996
|
+
!l && c && !r[o] && (r[o] = await pt(c, t, !0));
|
|
4005
3997
|
}
|
|
4006
3998
|
}
|
|
4007
|
-
const n = Object.values(
|
|
3999
|
+
const n = Object.values(r);
|
|
4008
4000
|
if (n.length) {
|
|
4009
|
-
const s = "http://www.w3.org/1999/xhtml",
|
|
4010
|
-
|
|
4011
|
-
const
|
|
4012
|
-
|
|
4001
|
+
const s = "http://www.w3.org/1999/xhtml", a = document.createElementNS(s, "svg");
|
|
4002
|
+
a.setAttribute("xmlns", s), a.style.position = "absolute", a.style.width = "0", a.style.height = "0", a.style.overflow = "hidden", a.style.display = "none";
|
|
4003
|
+
const o = document.createElementNS(s, "defs");
|
|
4004
|
+
a.appendChild(o);
|
|
4013
4005
|
for (let l = 0; l < n.length; l++)
|
|
4014
|
-
|
|
4015
|
-
e.appendChild(
|
|
4006
|
+
o.appendChild(n[l]);
|
|
4007
|
+
e.appendChild(a);
|
|
4016
4008
|
}
|
|
4017
4009
|
return e;
|
|
4018
4010
|
}
|
|
4019
|
-
async function
|
|
4020
|
-
return !
|
|
4011
|
+
async function pt(e, t, i) {
|
|
4012
|
+
return !i && t.filter && !t.filter(e) ? null : Promise.resolve(e).then((r) => is(r, t)).then((r) => ns(e, r, t)).then((r) => ls(e, r, t)).then((r) => cs(r, t));
|
|
4021
4013
|
}
|
|
4022
|
-
const We = /url\((['"]?)([^'"]+?)\1\)/g,
|
|
4023
|
-
function
|
|
4014
|
+
const We = /url\((['"]?)([^'"]+?)\1\)/g, hs = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, ds = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
|
|
4015
|
+
function us(e) {
|
|
4024
4016
|
const t = e.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
|
|
4025
4017
|
return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`, "g");
|
|
4026
4018
|
}
|
|
4027
|
-
function
|
|
4019
|
+
function ms(e) {
|
|
4028
4020
|
const t = [];
|
|
4029
|
-
return e.replace(We, (
|
|
4021
|
+
return e.replace(We, (i, r, n) => (t.push(n), i)), t.filter((i) => !Rt(i));
|
|
4030
4022
|
}
|
|
4031
|
-
async function
|
|
4023
|
+
async function bs(e, t, i, r, n) {
|
|
4032
4024
|
try {
|
|
4033
|
-
const s =
|
|
4034
|
-
let
|
|
4035
|
-
return n || (
|
|
4025
|
+
const s = i ? Fn(t, i) : t, a = Ot(t);
|
|
4026
|
+
let o;
|
|
4027
|
+
return n || (o = await zt(s, a, r)), e.replace(us(t), `$1${o}$3`);
|
|
4036
4028
|
} catch {
|
|
4037
4029
|
}
|
|
4038
4030
|
return e;
|
|
4039
4031
|
}
|
|
4040
|
-
function
|
|
4041
|
-
return t ? e.replace(
|
|
4032
|
+
function ps(e, { preferredFontFormat: t }) {
|
|
4033
|
+
return t ? e.replace(ds, (i) => {
|
|
4042
4034
|
for (; ; ) {
|
|
4043
|
-
const [
|
|
4035
|
+
const [r, , n] = hs.exec(i) || [];
|
|
4044
4036
|
if (!n)
|
|
4045
4037
|
return "";
|
|
4046
4038
|
if (n === t)
|
|
4047
|
-
return `src: ${
|
|
4039
|
+
return `src: ${r};`;
|
|
4048
4040
|
}
|
|
4049
4041
|
}) : e;
|
|
4050
4042
|
}
|
|
4051
4043
|
function Ve(e) {
|
|
4052
4044
|
return e.search(We) !== -1;
|
|
4053
4045
|
}
|
|
4054
|
-
async function Ye(e, t,
|
|
4046
|
+
async function Ye(e, t, i) {
|
|
4055
4047
|
if (!Ve(e))
|
|
4056
4048
|
return e;
|
|
4057
|
-
const
|
|
4058
|
-
return
|
|
4049
|
+
const r = ps(e, i);
|
|
4050
|
+
return ms(r).reduce((s, a) => s.then((o) => bs(o, a, t, i)), Promise.resolve(r));
|
|
4059
4051
|
}
|
|
4060
|
-
async function T(e, t,
|
|
4061
|
-
var
|
|
4062
|
-
const n = (
|
|
4052
|
+
async function T(e, t, i) {
|
|
4053
|
+
var r;
|
|
4054
|
+
const n = (r = t.style) === null || r === void 0 ? void 0 : r.getPropertyValue(e);
|
|
4063
4055
|
if (n) {
|
|
4064
|
-
const s = await Ye(n, null,
|
|
4056
|
+
const s = await Ye(n, null, i);
|
|
4065
4057
|
return t.style.setProperty(e, s, t.style.getPropertyPriority(e)), !0;
|
|
4066
4058
|
}
|
|
4067
4059
|
return !1;
|
|
4068
4060
|
}
|
|
4069
|
-
async function
|
|
4061
|
+
async function fs(e, t) {
|
|
4070
4062
|
await T("background", e, t) || await T("background-image", e, t), await T("mask", e, t) || await T("-webkit-mask", e, t) || await T("mask-image", e, t) || await T("-webkit-mask-image", e, t);
|
|
4071
4063
|
}
|
|
4072
|
-
async function
|
|
4073
|
-
const
|
|
4074
|
-
if (!(
|
|
4064
|
+
async function gs(e, t) {
|
|
4065
|
+
const i = p(e, HTMLImageElement);
|
|
4066
|
+
if (!(i && !Rt(e.src)) && !(p(e, SVGImageElement) && !Rt(e.href.baseVal)))
|
|
4075
4067
|
return;
|
|
4076
|
-
const
|
|
4077
|
-
await new Promise((s,
|
|
4068
|
+
const r = i ? e.src : e.href.baseVal, n = await zt(r, Ot(r), t);
|
|
4069
|
+
await new Promise((s, a) => {
|
|
4078
4070
|
e.onload = s, e.onerror = t.onImageErrorHandler ? (...l) => {
|
|
4079
4071
|
try {
|
|
4080
4072
|
s(t.onImageErrorHandler(...l));
|
|
4081
4073
|
} catch (c) {
|
|
4082
|
-
|
|
4074
|
+
a(c);
|
|
4083
4075
|
}
|
|
4084
|
-
} :
|
|
4085
|
-
const
|
|
4086
|
-
|
|
4076
|
+
} : a;
|
|
4077
|
+
const o = e;
|
|
4078
|
+
o.decode && (o.decode = s), o.loading === "lazy" && (o.loading = "eager"), i ? (e.srcset = "", e.src = n) : e.href.baseVal = n;
|
|
4087
4079
|
});
|
|
4088
4080
|
}
|
|
4089
4081
|
async function ws(e, t) {
|
|
4090
|
-
const
|
|
4091
|
-
await Promise.all(
|
|
4082
|
+
const r = v(e.childNodes).map((n) => Xe(n, t));
|
|
4083
|
+
await Promise.all(r).then(() => e);
|
|
4092
4084
|
}
|
|
4093
4085
|
async function Xe(e, t) {
|
|
4094
|
-
p(e, Element) && (await
|
|
4095
|
-
}
|
|
4096
|
-
function
|
|
4097
|
-
const { style:
|
|
4098
|
-
t.backgroundColor && (
|
|
4099
|
-
const
|
|
4100
|
-
return
|
|
4101
|
-
|
|
4086
|
+
p(e, Element) && (await fs(e, t), await gs(e, t), await ws(e, t));
|
|
4087
|
+
}
|
|
4088
|
+
function ys(e, t) {
|
|
4089
|
+
const { style: i } = e;
|
|
4090
|
+
t.backgroundColor && (i.backgroundColor = t.backgroundColor), t.width && (i.width = `${t.width}px`), t.height && (i.height = `${t.height}px`);
|
|
4091
|
+
const r = t.style;
|
|
4092
|
+
return r != null && Object.keys(r).forEach((n) => {
|
|
4093
|
+
i[n] = r[n];
|
|
4102
4094
|
}), e;
|
|
4103
4095
|
}
|
|
4104
4096
|
const me = {};
|
|
@@ -4106,54 +4098,54 @@ async function be(e) {
|
|
|
4106
4098
|
let t = me[e];
|
|
4107
4099
|
if (t != null)
|
|
4108
4100
|
return t;
|
|
4109
|
-
const
|
|
4110
|
-
return t = { url: e, cssText:
|
|
4101
|
+
const r = await (await fetch(e)).text();
|
|
4102
|
+
return t = { url: e, cssText: r }, me[e] = t, t;
|
|
4111
4103
|
}
|
|
4112
4104
|
async function pe(e, t) {
|
|
4113
|
-
let
|
|
4114
|
-
const
|
|
4115
|
-
let
|
|
4116
|
-
return
|
|
4105
|
+
let i = e.cssText;
|
|
4106
|
+
const r = /url\(["']?([^"')]+)["']?\)/g, s = (i.match(/url\([^)]+\)/g) || []).map(async (a) => {
|
|
4107
|
+
let o = a.replace(r, "$1");
|
|
4108
|
+
return o.startsWith("https://") || (o = new URL(o, e.url).href), je(o, t.fetchRequestInit, ({ result: l }) => (i = i.replace(a, `url(${l})`), [a, l]));
|
|
4117
4109
|
});
|
|
4118
|
-
return Promise.all(s).then(() =>
|
|
4110
|
+
return Promise.all(s).then(() => i);
|
|
4119
4111
|
}
|
|
4120
4112
|
function fe(e) {
|
|
4121
4113
|
if (e == null)
|
|
4122
4114
|
return [];
|
|
4123
|
-
const t = [],
|
|
4124
|
-
let
|
|
4115
|
+
const t = [], i = /(\/\*[\s\S]*?\*\/)/gi;
|
|
4116
|
+
let r = e.replace(i, "");
|
|
4125
4117
|
const n = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi");
|
|
4126
4118
|
for (; ; ) {
|
|
4127
|
-
const l = n.exec(
|
|
4119
|
+
const l = n.exec(r);
|
|
4128
4120
|
if (l === null)
|
|
4129
4121
|
break;
|
|
4130
4122
|
t.push(l[0]);
|
|
4131
4123
|
}
|
|
4132
|
-
|
|
4133
|
-
const s = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,
|
|
4124
|
+
r = r.replace(n, "");
|
|
4125
|
+
const s = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, a = "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", o = new RegExp(a, "gi");
|
|
4134
4126
|
for (; ; ) {
|
|
4135
|
-
let l = s.exec(
|
|
4127
|
+
let l = s.exec(r);
|
|
4136
4128
|
if (l === null) {
|
|
4137
|
-
if (l =
|
|
4129
|
+
if (l = o.exec(r), l === null)
|
|
4138
4130
|
break;
|
|
4139
|
-
s.lastIndex =
|
|
4131
|
+
s.lastIndex = o.lastIndex;
|
|
4140
4132
|
} else
|
|
4141
|
-
|
|
4133
|
+
o.lastIndex = s.lastIndex;
|
|
4142
4134
|
t.push(l[0]);
|
|
4143
4135
|
}
|
|
4144
4136
|
return t;
|
|
4145
4137
|
}
|
|
4146
|
-
async function
|
|
4147
|
-
const
|
|
4138
|
+
async function vs(e, t) {
|
|
4139
|
+
const i = [], r = [];
|
|
4148
4140
|
return e.forEach((n) => {
|
|
4149
4141
|
if ("cssRules" in n)
|
|
4150
4142
|
try {
|
|
4151
|
-
v(n.cssRules || []).forEach((s,
|
|
4143
|
+
v(n.cssRules || []).forEach((s, a) => {
|
|
4152
4144
|
if (s.type === CSSRule.IMPORT_RULE) {
|
|
4153
|
-
let
|
|
4145
|
+
let o = a + 1;
|
|
4154
4146
|
const l = s.href, c = be(l).then((h) => pe(h, t)).then((h) => fe(h).forEach((u) => {
|
|
4155
4147
|
try {
|
|
4156
|
-
n.insertRule(u, u.startsWith("@import") ?
|
|
4148
|
+
n.insertRule(u, u.startsWith("@import") ? o += 1 : n.cssRules.length);
|
|
4157
4149
|
} catch (m) {
|
|
4158
4150
|
console.error("Error inserting rule from remote css", {
|
|
4159
4151
|
rule: u,
|
|
@@ -4163,102 +4155,102 @@ async function xs(e, t) {
|
|
|
4163
4155
|
})).catch((h) => {
|
|
4164
4156
|
console.error("Error loading remote css", h.toString());
|
|
4165
4157
|
});
|
|
4166
|
-
|
|
4158
|
+
r.push(c);
|
|
4167
4159
|
}
|
|
4168
4160
|
});
|
|
4169
4161
|
} catch (s) {
|
|
4170
|
-
const
|
|
4171
|
-
n.href != null &&
|
|
4172
|
-
|
|
4173
|
-
})).catch((
|
|
4174
|
-
console.error("Error loading remote stylesheet",
|
|
4162
|
+
const a = e.find((o) => o.href == null) || document.styleSheets[0];
|
|
4163
|
+
n.href != null && r.push(be(n.href).then((o) => pe(o, t)).then((o) => fe(o).forEach((l) => {
|
|
4164
|
+
a.insertRule(l, a.cssRules.length);
|
|
4165
|
+
})).catch((o) => {
|
|
4166
|
+
console.error("Error loading remote stylesheet", o);
|
|
4175
4167
|
})), console.error("Error inlining remote css file", s);
|
|
4176
4168
|
}
|
|
4177
|
-
}), Promise.all(
|
|
4169
|
+
}), Promise.all(r).then(() => (e.forEach((n) => {
|
|
4178
4170
|
if ("cssRules" in n)
|
|
4179
4171
|
try {
|
|
4180
4172
|
v(n.cssRules || []).forEach((s) => {
|
|
4181
|
-
|
|
4173
|
+
i.push(s);
|
|
4182
4174
|
});
|
|
4183
4175
|
} catch (s) {
|
|
4184
4176
|
console.error(`Error while reading CSS rules from ${n.href}`, s);
|
|
4185
4177
|
}
|
|
4186
|
-
}),
|
|
4178
|
+
}), i));
|
|
4187
4179
|
}
|
|
4188
|
-
function
|
|
4180
|
+
function xs(e) {
|
|
4189
4181
|
return e.filter((t) => t.type === CSSRule.FONT_FACE_RULE).filter((t) => Ve(t.style.getPropertyValue("src")));
|
|
4190
4182
|
}
|
|
4191
|
-
async function
|
|
4183
|
+
async function ks(e, t) {
|
|
4192
4184
|
if (e.ownerDocument == null)
|
|
4193
4185
|
throw new Error("Provided element is not within a Document");
|
|
4194
|
-
const
|
|
4195
|
-
return
|
|
4186
|
+
const i = v(e.ownerDocument.styleSheets), r = await vs(i, t);
|
|
4187
|
+
return xs(r);
|
|
4196
4188
|
}
|
|
4197
4189
|
function Ke(e) {
|
|
4198
4190
|
return e.trim().replace(/["']/g, "");
|
|
4199
4191
|
}
|
|
4200
|
-
function
|
|
4192
|
+
function Es(e) {
|
|
4201
4193
|
const t = /* @__PURE__ */ new Set();
|
|
4202
|
-
function r
|
|
4203
|
-
(
|
|
4194
|
+
function i(r) {
|
|
4195
|
+
(r.style.fontFamily || getComputedStyle(r).fontFamily).split(",").forEach((s) => {
|
|
4204
4196
|
t.add(Ke(s));
|
|
4205
|
-
}), Array.from(
|
|
4206
|
-
s instanceof HTMLElement &&
|
|
4197
|
+
}), Array.from(r.children).forEach((s) => {
|
|
4198
|
+
s instanceof HTMLElement && i(s);
|
|
4207
4199
|
});
|
|
4208
4200
|
}
|
|
4209
|
-
return
|
|
4201
|
+
return i(e), t;
|
|
4210
4202
|
}
|
|
4211
4203
|
async function Ge(e, t) {
|
|
4212
|
-
const
|
|
4213
|
-
return (await Promise.all(
|
|
4214
|
-
const
|
|
4215
|
-
return Ye(s.cssText,
|
|
4204
|
+
const i = await ks(e, t), r = Es(e);
|
|
4205
|
+
return (await Promise.all(i.filter((s) => r.has(Ke(s.style.fontFamily))).map((s) => {
|
|
4206
|
+
const a = s.parentStyleSheet ? s.parentStyleSheet.href : null;
|
|
4207
|
+
return Ye(s.cssText, a, t);
|
|
4216
4208
|
}))).join(`
|
|
4217
4209
|
`);
|
|
4218
4210
|
}
|
|
4219
|
-
async function
|
|
4220
|
-
const
|
|
4221
|
-
if (
|
|
4222
|
-
const
|
|
4223
|
-
|
|
4211
|
+
async function Ss(e, t) {
|
|
4212
|
+
const i = t.fontEmbedCSS != null ? t.fontEmbedCSS : t.skipFonts ? null : await Ge(e, t);
|
|
4213
|
+
if (i) {
|
|
4214
|
+
const r = document.createElement("style"), n = document.createTextNode(i);
|
|
4215
|
+
r.appendChild(n), e.firstChild ? e.insertBefore(r, e.firstChild) : e.appendChild(r);
|
|
4224
4216
|
}
|
|
4225
4217
|
}
|
|
4226
4218
|
async function Je(e, t = {}) {
|
|
4227
|
-
const { width:
|
|
4228
|
-
return await
|
|
4219
|
+
const { width: i, height: r } = Nt(e, t), n = await pt(e, t, !0);
|
|
4220
|
+
return await Ss(n, t), await Xe(n, t), ys(n, t), await jn(n, i, r);
|
|
4221
|
+
}
|
|
4222
|
+
async function X(e, t = {}) {
|
|
4223
|
+
const { width: i, height: r } = Nt(e, t), n = await Je(e, t), s = await dt(n), a = document.createElement("canvas"), o = a.getContext("2d"), l = t.pixelRatio || On(), c = t.canvasWidth || i, h = t.canvasHeight || r;
|
|
4224
|
+
return a.width = c * l, a.height = h * l, t.skipAutoScale || zn(a), a.style.width = `${c}`, a.style.height = `${h}`, t.backgroundColor && (o.fillStyle = t.backgroundColor, o.fillRect(0, 0, a.width, a.height)), o.drawImage(s, 0, 0, a.width, a.height), a;
|
|
4229
4225
|
}
|
|
4230
|
-
async function
|
|
4231
|
-
const { width:
|
|
4232
|
-
return
|
|
4226
|
+
async function Cs(e, t = {}) {
|
|
4227
|
+
const { width: i, height: r } = Nt(e, t);
|
|
4228
|
+
return (await X(e, t)).getContext("2d").getImageData(0, 0, i, r).data;
|
|
4233
4229
|
}
|
|
4234
4230
|
async function Ts(e, t = {}) {
|
|
4235
|
-
|
|
4236
|
-
return (await K(e, t)).getContext("2d").getImageData(0, 0, r, i).data;
|
|
4231
|
+
return (await X(e, t)).toDataURL();
|
|
4237
4232
|
}
|
|
4238
4233
|
async function _s(e, t = {}) {
|
|
4239
|
-
return (await
|
|
4234
|
+
return (await X(e, t)).toDataURL("image/jpeg", t.quality || 1);
|
|
4240
4235
|
}
|
|
4241
4236
|
async function As(e, t = {}) {
|
|
4242
|
-
|
|
4237
|
+
const i = await X(e, t);
|
|
4238
|
+
return await $n(i);
|
|
4243
4239
|
}
|
|
4244
4240
|
async function Ls(e, t = {}) {
|
|
4245
|
-
const r = await K(e, t);
|
|
4246
|
-
return await zn(r);
|
|
4247
|
-
}
|
|
4248
|
-
async function Ps(e, t = {}) {
|
|
4249
4241
|
return Ge(e, t);
|
|
4250
4242
|
}
|
|
4251
|
-
const
|
|
4243
|
+
const Ps = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4252
4244
|
__proto__: null,
|
|
4253
|
-
getFontEmbedCSS:
|
|
4254
|
-
toBlob:
|
|
4255
|
-
toCanvas:
|
|
4256
|
-
toJpeg:
|
|
4257
|
-
toPixelData:
|
|
4258
|
-
toPng:
|
|
4245
|
+
getFontEmbedCSS: Ls,
|
|
4246
|
+
toBlob: As,
|
|
4247
|
+
toCanvas: X,
|
|
4248
|
+
toJpeg: _s,
|
|
4249
|
+
toPixelData: Cs,
|
|
4250
|
+
toPng: Ts,
|
|
4259
4251
|
toSvg: Je
|
|
4260
4252
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
4261
4253
|
export {
|
|
4262
|
-
|
|
4254
|
+
In as MakeThisBetter
|
|
4263
4255
|
};
|
|
4264
4256
|
//# sourceMappingURL=makethisbetter.standalone.js.map
|