@sphoro/bugcatch-web-sdk 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -1
- package/dist/bugcatch-call.umd.js +1 -1
- package/dist/bugcatch-core.es.js +652 -497
- package/dist/bugcatch-core.es.js.map +1 -1
- package/dist/bugcatch-panel.es.js +1307 -964
- package/dist/bugcatch-panel.es.js.map +1 -1
- package/dist/bugcatch-panel.umd.js +291 -158
- package/dist/bugcatch-panel.umd.js.map +1 -1
- package/dist/bugcatch.standalone.umd.js +284 -151
- package/dist/bugcatch.standalone.umd.js.map +1 -1
- package/dist/bugcatch.umd.js +8 -8
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/feedback.js +94 -0
- package/src/identity.js +1 -1
- package/src/index.d.ts +65 -6
- package/src/index.js +111 -7
- package/src/panel/call.js +3 -2
- package/src/panel/compose.js +8 -4
- package/src/panel/feedback.js +205 -0
- package/src/panel/icons.js +6 -0
- package/src/panel/index.js +91 -12
- package/src/panel/rate-due.js +155 -0
- package/src/panel/rating.js +87 -0
- package/src/panel/signin.js +1 -1
- package/src/panel/styles.js +75 -0
- package/src/panel/thread.js +3 -72
- package/src/widget.js +14 -1
package/dist/bugcatch.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(v,$){typeof exports=="object"&&typeof module<"u"?module.exports=$():typeof define=="function"&&define.amd?define($):(v=typeof globalThis<"u"?globalThis:v||self,v.BugCatch=$())})(this,function(){"use strict";var pt=v=>{throw TypeError(v)};var uo=(v,$,U)=>$.has(v)||pt("Cannot "+U);var gt=(v,$,U)=>$.has(v)?pt("Cannot add the same private member more than once"):$ instanceof WeakSet?$.add(v):$.set(v,U);var m=(v,$,U)=>(uo(v,$,"access private method"),U);var d,ne,mt,K,wt,ke,oe,ie,ve,bt,yt,xt,re,kt;const v="[REDACTED]",$=new Set(["auth","bearer","session","sid","phpsessid","otp","pass","passwd","pwd","sig","codeverifier"]),U=["token","secret","password","passwd","apikey","signature","credential","sessionid","privatekey","accesskey","authorization"],vt=new Set(["key","code","state","nonce","salt","hash"]),Ce=[/eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]+/g,/(?:AKIA|ASIA|AROA|AIDA|AGPA|ANPA|ANVA|APKA)[0-9A-Z]{16}/g,/AIza[\w-]{35}/g,/gh[pousr]_[A-Za-z0-9]{36,}/g,/github_pat_\w{22,}/g,/[sprk]k_(?:live|test)_[0-9A-Za-z]{10,}/g,/xox[abposr]-[A-Za-z0-9-]{10,}/g,/sk-ant-[\w-]{20,}/g,/sk-[\w-]{20,}/g,/glpat-[\w-]{20,}/g,/shp(?:at|ss|ca|pa)_[A-Za-z0-9]{32}/g],Ct=/\bBearer\s+[\w.~+/=-]{8,}/gi,It=/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;function Ie(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch{return t}}function St(t){return Ie(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function $t(t){return t.length>=20?!0:Ce.some(e=>(e.lastIndex=0,e.test(t)))}function Bt(t,e){const n=St(t);if(!n)return!1;if($.has(n))return!0;for(const o of U)if(n.includes(o))return!0;return vt.has(n)?$t(Ie(e)):!1}function se(t){return t.split("&").map(e=>{const n=e.indexOf("=");if(n===-1)return e;const o=e.slice(0,n),s=e.slice(n+1);return s&&Bt(o,s)?`${o}=${v}`:e}).join("&")}function Se(t){let e=t;for(const n of Ce)n.lastIndex=0,e=e.replace(n,v);return e}function $e(t){if(t==null)return t;let e=String(t);if(!e)return e;e=e.replace(It,`$1${v}@`);const n=e.indexOf("#");let o=n===-1?e:e.slice(0,n),s=n===-1?"":e.slice(n);const i=o.indexOf("?");if(i!==-1&&(o=o.slice(0,i+1)+se(o.slice(i+1))),s.length>1){const r=s.slice(1),a=r.indexOf("?");a!==-1?s=`#${r.slice(0,a+1)}${se(r.slice(a+1))}`:r.includes("=")&&(s=`#${se(r)}`)}return Se(o+s)}function Et(t){if(t==null)return t;let e=String(t);return e&&(e=e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g,n=>$e(n)),e=e.replace(Ct,`Bearer ${v}`),Se(e))}function W(t){const e=[];return{push(n){e.push(n),e.length>t&&e.splice(0,e.length-t)},all:()=>e.slice(),clear:()=>{e.length=0},get size(){return e.length}}}const Be=["log","info","warn","error","debug"];function Tt(t,{levels:e=["warn","error","log","info"]}={}){const n={};for(const o of Be)n[o]=console[o],e.includes(o)&&(console[o]=(...s)=>{try{t.push({level:o,text:s.map(Ae).join(" ").slice(0,2e3),at:new Date().toISOString()})}catch{}n[o].apply(console,s)});return()=>{for(const o of Be)console[o]=n[o]}}function At(t,{slowMs:e=2e3}={}){const n=window.fetch,o=XMLHttpRequest.prototype.open,s=XMLHttpRequest.prototype.send;return n&&(window.fetch=async function(...r){var h,u,B;const a=performance.now(),c=typeof r[0]=="string"?r[0]:(h=r[0])==null?void 0:h.url,l=((u=r[1])==null?void 0:u.method)||(typeof r[0]=="object"?(B=r[0])==null?void 0:B.method:"GET")||"GET";try{const y=await n.apply(this,r);return ae(t,{url:c,method:l,status:y.status,ms:Math.round(performance.now()-a),slowMs:e}),y}catch(y){throw ae(t,{url:c,method:l,status:0,error:String((y==null?void 0:y.message)||y),ms:Math.round(performance.now()-a),slowMs:e}),y}}),XMLHttpRequest.prototype.open=function(r,a,...c){return this.__bc={method:r,url:a,started:0},o.call(this,r,a,...c)},XMLHttpRequest.prototype.send=function(...r){return this.__bc&&(this.__bc.started=performance.now(),this.addEventListener("loadend",()=>{ae(t,{url:this.__bc.url,method:this.__bc.method,status:this.status,ms:Math.round(performance.now()-this.__bc.started),slowMs:e})})),s.apply(this,r)},()=>{n&&(window.fetch=n),XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=s}}function ae(t,{url:e,method:n,status:o,ms:s,error:i,slowMs:r}){try{t.push({url:$e(String(e)).slice(0,500),method:n,status:o,ms:s,error:i===void 0?void 0:Et(i),failed:o===0||o>=400,slow:s>=r,at:new Date().toISOString()})}catch{}}function jt(t){const e=o=>{const s=String(o.message||"Error"),i=o.filename?` (${o.filename}:${o.lineno}:${o.colno})`:"";t.push({level:"error",text:(/^uncaught/i.test(s)?s:`Uncaught ${s}`)+i,at:new Date().toISOString()})},n=o=>{t.push({level:"error",text:`Unhandled rejection: ${Ae(o.reason)}`,at:new Date().toISOString()})};return window.addEventListener("error",e),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",e),window.removeEventListener("unhandledrejection",n)}}async function Ee(){const t=Te();try{if(navigator.getBattery){const e=await navigator.getBattery();t.battery=Math.round(e.level*100),t.charging=e.charging}}catch{}return t}function Te(){var e,n,o,s,i,r,a,c,l;const t=window.navigator||{};return{userAgent:t.userAgent,platform:t.platform,language:t.language,languages:t.languages?[...t.languages]:null,online:t.onLine,cookieEnabled:t.cookieEnabled,maxTouchPoints:t.maxTouchPoints??null,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:(e=window.screen)==null?void 0:e.width,height:(n=window.screen)==null?void 0:n.height,availWidth:(o=window.screen)==null?void 0:o.availWidth,availHeight:(s=window.screen)==null?void 0:s.availHeight,colorDepth:(i=window.screen)==null?void 0:i.colorDepth,orientation:((a=(r=window.screen)==null?void 0:r.orientation)==null?void 0:a.type)||null},devicePixelRatio:window.devicePixelRatio,referrer:document.referrer||null,title:document.title,capturedAt:new Date().toISOString(),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timezoneOffsetMinutes:new Date().getTimezoneOffset(),browserMode:t.webdriver?"Automated":"Normal",doNotTrack:t.doNotTrack||null,hardwareConcurrency:t.hardwareConcurrency??null,deviceMemory:t.deviceMemory??null,connection:t.connection?{effectiveType:t.connection.effectiveType,downlink:t.connection.downlink,rtt:t.connection.rtt,saveData:t.connection.saveData}:null,prefersColorScheme:(c=window.matchMedia)!=null&&c.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light",prefersReducedMotion:((l=window.matchMedia)==null?void 0:l.call(window,"(prefers-reduced-motion: reduce)").matches)||!1}}function Ae(t){if(typeof t=="string")return t;if(t instanceof Error)return`${t.name}: ${t.message}`;try{return JSON.stringify(t)}catch{return String(t)}}const Ot='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9.5l6 6 6-6"/></svg>',Lt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',Rt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',Mt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',je='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',Oe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',Kt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',Le='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>',Ut='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>',ce="0.19.0",Nt="__bugcatchChunks",Pt=t=>`${t}@${ce}`;function Re(t){var e;return typeof window<"u"?(e=window[Nt])==null?void 0:e[Pt(t)]:void 0}function le(t,e){return console.warn(`[BugCatch] ${t}`),new Error("[BugCatch] part of the widget could not be loaded — check the connection and try again.")}function Me(t){let e=null;return(...n)=>(e||(e=t(...n).catch(o=>{throw e=null,o})),e)}const E=typeof document<"u"?document.currentScript:null,_t=(E==null?void 0:E.src)||null,Ke=(E==null?void 0:E.nonce)||"",Ue=(E==null?void 0:E.getAttribute("crossorigin"))??null,Ne=(E==null?void 0:E.referrerPolicy)||"";function Dt({chunkBase:t,loadedFrom:e,baseURI:n}){if(t)return new URL(String(t).replace(/\/*$/,"/"),n).href;if(!e)return null;const o=new URL(e);return/\.js$/i.test(o.pathname)?new URL(".",o).href:new URL(`${o.pathname.replace(/\/*$/,"/")}dist/`,o).href}function Pe(t,e){const n=Re(t);if(n)return Promise.resolve(n);const o=Dt({chunkBase:e,loadedFrom:_t,baseURI:document.baseURI});if(!o)return Promise.reject(le(`bugcatch-${t}.umd.js could not be loaded: this copy of the SDK was not loaded from an address, so there is nowhere to look for it. Set init({ chunkBase }) to the folder that holds it.`));const s=`${o}bugcatch-${t}.umd.js?v=${encodeURIComponent(ce)}`;return new Promise((i,r)=>{const a=document.createElement("script");a.src=s,a.async=!0,Ke&&(a.nonce=Ke),Ue!==null&&(a.crossOrigin=Ue),Ne&&(a.referrerPolicy=Ne);const c=()=>{a.onload=null,a.onerror=null,a.remove()};a.onload=()=>{c();const l=Re(t);l?i(l):r(le(`${s} loaded, but not as version ${ce} of the SDK — serve every file in dist/ from the same release.`))},a.onerror=()=>{c(),r(le(`could not load ${s}. The files in dist/ are served together: a self-hosted copy needs all of them (or init({ chunkBase }) pointing at them), and a Content-Security-Policy has to allow them in script-src.`))},(document.head||document.documentElement).appendChild(a)})}const _e=Me(t=>Pe("panel",t)),J=Me(t=>Pe("call",t)),Ht={info:Le,success:Kt,warning:Ut,critical:je};function zt(t,{where:e,onDismiss:n}){const o=document.createElement("div");o.className=`notice tone-${t.tone} at-${e}`,o.setAttribute("role","status");const s=document.createElement("span");s.className="notice-ico",s.setAttribute("aria-hidden","true"),s.innerHTML=Ht[t.tone]||Le;const i=document.createElement("div");i.className="notice-text";const r=document.createElement("strong");if(r.textContent=t.title,i.append(r),t.body){const a=document.createElement("p");a.textContent=t.body,i.append(a)}if(t.ctaHref&&t.ctaLabel){const a=document.createElement("a");a.className="notice-cta",a.href=t.ctaHref,a.textContent=t.ctaLabel,/^https?:/i.test(t.ctaHref)&&(a.target="_blank",a.rel="noopener noreferrer"),i.append(a)}if(o.append(s,i),t.dismissible&&n){const a=document.createElement("button");a.type="button",a.className="notice-x",a.setAttribute("aria-label","Dismiss this notice"),a.innerHTML=Oe,a.addEventListener("click",()=>n(t)),o.append(a)}return o}const De="#0e0e10",ue="#ffffff";function He(t){const e=Ft(t);if(!e)return ue;const[n,o,s]=e.map(r=>{const a=r/255;return a<=.03928?a/12.92:((a+.055)/1.055)**2.4});return .2126*n+.7152*o+.0722*s>.179?De:ue}function Ft(t){const e=String(t||"").trim();let n=/^#([0-9a-f]{3})$/i.exec(e);return n?[...n[1]].map(o=>parseInt(o+o,16)):(n=/^#([0-9a-f]{6})$/i.exec(e),n?[0,2,4].map(o=>parseInt(n[1].slice(o,o+2),16)):(n=/^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/i.exec(e),n?[n[1],n[2],n[3]].map(Number):null))}const ze={"bottom-right":"bottom:20px;right:20px;","bottom-left":"bottom:20px;left:20px;","top-right":"top:20px;right:20px;","top-left":"top:20px;left:20px;"},H=[{value:"light",label:"Light",icon:Lt},{value:"dark",label:"Dark",icon:Rt},{value:"auto",label:"System default",icon:Mt}],Fe="bugcatch:theme";function Xt(){try{const t=localStorage.getItem(Fe);return H.some(e=>e.value===t)?t:null}catch{return null}}function qt(t){try{localStorage.setItem(Fe,t)}catch{}}const Xe=`
|
|
1
|
+
(function(I,E){typeof exports=="object"&&typeof module<"u"?module.exports=E():typeof define=="function"&&define.amd?define(E):(I=typeof globalThis<"u"?globalThis:I||self,I.BugCatch=E())})(this,function(){"use strict";var pt=I=>{throw TypeError(I)};var wo=(I,E,P)=>E.has(I)||pt("Cannot "+P);var gt=(I,E,P)=>E.has(I)?pt("Cannot add the same private member more than once"):E instanceof WeakSet?E.add(I):E.set(I,P);var g=(I,E,P)=>(wo(I,E,"access private method"),P);var h,oe,mt,U,wt,Ie,W,ie,re,bt,yt,xt,se,kt;const I="[REDACTED]",E=new Set(["auth","bearer","session","sid","phpsessid","otp","pass","passwd","pwd","sig","codeverifier"]),P=["token","secret","password","passwd","apikey","signature","credential","sessionid","privatekey","accesskey","authorization"],vt=new Set(["key","code","state","nonce","salt","hash"]),Se=[/eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]+/g,/(?:AKIA|ASIA|AROA|AIDA|AGPA|ANPA|ANVA|APKA)[0-9A-Z]{16}/g,/AIza[\w-]{35}/g,/gh[pousr]_[A-Za-z0-9]{36,}/g,/github_pat_\w{22,}/g,/[sprk]k_(?:live|test)_[0-9A-Za-z]{10,}/g,/xox[abposr]-[A-Za-z0-9-]{10,}/g,/sk-ant-[\w-]{20,}/g,/sk-[\w-]{20,}/g,/glpat-[\w-]{20,}/g,/shp(?:at|ss|ca|pa)_[A-Za-z0-9]{32}/g],Ct=/\bBearer\s+[\w.~+/=-]{8,}/gi,It=/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;function Be(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch{return t}}function St(t){return Be(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function Bt(t){return t.length>=20?!0:Se.some(e=>(e.lastIndex=0,e.test(t)))}function $t(t,e){const n=St(t);if(!n)return!1;if(E.has(n))return!0;for(const o of P)if(n.includes(o))return!0;return vt.has(n)?Bt(Be(e)):!1}function ae(t){return t.split("&").map(e=>{const n=e.indexOf("=");if(n===-1)return e;const o=e.slice(0,n),r=e.slice(n+1);return r&&$t(o,r)?`${o}=${I}`:e}).join("&")}function $e(t){let e=t;for(const n of Se)n.lastIndex=0,e=e.replace(n,I);return e}function Ee(t){if(t==null)return t;let e=String(t);if(!e)return e;e=e.replace(It,`$1${I}@`);const n=e.indexOf("#");let o=n===-1?e:e.slice(0,n),r=n===-1?"":e.slice(n);const i=o.indexOf("?");if(i!==-1&&(o=o.slice(0,i+1)+ae(o.slice(i+1))),r.length>1){const s=r.slice(1),a=s.indexOf("?");a!==-1?r=`#${s.slice(0,a+1)}${ae(s.slice(a+1))}`:s.includes("=")&&(r=`#${ae(s)}`)}return $e(o+r)}function Et(t){if(t==null)return t;let e=String(t);return e&&(e=e.replace(/[A-Za-z][A-Za-z0-9+.-]{0,30}:\/\/[^\s"'<>)\]]+/g,n=>Ee(n)),e=e.replace(Ct,`Bearer ${I}`),$e(e))}function J(t){const e=[];return{push(n){e.push(n),e.length>t&&e.splice(0,e.length-t)},all:()=>e.slice(),clear:()=>{e.length=0},get size(){return e.length}}}const Ae=["log","info","warn","error","debug"];function At(t,{levels:e=["warn","error","log","info"]}={}){const n={};for(const o of Ae)n[o]=console[o],e.includes(o)&&(console[o]=(...r)=>{try{t.push({level:o,text:r.map(je).join(" ").slice(0,2e3),at:new Date().toISOString()})}catch{}n[o].apply(console,r)});return()=>{for(const o of Ae)console[o]=n[o]}}function Tt(t,{slowMs:e=2e3}={}){const n=window.fetch,o=XMLHttpRequest.prototype.open,r=XMLHttpRequest.prototype.send;return n&&(window.fetch=async function(...s){var d,u,B;const a=performance.now(),c=typeof s[0]=="string"?s[0]:(d=s[0])==null?void 0:d.url,l=((u=s[1])==null?void 0:u.method)||(typeof s[0]=="object"?(B=s[0])==null?void 0:B.method:"GET")||"GET";try{const x=await n.apply(this,s);return ce(t,{url:c,method:l,status:x.status,ms:Math.round(performance.now()-a),slowMs:e}),x}catch(x){throw ce(t,{url:c,method:l,status:0,error:String((x==null?void 0:x.message)||x),ms:Math.round(performance.now()-a),slowMs:e}),x}}),XMLHttpRequest.prototype.open=function(s,a,...c){return this.__bc={method:s,url:a,started:0},o.call(this,s,a,...c)},XMLHttpRequest.prototype.send=function(...s){return this.__bc&&(this.__bc.started=performance.now(),this.addEventListener("loadend",()=>{ce(t,{url:this.__bc.url,method:this.__bc.method,status:this.status,ms:Math.round(performance.now()-this.__bc.started),slowMs:e})})),r.apply(this,s)},()=>{n&&(window.fetch=n),XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=r}}function ce(t,{url:e,method:n,status:o,ms:r,error:i,slowMs:s}){try{t.push({url:Ee(String(e)).slice(0,500),method:n,status:o,ms:r,error:i===void 0?void 0:Et(i),failed:o===0||o>=400,slow:r>=s,at:new Date().toISOString()})}catch{}}function jt(t){const e=o=>{const r=String(o.message||"Error"),i=o.filename?` (${o.filename}:${o.lineno}:${o.colno})`:"";t.push({level:"error",text:(/^uncaught/i.test(r)?r:`Uncaught ${r}`)+i,at:new Date().toISOString()})},n=o=>{t.push({level:"error",text:`Unhandled rejection: ${je(o.reason)}`,at:new Date().toISOString()})};return window.addEventListener("error",e),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",e),window.removeEventListener("unhandledrejection",n)}}async function le(){const t=Te();try{if(navigator.getBattery){const e=await navigator.getBattery();t.battery=Math.round(e.level*100),t.charging=e.charging}}catch{}return t}function Te(){var e,n,o,r,i,s,a,c,l;const t=window.navigator||{};return{userAgent:t.userAgent,platform:t.platform,language:t.language,languages:t.languages?[...t.languages]:null,online:t.onLine,cookieEnabled:t.cookieEnabled,maxTouchPoints:t.maxTouchPoints??null,viewport:{width:window.innerWidth,height:window.innerHeight},screen:{width:(e=window.screen)==null?void 0:e.width,height:(n=window.screen)==null?void 0:n.height,availWidth:(o=window.screen)==null?void 0:o.availWidth,availHeight:(r=window.screen)==null?void 0:r.availHeight,colorDepth:(i=window.screen)==null?void 0:i.colorDepth,orientation:((a=(s=window.screen)==null?void 0:s.orientation)==null?void 0:a.type)||null},devicePixelRatio:window.devicePixelRatio,referrer:document.referrer||null,title:document.title,capturedAt:new Date().toISOString(),timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,timezoneOffsetMinutes:new Date().getTimezoneOffset(),browserMode:t.webdriver?"Automated":"Normal",doNotTrack:t.doNotTrack||null,hardwareConcurrency:t.hardwareConcurrency??null,deviceMemory:t.deviceMemory??null,connection:t.connection?{effectiveType:t.connection.effectiveType,downlink:t.connection.downlink,rtt:t.connection.rtt,saveData:t.connection.saveData}:null,prefersColorScheme:(c=window.matchMedia)!=null&&c.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light",prefersReducedMotion:((l=window.matchMedia)==null?void 0:l.call(window,"(prefers-reduced-motion: reduce)").matches)||!1}}function je(t){if(typeof t=="string")return t;if(t instanceof Error)return`${t.name}: ${t.message}`;try{return JSON.stringify(t)}catch{return String(t)}}const Ot='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9.5l6 6 6-6"/></svg>',Lt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.4 5.4l1.6 1.6M17 17l1.6 1.6M18.6 5.4L17 7M7 17l-1.6 1.6"/></svg>',Rt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13.4A8.2 8.2 0 1 1 10.6 4a6.6 6.6 0 0 0 9.4 9.4z"/></svg>',Mt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="2.8" y="4.4" width="18.4" height="12.6" rx="2.2"/><path d="M8.6 20.2h6.8"/><path d="M12 4.4v12.6"/><path d="M12 7.2a3.6 3.6 0 0 1 0 7.2z" fill="currentColor" stroke="none"/></svg>',Oe='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7.5v5.2M12 16.3h.01"/></svg>',Le='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',Kt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.8l4.6 4.4L19 7"/></svg>',Re='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.7h.01"/></svg>',Nt='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.3 4.2a2 2 0 0 1 3.4 0l7.6 13.1a2 2 0 0 1-1.7 3H4.4a2 2 0 0 1-1.7-3z"/><path d="M12 9.5v4.2M12 17h.01"/></svg>',de="0.21.0",Ut="__bugcatchChunks",Pt=t=>`${t}@${de}`;function Me(t){var e;return typeof window<"u"?(e=window[Ut])==null?void 0:e[Pt(t)]:void 0}function ue(t,e){return console.warn(`[BugCatch] ${t}`),new Error("[BugCatch] part of the widget could not be loaded — check the connection and try again.")}function Ke(t){let e=null;return(...n)=>(e||(e=t(...n).catch(o=>{throw e=null,o})),e)}const A=typeof document<"u"?document.currentScript:null,_t=(A==null?void 0:A.src)||null,Ne=(A==null?void 0:A.nonce)||"",Ue=(A==null?void 0:A.getAttribute("crossorigin"))??null,Pe=(A==null?void 0:A.referrerPolicy)||"";function Dt({chunkBase:t,loadedFrom:e,baseURI:n}){if(t)return new URL(String(t).replace(/\/*$/,"/"),n).href;if(!e)return null;const o=new URL(e);return/\.js$/i.test(o.pathname)?new URL(".",o).href:new URL(`${o.pathname.replace(/\/*$/,"/")}dist/`,o).href}function _e(t,e){const n=Me(t);if(n)return Promise.resolve(n);const o=Dt({chunkBase:e,loadedFrom:_t,baseURI:document.baseURI});if(!o)return Promise.reject(ue(`bugcatch-${t}.umd.js could not be loaded: this copy of the SDK was not loaded from an address, so there is nowhere to look for it. Set init({ chunkBase }) to the folder that holds it.`));const r=`${o}bugcatch-${t}.umd.js?v=${encodeURIComponent(de)}`;return new Promise((i,s)=>{const a=document.createElement("script");a.src=r,a.async=!0,Ne&&(a.nonce=Ne),Ue!==null&&(a.crossOrigin=Ue),Pe&&(a.referrerPolicy=Pe);const c=()=>{a.onload=null,a.onerror=null,a.remove()};a.onload=()=>{c();const l=Me(t);l?i(l):s(ue(`${r} loaded, but not as version ${de} of the SDK — serve every file in dist/ from the same release.`))},a.onerror=()=>{c(),s(ue(`could not load ${r}. The files in dist/ are served together: a self-hosted copy needs all of them (or init({ chunkBase }) pointing at them), and a Content-Security-Policy has to allow them in script-src.`))},(document.head||document.documentElement).appendChild(a)})}const De=Ke(t=>_e("panel",t)),Y=Ke(t=>_e("call",t)),Ht={info:Re,success:Kt,warning:Nt,critical:Oe};function zt(t,{where:e,onDismiss:n}){const o=document.createElement("div");o.className=`notice tone-${t.tone} at-${e}`,o.setAttribute("role","status");const r=document.createElement("span");r.className="notice-ico",r.setAttribute("aria-hidden","true"),r.innerHTML=Ht[t.tone]||Re;const i=document.createElement("div");i.className="notice-text";const s=document.createElement("strong");if(s.textContent=t.title,i.append(s),t.body){const a=document.createElement("p");a.textContent=t.body,i.append(a)}if(t.ctaHref&&t.ctaLabel){const a=document.createElement("a");a.className="notice-cta",a.href=t.ctaHref,a.textContent=t.ctaLabel,/^https?:/i.test(t.ctaHref)&&(a.target="_blank",a.rel="noopener noreferrer"),i.append(a)}if(o.append(r,i),t.dismissible&&n){const a=document.createElement("button");a.type="button",a.className="notice-x",a.setAttribute("aria-label","Dismiss this notice"),a.innerHTML=Le,a.addEventListener("click",()=>n(t)),o.append(a)}return o}const He="#0e0e10",he="#ffffff";function ze(t){const e=Ft(t);if(!e)return he;const[n,o,r]=e.map(s=>{const a=s/255;return a<=.03928?a/12.92:((a+.055)/1.055)**2.4});return .2126*n+.7152*o+.0722*r>.179?He:he}function Ft(t){const e=String(t||"").trim();let n=/^#([0-9a-f]{3})$/i.exec(e);return n?[...n[1]].map(o=>parseInt(o+o,16)):(n=/^#([0-9a-f]{6})$/i.exec(e),n?[0,2,4].map(o=>parseInt(n[1].slice(o,o+2),16)):(n=/^rgba?\(\s*(\d+)[\s,]+(\d+)[\s,]+(\d+)/i.exec(e),n?[n[1],n[2],n[3]].map(Number):null))}const Fe={"bottom-right":"bottom:20px;right:20px;","bottom-left":"bottom:20px;left:20px;","top-right":"top:20px;right:20px;","top-left":"top:20px;left:20px;"},z=[{value:"light",label:"Light",icon:Lt},{value:"dark",label:"Dark",icon:Rt},{value:"auto",label:"System default",icon:Mt}],Xe="bugcatch:theme";function Xt(){try{const t=localStorage.getItem(Xe);return z.some(e=>e.value===t)?t:null}catch{return null}}function qt(t){try{localStorage.setItem(Xe,t)}catch{}}const qe=`
|
|
2
2
|
--bc-bg: #151517;
|
|
3
3
|
--bc-elevated: #1c1c1f;
|
|
4
4
|
--bc-fg: #f3f2ef;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
:host { all: initial; }
|
|
21
21
|
:host {
|
|
22
22
|
--bc-accent: ${t||"var(--bc-fg)"};
|
|
23
|
-
--bc-on-accent: ${t?
|
|
23
|
+
--bc-on-accent: ${t?ze(t):"var(--bc-bg)"};
|
|
24
24
|
/* The assistant's orb: BugCatch's own three colours, or the host's accent
|
|
25
25
|
with two lighter cuts of it, so the orb on their site is in their colour. */
|
|
26
26
|
--bc-o1: ${t?`color-mix(in srgb, ${t} 32%, #fff)`:"#ffb3c9"};
|
|
@@ -68,10 +68,10 @@
|
|
|
68
68
|
--bc-fs-lg: 15px;
|
|
69
69
|
--bc-pad: 18px;
|
|
70
70
|
}
|
|
71
|
-
:host(.bc-dark) {${
|
|
71
|
+
:host(.bc-dark) {${qe}
|
|
72
72
|
}
|
|
73
73
|
@media (prefers-color-scheme: dark) {
|
|
74
|
-
:host(.bc-auto) {${
|
|
74
|
+
:host(.bc-auto) {${qe}
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -300,11 +300,11 @@ button:focus-visible, a:focus-visible, select:focus-visible, [tabindex]:focus-vi
|
|
|
300
300
|
}
|
|
301
301
|
.loadfail button[data-act="retry"] { text-decoration: underline; text-underline-offset: 2px; }
|
|
302
302
|
.loadfail button svg { font-size: 13px; margin: 0; }
|
|
303
|
-
`;function Jt(t){const e=document.createElement("div");e.setAttribute("data-bugcatch","widget");let n=Xt()||Yt(t.config.theme);e.className=
|
|
303
|
+
`;function Jt(t){const e=document.createElement("div");e.setAttribute("data-bugcatch","widget");let n=Xt()||Yt(t.config.theme);e.className=We(n);const o=e.attachShadow({mode:"open"}),r=document.createElement("style");r.textContent=Wt(t.config.accent||null),o.appendChild(r);const i=Fe[t.config.widgetPosition]?t.config.widgetPosition:"bottom-right",s=document.createElement("div");s.className=`dock ${i.includes("right")?"at-right":"at-left"}`+(i.startsWith("top")?" at-top":""),s.style.cssText=Fe[i];const a={current:()=>n,label:()=>z.find(w=>w.value===n).label,cycle(){const w=z[(z.findIndex(b=>b.value===n)+1)%z.length];return n=w.value,e.className=We(n),qt(n),w}},c=document.createElement("button");c.className="launcher",c.type="button",c.innerHTML=`<span class="ico" aria-hidden="true"><span class="when-closed"><span class="orb"></span></span><span class="when-open">${Ot}</span></span><span>Report a bug</span>`,c.setAttribute("aria-haspopup","dialog"),c.setAttribute("aria-expanded","false");let l=null;c.addEventListener("click",()=>{if(l){l.close();return}l=u()});let d="report";function u(){let w=d;d="report",N(),k();let b=null,f=!1;const S=()=>{f=!0,c.removeAttribute("aria-busy"),l=null},O={close:()=>b?b.close():S(),destroy:()=>b?b.destroy():S(),setMode:y=>{var R;b?(R=b.setMode)==null||R.call(b,y):w=y}};return c.setAttribute("aria-busy","true"),De(t.config.chunkBase).then(({openPanel:y})=>{f||(c.removeAttribute("aria-busy"),s.classList.add("over"),c.setAttribute("aria-expanded","true"),b=y({root:o,host:e,dock:s,client:t,preloadCall:C,themeControls:a,mode:w,onClose:()=>{l=null,s.classList.remove("over"),c.setAttribute("aria-expanded","false")}}))},()=>{f||(S(),L())}),O}const B=()=>{De(t.config.chunkBase).catch(()=>{})};for(const w of["pointerenter","touchstart","focus"])c.addEventListener(w,B,{once:!0,passive:!0});const x=Je(B);function C(){Y(t.config.chunkBase).catch(()=>{})}let m=null;function L(){N(),m=document.createElement("div"),m.className="msg err loadfail",m.setAttribute("role","alert"),m.innerHTML=`${Oe}<span>The report form didn't load. Check your connection and try again.</span><button type="button" data-act="retry">Try again</button><button type="button" data-act="dismiss" aria-label="Dismiss">${Le}</button>`,m.querySelector('[data-act="retry"]').addEventListener("click",()=>{c.focus(),l||(l=u())}),m.querySelector('[data-act="dismiss"]').addEventListener("click",()=>{c.focus(),N()}),s.prepend(m)}function N(){m==null||m.remove(),m=null}let j=null;function p(w){k(),j=zt(w,{where:"launcher",onDismiss:b=>{t.dismissAnnouncement(b),c.focus(),k()}}),m?m.after(j):s.prepend(j)}function k(){j==null||j.remove(),j=null}const v=t.config.announcements===!1?()=>{}:Je(()=>{t.announcements().then(w=>{const b=w.find(f=>f.placement==="launcher");b&&!l&&e.isConnected&&p(b)}).catch(()=>{})});return s.append(c),o.appendChild(s),document.body.appendChild(e),t.widgetControls={open:w=>{if(l){w&&l.setMode(w);return}d=w||"report",c.click()},close:()=>{l==null||l.close()},isOpen:()=>!!l},()=>{x(),v(),l==null||l.destroy(),e.remove(),t.widgetControls=null}}function Yt(t){return t==="dark"||t==="light"?t:"auto"}function We(t){return t==="dark"?"bc-dark":t==="light"?"bc-light":"bc-auto"}function Je(t){let e=()=>{};const n=()=>{if(typeof requestIdleCallback=="function"){const o=requestIdleCallback(t,{timeout:5e3});e=()=>cancelIdleCallback(o)}else{const o=setTimeout(t,1500);e=()=>clearTimeout(o)}};return document.readyState==="complete"?n():(window.addEventListener("load",n,{once:!0}),e=()=>window.removeEventListener("load",n)),()=>e()}const Vt="Too many requests are being sent from here at the moment. Please try again in a minute.";function _(t){return t||Vt}const Gt=typeof window<"u"&&window.fetch?window.fetch.bind(window):null,Zt=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.open:null,Qt=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.send:null,en=["image/png","image/jpeg","image/webp","image/gif","video/webm","video/mp4","audio/webm","audio/ogg","audio/mpeg","audio/mp4","audio/wav","application/pdf","text/plain","text/csv","application/json","application/zip","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],Ye=["image/png","image/jpeg","image/webp","video/webm","video/mp4"];function fe(t,e=en){const n=String(t||"").split(";")[0].trim().toLowerCase();return e.includes(n)?n:null}async function tn({apiBase:t,apiKey:e,blob:n,mime:o,onProgress:r}){var l;const i=fe(o||n.type);if(!i)throw new Error(`[BugCatch] ${o||n.type||"that file"} can't be attached.`);const s=await Gt(`${t}/ingest/presign`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e},body:JSON.stringify({mime:i})});if(s.status===429){let d="";try{d=((l=await s.json())==null?void 0:l.message)||""}catch{}throw new Error(`[BugCatch] ${_(typeof d=="string"?d:"")}`)}if(!s.ok)throw new Error(`[BugCatch] could not start the upload (HTTP ${s.status}).`);const{key:a,uploadUrl:c}=await s.json();return await nn(c,n,i,r),{storageKey:a,mime:i}}function nn(t,e,n,o){return new Promise((r,i)=>{const s=new XMLHttpRequest;Zt.call(s,"PUT",t,!0),s.setRequestHeader("Content-Type",n),s.upload.onprogress=a=>{a.lengthComputable&&(o==null||o(a.loaded/a.total))},s.onload=()=>{s.status>=200&&s.status<300?r():i(new Error(`[BugCatch] upload failed (HTTP ${s.status}).`))},s.onerror=()=>i(new Error("[BugCatch] the browser blocked the upload to storage. If this is a new environment, the media bucket is probably missing its CORS policy.")),s.onabort=()=>i(new Error("[BugCatch] upload cancelled.")),Qt.call(s,e)})}const V="bugcatch.watch",Ve=[2e3,5e3,15e3,3e4,6e4],on=5e3;let F=null;function rn(t){F=t||null}const pe=()=>F?`${V}:${F}`:V;function G(){return F?`?projectId=${encodeURIComponent(F)}`:""}function $(){try{const t=window.localStorage;return(t==null?void 0:t.getItem(pe()))||(t==null?void 0:t.getItem(V))||null}catch{return null}}function ge(t){var e;if(t)try{(e=window.localStorage)==null||e.setItem(pe(),t)}catch{}}function D(){var t,e;try{(t=window.localStorage)==null||t.removeItem(pe()),(e=window.localStorage)==null||e.removeItem(V)}catch{}Ge()}const Z="bugcatch.unread";function sn(t){return[(t==null?void 0:t.bugId)||"report",(t==null?void 0:t.kind)||"status",(t==null?void 0:t.at)||""].join("|")}function X(){var t;try{const e=(t=window.localStorage)==null?void 0:t.getItem(Z),n=e?JSON.parse(e):[];return Array.isArray(n)?n.filter(o=>o&&typeof o.id=="string"):[]}catch{return[]}}function Q(t){var e,n;try{t.length?(e=window.localStorage)==null||e.setItem(Z,JSON.stringify(t)):(n=window.localStorage)==null||n.removeItem(Z)}catch{}}function an(t){const e={...t,id:sn(t)},n=X().filter(o=>o.id!==e.id);return n.push(e),Q(n.slice(-20)),e}function cn(t){const e=X().filter(n=>n.id!==t);return Q(e),e}function ln(t){const e=X().filter(n=>n.bugId!==t);return Q(e),e}function Ge(){return Q([]),[]}function dn(t,e){let n=t,o=n.indexOf(`
|
|
304
304
|
|
|
305
|
-
`);for(;o!==-1;){const
|
|
306
|
-
`).filter(
|
|
305
|
+
`);for(;o!==-1;){const r=n.slice(0,o);n=n.slice(o+2);const i=r.split(`
|
|
306
|
+
`).filter(s=>s.startsWith("data:")).map(s=>s.slice(5).trim()).join(`
|
|
307
307
|
`);if(i)try{e(JSON.parse(i))}catch{}o=n.indexOf(`
|
|
308
308
|
|
|
309
|
-
`)}return n}async function dn({apiBase:t}){const e=C();if(!e)return{reporter:null,reports:[]};const n=await fetch(`${t}/ingest/watch/reports${V()}`,{headers:{Authorization:`Bearer ${e}`}});if(n.status===401)return N(),{reporter:null,reports:[]};if(!n.ok)throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);return n.json()}async function hn({apiBase:t,bugId:e}){const n=C();if(!n)return null;const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}${V()}`,{headers:{Authorization:`Bearer ${n}`}});if(o.status===401)return N(),null;if(o.status===404)return null;if(!o.ok)throw new Error(`[BugCatch] could not load that report (HTTP ${o.status})`);return o.json()}async function fn({apiBase:t,bugId:e,body:n,attachments:o}){const s=C();if(!s)throw new Error("[BugCatch] nothing filed from this browser yet.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({...n?{body:n}:{},...o!=null&&o.length?{attachments:o}:{}})});if(i.status===401)throw N(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!i.ok){let r="";try{const a=await i.json();r=Array.isArray(a.message)?a.message.join(", "):a.message||""}catch{}throw i.status===429?new Error(_(r)):new Error(r||`[BugCatch] could not send that (HTTP ${i.status}).`)}return i.json()}async function pn({apiBase:t,apiKey:e,projectId:n}){const o={agent:!1,live:!1};try{const s=await fetch(`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!s.ok)return o;const i=await s.json();return i!=null&&i.available?i.kinds&&typeof i.kinds=="object"?{agent:!1,live:!!i.kinds.live}:{agent:!1,live:i.kind==="live"}:o}catch{return o}}async function gn({apiBase:t,apiKey:e,token:n,payload:o,watchToken:s}){const i=await fetch(`${t}/ingest/calls`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e,...n?{"X-BugCatch-Session":n}:{}},body:JSON.stringify(s?{...o,watchToken:s}:o)});if(!i.ok){let r="";try{const c=await i.json();r=Array.isArray(c.message)?c.message.join(", "):c.message||""}catch{}const a=new Error(i.status===429?_(r):r||`[BugCatch] the call could not be started (HTTP ${i.status}).`);throw a.status=i.status,a}return i.json()}async function Ze({apiBase:t,bugId:e}){const n=C();if(!n)return!1;try{const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{headers:{Authorization:`Bearer ${n}`}});if(!o.ok)return!1;const s=await o.json();return!!(s!=null&&s.offered)}catch{return!1}}async function mn({apiBase:t,bugId:e}){const n=C();if(!n)throw new Error("[BugCatch] nothing filed from this browser yet.");const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{method:"POST",headers:{Authorization:`Bearer ${n}`}});if(o.status===401)throw N(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!o.ok){let s="";try{const i=await o.json();s=Array.isArray(i.message)?i.message.join(", "):i.message||""}catch{}throw new Error(s||`[BugCatch] the call could not be started (HTTP ${o.status}).`)}return o.json()}async function wn({apiBase:t,bugId:e,callId:n}){const o=C();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}async function bn({apiBase:t,bugId:e,callId:n}){const o=C();if(!o)throw new Error("[BugCatch] nothing filed from this browser yet.");const s=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(s.status===401)throw N(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(s.status===409)throw new Error("[BugCatch] that call is no longer ringing.");if(!s.ok){let i="";try{const r=await s.json();i=Array.isArray(r.message)?r.message.join(", "):r.message||""}catch{}throw new Error(i||`[BugCatch] the call could not be answered (HTTP ${s.status}).`)}return s.json()}async function Ge({apiBase:t,bugId:e,callId:n}){const o=C();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}function yn({apiBase:t,onUpdate:e}){let n=!0,o=0,s=null;async function i(){const r=C();if(!r)throw new Error("nothing filed from this browser yet");s=new AbortController;const a=await fetch(`${t}/ingest/watch/stream${V()}`,{headers:{Authorization:`Bearer ${r}`,Accept:"text/event-stream"},signal:s.signal});if(a.status===401)throw n=!1,N(),new Error("subscription no longer valid");if(!a.ok||!a.body)throw new Error(`stream failed (${a.status})`);const c=Date.now(),l=a.body.getReader(),h=new TextDecoder;let u="";try{for(;;){const{value:B,done:y}=await l.read();if(y)break;u+=h.decode(B,{stream:!0}),u=un(u,w=>{if(w.type!=="ping")try{e(w)}catch{}})}}finally{Date.now()-c>=on&&(o=0)}}return(async()=>{for(;n;){try{await i()}catch(a){if((a==null?void 0:a.name)==="AbortError")return}if(!n)return;const r=Ye[Math.min(o,Ye.length-1)];o+=1,await new Promise(a=>setTimeout(a,r))}})(),()=>{n=!1,s==null||s.abort(),s=null}}const xn={OPEN:"is open",IN_PROGRESS:"is being worked on",RESOLVED:"has been fixed",CLOSED:"has been closed"},kn={status:null,severity:"#f2a54a",assignment:"#79a8ff",reply:"#4fd19a"},T={bg:"#111113",fg:"#f3f2ef",muted:"#b3b0aa",faint:"#8f8c86",ring:"rgba(255,255,255,.09)",brand:"#a59cff"};function Qe(t){return t!=null&&t.summary?t.summary:`Your report ${xn[t==null?void 0:t.status]||"was updated"}`}function vn(t){var e;return(t==null?void 0:t.kind)==="reply"&&((e=t.reply)!=null&&e.body)?`${t.reply.author?`${t.reply.author}: `:""}${t.reply.body}`:(t==null?void 0:t.title)||""}function Cn(t){const e=Date.parse(t||"");if(!Number.isFinite(e))return"";const n=Math.round((Date.now()-e)/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;const o=Math.round(n/60);if(o<24)return`${o}h ago`;const s=Math.round(o/24);return s===1?"yesterday":`${s}d ago`}function In(){var t;try{const e=document.querySelector('[data-bugcatch="widget"]'),n=(t=e==null?void 0:e.shadowRoot)==null?void 0:t.querySelector(".dock"),o=(n==null?void 0:n.getBoundingClientRect().height)||0;return o?Math.round(o)+12:0}catch{return 0}}function Sn({accent:t=null,position:e="bottom-right",onRead:n=null,onReadAll:o=null,onCall:s=null}={}){const[i,r]=String(e).split("-"),a=i==="top",c=r==="left",l=new Map;let h=null,u=null;function B(){return h!=null&&h.isConnected||(h=document.createElement("div"),h.setAttribute("data-bugcatch","updates"),h.style.cssText=["position:fixed",`${a?"top":"bottom"}:${20+In()}px`,`${c?"left":"right"}:20px`,"z-index:2147482998","display:flex","flex-direction:column","gap:10px",`align-items:${c?"flex-start":"flex-end"}`,"width:min(320px,calc(100vw - 40px))","pointer-events:none"].join(";"),document.body.appendChild(h)),h}function y(f){if(!f._bcShown){f.remove();return}f.style.opacity="0",f.style.transform=`translateY(${a?-8:8}px)`,setTimeout(()=>f.remove(),250)}const w=t||ue,M=t?He(t):De;function j(f,k){const p=document.createElement("button");return p.type="button",p.textContent=f,p.style.cssText=["padding:6px 12px","border:0",`box-shadow:${k?"none":`inset 0 0 0 1px ${T.ring}`}`,"border-radius:999px",`background:${k?w:"rgba(255,255,255,.06)"}`,`color:${k?M:T.fg}`,"font:560 12px/1.4 inherit","cursor:pointer","white-space:nowrap"].join(";"),p}function A(f){var P;const k=document.createElement("div");k.setAttribute("role","status"),k.style.cssText=["box-sizing:border-box","width:100%","padding:13px 14px","border-radius:14px",`background:${T.bg}`,`color:${T.fg}`,'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',`box-shadow:0 0 0 1px ${T.ring},0 20px 44px -12px rgba(0,0,0,.55),0 4px 12px rgba(0,0,0,.25)`,"opacity:0",`transform:translateY(${a?-8:8}px)`,"transition:opacity .2s ease,transform .2s ease","pointer-events:auto"].join(";");const p=document.createElement("div");p.style.cssText="display:flex;align-items:baseline;gap:8px;font-weight:600;margin-bottom:2px";const b=document.createElement("span");b.setAttribute("aria-hidden","true"),b.style.cssText=`flex:none;width:7px;height:7px;border-radius:50%;transform:translateY(-1px);background:${kn[f==null?void 0:f.kind]||t||T.brand}`;const I=document.createElement("span");I.textContent=Qe(f),p.append(b,I);const g=document.createElement("div");g.style.cssText=(f==null?void 0:f.kind)==="reply"?`color:${T.muted};padding-left:15px;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden`:`color:${T.muted};padding-left:15px`,g.textContent=vn(f);const S=document.createElement("div");S.style.cssText="display:flex;align-items:center;gap:8px;margin-top:10px;padding-left:15px;flex-wrap:wrap";const O=document.createElement("span");O.style.cssText=`color:${T.faint};font-size:11px;margin-right:auto`,O.textContent=Cn(f==null?void 0:f.at);const x=j("Mark as read",!1);if(x.setAttribute("aria-label",`Mark as read: ${Qe(f)}`),x.addEventListener("click",()=>n==null?void 0:n(f.id)),S.append(O,x),(P=f==null?void 0:f.call)!=null&&P.offered&&typeof s=="function"){const ft=j("Talk it through",!0);ft.addEventListener("click",()=>s(f)),S.insertBefore(ft,x)}return k.append(p,g,S),k}function D(f){const k=document.createElement("div");k.style.cssText=["box-sizing:border-box","width:100%","display:flex","align-items:center","gap:8px","padding:8px 10px 8px 14px","border-radius:999px",`background:${T.bg}`,`color:${T.muted}`,'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',`box-shadow:0 0 0 1px ${T.ring},0 12px 30px -10px rgba(0,0,0,.5)`,"pointer-events:auto"].join(";");const p=document.createElement("span");p.style.cssText="margin-right:auto",p.textContent=`${f} more update${f===1?"":"s"}`;const b=j("Mark all as read",!1);return b.style.cssText+=";padding:4px 9px",b.addEventListener("click",()=>o==null?void 0:o()),k.append(p,b),k}return{render(f){const k=Array.isArray(f)?f:[];if(!k.length){for(const x of l.values())y(x);l.clear(),u==null||u.remove(),u=null,h==null||h.remove(),h=null;return}const p=k.slice(-3),b=new Set(p.map(x=>x.id)),I=B();for(const[x,P]of l)b.has(x)||(y(P),l.delete(x));const g=[];for(const x of p){if(l.has(x.id))continue;const P=A(x);l.set(x.id,P),g.push(P)}const S=a?[...p].reverse():p;for(const x of S)I.appendChild(l.get(x.id));const O=k.length-p.length;O>0?(u==null||u.remove(),u=D(O),a?I.appendChild(u):I.insertBefore(u,I.firstChild)):(u==null||u.remove(),u=null),requestAnimationFrame(()=>{for(const x of g)x.isConnected&&(x._bcShown=!0,x.style.opacity="1",x.style.transform="translateY(0)")})},destroy(){l.clear(),u=null,h==null||h.remove(),h=null}}}async function $n({apiBase:t,apiKey:e,projectId:n,sessionToken:o}){try{const s=await fetch(`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,{headers:pe(e,o)});if(!s.ok)return[];const i=await s.json();return Array.isArray(i==null?void 0:i.issues)?i.issues:[]}catch{return[]}}async function Bn({apiBase:t,apiKey:e,projectId:n,q:o,sessionToken:s,signal:i}){try{const r=`${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(o)}`,a=await fetch(r,{headers:pe(e,s),signal:i});if(!a.ok)return[];const c=await a.json();return Array.isArray(c==null?void 0:c.issues)?c.issues:[]}catch{return[]}}async function En({apiBase:t,apiKey:e,projectId:n,bugId:o,reporterEmail:s,reporterName:i,metadata:r,logs:a,sessionToken:c}){const l=C(),h=await fetch(`${t}/ingest/known-issues/${encodeURIComponent(o)}/join`,{method:"POST",headers:pe(e,c),body:JSON.stringify({projectId:n,reporterEmail:s,reporterName:i,metadata:r,logs:a,...l?{watchToken:l}:{}})});if(!h.ok)throw new Error(await Tn(h));const u=await h.json();return u!=null&&u.watchToken&&fe(u.watchToken),u}function pe(t,e){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function Tn(t){let e="";try{const n=await t.json();e=Array.isArray(n.message)?n.message.join(", "):n.message||""}catch{}return t.status===429?_(e):e||`Could not add you to this issue (HTTP ${t.status})`}async function An({apiBase:t,bugId:e,score:n,comment:o}){const s=C();if(!s)throw new Error("This browser cannot access that report.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/rating${V()}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({score:n,...o?{comment:o}:{}})}),r=await i.json().catch(()=>({}));if(!i.ok){const a=Array.isArray(r.message)?r.message.join(", "):r.message;throw new Error(a||"Could not send your rating. Please try again.")}return r}async function jn({apiBase:t,bugId:e,...n}){const o=C();if(!o)throw new Error("This browser cannot access that report.");const s=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify(n)}),i=await s.json().catch(()=>({}));if(!s.ok)throw new Error(i.message||"Could not record feedback. Please refresh and try again.");return i}const On="bugcatch.session.",ge=t=>`${On}${t}`,me=new Map;function R(t){var e;if(!t)return null;try{const n=(e=window.localStorage)==null?void 0:e.getItem(ge(t));if(n){const o=JSON.parse(n);if(o!=null&&o.token)return o}}catch{}return me.get(t)||null}function Ln(t,e){var o;if(!t||!(e!=null&&e.token))return;const n={token:e.token,email:e.email||null,name:e.name||null};me.set(t,n);try{(o=window.localStorage)==null||o.setItem(ge(t),JSON.stringify(n))}catch{}}function we(t){var e;if(t){me.delete(t);try{(e=window.localStorage)==null||e.removeItem(ge(t))}catch{}}}function Q({apiKey:t,token:e}){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function et(t){let e="";try{const n=await t.json();e=Array.isArray(n.message)?n.message.join(", "):n.message||""}catch{}return t.status===429?_(e):e||`Request failed (HTTP ${t.status})`}async function Rn({apiBase:t,apiKey:e,projectId:n,token:o}){const s={mode:"off",signedIn:null,signedOutReason:null};try{const i=await fetch(`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,{headers:Q({apiKey:e,token:o})});if(!i.ok)return s;const r=await i.json();return{mode:r.mode==="optional"||r.mode==="required"?r.mode:"off",signedIn:r.signedIn||null,signedOutReason:r.signedOutReason||null}}catch{return s}}async function Mn({apiBase:t,apiKey:e,projectId:n,email:o,name:s}){const i=await fetch(`${t}/ingest/login/start`,{method:"POST",headers:Q({apiKey:e}),body:JSON.stringify({projectId:n,email:o,...s?{name:s}:{}})});if(!i.ok)throw new Error(await et(i));return i.json()}async function Kn({apiBase:t,apiKey:e,projectId:n,email:o,code:s}){const i=await fetch(`${t}/ingest/login`,{method:"POST",headers:Q({apiKey:e}),body:JSON.stringify({projectId:n,email:o,code:s})});if(!i.ok)throw new Error(await et(i));const r=await i.json(),a={token:r.sessionToken,email:r.email,name:r.name};return Ln(n,a),a}async function Un({apiBase:t,apiKey:e,projectId:n,token:o}){if(we(n),!o)return{signedOut:!0};try{await fetch(`${t}/ingest/logout`,{method:"POST",headers:Q({apiKey:e,token:o}),body:JSON.stringify({projectId:n})})}catch{}return{signedOut:!0}}let tt=!1;if(typeof window<"u"&&window.addEventListener)for(const t of["pointerdown","keydown","touchstart"])window.addEventListener(t,()=>{tt=!0},{once:!0,capture:!0,passive:!0});function Nn(){return tt}async function Pn({apiBase:t,apiKey:e,projectId:n}){const o={policy:"off",fields:[]};try{const s=await fetch(`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!s.ok)return o;const i=await s.json(),r=i.policy==="optional"||i.policy==="required"?i.policy:"off",a=Array.isArray(i.fields)?i.fields:[];return a.length?{policy:r,fields:a}:o}catch{return o}}async function _n({apiBase:t,apiKey:e,projectId:n}){try{const o=await fetch(`${t}/ingest/agent-issues?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!o.ok)return[];const s=await o.json();return(Array.isArray(s==null?void 0:s.issues)?s.issues:[]).filter(i=>i&&typeof i.key=="string"&&typeof i.title=="string").map(i=>({key:i.key,title:i.title,hint:typeof i.hint=="string"?i.hint:""}))}catch{return[]}}const Dn=5*6e4,nt="bugcatch:announcements:seen",Hn=40,zn=["info","success","warning","critical"],ot=t=>`bugcatch:announcements:${t}`;async function Fn({apiBase:t,apiKey:e,projectId:n,fresh:o=!1}){var s;if(!o){const i=Zn(n);if(i)return i}try{const i=await fetch(`${t}/ingest/announcements?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}}),r=i.ok?Vn((s=await i.json())==null?void 0:s.announcements):[];return Gn(n,r),r}catch{return[]}}function Xn(t,{on:e=Jn(),seen:n=rt()}={}){return(t||[]).filter(o=>Yn(o,e)&&!(o.dismissible&&n.includes(it(o))))}function qn(t){if(!(!(t!=null&&t.id)||!t.dismissible))try{const e=it(t),n=[...rt().filter(o=>o!==e),e];localStorage.setItem(nt,JSON.stringify(n.slice(-Hn)))}catch{}}function Wn(t){return typeof t!="string"||!t||t.startsWith("//")?null:t.startsWith("/")||/^(https?:\/\/|mailto:)./i.test(t)?t:null}function Jn(t=new Date){const e=n=>String(n).padStart(2,"0");return`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}`}function Yn(t,e){return!(t.startsOn&&e<t.startsOn||t.endsOn&&e>t.endsOn)}function it(t){return`${t.id}#${t.revision||0}`}function Vn(t){return(Array.isArray(t)?t:[]).filter(e=>e&&typeof e.id=="string"&&typeof e.title=="string"&&e.title.trim()).map(e=>{const n=e.placement==="launcher"?"launcher":"panel",o=Wn(e.ctaHref);return{id:e.id,revision:Number.isInteger(e.revision)?e.revision:0,title:e.title,body:typeof e.body=="string"?e.body:"",tone:zn.includes(e.tone)?e.tone:"info",ctaLabel:o&&typeof e.ctaLabel=="string"?e.ctaLabel:"",ctaHref:o&&typeof e.ctaLabel=="string"?o:"",placement:n,dismissible:n==="launcher"||e.dismissible!==!1,startsOn:typeof e.startsOn=="string"?e.startsOn:"",endsOn:typeof e.endsOn=="string"?e.endsOn:""}})}function rt(){try{const t=JSON.parse(localStorage.getItem(nt)||"[]");return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}catch{return[]}}function Zn(t){try{const e=JSON.parse(localStorage.getItem(ot(t))||"null");if(!e||!Array.isArray(e.list)||typeof e.at!="number")return null;const n=Date.now()-e.at;return n>=0&&n<Dn?e.list:null}catch{return null}}function Gn(t,e){try{localStorage.setItem(ot(t),JSON.stringify({at:Date.now(),list:e}))}catch{}}const ee=120,Qn=500,te=30,eo=1e3,be={loanId:["loanId","loanNumber"],applicationId:["applicationId"],customerNumber:["customerNumber","customerId"]},to=/[\u0000-\u001f\u007f]/;function no(t){if(typeof t=="number")return Number.isFinite(t)?String(t):null;if(typeof t!="string")return null;const e=t.trim();return!e||e.length>ee||to.test(e)?null:e}function L(t){return t===null?"null":Array.isArray(t)?"an array":typeof t=="object"?"an object":`a ${typeof t}`}function ye(t,e,n,o,s){for(const i of n){if(!(i in t)||t[i]===void 0||t[i]===null||t[i]==="")continue;const r=no(t[i]);if(r)return r;const a=t[i];s(typeof a=="string"&&a.trim().length>ee?`${o}.${i} is longer than ${ee} characters and was dropped — pass the identifier itself, not a sentence or a URL.`:`${o}.${i} should be a string or number, got ${L(a)} — it was dropped.`)}return null}function st(t){if(t===null||typeof t=="boolean")return{ok:!0,value:t};if(typeof t=="number")return Number.isFinite(t)?{ok:!0,value:t}:{ok:!1};if(typeof t=="string")return{ok:!0,value:t.slice(0,Qn)};if(typeof t=="object")try{const e=JSON.stringify(t);if(e&&e.length<=eo)return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1}}const at=["email","name","phone"],oo=new Set(["id","userId",...at,...Object.values(be).flat()]);function ct(t,e=()=>{}){if(t==null)return null;if(typeof t!="object"||Array.isArray(t))return e(`identify() takes an object like { id, email, name } or null, got ${L(t)} — ignored.`),null;const n={};try{const o=ye(t,"id",["id","userId"],"identify()",e);o&&(n.id=o);for(const i of at){const r=t[i];if(r==null||r==="")continue;if(i==="phone"&&typeof r=="number"&&Number.isFinite(r)){n.phone=String(r);continue}if(typeof r!="string"){e(`identify().${i} should be a string, got ${L(r)} — it was dropped.`);continue}const a=r.trim().slice(0,i==="name"?200:ee);a&&(i==="email"&&!a.includes("@")&&e(`identify().email "${a}" does not look like an email address — reports cannot be threaded or followed up without one.`),n[i]=a)}for(const[i,r]of Object.entries(be)){const a=ye(t,i,r,"identify()",e);a&&(n[i]=a)}let s=0;for(const[i,r]of Object.entries(t)){if(oo.has(i)||r===void 0||typeof r=="function")continue;if(s>=te){e(`identify() was given more than ${te} extra fields; the rest were dropped.`);break}const a=st(r);if(!a.ok){e(`identify().${i} could not be sent (${L(r)} too large or not serialisable) — dropped.`);continue}n[i]=a.value,s+=1}}catch{}return!n.id&&!n.email&&e("identify() was called without an id or email — reports will not be attributed to anyone, and nothing can be looked up by user."),n}function lt(t,e,n=()=>{}){if(e===null)return{};const o={...t||{}};if(e===void 0)return o;if(typeof e!="object"||Array.isArray(e))return n(`setContext() takes an object like { loanId, screen } or null, got ${L(e)} — ignored.`),o;try{const s=new Map;for(const[i,r]of Object.entries(be))for(const a of r)s.set(a,i);for(const[i,r]of Object.entries(e)){const a=s.get(i);if(r==null){delete o[a||i];continue}if(a){const l=ye({[i]:r},a,[i],"setContext()",n);l?o[a]=l:delete o[a];continue}if(typeof r=="function")continue;if(!(i in o)&&Object.keys(o).length>=te){n(`setContext() holds at most ${te} keys; "${i}" was dropped.`);continue}const c=st(r);if(!c.ok){n(`setContext().${i} could not be sent (${L(r)} too large or not serialisable) — dropped.`);continue}o[i]=c.value}}catch{}return o}const ut=["apiBase","apiKey","projectId","consoleLimit","networkLimit","captureConsole","captureNetwork","captureErrors","widget","widgetPosition","theme","accent","attachments","maxAttachments","maxAttachmentBytes","maxRecordingMs","beforeSend","user","context","updates","updateToast","onUpdate","voice","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError","debug","drafts","knownIssues","agentIssues","release","environment","buildId","chunkBase","announcements"],io=["beforeSend","onUpdate","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError"];function ro(t){const e=t.toLowerCase().replace(/[-_]/g,"");return ut.find(n=>n.toLowerCase()===e)||null}const dt=/^(your[_-]|<|xxx|todo|changeme)/i,so=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ao(t,{pageHost:e=""}={}){const n=[],o=[];if(!t||typeof t!="object")return n.push("init() takes an options object: BugCatch.init({ apiBase, apiKey, projectId })."),{errors:n,warnings:o};const{apiKey:s,projectId:i,apiBase:r}=t;s?typeof s!="string"?n.push(`apiKey must be a string, got ${L(s)}.`):dt.test(s)?n.push(`apiKey is still the placeholder "${s}" — paste the key you saved when you created it.`):so.test(s)?o.push("apiKey looks like a project id — did you swap apiKey and projectId?"):s.startsWith("bc_")||o.push('apiKey does not look like a BugCatch key (they start with "bc_live_") — reports will be refused with HTTP 401.'):n.push("apiKey is required — create one under Workspace Settings → API Keys."),i?typeof i!="string"?n.push(`projectId must be a string, got ${L(i)}.`):dt.test(i)?n.push(`projectId is still the placeholder "${i}".`):i.startsWith("bc_")?o.push("projectId looks like an API key — did you swap apiKey and projectId?"):/\s/.test(i)&&o.push("projectId contains whitespace — check it was copied cleanly."):n.push("projectId is required — copy it from Project Settings → Web SDK."),r==null?!e||/^(localhost|127\.|0\.0\.0\.0|\[::1\])/.test(e)||o.push("apiBase is not set, so reports go to http://localhost:3000 — set apiBase to your BugCatch API URL."):(typeof r!="string"||!/^https?:\/\//.test(r))&&o.push(`apiBase should be an absolute http(s) URL, got ${JSON.stringify(r)}.`);for(const a of Object.keys(t)){if(ut.includes(a))continue;const c=ro(a);o.push(c?`unknown option "${a}" — did you mean "${c}"?`:`unknown option "${a}" is ignored.`)}for(const a of io){const c=t[a];c!=null&&typeof c!="function"&&o.push(`${a} should be a function, got ${L(c)} — it will not be called.`)}return{errors:n,warnings:o}}function co(t){return typeof t=="string"?t.replace(/\/+$/,""):t}const X={name:"@sphoro/bugcatch-web-sdk",version:"0.19.0"},q={apiBase:"http://localhost:3000",apiKey:null,projectId:null,consoleLimit:100,networkLimit:50,captureConsole:!0,captureNetwork:!0,captureErrors:!0,widget:!0,widgetPosition:"bottom-right",theme:"auto",accent:null,announcements:!0,attachments:!0,maxAttachments:5,maxAttachmentBytes:25*1024*1024,maxRecordingMs:12e4,beforeSend:null,user:null,updates:!0,updateToast:!0,onUpdate:null,voice:!0,onCallState:null,onIncomingCall:null,onReportSubmitted:null,onAssistantPhase:null,onError:null,context:null,chunkBase:null,debug:!1};function lo(t){const e=C();return e?{...t,watchToken:e}:t}class ht{constructor(){gt(this,d);this.config={...q},this.started=!1,this.teardown=[],this.consoleBuffer=W(q.consoleLimit),this.networkBuffer=W(q.networkLimit),this.stopWatching=null,this.notifier=null,this.call=null,this.callStarting=!1,this.ringing=null,this.listeners=new Map,this.context={},this.warned=new Set,this.phases=new Map}warn(e){this.warned.has(e)||(this.warned.add(e),console.warn(`[BugCatch] ${e}`))}debugLog(...e){this.config.debug&&console.info("[BugCatch]",...e)}init(e={}){if(this.started)return console.warn("[BugCatch] init() called twice — ignoring the second call."),this;const{errors:n,warnings:o}=ao(e,{pageHost:typeof location<"u"?location.hostname:""});if(n.length)throw new Error(`[BugCatch] ${n[0]}`);for(const i of o)this.warn(i);const s=this.config.user;return this.config={...q,...e,apiBase:co(e.apiBase??q.apiBase)},this.config.user=e.user!==void 0?ct(e.user,i=>this.warn(i.replace("identify()","init({ user })"))):s||null,e.context&&this.setContext(e.context),this.consoleBuffer=W(this.config.consoleLimit),this.networkBuffer=W(this.config.networkLimit),this.config.captureConsole&&this.teardown.push(Tt(this.consoleBuffer)),this.config.captureNetwork&&this.teardown.push(At(this.networkBuffer)),this.config.captureErrors&&this.teardown.push(jt(this.consoleBuffer)),rn(this.config.projectId),this.config.widget&&this.teardown.push(Jt(this)),this.config.updates&&C()&&(this.startWatching(),queueMicrotask(()=>m(this,d,K).call(this))),this.started=!0,m(this,d,mt).call(this),this.debugLog("initialised",{version:X.version,apiBase:this.config.apiBase,projectId:this.config.projectId,user:this.config.user,context:this.context}),this}startWatching(){if(this.stopWatching)return this;this.stopWatching=yn({apiBase:this.config.apiBase,onUpdate:n=>{if(n!=null&&n.incomingCall){m(this,d,xt).call(this,n);return}if(n!=null&&n.callWithdrawn){m(this,d,re).call(this,n.callWithdrawn.callId);return}const o=an(n);typeof this.config.onUpdate=="function"&&this.config.onUpdate(o),this.emit("update",o),m(this,d,K).call(this)}}),this.teardown.push(()=>{var n;return(n=this.stopWatching)==null?void 0:n.call(this)}),this.teardown.push(()=>m(this,d,re).call(this));const e=n=>{(n.key===Z||n.key===null)&&m(this,d,K).call(this)};return window.addEventListener("storage",e),this.teardown.push(()=>window.removeEventListener("storage",e)),this}on(e,n){if(typeof n!="function")return()=>{};const o=this.listeners.get(e)||new Set;return o.add(n),this.listeners.set(e,o),()=>this.off(e,n)}off(e,n){var o;return(o=this.listeners.get(e))==null||o.delete(n),this}emit(e,n){for(const o of this.listeners.get(e)||[])try{o(n)}catch(s){console.error(`[BugCatch] a '${e}' listener threw:`,s)}}unreadUpdates(){return F()}markUpdateRead(e){return cn(e),m(this,d,K).call(this),this}markReportRead(e){return ln(e),m(this,d,K).call(this),this}markUpdatesRead(){return Ve(),m(this,d,K).call(this),this}async verifyFix(e,{result:n,resolvedAt:o,note:s}){const i=n==="STILL_HAPPENING"?await m(this,d,ie).call(this,{}):{};return jn({apiBase:this.config.apiBase,bugId:e,result:n,resolvedAt:o,note:s,metadata:i.metadata,logs:i.logs})}async rate(e,{score:n,comment:o}={}){return An({apiBase:this.config.apiBase,bugId:e,score:n,comment:o})}async myReport(e){const n=await hn({apiBase:this.config.apiBase,bugId:e});return m(this,d,wt).call(this,e,n==null?void 0:n.assistant),n}replyToReport(e,{body:n,attachments:o}={}){return fn({apiBase:this.config.apiBase,bugId:e,body:n,attachments:o})}async canCallNow(){return!!await this.callKind()}async callKind(){return(await this.callKinds()).live?"live":null}async callKinds(){var n;const e={agent:!1,live:!1};return!this.config.voice||!((n=this.config.user)!=null&&n.email)?e:this.kinds!==void 0?this.kinds:(this.kinds=await pn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.kinds)}canCall(e){return this.config.voice?Ze({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}async startCall(e){var n;if(!this.config.voice)throw new Error("[BugCatch] calling is switched off.");if(this.call||this.callStarting)throw new Error("[BugCatch] a call is already running.");this.callStarting=!0;try{if(!await this.callKind())throw new Error((n=this.config.user)!=null&&n.email?"[BugCatch] calling is not available on this project.":"[BugCatch] a call needs to know who is calling — call identify() with an email first.");return await m(this,d,yt).call(this,e)}finally{this.callStarting=!1}}startLiveCall(e){return this.startCall(e)}canCallTeam(e){return this.config.voice?Ze({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}endCall(){var e;return(e=this.call)==null||e.hangUp(),this.call=null,this}myReports(){return dn({apiBase:this.config.apiBase})}hasReports(){return!!C()}forgetReports(){var e;return(e=this.stopWatching)==null||e.call(this),this.stopWatching=null,this.endCall(),N(),m(this,d,K).call(this),this}identify(e){const n=ct(e,o=>this.warn(o));return e!=null&&!n?this:(this.config.user=n,this.debugLog("identify",n),this)}setContext(e){return this.context=lt(this.context,e,n=>this.warn(n)),this.debugLog("context",this.context),this}getContext(){return{...this.context}}open(){return this.started?this.widgetControls?(this.widgetControls.open(),this):(this.warn("open() needs the built-in widget; it was turned off with widget: false."),this):(this.warn("open() was called before init() — nothing to open yet."),this)}close(){var e;return(e=this.widgetControls)==null||e.close(),this}isOpen(){var e;return!!((e=this.widgetControls)!=null&&e.isOpen())}async uploadAttachment(e,n,o){if(!this.started)throw new Error("[BugCatch] call init() first.");return tn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,blob:e,mime:n||(e==null?void 0:e.type),onProgress:o})}async report({title:e,description:n="",priority:o="MEDIUM",metadata:s={},attachments:i=[],references:r=[],context:a=null,issue:c=null}={}){var j,A,D,f,k,p,b,I;if(!this.started)throw new Error("[BugCatch] call init() first.");if(typeof e!="string"||!e.trim())throw new Error("[BugCatch] a title is required.");["LOW","MEDIUM","HIGH","CRITICAL"].includes(String(o).toUpperCase())||(this.warn(`priority "${o}" is not one of LOW, MEDIUM, HIGH, CRITICAL — sent as MEDIUM.`),o="MEDIUM");const l=(i||[]).filter(g=>(g==null?void 0:g.storageKey)&&de(g.mime,Je)).map(g=>({type:g.type==="VIDEO"?"VIDEO":"SCREENSHOT",storageKey:g.storageKey,mime:de(g.mime,Je)})),h=(Array.isArray(r)?r:[]).filter(g=>g&&typeof g.key=="string"&&g.key&&(typeof g.value=="string"||typeof g.value=="number")).map(g=>({key:g.key.slice(0,64),value:String(g.value).trim().slice(0,120)})).filter(g=>g.value);Array.isArray(r)&&h.length<r.length&&this.warn("report({ references }) takes [{ key, value }] with string values; malformed entries were dropped.");let u=await m(this,d,ie).call(this,{title:e.trim(),description:typeof n=="string"?n:String(n??""),priority:String(o).toUpperCase(),metadata:s,media:l,references:h,context:a,issue:typeof c=="string"&&c?c.slice(0,32):null});const B=m(this,d,ve).call(this,u);if(B===!1)return{cancelled:!0};u=B,this.debugLog("sending report",{title:u.title,user:(j=u.metadata)==null?void 0:j.user,context:(A=u.metadata)==null?void 0:A.context,references:u.references,console:(k=(f=(D=u.logs)==null?void 0:D.console)==null?void 0:f.entries)==null?void 0:k.length,network:(I=(b=(p=u.logs)==null?void 0:p.network)==null?void 0:b.entries)==null?void 0:I.length});const y=R(this.config.projectId);let w;try{w=await fetch(`${this.config.apiBase}/ingest/bugs`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey,...y!=null&&y.token?{"X-BugCatch-Session":y.token}:{}},body:JSON.stringify(lo(u))})}catch(g){const S=new Error(`[BugCatch] could not reach ${this.config.apiBase} — check apiBase, and that this site's origin is allowed by the API.`);throw S.cause=g,m(this,d,oe).call(this,"report",S),S}if(w.status===401&&y&&we(this.config.projectId),!w.ok){let g="";try{const O=await w.json();g=Array.isArray(O.message)?O.message.join(", "):O.message||""}catch{}w.status===401&&!y&&(g||(g="the apiKey was not accepted")),w.status===403&&(g||(g="the apiKey is not allowed to report to this projectId"));const S=w.status===429?new Error(`[BugCatch] ${_(g)}`):new Error(`[BugCatch] report failed (HTTP ${w.status})${g?": "+g:""}`);throw S.status=w.status,m(this,d,oe).call(this,"report",S),S}const M=await w.json();return m(this,d,ke).call(this,M,{title:u.title??e.trim(),via:"form"}),M.watchToken&&(fe(M.watchToken),this.config.updates&&this.startWatching()),M}loginState(){var e;return Rn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:(e=R(this.config.projectId))==null?void 0:e.token})}referenceFields(){return this.refFields?this.refFields:(this.refFields=Pn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.refFields)}agentIssues(){return this.agentIssueList?this.agentIssueList:(this.agentIssueList=_n({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.agentIssueList)}async announcements(){const e=await Fn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId});return Xn(e)}dismissAnnouncement(e){qn(e)}signedInAs(){const e=R(this.config.projectId);return e?{email:e.email,name:e.name}:null}signIn(e,{name:n}={}){var o;return Mn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,name:n??((o=this.config.user)==null?void 0:o.name)??null})}async confirmSignIn(e,n){var s;const o=await Kn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,code:n});return(s=this.config.user)!=null&&s.email||(this.config.user={email:o.email,name:o.name||void 0}),this.emit("signin",{email:o.email,name:o.name}),{email:o.email,name:o.name}}async signOut(){var o;const e=R(this.config.projectId),n=await Un({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:e==null?void 0:e.token});return e!=null&&e.email&&((o=this.config.user)==null?void 0:o.email)===e.email&&(this.config.user=null),this.emit("signout",{email:(e==null?void 0:e.email)||null}),n}knownIssues(){var e;return $n({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,sessionToken:(e=R(this.config.projectId))==null?void 0:e.token})}matchKnownIssues(e,{signal:n}={}){var o;return Bn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,q:e||"",sessionToken:(o=R(this.config.projectId))==null?void 0:o.token,signal:n})}async meToo(e,{email:n,name:o}={}){var r,a;const s=R(this.config.projectId),i=await Ee();return En({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,bugId:e,reporterEmail:n||((r=this.config.user)==null?void 0:r.email),reporterName:o||((a=this.config.user)==null?void 0:a.name),metadata:{...i,user:this.config.user||void 0,...Object.keys(this.context).length?{context:this.context}:{},sdk:X},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},sessionToken:s==null?void 0:s.token})}snapshot(){return{user:this.config.user||null,context:{...this.context},console:this.consoleBuffer.all(),network:this.networkBuffer.all(),environment:Te()}}clear(){this.consoleBuffer.clear(),this.networkBuffer.clear()}destroy(){this.endCall(),this.teardown.forEach(e=>{try{e()}catch{}}),this.teardown=[],this.notifier=null,this.started=!1}}d=new WeakSet,ne=function(e,n){const o=this.config[e];if(typeof o=="function")try{o(n)}catch(s){console.error(`[BugCatch] your ${e} callback threw:`,s)}},mt=function(){if(typeof window>"u"||typeof fetch!="function")return;const e=`bugcatch:hello:${this.config.projectId}`,n=new Date().toISOString().slice(0,10);try{if(window.localStorage.getItem(e)===n)return}catch{}const o=setTimeout(()=>{try{window.localStorage.setItem(e,n)}catch{}fetch(`${this.config.apiBase}/ingest/hello`,{method:"POST",keepalive:!0,headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey},body:JSON.stringify({projectId:this.config.projectId,version:X.version,identify:!!this.config.user,context:!!(this.context&&Object.keys(this.context).length),widget:!!this.config.widget,environment:this.config.environment||null,release:this.config.release||null})}).catch(()=>{})},5e3);this.teardown.push(()=>clearTimeout(o))},K=function(){const e=F();if(this.emit("unread",{count:e.length,updates:e}),!!this.config.updateToast){if(!this.notifier){if(!e.length)return;this.notifier=Sn({accent:this.config.accent,position:this.config.widgetPosition,onRead:n=>this.markUpdateRead(n),onReadAll:()=>this.markUpdatesRead(),onCall:this.config.voice?n=>{this.markUpdateRead(n.id),this.startCall(n.bugId)}:null}),this.teardown.push(()=>{var n;return(n=this.notifier)==null?void 0:n.destroy()})}this.notifier.render(e)}},wt=function(e,n){const o=n==null?void 0:n.phase;if(!e||typeof o!="string"||this.phases.get(e)===o)return;this.phases.set(e,o);const s={bugId:e,phase:o,title:n.title??null,detail:n.detail??null};this.debugLog("assistant",s),m(this,d,ne).call(this,"onAssistantPhase",s),this.emit("assistant",s)},ke=function(e,{title:n,via:o}){if(!(e!=null&&e.id))return;const s={bugId:e.id,title:n??null,via:o,result:e};this.debugLog("report accepted",s),m(this,d,ne).call(this,"onReportSubmitted",s),this.emit("report",s)},oe=function(e,n){m(this,d,ne).call(this,"onError",{action:e,error:n}),this.emit("error",{action:e,error:n})},ie=async function({title:e,description:n="",priority:o="MEDIUM",metadata:s={},media:i=[],references:r=[],context:a=null,issue:c=null}){var h,u;const l=a?lt(this.context,a,B=>this.warn(B.replace("setContext()","report({ context })"))):this.context;return{projectId:this.config.projectId,...e?{title:e}:{},description:n,priority:o,url:window.location.href,reporterEmail:(h=this.config.user)==null?void 0:h.email,reporterName:(u=this.config.user)==null?void 0:u.name,metadata:{...await Ee(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,...s,user:this.config.user||void 0,...Object.keys(l).length?{context:l}:{},sdk:X},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},...i.length?{attachments:i}:{},...r.length?{references:r}:{},...c?{issue:c}:{}}},ve=function(e){if(typeof this.config.beforeSend!="function")return e;let n;try{n=this.config.beforeSend(e)}catch(o){return this.warn(`beforeSend threw, so nothing was sent: ${(o==null?void 0:o.message)||o}`),!1}return n===!1?!1:n&&typeof n=="object"?n:e},bt=async function(){const e=R(this.config.projectId),n=m(this,d,ve).call(this,await m(this,d,ie).call(this,{}));if(n===!1)return this.debugLog("call cancelled by beforeSend"),{cancelled:!0};let o;try{o=await gn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:e==null?void 0:e.token,payload:n,watchToken:C()})}catch(s){throw s.status===401&&e&&we(this.config.projectId),m(this,d,oe).call(this,"call",s),s}return m(this,d,ke).call(this,o,{title:null,via:"call"}),o.watchToken&&(fe(o.watchToken),this.config.updates&&this.startWatching()),o},yt=async function(e){const{joinLiveCall:n,liveCallSupported:o,openMicrophone:s}=await J(this.config.chunkBase);if(!o())throw new Error("[BugCatch] this browser cannot make live calls.");const i=await s();let r,a=null;try{if(e)r=await mn({apiBase:this.config.apiBase,bugId:e});else if(a=await m(this,d,bt).call(this),e=a.id,r=a.live_call,!(r!=null&&r.realtime_url)){const l=new Error(`[BugCatch] the report was filed, but the team could not be rung${a.call_error?`: ${a.call_error}`:"."}`);throw l.filed=a,l.reason=a.call_error||null,l}}catch(l){for(const h of i.getTracks())h.stop();throw l}const c=await n({realtimeUrl:r.realtime_url,stream:i,ringsUntil:r.rings_until,onState:(l,h)=>{(l==="ended"||l==="failed"||l==="missed")&&(this.call=null),l==="missed"&&wn({apiBase:this.config.apiBase,bugId:e,callId:r.call_id}),typeof this.config.onCallState=="function"&&this.config.onCallState(l,{bugId:e,live:!0,...h}),this.emit("call",{bugId:e,live:!0,state:l,...h})}});return this.call=c,Object.assign(c,{bugId:e,callId:r.call_id,live:!0,filed:a,recorded:!!r.recorded})},xt=function(e){var s;const n=e.incomingCall;if(!this.config.voice||((s=this.ringing)==null?void 0:s.callId)===n.callId||this.call||this.callStarting)return;m(this,d,re).call(this);const o={callId:n.callId,dismiss:()=>{}};this.ringing=o,J(this.config.chunkBase).then(({liveCallSupported:i,showIncomingCall:r})=>{if(this.ringing!==o||(this.ringing=null,!i())||this.call||this.callStarting)return;const a=r({call:n,accent:this.config.accent,position:this.config.widgetPosition,touched:Nn,onAnswer:()=>{m(this,d,kt).call(this,e.bugId,n)},onDecline:()=>{this.ringing=null,Ge({apiBase:this.config.apiBase,bugId:e.bugId,callId:n.callId}),this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"declined"})},onExpire:()=>{this.ringing=null,this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"missed"})}});if(this.ringing={callId:n.callId,dismiss:a},typeof this.config.onIncomingCall=="function")try{this.config.onIncomingCall({bugId:e.bugId,...n})}catch{}this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"ringing"})},()=>{this.ringing===o&&(this.ringing=null)})},re=function(e){if(this.ringing&&!(e&&this.ringing.callId!==e)){try{this.ringing.dismiss()}catch{}this.ringing=null}},kt=async function(e,n){if(this.ringing=null,this.call||this.callStarting)return;this.callStarting=!0;let o,s;try{const r=await J(this.config.chunkBase);s=r.joinLiveCall,o=await r.openMicrophone()}catch(r){this.callStarting=!1,Ge({apiBase:this.config.apiBase,bugId:e,callId:n.callId}),this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:r});return}let i;try{i=await bn({apiBase:this.config.apiBase,bugId:e,callId:n.callId})}catch(r){for(const a of o.getTracks())a.stop();this.callStarting=!1,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"missed",error:r});return}try{const r=await s({realtimeUrl:i.realtime_url,stream:o,onState:(a,c)=>{(a==="ended"||a==="failed"||a==="missed")&&(this.call=null),typeof this.config.onCallState=="function"&&this.config.onCallState(a,{bugId:e,live:!0,incoming:!0,...c}),this.emit("call",{bugId:e,live:!0,incoming:!0,state:a,...c})}});this.call=r,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"answered"})}catch(r){for(const a of o.getTracks())a.stop();this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:r})}finally{this.callStarting=!1}};const xe=new ht;return xe.Client=ht,xe.version=X.version,xe});
|
|
309
|
+
`)}return n}async function un({apiBase:t}){const e=$();if(!e)return{reporter:null,reports:[]};const n=await fetch(`${t}/ingest/watch/reports${G()}`,{headers:{Authorization:`Bearer ${e}`}});if(n.status===401)return D(),{reporter:null,reports:[]};if(!n.ok)throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);return n.json()}async function hn({apiBase:t,bugId:e}){const n=$();if(!n)return null;const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}${G()}`,{headers:{Authorization:`Bearer ${n}`}});if(o.status===401)return D(),null;if(o.status===404)return null;if(!o.ok)throw new Error(`[BugCatch] could not load that report (HTTP ${o.status})`);return o.json()}async function fn({apiBase:t,bugId:e,body:n,attachments:o}){const r=$();if(!r)throw new Error("[BugCatch] nothing filed from this browser yet.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`},body:JSON.stringify({...n?{body:n}:{},...o!=null&&o.length?{attachments:o}:{}})});if(i.status===401)throw D(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!i.ok){let s="";try{const a=await i.json();s=Array.isArray(a.message)?a.message.join(", "):a.message||""}catch{}throw i.status===429?new Error(_(s)):new Error(s||`[BugCatch] could not send that (HTTP ${i.status}).`)}return i.json()}async function pn({apiBase:t,apiKey:e,projectId:n}){const o={agent:!1,live:!1};try{const r=await fetch(`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!r.ok)return o;const i=await r.json();return i!=null&&i.available?i.kinds&&typeof i.kinds=="object"?{agent:!1,live:!!i.kinds.live}:{agent:!1,live:i.kind==="live"}:o}catch{return o}}async function gn({apiBase:t,apiKey:e,token:n,payload:o,watchToken:r}){const i=await fetch(`${t}/ingest/calls`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e,...n?{"X-BugCatch-Session":n}:{}},body:JSON.stringify(r?{...o,watchToken:r}:o)});if(!i.ok){let s="";try{const c=await i.json();s=Array.isArray(c.message)?c.message.join(", "):c.message||""}catch{}const a=new Error(i.status===429?_(s):s||`[BugCatch] the call could not be started (HTTP ${i.status}).`);throw a.status=i.status,a}return i.json()}async function Ze({apiBase:t,bugId:e}){const n=$();if(!n)return!1;try{const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{headers:{Authorization:`Bearer ${n}`}});if(!o.ok)return!1;const r=await o.json();return!!(r!=null&&r.offered)}catch{return!1}}async function mn({apiBase:t,bugId:e}){const n=$();if(!n)throw new Error("[BugCatch] nothing filed from this browser yet.");const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{method:"POST",headers:{Authorization:`Bearer ${n}`}});if(o.status===401)throw D(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!o.ok){let r="";try{const i=await o.json();r=Array.isArray(i.message)?i.message.join(", "):i.message||""}catch{}throw new Error(r||`[BugCatch] the call could not be started (HTTP ${o.status}).`)}return o.json()}async function wn({apiBase:t,bugId:e,callId:n}){const o=$();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}async function bn({apiBase:t,bugId:e,callId:n}){const o=$();if(!o)throw new Error("[BugCatch] nothing filed from this browser yet.");const r=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(r.status===401)throw D(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(r.status===409)throw new Error("[BugCatch] that call is no longer ringing.");if(!r.ok){let i="";try{const s=await r.json();i=Array.isArray(s.message)?s.message.join(", "):s.message||""}catch{}throw new Error(i||`[BugCatch] the call could not be answered (HTTP ${r.status}).`)}return r.json()}async function Qe({apiBase:t,bugId:e,callId:n}){const o=$();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}function yn({apiBase:t,onUpdate:e}){let n=!0,o=0,r=null;async function i(){const s=$();if(!s)throw new Error("nothing filed from this browser yet");r=new AbortController;const a=await fetch(`${t}/ingest/watch/stream${G()}`,{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"},signal:r.signal});if(a.status===401)throw n=!1,D(),new Error("subscription no longer valid");if(!a.ok||!a.body)throw new Error(`stream failed (${a.status})`);const c=Date.now(),l=a.body.getReader(),d=new TextDecoder;let u="";try{for(;;){const{value:B,done:x}=await l.read();if(x)break;u+=d.decode(B,{stream:!0}),u=dn(u,C=>{if(C.type!=="ping")try{e(C)}catch{}})}}finally{Date.now()-c>=on&&(o=0)}}return(async()=>{for(;n;){try{await i()}catch(a){if((a==null?void 0:a.name)==="AbortError")return}if(!n)return;const s=Ve[Math.min(o,Ve.length-1)];o+=1,await new Promise(a=>setTimeout(a,s))}})(),()=>{n=!1,r==null||r.abort(),r=null}}const xn={OPEN:"is open",IN_PROGRESS:"is being worked on",RESOLVED:"has been fixed",CLOSED:"has been closed"},kn={status:null,severity:"#f2a54a",assignment:"#79a8ff",reply:"#4fd19a"},T={bg:"#111113",fg:"#f3f2ef",muted:"#b3b0aa",faint:"#8f8c86",ring:"rgba(255,255,255,.09)",brand:"#a59cff"};function et(t){return t!=null&&t.summary?t.summary:`Your report ${xn[t==null?void 0:t.status]||"was updated"}`}function vn(t){var e;return(t==null?void 0:t.kind)==="reply"&&((e=t.reply)!=null&&e.body)?`${t.reply.author?`${t.reply.author}: `:""}${t.reply.body}`:(t==null?void 0:t.title)||""}function Cn(t){const e=Date.parse(t||"");if(!Number.isFinite(e))return"";const n=Math.round((Date.now()-e)/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;const o=Math.round(n/60);if(o<24)return`${o}h ago`;const r=Math.round(o/24);return r===1?"yesterday":`${r}d ago`}function In(){var t;try{const e=document.querySelector('[data-bugcatch="widget"]'),n=(t=e==null?void 0:e.shadowRoot)==null?void 0:t.querySelector(".dock"),o=(n==null?void 0:n.getBoundingClientRect().height)||0;return o?Math.round(o)+12:0}catch{return 0}}function Sn({accent:t=null,position:e="bottom-right",onRead:n=null,onReadAll:o=null,onCall:r=null}={}){const[i,s]=String(e).split("-"),a=i==="top",c=s==="left",l=new Map;let d=null,u=null;function B(){return d!=null&&d.isConnected||(d=document.createElement("div"),d.setAttribute("data-bugcatch","updates"),d.style.cssText=["position:fixed",`${a?"top":"bottom"}:${20+In()}px`,`${c?"left":"right"}:20px`,"z-index:2147482998","display:flex","flex-direction:column","gap:10px",`align-items:${c?"flex-start":"flex-end"}`,"width:min(320px,calc(100vw - 40px))","pointer-events:none"].join(";"),document.body.appendChild(d)),d}function x(p){if(!p._bcShown){p.remove();return}p.style.opacity="0",p.style.transform=`translateY(${a?-8:8}px)`,setTimeout(()=>p.remove(),250)}const C=t||he,m=t?ze(t):He;function L(p,k){const v=document.createElement("button");return v.type="button",v.textContent=p,v.style.cssText=["padding:6px 12px","border:0",`box-shadow:${k?"none":`inset 0 0 0 1px ${T.ring}`}`,"border-radius:999px",`background:${k?C:"rgba(255,255,255,.06)"}`,`color:${k?m:T.fg}`,"font:560 12px/1.4 inherit","cursor:pointer","white-space:nowrap"].join(";"),v}function N(p){var R;const k=document.createElement("div");k.setAttribute("role","status"),k.style.cssText=["box-sizing:border-box","width:100%","padding:13px 14px","border-radius:14px",`background:${T.bg}`,`color:${T.fg}`,'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',`box-shadow:0 0 0 1px ${T.ring},0 20px 44px -12px rgba(0,0,0,.55),0 4px 12px rgba(0,0,0,.25)`,"opacity:0",`transform:translateY(${a?-8:8}px)`,"transition:opacity .2s ease,transform .2s ease","pointer-events:auto"].join(";");const v=document.createElement("div");v.style.cssText="display:flex;align-items:baseline;gap:8px;font-weight:600;margin-bottom:2px";const w=document.createElement("span");w.setAttribute("aria-hidden","true"),w.style.cssText=`flex:none;width:7px;height:7px;border-radius:50%;transform:translateY(-1px);background:${kn[p==null?void 0:p.kind]||t||T.brand}`;const b=document.createElement("span");b.textContent=et(p),v.append(w,b);const f=document.createElement("div");f.style.cssText=(p==null?void 0:p.kind)==="reply"?`color:${T.muted};padding-left:15px;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden`:`color:${T.muted};padding-left:15px`,f.textContent=vn(p);const S=document.createElement("div");S.style.cssText="display:flex;align-items:center;gap:8px;margin-top:10px;padding-left:15px;flex-wrap:wrap";const O=document.createElement("span");O.style.cssText=`color:${T.faint};font-size:11px;margin-right:auto`,O.textContent=Cn(p==null?void 0:p.at);const y=L("Mark as read",!1);if(y.setAttribute("aria-label",`Mark as read: ${et(p)}`),y.addEventListener("click",()=>n==null?void 0:n(p.id)),S.append(O,y),(R=p==null?void 0:p.call)!=null&&R.offered&&typeof r=="function"){const ft=L("Talk it through",!0);ft.addEventListener("click",()=>r(p)),S.insertBefore(ft,y)}return k.append(v,f,S),k}function j(p){const k=document.createElement("div");k.style.cssText=["box-sizing:border-box","width:100%","display:flex","align-items:center","gap:8px","padding:8px 10px 8px 14px","border-radius:999px",`background:${T.bg}`,`color:${T.muted}`,'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',`box-shadow:0 0 0 1px ${T.ring},0 12px 30px -10px rgba(0,0,0,.5)`,"pointer-events:auto"].join(";");const v=document.createElement("span");v.style.cssText="margin-right:auto",v.textContent=`${p} more update${p===1?"":"s"}`;const w=L("Mark all as read",!1);return w.style.cssText+=";padding:4px 9px",w.addEventListener("click",()=>o==null?void 0:o()),k.append(v,w),k}return{render(p){const k=Array.isArray(p)?p:[];if(!k.length){for(const y of l.values())x(y);l.clear(),u==null||u.remove(),u=null,d==null||d.remove(),d=null;return}const v=k.slice(-3),w=new Set(v.map(y=>y.id)),b=B();for(const[y,R]of l)w.has(y)||(x(R),l.delete(y));const f=[];for(const y of v){if(l.has(y.id))continue;const R=N(y);l.set(y.id,R),f.push(R)}const S=a?[...v].reverse():v;for(const y of S)b.appendChild(l.get(y.id));const O=k.length-v.length;O>0?(u==null||u.remove(),u=j(O),a?b.appendChild(u):b.insertBefore(u,b.firstChild)):(u==null||u.remove(),u=null),requestAnimationFrame(()=>{for(const y of f)y.isConnected&&(y._bcShown=!0,y.style.opacity="1",y.style.transform="translateY(0)")})},destroy(){l.clear(),u=null,d==null||d.remove(),d=null}}}async function Bn({apiBase:t,apiKey:e,projectId:n,sessionToken:o}){try{const r=await fetch(`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,{headers:me(e,o)});if(!r.ok)return[];const i=await r.json();return Array.isArray(i==null?void 0:i.issues)?i.issues:[]}catch{return[]}}async function $n({apiBase:t,apiKey:e,projectId:n,q:o,sessionToken:r,signal:i}){try{const s=`${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(o)}`,a=await fetch(s,{headers:me(e,r),signal:i});if(!a.ok)return[];const c=await a.json();return Array.isArray(c==null?void 0:c.issues)?c.issues:[]}catch{return[]}}async function En({apiBase:t,apiKey:e,projectId:n,bugId:o,reporterEmail:r,reporterName:i,metadata:s,logs:a,sessionToken:c}){const l=$(),d=await fetch(`${t}/ingest/known-issues/${encodeURIComponent(o)}/join`,{method:"POST",headers:me(e,c),body:JSON.stringify({projectId:n,reporterEmail:r,reporterName:i,metadata:s,logs:a,...l?{watchToken:l}:{}})});if(!d.ok)throw new Error(await An(d));const u=await d.json();return u!=null&&u.watchToken&&ge(u.watchToken),u}function me(t,e){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function An(t){let e="";try{const n=await t.json();e=Array.isArray(n.message)?n.message.join(", "):n.message||""}catch{}return t.status===429?_(e):e||`Could not add you to this issue (HTTP ${t.status})`}async function Tn({apiBase:t,bugId:e,score:n,comment:o}){const r=$();if(!r)throw new Error("This browser cannot access that report.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/rating${G()}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`},body:JSON.stringify({score:n,...o?{comment:o}:{}})}),s=await i.json().catch(()=>({}));if(!i.ok){const a=Array.isArray(s.message)?s.message.join(", "):s.message;throw new Error(a||"Could not send your rating. Please try again.")}return s}async function jn({apiBase:t,bugId:e,...n}){const o=$();if(!o)throw new Error("This browser cannot access that report.");const r=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify(n)}),i=await r.json().catch(()=>({}));if(!r.ok)throw new Error(i.message||"Could not record feedback. Please refresh and try again.");return i}const On="bugcatch.session.",we=t=>`${On}${t}`,be=new Map;function M(t){var e;if(!t)return null;try{const n=(e=window.localStorage)==null?void 0:e.getItem(we(t));if(n){const o=JSON.parse(n);if(o!=null&&o.token)return o}}catch{}return be.get(t)||null}function Ln(t,e){var o;if(!t||!(e!=null&&e.token))return;const n={token:e.token,email:e.email||null,name:e.name||null};be.set(t,n);try{(o=window.localStorage)==null||o.setItem(we(t),JSON.stringify(n))}catch{}}function ye(t){var e;if(t){be.delete(t);try{(e=window.localStorage)==null||e.removeItem(we(t))}catch{}}}function ee({apiKey:t,token:e}){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function tt(t){let e="";try{const n=await t.json();e=Array.isArray(n.message)?n.message.join(", "):n.message||""}catch{}return t.status===429?_(e):e||`Request failed (HTTP ${t.status})`}async function Rn({apiBase:t,apiKey:e,projectId:n,token:o}){const r={mode:"off",signedIn:null,signedOutReason:null};try{const i=await fetch(`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,{headers:ee({apiKey:e,token:o})});if(!i.ok)return r;const s=await i.json();return{mode:s.mode==="optional"||s.mode==="required"?s.mode:"off",signedIn:s.signedIn||null,signedOutReason:s.signedOutReason||null}}catch{return r}}async function Mn({apiBase:t,apiKey:e,projectId:n,email:o,name:r}){const i=await fetch(`${t}/ingest/login/start`,{method:"POST",headers:ee({apiKey:e}),body:JSON.stringify({projectId:n,email:o,...r?{name:r}:{}})});if(!i.ok)throw new Error(await tt(i));return i.json()}async function Kn({apiBase:t,apiKey:e,projectId:n,email:o,code:r}){const i=await fetch(`${t}/ingest/login`,{method:"POST",headers:ee({apiKey:e}),body:JSON.stringify({projectId:n,email:o,code:r})});if(!i.ok)throw new Error(await tt(i));const s=await i.json(),a={token:s.sessionToken,email:s.email,name:s.name};return Ln(n,a),a}async function Nn({apiBase:t,apiKey:e,projectId:n,token:o}){if(ye(n),!o)return{signedOut:!0};try{await fetch(`${t}/ingest/logout`,{method:"POST",headers:ee({apiKey:e,token:o}),body:JSON.stringify({projectId:n})})}catch{}return{signedOut:!0}}let nt=!1;if(typeof window<"u"&&window.addEventListener)for(const t of["pointerdown","keydown","touchstart"])window.addEventListener(t,()=>{nt=!0},{once:!0,capture:!0,passive:!0});function Un(){return nt}async function Pn({apiBase:t,apiKey:e,projectId:n}){const o={policy:"off",fields:[]};try{const r=await fetch(`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!r.ok)return o;const i=await r.json(),s=i.policy==="optional"||i.policy==="required"?i.policy:"off",a=Array.isArray(i.fields)?i.fields:[];return a.length?{policy:s,fields:a}:o}catch{return o}}async function _n({apiBase:t,apiKey:e,projectId:n}){try{const o=await fetch(`${t}/ingest/agent-issues?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!o.ok)return[];const r=await o.json();return(Array.isArray(r==null?void 0:r.issues)?r.issues:[]).filter(i=>i&&typeof i.key=="string"&&typeof i.title=="string").map(i=>({key:i.key,title:i.title,hint:typeof i.hint=="string"?i.hint:""}))}catch{return[]}}const Dn=5*6e4,ot="bugcatch:announcements:seen",Hn=40,zn=["info","success","warning","critical"],it=t=>`bugcatch:announcements:${t}`;async function Fn({apiBase:t,apiKey:e,projectId:n,fresh:o=!1}){var r;if(!o){const i=Gn(n);if(i)return i}try{const i=await fetch(`${t}/ingest/announcements?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}}),s=i.ok?Vn((r=await i.json())==null?void 0:r.announcements):[];return Zn(n,s),s}catch{return[]}}function Xn(t,{on:e=Jn(),seen:n=st()}={}){return(t||[]).filter(o=>Yn(o,e)&&!(o.dismissible&&n.includes(rt(o))))}function qn(t){if(!(!(t!=null&&t.id)||!t.dismissible))try{const e=rt(t),n=[...st().filter(o=>o!==e),e];localStorage.setItem(ot,JSON.stringify(n.slice(-Hn)))}catch{}}function Wn(t){return typeof t!="string"||!t||t.startsWith("//")?null:t.startsWith("/")||/^(https?:\/\/|mailto:)./i.test(t)?t:null}function Jn(t=new Date){const e=n=>String(n).padStart(2,"0");return`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}`}function Yn(t,e){return!(t.startsOn&&e<t.startsOn||t.endsOn&&e>t.endsOn)}function rt(t){return`${t.id}#${t.revision||0}`}function Vn(t){return(Array.isArray(t)?t:[]).filter(e=>e&&typeof e.id=="string"&&typeof e.title=="string"&&e.title.trim()).map(e=>{const n=e.placement==="launcher"?"launcher":"panel",o=Wn(e.ctaHref);return{id:e.id,revision:Number.isInteger(e.revision)?e.revision:0,title:e.title,body:typeof e.body=="string"?e.body:"",tone:zn.includes(e.tone)?e.tone:"info",ctaLabel:o&&typeof e.ctaLabel=="string"?e.ctaLabel:"",ctaHref:o&&typeof e.ctaLabel=="string"?o:"",placement:n,dismissible:n==="launcher"||e.dismissible!==!1,startsOn:typeof e.startsOn=="string"?e.startsOn:"",endsOn:typeof e.endsOn=="string"?e.endsOn:""}})}function st(){try{const t=JSON.parse(localStorage.getItem(ot)||"[]");return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}catch{return[]}}function Gn(t){try{const e=JSON.parse(localStorage.getItem(it(t))||"null");if(!e||!Array.isArray(e.list)||typeof e.at!="number")return null;const n=Date.now()-e.at;return n>=0&&n<Dn?e.list:null}catch{return null}}function Zn(t,e){try{localStorage.setItem(it(t),JSON.stringify({at:Date.now(),list:e}))}catch{}}const Qn=["idea","praise","confusing","other"],eo=5,to=4e3;async function no({apiBase:t,apiKey:e,projectId:n}){try{const o=await fetch(`${t}/ingest/feedback?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!o.ok)return!1;const r=await o.json();return(r==null?void 0:r.enabled)===!0}catch{return!1}}function oo({message:t,kind:e,score:n,email:o,name:r}={}){const i=typeof t=="string"?t.trim().slice(0,to):"";if(!i)throw new Error("[BugCatch] feedback needs a message.");const s=typeof n=="string"&&n.trim()!==""?Number(n):n,a=typeof o=="string"?o.trim():"",c=typeof r=="string"?r.trim():"";return{message:i,...Qn.includes(e)?{kind:e}:{},...Number.isInteger(s)&&s>=1&&s<=eo?{score:s}:{},...a?{email:a.slice(0,254)}:{},...c?{name:c.slice(0,120)}:{}}}async function io({apiBase:t,apiKey:e,token:n,payload:o}){let r;try{r=await fetch(`${t}/ingest/feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e,...n?{"X-BugCatch-Session":n}:{}},body:JSON.stringify(o)})}catch(i){const s=new Error(`[BugCatch] could not reach ${t} — check your connection and try again.`);throw s.cause=i,s}if(!r.ok){let i="";try{const a=await r.json();i=Array.isArray(a.message)?a.message.join(", "):a.message||""}catch{}const s=r.status===429?new Error(`[BugCatch] ${_(i)}`):new Error(`[BugCatch] ${i||`feedback could not be sent (HTTP ${r.status})`}`);throw s.status=r.status,s}return r.json()}const te=120,ro=500,ne=30,so=1e3,xe={loanId:["loanId","loanNumber"],applicationId:["applicationId"],customerNumber:["customerNumber","customerId"]},ao=/[\u0000-\u001f\u007f]/;function co(t){if(typeof t=="number")return Number.isFinite(t)?String(t):null;if(typeof t!="string")return null;const e=t.trim();return!e||e.length>te||ao.test(e)?null:e}function K(t){return t===null?"null":Array.isArray(t)?"an array":typeof t=="object"?"an object":`a ${typeof t}`}function ke(t,e,n,o,r){for(const i of n){if(!(i in t)||t[i]===void 0||t[i]===null||t[i]==="")continue;const s=co(t[i]);if(s)return s;const a=t[i];r(typeof a=="string"&&a.trim().length>te?`${o}.${i} is longer than ${te} characters and was dropped — pass the identifier itself, not a sentence or a URL.`:`${o}.${i} should be a string or number, got ${K(a)} — it was dropped.`)}return null}function at(t){if(t===null||typeof t=="boolean")return{ok:!0,value:t};if(typeof t=="number")return Number.isFinite(t)?{ok:!0,value:t}:{ok:!1};if(typeof t=="string")return{ok:!0,value:t.slice(0,ro)};if(typeof t=="object")try{const e=JSON.stringify(t);if(e&&e.length<=so)return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1}}const ct=["email","name","phone"],lo=new Set(["id","userId",...ct,...Object.values(xe).flat()]);function lt(t,e=()=>{}){if(t==null)return null;if(typeof t!="object"||Array.isArray(t))return e(`identify() takes an object like { id, email, name } or null, got ${K(t)} — ignored.`),null;const n={};try{const o=ke(t,"id",["id","userId"],"identify()",e);o&&(n.id=o);for(const i of ct){const s=t[i];if(s==null||s==="")continue;if(i==="phone"&&typeof s=="number"&&Number.isFinite(s)){n.phone=String(s);continue}if(typeof s!="string"){e(`identify().${i} should be a string, got ${K(s)} — it was dropped.`);continue}const a=s.trim().slice(0,i==="name"?200:te);a&&(i==="email"&&!a.includes("@")&&e(`identify().email "${a}" does not look like an email address — reports cannot be threaded or followed up without one.`),n[i]=a)}for(const[i,s]of Object.entries(xe)){const a=ke(t,i,s,"identify()",e);a&&(n[i]=a)}let r=0;for(const[i,s]of Object.entries(t)){if(lo.has(i)||s===void 0||typeof s=="function")continue;if(r>=ne){e(`identify() was given more than ${ne} extra fields; the rest were dropped.`);break}const a=at(s);if(!a.ok){e(`identify().${i} could not be sent (${K(s)} too large or not serialisable) — dropped.`);continue}n[i]=a.value,r+=1}}catch{}return!n.id&&!n.email&&e("identify() was called without an id or email — reports will not be attributed to anyone, and nothing can be looked up by user."),n}function ve(t,e,n=()=>{}){if(e===null)return{};const o={...t||{}};if(e===void 0)return o;if(typeof e!="object"||Array.isArray(e))return n(`setContext() takes an object like { loanId, screen } or null, got ${K(e)} — ignored.`),o;try{const r=new Map;for(const[i,s]of Object.entries(xe))for(const a of s)r.set(a,i);for(const[i,s]of Object.entries(e)){const a=r.get(i);if(s==null){delete o[a||i];continue}if(a){const l=ke({[i]:s},a,[i],"setContext()",n);l?o[a]=l:delete o[a];continue}if(typeof s=="function")continue;if(!(i in o)&&Object.keys(o).length>=ne){n(`setContext() holds at most ${ne} keys; "${i}" was dropped.`);continue}const c=at(s);if(!c.ok){n(`setContext().${i} could not be sent (${K(s)} too large or not serialisable) — dropped.`);continue}o[i]=c.value}}catch{}return o}const dt=["apiBase","apiKey","projectId","consoleLimit","networkLimit","captureConsole","captureNetwork","captureErrors","widget","widgetPosition","theme","accent","attachments","maxAttachments","maxAttachmentBytes","maxRecordingMs","beforeSend","user","context","updates","updateToast","onUpdate","voice","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError","debug","drafts","knownIssues","agentIssues","release","environment","buildId","chunkBase","announcements","feedback"],uo=["beforeSend","onUpdate","onCallState","onIncomingCall","onReportSubmitted","onAssistantPhase","onError"];function ho(t){const e=t.toLowerCase().replace(/[-_]/g,"");return dt.find(n=>n.toLowerCase()===e)||null}const ut=/^(your[_-]|<|xxx|todo|changeme)/i,fo=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function po(t,{pageHost:e=""}={}){const n=[],o=[];if(!t||typeof t!="object")return n.push("init() takes an options object: BugCatch.init({ apiBase, apiKey, projectId })."),{errors:n,warnings:o};const{apiKey:r,projectId:i,apiBase:s}=t;r?typeof r!="string"?n.push(`apiKey must be a string, got ${K(r)}.`):ut.test(r)?n.push(`apiKey is still the placeholder "${r}" — paste the key you saved when you created it.`):fo.test(r)?o.push("apiKey looks like a project id — did you swap apiKey and projectId?"):r.startsWith("bc_")||o.push('apiKey does not look like a BugCatch key (they start with "bc_live_") — reports will be refused with HTTP 401.'):n.push("apiKey is required — create one under Workspace Settings → API Keys."),i?typeof i!="string"?n.push(`projectId must be a string, got ${K(i)}.`):ut.test(i)?n.push(`projectId is still the placeholder "${i}".`):i.startsWith("bc_")?o.push("projectId looks like an API key — did you swap apiKey and projectId?"):/\s/.test(i)&&o.push("projectId contains whitespace — check it was copied cleanly."):n.push("projectId is required — copy it from Project Settings → Web SDK."),s==null?!e||/^(localhost|127\.|0\.0\.0\.0|\[::1\])/.test(e)||o.push("apiBase is not set, so reports go to http://localhost:3000 — set apiBase to your BugCatch API URL."):(typeof s!="string"||!/^https?:\/\//.test(s))&&o.push(`apiBase should be an absolute http(s) URL, got ${JSON.stringify(s)}.`);for(const a of Object.keys(t)){if(dt.includes(a))continue;const c=ho(a);o.push(c?`unknown option "${a}" — did you mean "${c}"?`:`unknown option "${a}" is ignored.`)}for(const a of uo){const c=t[a];c!=null&&typeof c!="function"&&o.push(`${a} should be a function, got ${K(c)} — it will not be called.`)}return{errors:n,warnings:o}}function go(t){return typeof t=="string"?t.replace(/\/+$/,""):t}const H={name:"@sphoro/bugcatch-web-sdk",version:"0.21.0"},q={apiBase:"http://localhost:3000",apiKey:null,projectId:null,consoleLimit:100,networkLimit:50,captureConsole:!0,captureNetwork:!0,captureErrors:!0,widget:!0,widgetPosition:"bottom-right",theme:"auto",accent:null,announcements:!0,feedback:!0,attachments:!0,maxAttachments:5,maxAttachmentBytes:25*1024*1024,maxRecordingMs:12e4,beforeSend:null,user:null,updates:!0,updateToast:!0,onUpdate:null,voice:!0,onCallState:null,onIncomingCall:null,onReportSubmitted:null,onAssistantPhase:null,onError:null,context:null,chunkBase:null,debug:!1};function mo(t){const e=$();return e?{...t,watchToken:e}:t}class ht{constructor(){gt(this,h);this.config={...q},this.started=!1,this.teardown=[],this.consoleBuffer=J(q.consoleLimit),this.networkBuffer=J(q.networkLimit),this.stopWatching=null,this.notifier=null,this.call=null,this.callStarting=!1,this.ringing=null,this.listeners=new Map,this.context={},this.warned=new Set,this.phases=new Map}warn(e){this.warned.has(e)||(this.warned.add(e),console.warn(`[BugCatch] ${e}`))}debugLog(...e){this.config.debug&&console.info("[BugCatch]",...e)}init(e={}){if(this.started)return console.warn("[BugCatch] init() called twice — ignoring the second call."),this;const{errors:n,warnings:o}=po(e,{pageHost:typeof location<"u"?location.hostname:""});if(n.length)throw new Error(`[BugCatch] ${n[0]}`);for(const i of o)this.warn(i);const r=this.config.user;return this.config={...q,...e,apiBase:go(e.apiBase??q.apiBase)},this.config.user=e.user!==void 0?lt(e.user,i=>this.warn(i.replace("identify()","init({ user })"))):r||null,e.context&&this.setContext(e.context),this.consoleBuffer=J(this.config.consoleLimit),this.networkBuffer=J(this.config.networkLimit),this.config.captureConsole&&this.teardown.push(At(this.consoleBuffer)),this.config.captureNetwork&&this.teardown.push(Tt(this.networkBuffer)),this.config.captureErrors&&this.teardown.push(jt(this.consoleBuffer)),rn(this.config.projectId),this.config.widget&&this.teardown.push(Jt(this)),this.config.updates&&$()&&(this.startWatching(),queueMicrotask(()=>g(this,h,U).call(this))),this.started=!0,g(this,h,mt).call(this),this.debugLog("initialised",{version:H.version,apiBase:this.config.apiBase,projectId:this.config.projectId,user:this.config.user,context:this.context}),this}startWatching(){if(this.stopWatching)return this;this.stopWatching=yn({apiBase:this.config.apiBase,onUpdate:n=>{if(n!=null&&n.incomingCall){g(this,h,xt).call(this,n);return}if(n!=null&&n.callWithdrawn){g(this,h,se).call(this,n.callWithdrawn.callId);return}const o=an(n);typeof this.config.onUpdate=="function"&&this.config.onUpdate(o),this.emit("update",o),g(this,h,U).call(this)}}),this.teardown.push(()=>{var n;return(n=this.stopWatching)==null?void 0:n.call(this)}),this.teardown.push(()=>g(this,h,se).call(this));const e=n=>{(n.key===Z||n.key===null)&&g(this,h,U).call(this)};return window.addEventListener("storage",e),this.teardown.push(()=>window.removeEventListener("storage",e)),this}on(e,n){if(typeof n!="function")return()=>{};const o=this.listeners.get(e)||new Set;return o.add(n),this.listeners.set(e,o),()=>this.off(e,n)}off(e,n){var o;return(o=this.listeners.get(e))==null||o.delete(n),this}emit(e,n){for(const o of this.listeners.get(e)||[])try{o(n)}catch(r){console.error(`[BugCatch] a '${e}' listener threw:`,r)}}unreadUpdates(){return X()}markUpdateRead(e){return cn(e),g(this,h,U).call(this),this}markReportRead(e){return ln(e),g(this,h,U).call(this),this}markUpdatesRead(){return Ge(),g(this,h,U).call(this),this}async verifyFix(e,{result:n,resolvedAt:o,note:r}){const i=n==="STILL_HAPPENING"?await g(this,h,ie).call(this,{}):{};return jn({apiBase:this.config.apiBase,bugId:e,result:n,resolvedAt:o,note:r,metadata:i.metadata,logs:i.logs})}async rate(e,{score:n,comment:o}={}){return Tn({apiBase:this.config.apiBase,bugId:e,score:n,comment:o})}async myReport(e){const n=await hn({apiBase:this.config.apiBase,bugId:e});return g(this,h,wt).call(this,e,n==null?void 0:n.assistant),n}replyToReport(e,{body:n,attachments:o}={}){return fn({apiBase:this.config.apiBase,bugId:e,body:n,attachments:o})}async canCallNow(){return!!await this.callKind()}async callKind(){return(await this.callKinds()).live?"live":null}async callKinds(){var n;const e={agent:!1,live:!1};return!this.config.voice||!((n=this.config.user)!=null&&n.email)?e:this.kinds!==void 0?this.kinds:(this.kinds=await pn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.kinds)}canCall(e){return this.config.voice?Ze({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}async startCall(e){var n;if(!this.config.voice)throw new Error("[BugCatch] calling is switched off.");if(this.call||this.callStarting)throw new Error("[BugCatch] a call is already running.");this.callStarting=!0;try{if(!await this.callKind())throw new Error((n=this.config.user)!=null&&n.email?"[BugCatch] calling is not available on this project.":"[BugCatch] a call needs to know who is calling — call identify() with an email first.");return await g(this,h,yt).call(this,e)}finally{this.callStarting=!1}}startLiveCall(e){return this.startCall(e)}canCallTeam(e){return this.config.voice?Ze({apiBase:this.config.apiBase,bugId:e}):Promise.resolve(!1)}endCall(){var e;return(e=this.call)==null||e.hangUp(),this.call=null,this}myReports(){return un({apiBase:this.config.apiBase})}hasReports(){return!!$()}forgetReports(){var e;return(e=this.stopWatching)==null||e.call(this),this.stopWatching=null,this.endCall(),D(),g(this,h,U).call(this),this}identify(e){const n=lt(e,o=>this.warn(o));return e!=null&&!n?this:(this.config.user=n,this.debugLog("identify",n),this)}setContext(e){return this.context=ve(this.context,e,n=>this.warn(n)),this.debugLog("context",this.context),this}getContext(){return{...this.context}}open({mode:e}={}){return this.started?this.widgetControls?(e!==void 0&&e!=="report"&&e!=="feedback"&&(this.warn(`open({ mode: "${e}" }) is not 'report' or 'feedback' — opened the report form.`),e="report"),this.widgetControls.open(e),this):(this.warn("open() needs the built-in widget; it was turned off with widget: false."),this):(this.warn("open() was called before init() — nothing to open yet."),this)}close(){var e;return(e=this.widgetControls)==null||e.close(),this}isOpen(){var e;return!!((e=this.widgetControls)!=null&&e.isOpen())}async uploadAttachment(e,n,o){if(!this.started)throw new Error("[BugCatch] call init() first.");return tn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,blob:e,mime:n||(e==null?void 0:e.type),onProgress:o})}async report({title:e,description:n="",priority:o="MEDIUM",metadata:r={},attachments:i=[],references:s=[],context:a=null,issue:c=null}={}){var L,N,j,p,k,v,w,b;if(!this.started)throw new Error("[BugCatch] call init() first.");if(typeof e!="string"||!e.trim())throw new Error("[BugCatch] a title is required.");["LOW","MEDIUM","HIGH","CRITICAL"].includes(String(o).toUpperCase())||(this.warn(`priority "${o}" is not one of LOW, MEDIUM, HIGH, CRITICAL — sent as MEDIUM.`),o="MEDIUM");const l=(i||[]).filter(f=>(f==null?void 0:f.storageKey)&&fe(f.mime,Ye)).map(f=>({type:f.type==="VIDEO"?"VIDEO":"SCREENSHOT",storageKey:f.storageKey,mime:fe(f.mime,Ye)})),d=(Array.isArray(s)?s:[]).filter(f=>f&&typeof f.key=="string"&&f.key&&(typeof f.value=="string"||typeof f.value=="number")).map(f=>({key:f.key.slice(0,64),value:String(f.value).trim().slice(0,120)})).filter(f=>f.value);Array.isArray(s)&&d.length<s.length&&this.warn("report({ references }) takes [{ key, value }] with string values; malformed entries were dropped.");let u=await g(this,h,ie).call(this,{title:e.trim(),description:typeof n=="string"?n:String(n??""),priority:String(o).toUpperCase(),metadata:r,media:l,references:d,context:a,issue:typeof c=="string"&&c?c.slice(0,32):null});const B=g(this,h,re).call(this,u,{type:"report"});if(B===!1)return{cancelled:!0};u=B,this.debugLog("sending report",{title:u.title,user:(L=u.metadata)==null?void 0:L.user,context:(N=u.metadata)==null?void 0:N.context,references:u.references,console:(k=(p=(j=u.logs)==null?void 0:j.console)==null?void 0:p.entries)==null?void 0:k.length,network:(b=(w=(v=u.logs)==null?void 0:v.network)==null?void 0:w.entries)==null?void 0:b.length});const x=M(this.config.projectId);let C;try{C=await fetch(`${this.config.apiBase}/ingest/bugs`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey,...x!=null&&x.token?{"X-BugCatch-Session":x.token}:{}},body:JSON.stringify(mo(u))})}catch(f){const S=new Error(`[BugCatch] could not reach ${this.config.apiBase} — check apiBase, and that this site's origin is allowed by the API.`);throw S.cause=f,g(this,h,W).call(this,"report",S),S}if(C.status===401&&x&&ye(this.config.projectId),!C.ok){let f="";try{const O=await C.json();f=Array.isArray(O.message)?O.message.join(", "):O.message||""}catch{}C.status===401&&!x&&(f||(f="the apiKey was not accepted")),C.status===403&&(f||(f="the apiKey is not allowed to report to this projectId"));const S=C.status===429?new Error(`[BugCatch] ${_(f)}`):new Error(`[BugCatch] report failed (HTTP ${C.status})${f?": "+f:""}`);throw S.status=C.status,g(this,h,W).call(this,"report",S),S}const m=await C.json();return g(this,h,Ie).call(this,m,{title:u.title??e.trim(),via:"form"}),m.watchToken&&(ge(m.watchToken),this.config.updates&&this.startWatching()),m}loginState(){var e;return Rn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:(e=M(this.config.projectId))==null?void 0:e.token})}referenceFields(){return this.refFields?this.refFields:(this.refFields=Pn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.refFields)}agentIssues(){return this.agentIssueList?this.agentIssueList:(this.agentIssueList=_n({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.agentIssueList)}async announcements(){const e=await Fn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId});return Xn(e)}dismissAnnouncement(e){qn(e)}feedbackEnabled(){return this.feedbackState?this.feedbackState:(this.feedbackState=no({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.feedbackState)}async feedback({message:e,kind:n,score:o,email:r,name:i,context:s=null}={}){var u,B,x,C;if(!this.started)throw new Error("[BugCatch] call init() first.");const a=oo({message:e,kind:n,score:o,email:r??((u=this.config.user)==null?void 0:u.email),name:i??((B=this.config.user)==null?void 0:B.name)});n!=null&&!a.kind&&this.warn(`feedback({ kind: "${n}" }) is not one of idea, praise, confusing, other — sent without one.`);const c=s?ve(this.context,s,m=>this.warn(m.replace("setContext()","feedback({ context })"))):this.context;let l={projectId:this.config.projectId,...a,url:window.location.href,metadata:{...await le(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,user:this.config.user||void 0,...Object.keys(c).length?{context:c}:{},sdk:H}};const d=g(this,h,re).call(this,l,{type:"feedback"});if(d===!1)return{cancelled:!0};l=d,this.debugLog("sending feedback",{kind:l.kind,score:l.score,user:(x=l.metadata)==null?void 0:x.user});try{const m=await io({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:(C=M(this.config.projectId))==null?void 0:C.token,payload:l}),L={id:(m==null?void 0:m.id)??null,kind:l.kind??null,score:l.score??null};return this.debugLog("feedback accepted",L),this.emit("feedback",L),m}catch(m){throw g(this,h,W).call(this,"feedback",m),m}}signedInAs(){const e=M(this.config.projectId);return e?{email:e.email,name:e.name}:null}signIn(e,{name:n}={}){var o;return Mn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,name:n??((o=this.config.user)==null?void 0:o.name)??null})}async confirmSignIn(e,n){var r;const o=await Kn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,code:n});return(r=this.config.user)!=null&&r.email||(this.config.user={email:o.email,name:o.name||void 0}),this.emit("signin",{email:o.email,name:o.name}),{email:o.email,name:o.name}}async signOut(){var o;const e=M(this.config.projectId),n=await Nn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:e==null?void 0:e.token});return e!=null&&e.email&&((o=this.config.user)==null?void 0:o.email)===e.email&&(this.config.user=null),this.emit("signout",{email:(e==null?void 0:e.email)||null}),n}knownIssues(){var e;return Bn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,sessionToken:(e=M(this.config.projectId))==null?void 0:e.token})}matchKnownIssues(e,{signal:n}={}){var o;return $n({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,q:e||"",sessionToken:(o=M(this.config.projectId))==null?void 0:o.token,signal:n})}async meToo(e,{email:n,name:o}={}){var s,a;const r=M(this.config.projectId),i=await le();return En({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,bugId:e,reporterEmail:n||((s=this.config.user)==null?void 0:s.email),reporterName:o||((a=this.config.user)==null?void 0:a.name),metadata:{...i,user:this.config.user||void 0,...Object.keys(this.context).length?{context:this.context}:{},sdk:H},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},sessionToken:r==null?void 0:r.token})}snapshot(){return{user:this.config.user||null,context:{...this.context},console:this.consoleBuffer.all(),network:this.networkBuffer.all(),environment:Te()}}clear(){this.consoleBuffer.clear(),this.networkBuffer.clear()}destroy(){this.endCall(),this.teardown.forEach(e=>{try{e()}catch{}}),this.teardown=[],this.notifier=null,this.started=!1}}h=new WeakSet,oe=function(e,n){const o=this.config[e];if(typeof o=="function")try{o(n)}catch(r){console.error(`[BugCatch] your ${e} callback threw:`,r)}},mt=function(){if(typeof window>"u"||typeof fetch!="function")return;const e=`bugcatch:hello:${this.config.projectId}`,n=new Date().toISOString().slice(0,10);try{if(window.localStorage.getItem(e)===n)return}catch{}const o=setTimeout(()=>{try{window.localStorage.setItem(e,n)}catch{}fetch(`${this.config.apiBase}/ingest/hello`,{method:"POST",keepalive:!0,headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey},body:JSON.stringify({projectId:this.config.projectId,version:H.version,identify:!!this.config.user,context:!!(this.context&&Object.keys(this.context).length),widget:!!this.config.widget,environment:this.config.environment||null,release:this.config.release||null})}).catch(()=>{})},5e3);this.teardown.push(()=>clearTimeout(o))},U=function(){const e=X();if(this.emit("unread",{count:e.length,updates:e}),!!this.config.updateToast){if(!this.notifier){if(!e.length)return;this.notifier=Sn({accent:this.config.accent,position:this.config.widgetPosition,onRead:n=>this.markUpdateRead(n),onReadAll:()=>this.markUpdatesRead(),onCall:this.config.voice?n=>{this.markUpdateRead(n.id),this.startCall(n.bugId)}:null}),this.teardown.push(()=>{var n;return(n=this.notifier)==null?void 0:n.destroy()})}this.notifier.render(e)}},wt=function(e,n){const o=n==null?void 0:n.phase;if(!e||typeof o!="string"||this.phases.get(e)===o)return;this.phases.set(e,o);const r={bugId:e,phase:o,title:n.title??null,detail:n.detail??null};this.debugLog("assistant",r),g(this,h,oe).call(this,"onAssistantPhase",r),this.emit("assistant",r)},Ie=function(e,{title:n,via:o}){if(!(e!=null&&e.id))return;const r={bugId:e.id,title:n??null,via:o,result:e};this.debugLog("report accepted",r),g(this,h,oe).call(this,"onReportSubmitted",r),this.emit("report",r)},W=function(e,n){g(this,h,oe).call(this,"onError",{action:e,error:n}),this.emit("error",{action:e,error:n})},ie=async function({title:e,description:n="",priority:o="MEDIUM",metadata:r={},media:i=[],references:s=[],context:a=null,issue:c=null}){var d,u;const l=a?ve(this.context,a,B=>this.warn(B.replace("setContext()","report({ context })"))):this.context;return{projectId:this.config.projectId,...e?{title:e}:{},description:n,priority:o,url:window.location.href,reporterEmail:(d=this.config.user)==null?void 0:d.email,reporterName:(u=this.config.user)==null?void 0:u.name,metadata:{...await le(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,...r,user:this.config.user||void 0,...Object.keys(l).length?{context:l}:{},sdk:H},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},...i.length?{attachments:i}:{},...s.length?{references:s}:{},...c?{issue:c}:{}}},re=function(e,n={type:"report"}){if(typeof this.config.beforeSend!="function")return e;let o;try{o=this.config.beforeSend(e,n)}catch(r){return this.warn(`beforeSend threw, so nothing was sent: ${(r==null?void 0:r.message)||r}`),!1}return o===!1?!1:o&&typeof o=="object"?o:e},bt=async function(){const e=M(this.config.projectId),n=g(this,h,re).call(this,await g(this,h,ie).call(this,{}));if(n===!1)return this.debugLog("call cancelled by beforeSend"),{cancelled:!0};let o;try{o=await gn({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:e==null?void 0:e.token,payload:n,watchToken:$()})}catch(r){throw r.status===401&&e&&ye(this.config.projectId),g(this,h,W).call(this,"call",r),r}return g(this,h,Ie).call(this,o,{title:null,via:"call"}),o.watchToken&&(ge(o.watchToken),this.config.updates&&this.startWatching()),o},yt=async function(e){const{joinLiveCall:n,liveCallSupported:o,openMicrophone:r}=await Y(this.config.chunkBase);if(!o())throw new Error("[BugCatch] this browser cannot make live calls.");const i=await r();let s,a=null;try{if(e)s=await mn({apiBase:this.config.apiBase,bugId:e});else if(a=await g(this,h,bt).call(this),e=a.id,s=a.live_call,!(s!=null&&s.realtime_url)){const l=new Error(`[BugCatch] the report was filed, but the team could not be rung${a.call_error?`: ${a.call_error}`:"."}`);throw l.filed=a,l.reason=a.call_error||null,l}}catch(l){for(const d of i.getTracks())d.stop();throw l}const c=await n({realtimeUrl:s.realtime_url,stream:i,ringsUntil:s.rings_until,onState:(l,d)=>{(l==="ended"||l==="failed"||l==="missed")&&(this.call=null),l==="missed"&&wn({apiBase:this.config.apiBase,bugId:e,callId:s.call_id}),typeof this.config.onCallState=="function"&&this.config.onCallState(l,{bugId:e,live:!0,...d}),this.emit("call",{bugId:e,live:!0,state:l,...d})}});return this.call=c,Object.assign(c,{bugId:e,callId:s.call_id,live:!0,filed:a,recorded:!!s.recorded})},xt=function(e){var r;const n=e.incomingCall;if(!this.config.voice||((r=this.ringing)==null?void 0:r.callId)===n.callId||this.call||this.callStarting)return;g(this,h,se).call(this);const o={callId:n.callId,dismiss:()=>{}};this.ringing=o,Y(this.config.chunkBase).then(({liveCallSupported:i,showIncomingCall:s})=>{if(this.ringing!==o||(this.ringing=null,!i())||this.call||this.callStarting)return;const a=s({call:n,accent:this.config.accent,position:this.config.widgetPosition,touched:Un,onAnswer:()=>{g(this,h,kt).call(this,e.bugId,n)},onDecline:()=>{this.ringing=null,Qe({apiBase:this.config.apiBase,bugId:e.bugId,callId:n.callId}),this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"declined"})},onExpire:()=>{this.ringing=null,this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"missed"})}});if(this.ringing={callId:n.callId,dismiss:a},typeof this.config.onIncomingCall=="function")try{this.config.onIncomingCall({bugId:e.bugId,...n})}catch{}this.emit("incoming-call",{bugId:e.bugId,callId:n.callId,state:"ringing"})},()=>{this.ringing===o&&(this.ringing=null)})},se=function(e){if(this.ringing&&!(e&&this.ringing.callId!==e)){try{this.ringing.dismiss()}catch{}this.ringing=null}},kt=async function(e,n){if(this.ringing=null,this.call||this.callStarting)return;this.callStarting=!0;let o,r;try{const s=await Y(this.config.chunkBase);r=s.joinLiveCall,o=await s.openMicrophone()}catch(s){this.callStarting=!1,Qe({apiBase:this.config.apiBase,bugId:e,callId:n.callId}),this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:s});return}let i;try{i=await bn({apiBase:this.config.apiBase,bugId:e,callId:n.callId})}catch(s){for(const a of o.getTracks())a.stop();this.callStarting=!1,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"missed",error:s});return}try{const s=await r({realtimeUrl:i.realtime_url,stream:o,onState:(a,c)=>{(a==="ended"||a==="failed"||a==="missed")&&(this.call=null),typeof this.config.onCallState=="function"&&this.config.onCallState(a,{bugId:e,live:!0,incoming:!0,...c}),this.emit("call",{bugId:e,live:!0,incoming:!0,state:a,...c})}});this.call=s,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"answered"})}catch(s){for(const a of o.getTracks())a.stop();this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:s})}finally{this.callStarting=!1}};const Ce=new ht;return Ce.Client=ht,Ce.version=H.version,Ce});
|
|
310
310
|
//# sourceMappingURL=bugcatch.umd.js.map
|