@sphoro/bugcatch-web-sdk 0.14.2 → 0.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bugcatch.es.js +1297 -1233
- package/dist/bugcatch.es.js.map +1 -1
- package/dist/bugcatch.umd.js +124 -82
- package/dist/bugcatch.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/widget.js +103 -5
package/dist/bugcatch.umd.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
(function(H,te){typeof exports=="object"&&typeof module<"u"?module.exports=te():typeof define=="function"&&define.amd?define(te):(H=typeof globalThis<"u"?globalThis:H||self,H.BugCatch=te())})(this,function(){"use strict";var An=H=>{throw TypeError(H)};var Ea=(H,te,we)=>te.has(H)||An("Cannot "+we);var Rn=(H,te,we)=>te.has(H)?An("Cannot add the same private member more than once"):te instanceof WeakSet?te.add(H):te.set(H,we);var V=(H,te,we)=>(Ea(H,te,"access private method"),we);var B,ye,ct,Qn,jn,zn,lt,On;const H="[REDACTED]",te=new Set(["auth","bearer","session","sid","phpsessid","otp","pass","passwd","pwd","sig","codeverifier"]),we=["token","secret","password","passwd","apikey","signature","credential","sessionid","privatekey","accesskey","authorization"],Hn=new Set(["key","code","state","nonce","salt","hash"]),Bt=[/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],qn=/\bBearer\s+[\w.~+/=-]{8,}/gi,Dn=/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;function At(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch{return t}}function Nn(t){return At(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function Un(t){return t.length>=20?!0:Bt.some(e=>(e.lastIndex=0,e.test(t)))}function Vn(t,e){const n=Nn(t);if(!n)return!1;if(te.has(n))return!0;for(const o of we)if(n.includes(o))return!0;return Hn.has(n)?Un(At(e)):!1}function dt(t){return t.split("&").map(e=>{const n=e.indexOf("=");if(n===-1)return e;const o=e.slice(0,n),i=e.slice(n+1);return i&&Vn(o,i)?`${o}=${H}`:e}).join("&")}function Rt(t){let e=t;for(const n of Bt)n.lastIndex=0,e=e.replace(n,H);return e}function Qt(t){if(t==null)return t;let e=String(t);if(!e)return e;e=e.replace(Dn,`$1${H}@`);const n=e.indexOf("#");let o=n===-1?e:e.slice(0,n),i=n===-1?"":e.slice(n);const r=o.indexOf("?");if(r!==-1&&(o=o.slice(0,r+1)+dt(o.slice(r+1))),i.length>1){const s=i.slice(1),l=s.indexOf("?");l!==-1?i=`#${s.slice(0,l+1)}${dt(s.slice(l+1))}`:s.includes("=")&&(i=`#${dt(s)}`)}return Rt(o+i)}function Kn(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=>Qt(n)),e=e.replace(qn,`Bearer ${H}`),Rt(e))}function Pe(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 jt=["log","info","warn","error","debug"];function Pn(t,{levels:e=["warn","error","log","info"]}={}){const n={};for(const o of jt)n[o]=console[o],e.includes(o)&&(console[o]=(...i)=>{try{t.push({level:o,text:i.map(Ht).join(" ").slice(0,2e3),at:new Date().toISOString()})}catch{}n[o].apply(console,i)});return()=>{for(const o of jt)console[o]=n[o]}}function _n(t,{slowMs:e=2e3}={}){const n=window.fetch,o=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;return n&&(window.fetch=async function(...s){var y,p,b;const l=performance.now(),u=typeof s[0]=="string"?s[0]:(y=s[0])==null?void 0:y.url,g=((p=s[1])==null?void 0:p.method)||(typeof s[0]=="object"?(b=s[0])==null?void 0:b.method:"GET")||"GET";try{const h=await n.apply(this,s);return ut(t,{url:u,method:g,status:h.status,ms:Math.round(performance.now()-l),slowMs:e}),h}catch(h){throw ut(t,{url:u,method:g,status:0,error:String((h==null?void 0:h.message)||h),ms:Math.round(performance.now()-l),slowMs:e}),h}}),XMLHttpRequest.prototype.open=function(s,l,...u){return this.__bc={method:s,url:l,started:0},o.call(this,s,l,...u)},XMLHttpRequest.prototype.send=function(...s){return this.__bc&&(this.__bc.started=performance.now(),this.addEventListener("loadend",()=>{ut(t,{url:this.__bc.url,method:this.__bc.method,status:this.status,ms:Math.round(performance.now()-this.__bc.started),slowMs:e})})),i.apply(this,s)},()=>{n&&(window.fetch=n),XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.send=i}}function ut(t,{url:e,method:n,status:o,ms:i,error:r,slowMs:s}){try{t.push({url:Qt(String(e)).slice(0,500),method:n,status:o,ms:i,error:r===void 0?void 0:Kn(r),failed:o===0||o>=400,slow:i>=s,at:new Date().toISOString()})}catch{}}function Fn(t){const e=o=>{const i=String(o.message||"Error"),r=o.filename?` (${o.filename}:${o.lineno}:${o.colno})`:"";t.push({level:"error",text:(/^uncaught/i.test(i)?i:`Uncaught ${i}`)+r,at:new Date().toISOString()})},n=o=>{t.push({level:"error",text:`Unhandled rejection: ${Ht(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 zt(){const t=Ot();try{if(navigator.getBattery){const e=await navigator.getBattery();t.battery=Math.round(e.level*100),t.charging=e.charging}}catch{}return t}function Ot(){var e,n,o,i,r,s,l,u,g;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:(i=window.screen)==null?void 0:i.availHeight,colorDepth:(r=window.screen)==null?void 0:r.colorDepth,orientation:((l=(s=window.screen)==null?void 0:s.orientation)==null?void 0:l.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:(u=window.matchMedia)!=null&&u.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light",prefersReducedMotion:((g=window.matchMedia)==null?void 0:g.call(window,"(prefers-reduced-motion: reduce)").matches)||!1}}function Ht(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 Wn=typeof window<"u"&&window.fetch?window.fetch.bind(window):null,Yn=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.open:null,Xn=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.send:null,qt=["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"],_e=["image/png","image/jpeg","image/webp","video/webm","video/mp4"],Zn=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getUserMedia&&typeof MediaRecorder<"u")},Jn=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia&&typeof MediaRecorder<"u")},Gn=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia)};function Fe(t,e=qt){const n=String(t||"").split(";")[0].trim().toLowerCase();return e.includes(n)?n:null}async function eo(){const t=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:1},audio:!1});try{const e=t.getVideoTracks()[0],n=document.createElement("video");n.srcObject=t,n.muted=!0,n.playsInline=!0,await n.play(),await new Promise(l=>requestAnimationFrame(()=>requestAnimationFrame(l)));const{width:o,height:i}=e.getSettings(),r=document.createElement("canvas");r.width=o||n.videoWidth,r.height=i||n.videoHeight,r.getContext("2d").drawImage(n,0,0,r.width,r.height);const s=await new Promise(l=>r.toBlob(l,"image/png"));if(!s)throw new Error("The browser returned an empty screenshot.");return{blob:s,mime:"image/png",kind:"SCREENSHOT"}}finally{t.getTracks().forEach(e=>e.stop())}}async function to({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const o=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1}),i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"].find(h=>MediaRecorder.isTypeSupported(h))||"video/webm",r=new MediaRecorder(o,{mimeType:i,videoBitsPerSecond:25e5}),s=[];r.ondataavailable=h=>{h.data.size&&s.push(h.data)},r.start(1e3);const l=Date.now(),u=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),g=()=>{clearInterval(u),clearTimeout(b),o.getTracks().forEach(h=>h.stop())},y=new Promise(h=>{r.onstop=()=>{g(),h(new Blob(s,{type:i}))}}),p=()=>{r.state!=="inactive"&&r.stop(),n==null||n()};o.getVideoTracks()[0].addEventListener("ended",p);const b=setTimeout(p,t);return{mime:i,maxMs:t,async stop(){return clearTimeout(b),r.state!=="inactive"&&r.stop(),{blob:await y,mime:i,kind:"VIDEO"}},cancel(){g(),r.state!=="inactive"&&r.stop()}}}async function no({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const o=await navigator.mediaDevices.getUserMedia({audio:!0}),i=["audio/webm;codecs=opus","audio/webm","audio/mp4","audio/ogg"].find(h=>MediaRecorder.isTypeSupported(h))||"",r=new MediaRecorder(o,i?{mimeType:i}:void 0),s=[];r.ondataavailable=h=>{h.data.size&&s.push(h.data)},r.start(1e3);const l=Date.now(),u=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),g=()=>{clearInterval(u),clearTimeout(b),o.getTracks().forEach(h=>h.stop())},y=new Promise(h=>{r.onstop=()=>{g(),h(new Blob(s,{type:r.mimeType||i}))}}),b=setTimeout(()=>{r.state!=="inactive"&&r.stop(),n==null||n()},t);return{mime:r.mimeType||i,maxMs:t,async stop(){clearTimeout(b),r.state!=="inactive"&&r.stop();const h=await y;return{blob:h,mime:h.type||r.mimeType||i,kind:"AUDIO"}},cancel(){g(),r.state!=="inactive"&&r.stop()}}}async function oo({apiBase:t,apiKey:e,blob:n,mime:o,onProgress:i}){const r=Fe(o||n.type);if(!r)throw new Error(`[BugCatch] ${o||n.type||"that file"} can't be attached.`);const s=await Wn(`${t}/ingest/presign`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e},body:JSON.stringify({mime:r})});if(!s.ok)throw new Error(`[BugCatch] could not start the upload (HTTP ${s.status}).`);const{key:l,uploadUrl:u}=await s.json();return await ao(u,n,r,i),{storageKey:l,mime:r}}function ao(t,e,n,o){return new Promise((i,r)=>{const s=new XMLHttpRequest;Yn.call(s,"PUT",t,!0),s.setRequestHeader("Content-Type",n),s.upload.onprogress=l=>{l.lengthComputable&&(o==null||o(l.loaded/l.total))},s.onload=()=>{s.status>=200&&s.status<300?i():r(new Error(`[BugCatch] upload failed (HTTP ${s.status}).`))},s.onerror=()=>r(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=()=>r(new Error("[BugCatch] upload cancelled.")),Xn.call(s,e)})}function Me(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(0)} KB`:`${(t/1024/1024).toFixed(1)} MB`}function We(t){const e=Math.floor(t/60),n=t%60;return`${e}:${String(n).padStart(2,"0")}`}const ro=7*24*60*60*1e3;let Ye;function io(){return Ye||(Ye=new Promise((t,e)=>{const n=indexedDB.open("bugcatch-drafts",1);n.onupgradeneeded=()=>n.result.createObjectStore("drafts"),n.onsuccess=()=>t(n.result),n.onerror=()=>e(n.error),n.onblocked=()=>e(new Error("Draft storage is blocked."))}).catch(t=>{throw Ye=null,t})),Ye}function so(t,e){var n,o;return JSON.stringify([t.apiBase,t.projectId,e||((n=t.user)==null?void 0:n.email)||((o=t.user)==null?void 0:o.id)||"anonymous"])}async function Xe(t,e){const n=await io();return new Promise((o,i)=>{const r=n.transaction("drafts",e===void 0?"readonly":"readwrite"),s=r.objectStore("drafts"),l=e===void 0?s.get(t):e===null?s.delete(t):s.put({...e,savedAt:Date.now()},t);r.oncomplete=()=>o(l.result),r.onerror=()=>i(r.error),r.onabort=()=>i(r.error||new Error("Draft was not saved."))})}async function co(t){const e=await Xe(t);return e&&Date.now()-e.savedAt>ro?(await Xe(t,null),null):e||null}const lo="bugcatch.session.",pt=t=>`${lo}${t}`,ht=new Map;function he(t){var e;if(!t)return null;try{const n=(e=window.localStorage)==null?void 0:e.getItem(pt(t));if(n){const o=JSON.parse(n);if(o!=null&&o.token)return o}}catch{}return ht.get(t)||null}function uo(t,e){var o;if(!t||!(e!=null&&e.token))return;const n={token:e.token,email:e.email||null,name:e.name||null};ht.set(t,n);try{(o=window.localStorage)==null||o.setItem(pt(t),JSON.stringify(n))}catch{}}function ft(t){var e;if(t){ht.delete(t);try{(e=window.localStorage)==null||e.removeItem(pt(t))}catch{}}}function Ze({apiKey:t,token:e}){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function Dt(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Request failed (HTTP ${t.status})`}async function po({apiBase:t,apiKey:e,projectId:n,token:o}){const i={mode:"off",signedIn:null,signedOutReason:null};try{const r=await fetch(`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,{headers:Ze({apiKey:e,token:o})});if(!r.ok)return i;const s=await r.json();return{mode:s.mode==="optional"||s.mode==="required"?s.mode:"off",signedIn:s.signedIn||null,signedOutReason:s.signedOutReason||null}}catch{return i}}async function ho({apiBase:t,apiKey:e,projectId:n,email:o,name:i}){const r=await fetch(`${t}/ingest/login/start`,{method:"POST",headers:Ze({apiKey:e}),body:JSON.stringify({projectId:n,email:o,...i?{name:i}:{}})});if(!r.ok)throw new Error(await Dt(r));return r.json()}async function fo({apiBase:t,apiKey:e,projectId:n,email:o,code:i}){const r=await fetch(`${t}/ingest/login`,{method:"POST",headers:Ze({apiKey:e}),body:JSON.stringify({projectId:n,email:o,code:i})});if(!r.ok)throw new Error(await Dt(r));const s=await r.json(),l={token:s.sessionToken,email:s.email,name:s.name};return uo(n,l),l}async function go({apiBase:t,apiKey:e,projectId:n,token:o}){if(ft(n),!o)return{signedOut:!0};try{await fetch(`${t}/ingest/logout`,{method:"POST",headers:Ze({apiKey:e,token:o}),body:JSON.stringify({projectId:n})})}catch{}return{signedOut:!0}}const gt="bugcatch.watch",Nt=[2e3,5e3,15e3,3e4,6e4],mo=5e3;function re(){var t;try{return((t=window.localStorage)==null?void 0:t.getItem(gt))||null}catch{return null}}function mt(t){var e;if(t)try{(e=window.localStorage)==null||e.setItem(gt,t)}catch{}}function ve(){var t;try{(t=window.localStorage)==null||t.removeItem(gt)}catch{}Ut()}const Je="bugcatch.unread";function bo(t){return[(t==null?void 0:t.bugId)||"report",(t==null?void 0:t.kind)||"status",(t==null?void 0:t.at)||""].join("|")}function qe(){var t;try{const e=(t=window.localStorage)==null?void 0:t.getItem(Je),n=e?JSON.parse(e):[];return Array.isArray(n)?n.filter(o=>o&&typeof o.id=="string"):[]}catch{return[]}}function Ge(t){var e,n;try{t.length?(e=window.localStorage)==null||e.setItem(Je,JSON.stringify(t)):(n=window.localStorage)==null||n.removeItem(Je)}catch{}}function yo(t){const e={...t,id:bo(t)},n=qe().filter(o=>o.id!==e.id);return n.push(e),Ge(n.slice(-20)),e}function wo(t){const e=qe().filter(n=>n.id!==t);return Ge(e),e}function vo(t){const e=qe().filter(n=>n.bugId!==t);return Ge(e),e}function Ut(){return Ge([]),[]}function xo(t,e){let n=t,o=n.indexOf(`
|
|
1
|
+
(function(N,te){typeof exports=="object"&&typeof module<"u"?module.exports=te():typeof define=="function"&&define.amd?define(te):(N=typeof globalThis<"u"?globalThis:N||self,N.BugCatch=te())})(this,function(){"use strict";var jn=N=>{throw TypeError(N)};var Io=(N,te,we)=>te.has(N)||jn("Cannot "+we);var zn=(N,te,we)=>te.has(N)?jn("Cannot add the same private member more than once"):te instanceof WeakSet?te.add(N):te.set(N,we);var _=(N,te,we)=>(Io(N,te,"access private method"),we);var B,ye,lt,On,Hn,qn,dt,Dn;const N="[REDACTED]",te=new Set(["auth","bearer","session","sid","phpsessid","otp","pass","passwd","pwd","sig","codeverifier"]),we=["token","secret","password","passwd","apikey","signature","credential","sessionid","privatekey","accesskey","authorization"],Nn=new Set(["key","code","state","nonce","salt","hash"]),Rt=[/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],Un=/\bBearer\s+[\w.~+/=-]{8,}/gi,Vn=/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^/?#@]+)@/;function Qt(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch{return t}}function Kn(t){return Qt(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function Pn(t){return t.length>=20?!0:Rt.some(e=>(e.lastIndex=0,e.test(t)))}function _n(t,e){const n=Kn(t);if(!n)return!1;if(te.has(n))return!0;for(const a of we)if(n.includes(a))return!0;return Nn.has(n)?Pn(Qt(e)):!1}function ut(t){return t.split("&").map(e=>{const n=e.indexOf("=");if(n===-1)return e;const a=e.slice(0,n),i=e.slice(n+1);return i&&_n(a,i)?`${a}=${N}`:e}).join("&")}function jt(t){let e=t;for(const n of Rt)n.lastIndex=0,e=e.replace(n,N);return e}function zt(t){if(t==null)return t;let e=String(t);if(!e)return e;e=e.replace(Vn,`$1${N}@`);const n=e.indexOf("#");let a=n===-1?e:e.slice(0,n),i=n===-1?"":e.slice(n);const r=a.indexOf("?");if(r!==-1&&(a=a.slice(0,r+1)+ut(a.slice(r+1))),i.length>1){const s=i.slice(1),l=s.indexOf("?");l!==-1?i=`#${s.slice(0,l+1)}${ut(s.slice(l+1))}`:s.includes("=")&&(i=`#${ut(s)}`)}return jt(a+i)}function Fn(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=>zt(n)),e=e.replace(Un,`Bearer ${N}`),jt(e))}function Pe(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 Ot=["log","info","warn","error","debug"];function Wn(t,{levels:e=["warn","error","log","info"]}={}){const n={};for(const a of Ot)n[a]=console[a],e.includes(a)&&(console[a]=(...i)=>{try{t.push({level:a,text:i.map(Dt).join(" ").slice(0,2e3),at:new Date().toISOString()})}catch{}n[a].apply(console,i)});return()=>{for(const a of Ot)console[a]=n[a]}}function Yn(t,{slowMs:e=2e3}={}){const n=window.fetch,a=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;return n&&(window.fetch=async function(...s){var y,h,b;const l=performance.now(),p=typeof s[0]=="string"?s[0]:(y=s[0])==null?void 0:y.url,f=((h=s[1])==null?void 0:h.method)||(typeof s[0]=="object"?(b=s[0])==null?void 0:b.method:"GET")||"GET";try{const g=await n.apply(this,s);return pt(t,{url:p,method:f,status:g.status,ms:Math.round(performance.now()-l),slowMs:e}),g}catch(g){throw pt(t,{url:p,method:f,status:0,error:String((g==null?void 0:g.message)||g),ms:Math.round(performance.now()-l),slowMs:e}),g}}),XMLHttpRequest.prototype.open=function(s,l,...p){return this.__bc={method:s,url:l,started:0},a.call(this,s,l,...p)},XMLHttpRequest.prototype.send=function(...s){return this.__bc&&(this.__bc.started=performance.now(),this.addEventListener("loadend",()=>{pt(t,{url:this.__bc.url,method:this.__bc.method,status:this.status,ms:Math.round(performance.now()-this.__bc.started),slowMs:e})})),i.apply(this,s)},()=>{n&&(window.fetch=n),XMLHttpRequest.prototype.open=a,XMLHttpRequest.prototype.send=i}}function pt(t,{url:e,method:n,status:a,ms:i,error:r,slowMs:s}){try{t.push({url:zt(String(e)).slice(0,500),method:n,status:a,ms:i,error:r===void 0?void 0:Fn(r),failed:a===0||a>=400,slow:i>=s,at:new Date().toISOString()})}catch{}}function Xn(t){const e=a=>{const i=String(a.message||"Error"),r=a.filename?` (${a.filename}:${a.lineno}:${a.colno})`:"";t.push({level:"error",text:(/^uncaught/i.test(i)?i:`Uncaught ${i}`)+r,at:new Date().toISOString()})},n=a=>{t.push({level:"error",text:`Unhandled rejection: ${Dt(a.reason)}`,at:new Date().toISOString()})};return window.addEventListener("error",e),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",e),window.removeEventListener("unhandledrejection",n)}}async function Ht(){const t=qt();try{if(navigator.getBattery){const e=await navigator.getBattery();t.battery=Math.round(e.level*100),t.charging=e.charging}}catch{}return t}function qt(){var e,n,a,i,r,s,l,p,f;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:(a=window.screen)==null?void 0:a.availWidth,availHeight:(i=window.screen)==null?void 0:i.availHeight,colorDepth:(r=window.screen)==null?void 0:r.colorDepth,orientation:((l=(s=window.screen)==null?void 0:s.orientation)==null?void 0:l.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:(p=window.matchMedia)!=null&&p.call(window,"(prefers-color-scheme: dark)").matches?"dark":"light",prefersReducedMotion:((f=window.matchMedia)==null?void 0:f.call(window,"(prefers-reduced-motion: reduce)").matches)||!1}}function Dt(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 Zn=typeof window<"u"&&window.fetch?window.fetch.bind(window):null,Jn=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.open:null,Gn=typeof XMLHttpRequest<"u"?XMLHttpRequest.prototype.send:null,Nt=["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"],_e=["image/png","image/jpeg","image/webp","video/webm","video/mp4"],ea=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getUserMedia&&typeof MediaRecorder<"u")},ta=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia&&typeof MediaRecorder<"u")},na=()=>{var t;return!!((t=navigator==null?void 0:navigator.mediaDevices)!=null&&t.getDisplayMedia)};function Fe(t,e=Nt){const n=String(t||"").split(";")[0].trim().toLowerCase();return e.includes(n)?n:null}async function aa(){const t=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:1},audio:!1});try{const e=t.getVideoTracks()[0],n=document.createElement("video");n.srcObject=t,n.muted=!0,n.playsInline=!0,await n.play(),await new Promise(l=>requestAnimationFrame(()=>requestAnimationFrame(l)));const{width:a,height:i}=e.getSettings(),r=document.createElement("canvas");r.width=a||n.videoWidth,r.height=i||n.videoHeight,r.getContext("2d").drawImage(n,0,0,r.width,r.height);const s=await new Promise(l=>r.toBlob(l,"image/png"));if(!s)throw new Error("The browser returned an empty screenshot.");return{blob:s,mime:"image/png",kind:"SCREENSHOT"}}finally{t.getTracks().forEach(e=>e.stop())}}async function oa({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const a=await navigator.mediaDevices.getDisplayMedia({video:{frameRate:15},audio:!1}),i=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"].find(g=>MediaRecorder.isTypeSupported(g))||"video/webm",r=new MediaRecorder(a,{mimeType:i,videoBitsPerSecond:25e5}),s=[];r.ondataavailable=g=>{g.data.size&&s.push(g.data)},r.start(1e3);const l=Date.now(),p=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),f=()=>{clearInterval(p),clearTimeout(b),a.getTracks().forEach(g=>g.stop())},y=new Promise(g=>{r.onstop=()=>{f(),g(new Blob(s,{type:i}))}}),h=()=>{r.state!=="inactive"&&r.stop(),n==null||n()};a.getVideoTracks()[0].addEventListener("ended",h);const b=setTimeout(h,t);return{mime:i,maxMs:t,async stop(){return clearTimeout(b),r.state!=="inactive"&&r.stop(),{blob:await y,mime:i,kind:"VIDEO"}},cancel(){f(),r.state!=="inactive"&&r.stop()}}}async function ra({maxMs:t=12e4,onTick:e,onAutoStop:n}={}){const a=await navigator.mediaDevices.getUserMedia({audio:!0}),i=["audio/webm;codecs=opus","audio/webm","audio/mp4","audio/ogg"].find(g=>MediaRecorder.isTypeSupported(g))||"",r=new MediaRecorder(a,i?{mimeType:i}:void 0),s=[];r.ondataavailable=g=>{g.data.size&&s.push(g.data)},r.start(1e3);const l=Date.now(),p=setInterval(()=>e==null?void 0:e(Math.floor((Date.now()-l)/1e3)),500),f=()=>{clearInterval(p),clearTimeout(b),a.getTracks().forEach(g=>g.stop())},y=new Promise(g=>{r.onstop=()=>{f(),g(new Blob(s,{type:r.mimeType||i}))}}),b=setTimeout(()=>{r.state!=="inactive"&&r.stop(),n==null||n()},t);return{mime:r.mimeType||i,maxMs:t,async stop(){clearTimeout(b),r.state!=="inactive"&&r.stop();const g=await y;return{blob:g,mime:g.type||r.mimeType||i,kind:"AUDIO"}},cancel(){f(),r.state!=="inactive"&&r.stop()}}}async function ia({apiBase:t,apiKey:e,blob:n,mime:a,onProgress:i}){const r=Fe(a||n.type);if(!r)throw new Error(`[BugCatch] ${a||n.type||"that file"} can't be attached.`);const s=await Zn(`${t}/ingest/presign`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":e},body:JSON.stringify({mime:r})});if(!s.ok)throw new Error(`[BugCatch] could not start the upload (HTTP ${s.status}).`);const{key:l,uploadUrl:p}=await s.json();return await sa(p,n,r,i),{storageKey:l,mime:r}}function sa(t,e,n,a){return new Promise((i,r)=>{const s=new XMLHttpRequest;Jn.call(s,"PUT",t,!0),s.setRequestHeader("Content-Type",n),s.upload.onprogress=l=>{l.lengthComputable&&(a==null||a(l.loaded/l.total))},s.onload=()=>{s.status>=200&&s.status<300?i():r(new Error(`[BugCatch] upload failed (HTTP ${s.status}).`))},s.onerror=()=>r(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=()=>r(new Error("[BugCatch] upload cancelled.")),Gn.call(s,e)})}function Me(t){return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(0)} KB`:`${(t/1024/1024).toFixed(1)} MB`}function We(t){const e=Math.floor(t/60),n=t%60;return`${e}:${String(n).padStart(2,"0")}`}const ca=7*24*60*60*1e3;let Ye;function la(){return Ye||(Ye=new Promise((t,e)=>{const n=indexedDB.open("bugcatch-drafts",1);n.onupgradeneeded=()=>n.result.createObjectStore("drafts"),n.onsuccess=()=>t(n.result),n.onerror=()=>e(n.error),n.onblocked=()=>e(new Error("Draft storage is blocked."))}).catch(t=>{throw Ye=null,t})),Ye}function da(t,e){var n,a;return JSON.stringify([t.apiBase,t.projectId,e||((n=t.user)==null?void 0:n.email)||((a=t.user)==null?void 0:a.id)||"anonymous"])}async function Xe(t,e){const n=await la();return new Promise((a,i)=>{const r=n.transaction("drafts",e===void 0?"readonly":"readwrite"),s=r.objectStore("drafts"),l=e===void 0?s.get(t):e===null?s.delete(t):s.put({...e,savedAt:Date.now()},t);r.oncomplete=()=>a(l.result),r.onerror=()=>i(r.error),r.onabort=()=>i(r.error||new Error("Draft was not saved."))})}async function ua(t){const e=await Xe(t);return e&&Date.now()-e.savedAt>ca?(await Xe(t,null),null):e||null}const pa="bugcatch.session.",ht=t=>`${pa}${t}`,ft=new Map;function fe(t){var e;if(!t)return null;try{const n=(e=window.localStorage)==null?void 0:e.getItem(ht(t));if(n){const a=JSON.parse(n);if(a!=null&&a.token)return a}}catch{}return ft.get(t)||null}function ha(t,e){var a;if(!t||!(e!=null&&e.token))return;const n={token:e.token,email:e.email||null,name:e.name||null};ft.set(t,n);try{(a=window.localStorage)==null||a.setItem(ht(t),JSON.stringify(n))}catch{}}function gt(t){var e;if(t){ft.delete(t);try{(e=window.localStorage)==null||e.removeItem(ht(t))}catch{}}}function Ze({apiKey:t,token:e}){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function Ut(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Request failed (HTTP ${t.status})`}async function fa({apiBase:t,apiKey:e,projectId:n,token:a}){const i={mode:"off",signedIn:null,signedOutReason:null};try{const r=await fetch(`${t}/ingest/login?projectId=${encodeURIComponent(n)}`,{headers:Ze({apiKey:e,token:a})});if(!r.ok)return i;const s=await r.json();return{mode:s.mode==="optional"||s.mode==="required"?s.mode:"off",signedIn:s.signedIn||null,signedOutReason:s.signedOutReason||null}}catch{return i}}async function ga({apiBase:t,apiKey:e,projectId:n,email:a,name:i}){const r=await fetch(`${t}/ingest/login/start`,{method:"POST",headers:Ze({apiKey:e}),body:JSON.stringify({projectId:n,email:a,...i?{name:i}:{}})});if(!r.ok)throw new Error(await Ut(r));return r.json()}async function ma({apiBase:t,apiKey:e,projectId:n,email:a,code:i}){const r=await fetch(`${t}/ingest/login`,{method:"POST",headers:Ze({apiKey:e}),body:JSON.stringify({projectId:n,email:a,code:i})});if(!r.ok)throw new Error(await Ut(r));const s=await r.json(),l={token:s.sessionToken,email:s.email,name:s.name};return ha(n,l),l}async function ba({apiBase:t,apiKey:e,projectId:n,token:a}){if(gt(n),!a)return{signedOut:!0};try{await fetch(`${t}/ingest/logout`,{method:"POST",headers:Ze({apiKey:e,token:a}),body:JSON.stringify({projectId:n})})}catch{}return{signedOut:!0}}const mt="bugcatch.watch",Vt=[2e3,5e3,15e3,3e4,6e4],ya=5e3;function re(){var t;try{return((t=window.localStorage)==null?void 0:t.getItem(mt))||null}catch{return null}}function bt(t){var e;if(t)try{(e=window.localStorage)==null||e.setItem(mt,t)}catch{}}function ve(){var t;try{(t=window.localStorage)==null||t.removeItem(mt)}catch{}Kt()}const Je="bugcatch.unread";function wa(t){return[(t==null?void 0:t.bugId)||"report",(t==null?void 0:t.kind)||"status",(t==null?void 0:t.at)||""].join("|")}function qe(){var t;try{const e=(t=window.localStorage)==null?void 0:t.getItem(Je),n=e?JSON.parse(e):[];return Array.isArray(n)?n.filter(a=>a&&typeof a.id=="string"):[]}catch{return[]}}function Ge(t){var e,n;try{t.length?(e=window.localStorage)==null||e.setItem(Je,JSON.stringify(t)):(n=window.localStorage)==null||n.removeItem(Je)}catch{}}function va(t){const e={...t,id:wa(t)},n=qe().filter(a=>a.id!==e.id);return n.push(e),Ge(n.slice(-20)),e}function xa(t){const e=qe().filter(n=>n.id!==t);return Ge(e),e}function ka(t){const e=qe().filter(n=>n.bugId!==t);return Ge(e),e}function Kt(){return Ge([]),[]}function Sa(t,e){let n=t,a=n.indexOf(`
|
|
2
2
|
|
|
3
|
-
`);for(;
|
|
3
|
+
`);for(;a!==-1;){const i=n.slice(0,a);n=n.slice(a+2);const r=i.split(`
|
|
4
4
|
`).filter(s=>s.startsWith("data:")).map(s=>s.slice(5).trim()).join(`
|
|
5
|
-
`);if(r)try{e(JSON.parse(r))}catch{}
|
|
5
|
+
`);if(r)try{e(JSON.parse(r))}catch{}a=n.indexOf(`
|
|
6
6
|
|
|
7
|
-
`)}return n}async function ko({apiBase:t}){const e=re();if(!e)return{reporter:null,reports:[]};const n=await fetch(`${t}/ingest/watch/reports`,{headers:{Authorization:`Bearer ${e}`}});if(n.status===401)return ve(),{reporter:null,reports:[]};if(!n.ok)throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);return n.json()}async function So({apiBase:t,bugId:e}){const n=re();if(!n)return null;const o=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}`,{headers:{Authorization:`Bearer ${n}`}});if(o.status===401)return ve(),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 Vt({apiBase:t,bugId:e,body:n,attachments:o}){const i=re();if(!i)throw new Error("[BugCatch] nothing filed from this browser yet.");const r=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({...n?{body:n}:{},...o!=null&&o.length?{attachments:o}:{}})});if(r.status===401)throw ve(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!r.ok){let s="";try{const l=await r.json();s=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}throw new Error(s||`[BugCatch] could not send that (HTTP ${r.status}).`)}return r.json()}async function Co({apiBase:t,apiKey:e,projectId:n}){const o={agent:!1,live:!1};try{const i=await fetch(`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return o;const r=await i.json();return r!=null&&r.available?r.kinds&&typeof r.kinds=="object"?{agent:!1,live:!!r.kinds.live}:{agent:!1,live:r.kind==="live"}:o}catch{return o}}async function Eo({apiBase:t,apiKey:e,token:n,payload:o}){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(o)});if(!i.ok){let r="";try{const l=await i.json();r=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}const s=new Error(r||`[BugCatch] the call could not be started (HTTP ${i.status}).`);throw s.status=i.status,s}return i.json()}async function Kt({apiBase:t,bugId:e}){const n=re();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 i=await o.json();return!!(i!=null&&i.offered)}catch{return!1}}async function $o({apiBase:t,bugId:e}){const n=re();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 ve(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!o.ok){let i="";try{const r=await o.json();i=Array.isArray(r.message)?r.message.join(", "):r.message||""}catch{}throw new Error(i||`[BugCatch] the call could not be started (HTTP ${o.status}).`)}return o.json()}async function To({apiBase:t,bugId:e,callId:n}){const o=re();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 Io({apiBase:t,bugId:e,callId:n}){const o=re();if(!o)throw new Error("[BugCatch] nothing filed from this browser yet.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,{method:"POST",headers:{Authorization:`Bearer ${o}`}});if(i.status===401)throw ve(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(i.status===409)throw new Error("[BugCatch] that call is no longer ringing.");if(!i.ok){let r="";try{const s=await i.json();r=Array.isArray(s.message)?s.message.join(", "):s.message||""}catch{}throw new Error(r||`[BugCatch] the call could not be answered (HTTP ${i.status}).`)}return i.json()}async function Pt({apiBase:t,bugId:e,callId:n}){const o=re();if(o)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,{method:"POST",headers:{Authorization:`Bearer ${o}`}})}catch{}}function Mo({apiBase:t,onUpdate:e}){let n=!0,o=0,i=null;async function r(){const s=re();if(!s)throw new Error("nothing filed from this browser yet");i=new AbortController;const l=await fetch(`${t}/ingest/watch/stream`,{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"},signal:i.signal});if(l.status===401)throw n=!1,ve(),new Error("subscription no longer valid");if(!l.ok||!l.body)throw new Error(`stream failed (${l.status})`);const u=Date.now(),g=l.body.getReader(),y=new TextDecoder;let p="";try{for(;;){const{value:b,done:h}=await g.read();if(h)break;p+=y.decode(b,{stream:!0}),p=xo(p,k=>{if(k.type!=="ping")try{e(k)}catch{}})}}finally{Date.now()-u>=mo&&(o=0)}}return(async()=>{for(;n;){try{await r()}catch(l){if((l==null?void 0:l.name)==="AbortError")return}if(!n)return;const s=Nt[Math.min(o,Nt.length-1)];o+=1,await new Promise(l=>setTimeout(l,s))}})(),()=>{n=!1,i==null||i.abort(),i=null}}const Lo={OPEN:"is open",IN_PROGRESS:"is being worked on",RESOLVED:"has been fixed",CLOSED:"has been closed"},Bo={status:null,severity:"#e8912a",assignment:"#4da3ff",reply:"#35b87f"};function _t(t){return t!=null&&t.summary?t.summary:`Your report ${Lo[t==null?void 0:t.status]||"was updated"}`}function Ao(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 Ro(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 i=Math.round(o/24);return i===1?"yesterday":`${i}d ago`}function Qo(){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 jo({accent:t="#4F46E5",position:e="bottom-right",onRead:n=null,onReadAll:o=null,onCall:i=null}={}){const[r,s]=String(e).split("-"),l=r==="top",u=s==="left",g=new Map;let y=null,p=null;function b(){return y!=null&&y.isConnected||(y=document.createElement("div"),y.setAttribute("data-bugcatch","updates"),y.style.cssText=["position:fixed",`${l?"top":"bottom"}:${20+Qo()}px`,`${u?"left":"right"}:20px`,"z-index:2147482998","display:flex","flex-direction:column","gap:10px",`align-items:${u?"flex-start":"flex-end"}`,"width:min(320px,calc(100vw - 40px))","pointer-events:none"].join(";"),document.body.appendChild(y)),y}function h(S){if(!S._bcShown){S.remove();return}S.style.opacity="0",S.style.transform=`translateY(${l?-8:8}px)`,setTimeout(()=>S.remove(),250)}function k(S,E){const T=document.createElement("button");return T.type="button",T.textContent=S,T.style.cssText=["padding:5px 11px",`border:${E?"0":"1px solid rgba(236,238,242,.24)"}`,"border-radius:6px",`background:${E?t:"transparent"}`,`color:${E?"#fff":"#eceef2"}`,"font:600 12px/1.4 inherit","cursor:pointer","white-space:nowrap"].join(";"),T}function A(S){var D;const E=document.createElement("div");E.setAttribute("role","status"),E.style.cssText=["box-sizing:border-box","width:100%","padding:12px 14px","border-radius:10px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)",`border-left:3px solid ${Bo[S==null?void 0:S.kind]||t}`,"opacity:0",`transform:translateY(${l?-8:8}px)`,"transition:opacity .2s ease,transform .2s ease","pointer-events:auto"].join(";");const T=document.createElement("div");T.style.cssText="font-weight:600;margin-bottom:2px",T.textContent=_t(S);const L=document.createElement("div");L.style.cssText=(S==null?void 0:S.kind)==="reply"?"color:#a4abba;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden":"color:#a4abba",L.textContent=Ao(S);const X=document.createElement("div");X.style.cssText="display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap";const q=document.createElement("span");q.style.cssText="color:#7b8394;font-size:11px;margin-right:auto",q.textContent=Ro(S==null?void 0:S.at);const Q=k("Mark as read",!1);if(Q.setAttribute("aria-label",`Mark as read: ${_t(S)}`),Q.addEventListener("click",()=>n==null?void 0:n(S.id)),X.append(q,Q),(D=S==null?void 0:S.call)!=null&&D.offered&&typeof i=="function"){const $=k("Talk it through",!0);$.addEventListener("click",()=>i(S)),X.insertBefore($,Q)}return E.append(T,L,X),E}function ie(S){const E=document.createElement("div");E.style.cssText=["box-sizing:border-box","width:100%","display:flex","align-items:center","gap:8px","padding:8px 12px","border-radius:10px","background:#1b1e26","color:#a4abba",'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)","pointer-events:auto"].join(";");const T=document.createElement("span");T.style.cssText="margin-right:auto",T.textContent=`${S} more update${S===1?"":"s"}`;const L=k("Mark all as read",!1);return L.style.cssText+=";padding:4px 9px",L.addEventListener("click",()=>o==null?void 0:o()),E.append(T,L),E}return{render(S){const E=Array.isArray(S)?S:[];if(!E.length){for(const $ of g.values())h($);g.clear(),p==null||p.remove(),p=null,y==null||y.remove(),y=null;return}const T=E.slice(-3),L=new Set(T.map($=>$.id)),X=b();for(const[$,se]of g)L.has($)||(h(se),g.delete($));const q=[];for(const $ of T){if(g.has($.id))continue;const se=A($);g.set($.id,se),q.push(se)}const Q=l?[...T].reverse():T;for(const $ of Q)X.appendChild(g.get($.id));const D=E.length-T.length;D>0?(p==null||p.remove(),p=ie(D),l?X.appendChild(p):X.insertBefore(p,X.firstChild)):(p==null||p.remove(),p=null),requestAnimationFrame(()=>{for(const $ of q)$.isConnected&&($._bcShown=!0,$.style.opacity="1",$.style.transform="translateY(0)")})},destroy(){g.clear(),p=null,y==null||y.remove(),y=null}}}async function zo({apiBase:t,apiKey:e,projectId:n,sessionToken:o}){try{const i=await fetch(`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,{headers:bt(e,o)});if(!i.ok)return[];const r=await i.json();return Array.isArray(r==null?void 0:r.issues)?r.issues:[]}catch{return[]}}async function Oo({apiBase:t,apiKey:e,projectId:n,q:o,sessionToken:i,signal:r}){try{const s=`${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(o)}`,l=await fetch(s,{headers:bt(e,i),signal:r});if(!l.ok)return[];const u=await l.json();return Array.isArray(u==null?void 0:u.issues)?u.issues:[]}catch{return[]}}async function Ho({apiBase:t,apiKey:e,projectId:n,bugId:o,reporterEmail:i,reporterName:r,metadata:s,logs:l,sessionToken:u}){const g=await fetch(`${t}/ingest/known-issues/${encodeURIComponent(o)}/join`,{method:"POST",headers:bt(e,u),body:JSON.stringify({projectId:n,reporterEmail:i,reporterName:r,metadata:s,logs:l})});if(!g.ok)throw new Error(await qo(g));const y=await g.json();return y!=null&&y.watchToken&&mt(y.watchToken),y}function bt(t,e){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function qo(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Could not add you to this issue (HTTP ${t.status})`}async function Do({apiBase:t,bugId:e,...n}){const o=re();if(!o)throw new Error("This browser cannot access that report.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify(n)}),r=await i.json().catch(()=>({}));if(!i.ok)throw new Error(r.message||"Could not record feedback. Please refresh and try again.");return r}const No=2e4,Ft=120,Wt=200;function Yt(t){if(typeof t!="string"||!t.trim()||t.length>400)return null;try{return new RegExp(t.trim(),"gi")}catch{return null}}const Uo=t=>String(t).replace(/\s+/g," ").trim().slice(0,Ft);function Xt(t){const e=t.length>1&&t[1]!==void 0?t[1]:t[0];return typeof e!="string"||!e.trim()?null:{value:Uo(e),start:t.index,end:t.index+t[0].length}}function Vo(t,e){const n=[],o=new Set;for(const i of e||[]){const r=typeof i=="string"?i.slice(0,No):"";if(!r)continue;const s=[],l=(u,g)=>s.some(([y,p])=>u<p&&g>y);for(const u of t||[]){if(!u||u.scan===!1)continue;const g=Yt(u.pattern);if(!g)continue;let y,p=0;for(g.lastIndex=0;(y=g.exec(r))!==null&&!(++p>Wt);){if(y[0]===""){g.lastIndex+=1;continue}const b=Xt(y);if(b&&!l(b.start,b.end)){s.push([b.start,b.end]);const h=`${u.key}:${b.value.toLowerCase()}`;o.has(h)||(o.add(h),n.push({key:u.key,label:u.label,value:b.value}))}}}}return n}function Ko(t,e){const n=typeof e=="string"?e.trim():"";if(!n||n.length>Ft)return null;const o=Yt(t&&(t.valuePattern||t.pattern));if(!o)return null;let i,r=0;for(o.lastIndex=0;(i=o.exec(n))!==null&&!(++r>Wt);){if(i[0]===""){o.lastIndex+=1;continue}const s=i.index+i[0].length===n.length,l=i.index===0||i.index===1;if(s&&l){const u=Xt(i);if(u)return u.value}}return null}async function Po({apiBase:t,apiKey:e,projectId:n}){const o={policy:"off",fields:[]};try{const i=await fetch(`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return o;const r=await i.json(),s=r.policy==="optional"||r.policy==="required"?r.policy:"off",l=Array.isArray(r.fields)?r.fields:[];return l.length?{policy:s,fields:l}:o}catch{return o}}const Zt={"bottom-right":"bottom:20px;right:20px;","bottom-left":"bottom:20px;left:20px;","top-right":"top:20px;right:20px;","top-left":"top:20px;left:20px;"},Jt=[{value:"LOW",label:"Low"},{value:"MEDIUM",label:"Medium"},{value:"HIGH",label:"High"},{value:"CRITICAL",label:"Critical"}],R={camera:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',video:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',paperclip:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',mic:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>',stopSquare:'<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',back:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>',phone:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>',phoneOff:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/><path d="M3 21L21 3"/></svg>',bug:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>',check:'<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>',retry:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>',sun:'<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>',moon:'<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>',auto:'<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>'},_o='<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>',Gt=[{value:"light",label:"Light",icon:R.sun},{value:"dark",label:"Dark",icon:R.moon},{value:"auto",label:"System default",icon:R.auto}],en="bugcatch:theme";function Fo(){try{const t=localStorage.getItem(en);return Gt.some(e=>e.value===t)?t:null}catch{return null}}function Wo(t){try{localStorage.setItem(en,t)}catch{}}const Yo=t=>`
|
|
7
|
+
`)}return n}async function Ca({apiBase:t}){const e=re();if(!e)return{reporter:null,reports:[]};const n=await fetch(`${t}/ingest/watch/reports`,{headers:{Authorization:`Bearer ${e}`}});if(n.status===401)return ve(),{reporter:null,reports:[]};if(!n.ok)throw new Error(`[BugCatch] could not load your reports (HTTP ${n.status})`);return n.json()}async function $a({apiBase:t,bugId:e}){const n=re();if(!n)return null;const a=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}`,{headers:{Authorization:`Bearer ${n}`}});if(a.status===401)return ve(),null;if(a.status===404)return null;if(!a.ok)throw new Error(`[BugCatch] could not load that report (HTTP ${a.status})`);return a.json()}async function Pt({apiBase:t,bugId:e,body:n,attachments:a}){const i=re();if(!i)throw new Error("[BugCatch] nothing filed from this browser yet.");const r=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/messages`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`},body:JSON.stringify({...n?{body:n}:{},...a!=null&&a.length?{attachments:a}:{}})});if(r.status===401)throw ve(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!r.ok){let s="";try{const l=await r.json();s=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}throw new Error(s||`[BugCatch] could not send that (HTTP ${r.status}).`)}return r.json()}async function Ea({apiBase:t,apiKey:e,projectId:n}){const a={agent:!1,live:!1};try{const i=await fetch(`${t}/ingest/calls?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return a;const r=await i.json();return r!=null&&r.available?r.kinds&&typeof r.kinds=="object"?{agent:!1,live:!!r.kinds.live}:{agent:!1,live:r.kind==="live"}:a}catch{return a}}async function Ta({apiBase:t,apiKey:e,token:n,payload:a}){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(a)});if(!i.ok){let r="";try{const l=await i.json();r=Array.isArray(l.message)?l.message.join(", "):l.message||""}catch{}const s=new Error(r||`[BugCatch] the call could not be started (HTTP ${i.status}).`);throw s.status=i.status,s}return i.json()}async function _t({apiBase:t,bugId:e}){const n=re();if(!n)return!1;try{const a=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{headers:{Authorization:`Bearer ${n}`}});if(!a.ok)return!1;const i=await a.json();return!!(i!=null&&i.offered)}catch{return!1}}async function Ia({apiBase:t,bugId:e}){const n=re();if(!n)throw new Error("[BugCatch] nothing filed from this browser yet.");const a=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call`,{method:"POST",headers:{Authorization:`Bearer ${n}`}});if(a.status===401)throw ve(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(!a.ok){let i="";try{const r=await a.json();i=Array.isArray(r.message)?r.message.join(", "):r.message||""}catch{}throw new Error(i||`[BugCatch] the call could not be started (HTTP ${a.status}).`)}return a.json()}async function Ma({apiBase:t,bugId:e,callId:n}){const a=re();if(a)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/give-up`,{method:"POST",headers:{Authorization:`Bearer ${a}`}})}catch{}}async function La({apiBase:t,bugId:e,callId:n}){const a=re();if(!a)throw new Error("[BugCatch] nothing filed from this browser yet.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/answer`,{method:"POST",headers:{Authorization:`Bearer ${a}`}});if(i.status===401)throw ve(),new Error("[BugCatch] this browser can no longer prove it filed that report.");if(i.status===409)throw new Error("[BugCatch] that call is no longer ringing.");if(!i.ok){let r="";try{const s=await i.json();r=Array.isArray(s.message)?s.message.join(", "):s.message||""}catch{}throw new Error(r||`[BugCatch] the call could not be answered (HTTP ${i.status}).`)}return i.json()}async function Ft({apiBase:t,bugId:e,callId:n}){const a=re();if(a)try{await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/live-call/${encodeURIComponent(n)}/decline`,{method:"POST",headers:{Authorization:`Bearer ${a}`}})}catch{}}function Ba({apiBase:t,onUpdate:e}){let n=!0,a=0,i=null;async function r(){const s=re();if(!s)throw new Error("nothing filed from this browser yet");i=new AbortController;const l=await fetch(`${t}/ingest/watch/stream`,{headers:{Authorization:`Bearer ${s}`,Accept:"text/event-stream"},signal:i.signal});if(l.status===401)throw n=!1,ve(),new Error("subscription no longer valid");if(!l.ok||!l.body)throw new Error(`stream failed (${l.status})`);const p=Date.now(),f=l.body.getReader(),y=new TextDecoder;let h="";try{for(;;){const{value:b,done:g}=await f.read();if(g)break;h+=y.decode(b,{stream:!0}),h=Sa(h,S=>{if(S.type!=="ping")try{e(S)}catch{}})}}finally{Date.now()-p>=ya&&(a=0)}}return(async()=>{for(;n;){try{await r()}catch(l){if((l==null?void 0:l.name)==="AbortError")return}if(!n)return;const s=Vt[Math.min(a,Vt.length-1)];a+=1,await new Promise(l=>setTimeout(l,s))}})(),()=>{n=!1,i==null||i.abort(),i=null}}const Aa={OPEN:"is open",IN_PROGRESS:"is being worked on",RESOLVED:"has been fixed",CLOSED:"has been closed"},Ra={status:null,severity:"#e8912a",assignment:"#4da3ff",reply:"#35b87f"};function Wt(t){return t!=null&&t.summary?t.summary:`Your report ${Aa[t==null?void 0:t.status]||"was updated"}`}function Qa(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 ja(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 a=Math.round(n/60);if(a<24)return`${a}h ago`;const i=Math.round(a/24);return i===1?"yesterday":`${i}d ago`}function za(){var t;try{const e=document.querySelector('[data-bugcatch="widget"]'),n=(t=e==null?void 0:e.shadowRoot)==null?void 0:t.querySelector(".dock"),a=(n==null?void 0:n.getBoundingClientRect().height)||0;return a?Math.round(a)+12:0}catch{return 0}}function Oa({accent:t="#4F46E5",position:e="bottom-right",onRead:n=null,onReadAll:a=null,onCall:i=null}={}){const[r,s]=String(e).split("-"),l=r==="top",p=s==="left",f=new Map;let y=null,h=null;function b(){return y!=null&&y.isConnected||(y=document.createElement("div"),y.setAttribute("data-bugcatch","updates"),y.style.cssText=["position:fixed",`${l?"top":"bottom"}:${20+za()}px`,`${p?"left":"right"}:20px`,"z-index:2147482998","display:flex","flex-direction:column","gap:10px",`align-items:${p?"flex-start":"flex-end"}`,"width:min(320px,calc(100vw - 40px))","pointer-events:none"].join(";"),document.body.appendChild(y)),y}function g(C){if(!C._bcShown){C.remove();return}C.style.opacity="0",C.style.transform=`translateY(${l?-8:8}px)`,setTimeout(()=>C.remove(),250)}function S(C,$){const T=document.createElement("button");return T.type="button",T.textContent=C,T.style.cssText=["padding:5px 11px",`border:${$?"0":"1px solid rgba(236,238,242,.24)"}`,"border-radius:6px",`background:${$?t:"transparent"}`,`color:${$?"#fff":"#eceef2"}`,"font:600 12px/1.4 inherit","cursor:pointer","white-space:nowrap"].join(";"),T}function A(C){var V;const $=document.createElement("div");$.setAttribute("role","status"),$.style.cssText=["box-sizing:border-box","width:100%","padding:12px 14px","border-radius:10px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)",`border-left:3px solid ${Ra[C==null?void 0:C.kind]||t}`,"opacity:0",`transform:translateY(${l?-8:8}px)`,"transition:opacity .2s ease,transform .2s ease","pointer-events:auto"].join(";");const T=document.createElement("div");T.style.cssText="font-weight:600;margin-bottom:2px",T.textContent=Wt(C);const L=document.createElement("div");L.style.cssText=(C==null?void 0:C.kind)==="reply"?"color:#a4abba;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden":"color:#a4abba",L.textContent=Qa(C);const X=document.createElement("div");X.style.cssText="display:flex;align-items:center;gap:8px;margin-top:10px;flex-wrap:wrap";const U=document.createElement("span");U.style.cssText="color:#7b8394;font-size:11px;margin-right:auto",U.textContent=ja(C==null?void 0:C.at);const j=S("Mark as read",!1);if(j.setAttribute("aria-label",`Mark as read: ${Wt(C)}`),j.addEventListener("click",()=>n==null?void 0:n(C.id)),X.append(U,j),(V=C==null?void 0:C.call)!=null&&V.offered&&typeof i=="function"){const E=S("Talk it through",!0);E.addEventListener("click",()=>i(C)),X.insertBefore(E,j)}return $.append(T,L,X),$}function ie(C){const $=document.createElement("div");$.style.cssText=["box-sizing:border-box","width:100%","display:flex","align-items:center","gap:8px","padding:8px 12px","border-radius:10px","background:#1b1e26","color:#a4abba",'font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 12px 30px rgba(0,0,0,0.45)","pointer-events:auto"].join(";");const T=document.createElement("span");T.style.cssText="margin-right:auto",T.textContent=`${C} more update${C===1?"":"s"}`;const L=S("Mark all as read",!1);return L.style.cssText+=";padding:4px 9px",L.addEventListener("click",()=>a==null?void 0:a()),$.append(T,L),$}return{render(C){const $=Array.isArray(C)?C:[];if(!$.length){for(const E of f.values())g(E);f.clear(),h==null||h.remove(),h=null,y==null||y.remove(),y=null;return}const T=$.slice(-3),L=new Set(T.map(E=>E.id)),X=b();for(const[E,se]of f)L.has(E)||(g(se),f.delete(E));const U=[];for(const E of T){if(f.has(E.id))continue;const se=A(E);f.set(E.id,se),U.push(se)}const j=l?[...T].reverse():T;for(const E of j)X.appendChild(f.get(E.id));const V=$.length-T.length;V>0?(h==null||h.remove(),h=ie(V),l?X.appendChild(h):X.insertBefore(h,X.firstChild)):(h==null||h.remove(),h=null),requestAnimationFrame(()=>{for(const E of U)E.isConnected&&(E._bcShown=!0,E.style.opacity="1",E.style.transform="translateY(0)")})},destroy(){f.clear(),h=null,y==null||y.remove(),y=null}}}async function Ha({apiBase:t,apiKey:e,projectId:n,sessionToken:a}){try{const i=await fetch(`${t}/ingest/known-issues?projectId=${encodeURIComponent(n)}`,{headers:yt(e,a)});if(!i.ok)return[];const r=await i.json();return Array.isArray(r==null?void 0:r.issues)?r.issues:[]}catch{return[]}}async function qa({apiBase:t,apiKey:e,projectId:n,q:a,sessionToken:i,signal:r}){try{const s=`${t}/ingest/known-issues/match?projectId=${encodeURIComponent(n)}&q=${encodeURIComponent(a)}`,l=await fetch(s,{headers:yt(e,i),signal:r});if(!l.ok)return[];const p=await l.json();return Array.isArray(p==null?void 0:p.issues)?p.issues:[]}catch{return[]}}async function Da({apiBase:t,apiKey:e,projectId:n,bugId:a,reporterEmail:i,reporterName:r,metadata:s,logs:l,sessionToken:p}){const f=await fetch(`${t}/ingest/known-issues/${encodeURIComponent(a)}/join`,{method:"POST",headers:yt(e,p),body:JSON.stringify({projectId:n,reporterEmail:i,reporterName:r,metadata:s,logs:l})});if(!f.ok)throw new Error(await Na(f));const y=await f.json();return y!=null&&y.watchToken&&bt(y.watchToken),y}function yt(t,e){return{"Content-Type":"application/json","X-BugCatch-Key":t,...e?{"X-BugCatch-Session":e}:{}}}async function Na(t){try{const e=await t.json(),n=Array.isArray(e.message)?e.message.join(", "):e.message;if(n)return n}catch{}return`Could not add you to this issue (HTTP ${t.status})`}async function Ua({apiBase:t,bugId:e,...n}){const a=re();if(!a)throw new Error("This browser cannot access that report.");const i=await fetch(`${t}/ingest/watch/reports/${encodeURIComponent(e)}/verification`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify(n)}),r=await i.json().catch(()=>({}));if(!i.ok)throw new Error(r.message||"Could not record feedback. Please refresh and try again.");return r}const Va=2e4,Yt=120,Xt=200;function Zt(t){if(typeof t!="string"||!t.trim()||t.length>400)return null;try{return new RegExp(t.trim(),"gi")}catch{return null}}const Ka=t=>String(t).replace(/\s+/g," ").trim().slice(0,Yt);function Jt(t){const e=t.length>1&&t[1]!==void 0?t[1]:t[0];return typeof e!="string"||!e.trim()?null:{value:Ka(e),start:t.index,end:t.index+t[0].length}}function Pa(t,e){const n=[],a=new Set;for(const i of e||[]){const r=typeof i=="string"?i.slice(0,Va):"";if(!r)continue;const s=[],l=(p,f)=>s.some(([y,h])=>p<h&&f>y);for(const p of t||[]){if(!p||p.scan===!1)continue;const f=Zt(p.pattern);if(!f)continue;let y,h=0;for(f.lastIndex=0;(y=f.exec(r))!==null&&!(++h>Xt);){if(y[0]===""){f.lastIndex+=1;continue}const b=Jt(y);if(b&&!l(b.start,b.end)){s.push([b.start,b.end]);const g=`${p.key}:${b.value.toLowerCase()}`;a.has(g)||(a.add(g),n.push({key:p.key,label:p.label,value:b.value}))}}}}return n}function _a(t,e){const n=typeof e=="string"?e.trim():"";if(!n||n.length>Yt)return null;const a=Zt(t&&(t.valuePattern||t.pattern));if(!a)return null;let i,r=0;for(a.lastIndex=0;(i=a.exec(n))!==null&&!(++r>Xt);){if(i[0]===""){a.lastIndex+=1;continue}const s=i.index+i[0].length===n.length,l=i.index===0||i.index===1;if(s&&l){const p=Jt(i);if(p)return p.value}}return null}async function Fa({apiBase:t,apiKey:e,projectId:n}){const a={policy:"off",fields:[]};try{const i=await fetch(`${t}/ingest/reference-fields?projectId=${encodeURIComponent(n)}`,{headers:{"X-BugCatch-Key":e}});if(!i.ok)return a;const r=await i.json(),s=r.policy==="optional"||r.policy==="required"?r.policy:"off",l=Array.isArray(r.fields)?r.fields:[];return l.length?{policy:s,fields:l}:a}catch{return a}}const Gt={"bottom-right":"bottom:20px;right:20px;","bottom-left":"bottom:20px;left:20px;","top-right":"top:20px;right:20px;","top-left":"top:20px;left:20px;"},en=[{value:"LOW",label:"Low"},{value:"MEDIUM",label:"Medium"},{value:"HIGH",label:"High"},{value:"CRITICAL",label:"Critical"}],Q={camera:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8.5A1.5 1.5 0 0 1 4.5 7h2.2a1 1 0 0 0 .83-.45l.94-1.4A1 1 0 0 1 9.3 4.7h5.4a1 1 0 0 1 .83.45l.94 1.4a1 1 0 0 0 .83.45h2.2A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z"/><circle cx="12" cy="13" r="3.4"/></svg>',video:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="6" width="12.5" height="12" rx="2.2"/><path d="M15.5 10.8l4.2-2.6a.6.6 0 0 1 .92.5v6.6a.6.6 0 0 1-.92.5l-4.2-2.6z"/></svg>',paperclip:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M20 11.5l-7.6 7.6a4.6 4.6 0 0 1-6.5-6.5l8-8a3.2 3.2 0 0 1 4.5 4.5l-8 8a1.8 1.8 0 0 1-2.5-2.5l7.1-7.1"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>',mic:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2.5" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21M9 21h6"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12l16-8-6 16-2.6-6.2L4 12Z"/></svg>',stopSquare:'<svg viewBox="0 0 24 24" fill="currentColor"><rect x="7" y="7" width="10" height="10" rx="2"/></svg>',back:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 5.5L8 12l6.5 6.5"/></svg>',phone:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/></svg>',phoneOff:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6.2 3.5h3l1.5 3.7-2 1.4a11.5 11.5 0 0 0 5.7 5.7l1.4-2 3.7 1.5v3a1.8 1.8 0 0 1-2 1.8A15.6 15.6 0 0 1 4.4 5.5a1.8 1.8 0 0 1 1.8-2z"/><path d="M3 21L21 3"/></svg>',bug:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6a4 4 0 0 1 8 0"/><rect x="7" y="7.5" width="10" height="12" rx="5"/><path d="M7 11H3.5M7 15.5H4M17 11h3.5M17 15.5h3M12 8v11.5"/></svg>',check:'<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>',retry:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 12a8 8 0 1 1-2.6-5.9M20 4v4.5h-4.5"/></svg>',sun:'<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>',moon:'<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>',auto:'<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>'},Wa='<svg class="bc-brand" viewBox="0 0 254 60" fill="none" role="img" aria-label="sphoro BugCatch"><g fill="currentColor"><path transform="translate(0.00 40.00) scale(0.04000 -0.04000)" d="M276.00 -14.00Q179.00 -14.00 117.00 28.00Q55.00 70.00 42.00 148.00L158.00 178.00Q165.00 143.00 181.50 123.00Q198.00 103.00 222.50 94.50Q247.00 86.00 276.00 86.00Q320.00 86.00 341.00 101.50Q362.00 117.00 362.00 140.00Q362.00 163.00 342.00 175.50Q322.00 188.00 278.00 196.00L250.00 201.00Q198.00 211.00 155.00 228.50Q112.00 246.00 86.00 277.00Q60.00 308.00 60.00 357.00Q60.00 431.00 114.00 470.50Q168.00 510.00 256.00 510.00Q339.00 510.00 394.00 473.00Q449.00 436.00 466.00 376.00L349.00 340.00Q341.00 378.00 316.50 394.00Q292.00 410.00 256.00 410.00Q220.00 410.00 201.00 397.50Q182.00 385.00 182.00 363.00Q182.00 339.00 202.00 327.50Q222.00 316.00 256.00 310.00L284.00 305.00Q340.00 295.00 385.50 278.50Q431.00 262.00 457.50 231.50Q484.00 201.00 484.00 149.00Q484.00 71.00 427.50 28.50Q371.00 -14.00 276.00 -14.00Z"/><path transform="translate(19.56 40.00) scale(0.04000 -0.04000)" d="M70.00 -200.00V496.00H194.00V436.00H212.00Q229.00 465.00 265.00 487.50Q301.00 510.00 368.00 510.00Q428.00 510.00 479.00 480.50Q530.00 451.00 561.00 394.00Q592.00 337.00 592.00 256.00V240.00Q592.00 159.00 561.00 102.00Q530.00 45.00 479.00 15.50Q428.00 -14.00 368.00 -14.00Q323.00 -14.00 292.50 -3.50Q262.00 7.00 243.50 23.50Q225.00 40.00 214.00 57.00H196.00V-200.00ZM330.00 96.00Q389.00 96.00 427.50 133.50Q466.00 171.00 466.00 243.00V253.00Q466.00 325.00 427.00 362.50Q388.00 400.00 330.00 400.00Q272.00 400.00 233.00 362.50Q194.00 325.00 194.00 253.00V243.00Q194.00 171.00 233.00 133.50Q272.00 96.00 330.00 96.00Z"/><path transform="translate(43.68 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V700.00H196.00V435.00H214.00Q222.00 451.00 239.00 467.00Q256.00 483.00 284.50 493.50Q313.00 504.00 357.00 504.00Q415.00 504.00 458.50 477.50Q502.00 451.00 526.00 404.50Q550.00 358.00 550.00 296.00V0.00H424.00V286.00Q424.00 342.00 396.50 370.00Q369.00 398.00 318.00 398.00Q260.00 398.00 228.00 359.50Q196.00 321.00 196.00 252.00V0.00Z"/><path transform="translate(66.92 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/><path transform="translate(90.00 40.00) scale(0.04000 -0.04000)" d="M70.00 0.00V496.00H194.00V440.00H212.00Q223.00 470.00 248.50 484.00Q274.00 498.00 308.00 498.00H368.00V386.00H306.00Q258.00 386.00 227.00 360.50Q196.00 335.00 196.00 282.00V0.00Z"/><path transform="translate(104.44 40.00) scale(0.04000 -0.04000)" d="M306.00 -14.00Q232.00 -14.00 173.00 16.00Q114.00 46.00 80.00 103.00Q46.00 160.00 46.00 240.00V256.00Q46.00 336.00 80.00 393.00Q114.00 450.00 173.00 480.00Q232.00 510.00 306.00 510.00Q380.00 510.00 439.00 480.00Q498.00 450.00 532.00 393.00Q566.00 336.00 566.00 256.00V240.00Q566.00 160.00 532.00 103.00Q498.00 46.00 439.00 16.00Q380.00 -14.00 306.00 -14.00ZM306.00 98.00Q364.00 98.00 402.00 135.50Q440.00 173.00 440.00 243.00V253.00Q440.00 323.00 402.50 360.50Q365.00 398.00 306.00 398.00Q248.00 398.00 210.00 360.50Q172.00 323.00 172.00 253.00V243.00Q172.00 173.00 210.00 135.50Q248.00 98.00 306.00 98.00Z"/></g><rect x="139.52" y="16" width="1.6" height="26" rx="0.8" fill="var(--bc-brand-mark, #5647ee)" opacity="0.4"/><g fill="var(--bc-brand-mark, #5647ee)"><path transform="translate(154.52 35.00) scale(0.01400 -0.01400)" d="M46.35 0.00V105.85H139.75V594.15H46.35V700.00H404.08Q467.38 700.00 514.79 678.41Q562.20 656.83 588.70 617.33Q615.20 577.83 615.20 523.35V513.70Q615.20 465.52 597.03 434.76Q578.85 404.00 553.91 387.24Q528.98 370.48 506.28 363.30V346.35Q528.98 340.35 555.24 323.50Q581.50 306.65 600.00 275.48Q618.50 244.30 618.50 194.48V184.48Q618.50 126.65 591.41 85.24Q564.33 43.83 516.83 21.91Q469.33 0.00 406.85 0.00ZM259.85 109.15H392.60Q441.20 109.15 469.80 132.60Q498.40 156.05 498.40 198.55V208.20Q498.40 250.70 470.21 274.15Q442.02 297.60 392.60 297.60H259.85ZM259.85 406.75H391.65Q437.55 406.75 466.32 430.11Q495.10 453.48 495.10 493.80V503.80Q495.10 544.95 466.74 567.90Q438.37 590.85 391.65 590.85H259.85Z"/><path transform="translate(167.00 35.00) scale(0.01400 -0.01400)" d="M335.30 -14.00Q251.22 -14.00 190.60 16.63Q129.97 47.25 97.56 104.96Q65.15 162.68 65.15 243.03V700.00H185.25V239.73Q185.25 170.48 224.03 131.99Q262.80 93.50 335.30 93.50Q407.80 93.50 446.57 131.99Q485.35 170.48 485.35 239.73V700.00H605.45V243.03Q605.45 162.68 573.13 104.96Q540.80 47.25 480.09 16.63Q419.38 -14.00 335.30 -14.00Z"/><path transform="translate(179.60 35.00) scale(0.01400 -0.01400)" d="M311.85 -14.00Q238.45 -14.00 179.69 18.50Q120.92 51.00 86.69 113.67Q52.45 176.35 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.23 645.59Q598.33 577.17 598.33 460.87V456.70H479.87V464.52Q479.87 504.67 463.76 536.86Q447.65 569.05 414.99 587.77Q382.32 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 138.89Q257.63 91.85 334.00 91.85Q410.02 91.85 445.12 132.83Q480.22 173.80 480.22 237.92V249.67H302.85V351.88H598.33V0.00H487.52V69.10H470.57Q462.70 50.87 446.06 31.44Q429.42 12.00 397.64 -1.00Q365.85 -14.00 311.85 -14.00Z"/><path transform="translate(192.05 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(204.25 35.00) scale(0.01400 -0.01400)" d="M19.75 0.00 211.62 700.00H421.33L613.20 0.00H489.27L447.42 159.60H185.53L143.68 0.00ZM214.25 270.40H418.70L324.95 624.87H308.00Z"/><path transform="translate(216.31 35.00) scale(0.01400 -0.01400)" d="M233.95 0.00V590.85H24.70V700.00H563.30V590.85H354.05V0.00Z"/><path transform="translate(227.75 35.00) scale(0.01400 -0.01400)" d="M332.35 -14.00Q203.57 -14.00 128.01 58.50Q52.45 131.00 52.45 266.87V433.13Q52.45 569.00 128.01 641.50Q203.57 714.00 332.35 714.00Q460.13 714.00 529.58 643.85Q599.03 573.70 599.03 451.57V445.75H480.57V455.22Q480.57 521.42 444.15 563.96Q407.72 606.50 332.35 606.50Q257.63 606.50 215.09 560.70Q172.55 514.90 172.55 435.13V264.87Q172.55 185.93 215.09 139.71Q257.63 93.50 332.35 93.50Q407.72 93.50 444.15 136.45Q480.57 179.40 480.57 244.78V262.25H599.03V248.43Q599.03 126.30 529.58 56.15Q460.13 -14.00 332.35 -14.00Z"/><path transform="translate(239.95 35.00) scale(0.01400 -0.01400)" d="M69.50 0.00V700.00H189.60V405.58H466.40V700.00H586.50V0.00H466.40V296.42H189.60V0.00Z"/></g></svg>',tn=[{value:"light",label:"Light",icon:Q.sun},{value:"dark",label:"Dark",icon:Q.moon},{value:"auto",label:"System default",icon:Q.auto}],nn="bugcatch:theme";function Ya(){try{const t=localStorage.getItem(nn);return tn.some(e=>e.value===t)?t:null}catch{return null}}function Xa(t){try{localStorage.setItem(nn,t)}catch{}}const Za=t=>`
|
|
8
8
|
:host { all: initial; }
|
|
9
9
|
:host {
|
|
10
10
|
--bc-accent: ${t};
|
|
@@ -538,6 +538,36 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
538
538
|
.att .file .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
539
539
|
.att .file .sz { flex: none; color: var(--bc-faint); font-size: 11px; }
|
|
540
540
|
|
|
541
|
+
/* The assistant's live card, above the conversation. */
|
|
542
|
+
.assistant { margin: 8px 12px 4px; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--bc-border); background: var(--bc-subtle); }
|
|
543
|
+
.assistant.analyzing, .assistant.confirming, .assistant.needs_info { border-color: color-mix(in srgb, var(--bc-accent) 45%, transparent); }
|
|
544
|
+
.as-top { display: flex; gap: 10px; align-items: flex-start; }
|
|
545
|
+
.as-orb { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-size: 12px; background: var(--bc-accent); }
|
|
546
|
+
.as-spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; animation: as-rot .8s linear infinite; }
|
|
547
|
+
@keyframes as-rot { to { transform: rotate(360deg); } }
|
|
548
|
+
.as-title { font-weight: 600; font-size: 14px; }
|
|
549
|
+
.assistant.analyzing .as-title::after { content: ''; animation: as-dots 1.4s steps(4) infinite; }
|
|
550
|
+
@keyframes as-dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }
|
|
551
|
+
.as-detail { font-size: 12.5px; color: var(--bc-muted); margin-top: 2px; }
|
|
552
|
+
.as-steps { list-style: none; display: flex; gap: 6px; margin: 10px 0 0; padding: 0; flex-wrap: wrap; font-size: 11.5px; color: var(--bc-muted); }
|
|
553
|
+
.as-steps li { display: flex; align-items: center; gap: 4px; }
|
|
554
|
+
.as-steps li span { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid currentColor; }
|
|
555
|
+
.as-steps li.done { color: var(--bc-accent); }
|
|
556
|
+
.as-steps li.done span { background: var(--bc-accent); border-color: var(--bc-accent); }
|
|
557
|
+
.as-steps li.active { color: var(--bc-fg); font-weight: 600; }
|
|
558
|
+
.as-steps li.active span { border-color: var(--bc-accent); animation: as-pulse 1s ease-in-out infinite; }
|
|
559
|
+
@keyframes as-pulse { 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--bc-accent) 25%, transparent); } }
|
|
560
|
+
@media (prefers-reduced-motion: reduce) { .as-spin, .as-steps li.active span, .assistant.analyzing .as-title::after { animation: none; } }
|
|
561
|
+
|
|
562
|
+
/* Quick answers under the confirm question — only on the latest message. */
|
|
563
|
+
.msg-row .quick { display: none; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
|
|
564
|
+
.msg-row:last-child .quick { display: flex; }
|
|
565
|
+
.quick button {
|
|
566
|
+
font: inherit; font-size: 13px; padding: 6px 12px; border-radius: 999px; cursor: pointer;
|
|
567
|
+
border: 1px solid var(--bc-accent); background: transparent; color: var(--bc-accent);
|
|
568
|
+
}
|
|
569
|
+
.quick button:hover { background: color-mix(in srgb, var(--bc-accent) 12%, transparent); }
|
|
570
|
+
|
|
541
571
|
/* ---------- the composer ---------- */
|
|
542
572
|
.composer {
|
|
543
573
|
position: sticky; bottom: 0; margin-top: auto;
|
|
@@ -773,15 +803,15 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
773
803
|
.launcher:hover { transform: none; filter: none; box-shadow: 0 6px 18px rgba(10,12,16,.22), 0 1px 3px rgba(10,12,16,.16); }
|
|
774
804
|
.tool:hover, .themer button:hover { border-color: var(--bc-border); }
|
|
775
805
|
}
|
|
776
|
-
`;function
|
|
806
|
+
`;function Ja(t){const e=document.createElement("div");e.setAttribute("data-bugcatch","widget");let n=Ya()||Ga(t.config.theme);e.className=an(n);const a=e.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=Za(t.config.accent||"#4F46E5"),a.appendChild(i);const r=Gt[t.config.widgetPosition]?t.config.widgetPosition:"bottom-right",s=document.createElement("div");s.className=`dock ${r.includes("right")?"at-right":"at-left"}`+(r.startsWith("top")?" at-top":""),s.style.cssText=Gt[r];const l=document.createElement("div");l.className="themer",l.setAttribute("role","group"),l.setAttribute("aria-label","Report widget theme"),l.innerHTML=tn.map(y=>`<button type="button" data-theme="${y.value}" title="${y.label}" aria-label="${y.label}" aria-pressed="${y.value===n}">${y.icon}</button>`).join(""),l.addEventListener("click",y=>{const h=y.target.closest("button[data-theme]");!h||h.dataset.theme===n||(n=h.dataset.theme,e.className=an(n),Xa(n),l.querySelectorAll("button").forEach(b=>{b.setAttribute("aria-pressed",String(b.dataset.theme===n))}))});const p=document.createElement("button");p.className="launcher",p.type="button",p.innerHTML=`${Q.bug}<span>Report a bug</span>`,p.setAttribute("aria-haspopup","dialog"),p.setAttribute("aria-expanded","false");let f=null;return p.addEventListener("click",()=>{if(f){f.close();return}s.classList.add("over"),p.setAttribute("aria-expanded","true"),f=eo({root:a,host:e,dock:s,client:t,onClose:()=>{f=null,s.classList.remove("over"),p.setAttribute("aria-expanded","false")}})}),s.append(l,p),a.appendChild(s),document.body.appendChild(e),()=>{f==null||f.destroy(),e.remove()}}function Ga(t){return t==="dark"||t==="light"?t:"auto"}function an(t){return t==="dark"?"bc-dark":t==="light"?"bc-light":"bc-auto"}function eo({root:t,host:e,dock:n,client:a,onClose:i}){var In,Mn,Ln,Bn,An,Rn;const r=a.config,s=r.attachments!==!1,l=s&&na(),p=s&&ta(),f=[];let y="MEDIUM",h=null,b=!1;const g=document.createElement("div");g.className=`scrim ${n.classList.contains("at-left")?"at-left":"at-right"} ${n.classList.contains("at-top")?"at-top":"at-bottom"}`,g.style.setProperty("--bc-dock-h",`${Math.round(n.getBoundingClientRect().height)}px`),g.innerHTML=`
|
|
777
807
|
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="bc-h">
|
|
778
808
|
<div class="head">
|
|
779
|
-
<div class="mark">${
|
|
809
|
+
<div class="mark">${Q.bug}</div>
|
|
780
810
|
<div class="titles">
|
|
781
811
|
<h2 id="bc-h">Report a bug</h2>
|
|
782
812
|
<p>We'll attach what the page was doing, so you don't have to explain it.</p>
|
|
783
813
|
</div>
|
|
784
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
814
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${Q.close}</button>
|
|
785
815
|
</div>
|
|
786
816
|
<div class="body">
|
|
787
817
|
<div class="slot"></div>
|
|
@@ -804,8 +834,8 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
804
834
|
<div class="field">
|
|
805
835
|
<label id="bc-prio-l">Severity</label>
|
|
806
836
|
<div class="seg" role="group" aria-labelledby="bc-prio-l">
|
|
807
|
-
${
|
|
808
|
-
<button type="button" data-prio="${
|
|
837
|
+
${en.map(o=>`
|
|
838
|
+
<button type="button" data-prio="${o.value}" aria-pressed="${o.value===y}">${o.label}</button>
|
|
809
839
|
`).join("")}
|
|
810
840
|
</div>
|
|
811
841
|
</div>
|
|
@@ -813,9 +843,9 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
813
843
|
<div class="field">
|
|
814
844
|
<label>Attach <span style="font-weight:450;color:var(--bc-faint)">(optional)</span></label>
|
|
815
845
|
<div class="tools">
|
|
816
|
-
${l?`<button class="tool" type="button" data-act="shot">${
|
|
817
|
-
${
|
|
818
|
-
<button class="tool" type="button" data-act="file">${
|
|
846
|
+
${l?`<button class="tool" type="button" data-act="shot">${Q.camera}Screenshot</button>`:""}
|
|
847
|
+
${p?`<button class="tool" type="button" data-act="rec">${Q.video}Record</button>`:""}
|
|
848
|
+
<button class="tool" type="button" data-act="file">${Q.paperclip}File</button>
|
|
819
849
|
</div>
|
|
820
850
|
<div class="thumbs"></div>
|
|
821
851
|
<input type="file" accept="${_e.join(",")}" multiple hidden />
|
|
@@ -823,10 +853,10 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
823
853
|
</div>
|
|
824
854
|
</div>
|
|
825
855
|
<div class="foot">
|
|
826
|
-
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${
|
|
856
|
+
<a class="brand-credit" href="https://bugcatch.sphoro.com" target="_blank" rel="noopener noreferrer" aria-label="BugCatch">${Wa}</a>
|
|
827
857
|
<span class="note"></span>
|
|
828
858
|
<span class="spacer"></span>
|
|
829
|
-
${
|
|
859
|
+
${a.hasReports()?'<button class="ghost" type="button" data-act="history">Your reports</button>':""}
|
|
830
860
|
<button class="ghost" type="button" data-act="cancel">Cancel</button>
|
|
831
861
|
<!-- Hidden until the API confirms this project can take a call, which
|
|
832
862
|
most cannot. Drawn here rather than as a second launcher because it
|
|
@@ -835,51 +865,51 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
835
865
|
<button class="ghost" type="button" data-act="call" hidden>Talk to the team</button>
|
|
836
866
|
<button class="primary" type="button" data-act="send">Send report</button>
|
|
837
867
|
</div>
|
|
838
|
-
</div>`;const
|
|
839
|
-
${
|
|
840
|
-
<span class="kind">${
|
|
841
|
-
<button class="drop" type="button" data-act="drop" aria-label="Remove ${
|
|
842
|
-
${
|
|
868
|
+
</div>`;const S=o=>g.querySelector(o),A=S("#bc-title"),ie=S(".slot"),C=S(".thumbs"),$=g.querySelector("input[type=file]"),T=S('[data-act="send"]'),L=S('[data-act="call"]'),X=S(".note"),U=S(".compose"),j=S(".whoami"),V=S(".refs"),E=S(".known"),se=S('[data-act="history"]'),ne=document.createElement("div");ne.setAttribute("role","status"),ne.className="note",U.prepend(ne);const De=da(r,(In=fe(r.projectId))==null?void 0:In.email);let xe=r.drafts===!1,at=!1,ke=Promise.resolve(),K;function ae(){if(clearTimeout(K),!xe||at||r.drafts===!1)return ke;const o=A.value||S("#bc-desc").value||f.length?{title:A.value,description:S("#bc-desc").value,priority:y,items:f.map(({blob:c,mime:u,kind:d})=>({blob:c,mime:u,kind:d}))}:null;return ke=ke.catch(()=>{}).then(()=>Xe(De,o)).then(()=>{ne.textContent=o?"Draft saved on this device":""}).catch(()=>{ne.textContent="Draft could not be saved. Keep this tab open."}),ke}function Le(){clearTimeout(K),K=setTimeout(ae,250)}U.addEventListener("input",Le),U.addEventListener("change",Le);const ot=()=>{ae()};window.addEventListener("pagehide",ot);function Ne(){f.filter(o=>o.status==="failed").forEach(Qe)}window.addEventListener("online",Ne),r.drafts!==!1&&(U.inert=!0,ua(De).then(o=>{Ae||!o||(ne.innerHTML='Unfinished report on this device. <button type="button" data-resume>Resume report</button> <button type="button" data-discard>Discard</button>',ne.querySelector("[data-resume]").onclick=()=>{A.value=o.title||"",S("#bc-desc").value=o.description||"",y=en.some(c=>c.value===o.priority)?o.priority:"MEDIUM",g.querySelectorAll("[data-prio]").forEach(c=>c.setAttribute("aria-pressed",String(c.dataset.prio===y)));for(const c of(o.items||[]).slice(0,r.maxAttachments??5))Ce(c);xe=!0,ae()},ne.querySelector("[data-discard]").onclick=()=>{xe=!0,ae()})}).catch(()=>{ne.textContent="Draft storage is unavailable. Keep this tab open."}).finally(()=>{U.inert=!1,ne.querySelector("[data-resume]")||(xe=!0)}));const me=document.activeElement,Be=document.documentElement.style,St=Be.overflow;Be.overflow="hidden";let Ae=!1,Se=null;function Ue(){var o;Ae||(ae(),Ae=!0,clearTimeout(K),window.removeEventListener("pagehide",ot),window.removeEventListener("online",Ne),h==null||h.cancel(),Se==null||Se(),f.forEach(c=>c.previewUrl&&URL.revokeObjectURL(c.previewUrl)),Be.overflow=St,document.removeEventListener("keydown",Re,!0),g.remove(),(o=t.querySelector(".recbar"))==null||o.remove(),n.hidden=!1,e.style.opacity="",i==null||i())}function ce(){var o;if(!Ae){g.classList.add("closing"),setTimeout(Ue,160);try{(o=me==null?void 0:me.focus)==null||o.call(me)}catch{}}}function Re(o){if(o.key==="Escape"){if(o.stopPropagation(),h){je({keep:!1});return}b||ce();return}if(o.key!=="Tab"||h)return;const c=[...g.querySelectorAll("button:not(:disabled), input:not([hidden]), textarea, select, [href]")].filter(w=>w.offsetParent!==null||w===document.activeElement);if(!c.length)return;const u=c[0],d=c[c.length-1],k=g.getRootNode().activeElement;o.shiftKey&&k===u?(o.preventDefault(),d.focus()):!o.shiftKey&&k===d&&(o.preventDefault(),u.focus())}document.addEventListener("keydown",Re,!0),g.addEventListener("click",o=>{o.target===g&&!b&&ce()}),S('[data-act="close"]').addEventListener("click",ce),S('[data-act="cancel"]').addEventListener("click",ce),g.querySelectorAll("[data-prio]").forEach(o=>{o.addEventListener("click",()=>{y=o.dataset.prio,Le(),g.querySelectorAll("[data-prio]").forEach(c=>{c.setAttribute("aria-pressed",String(c===o))})})});function H(o,c="err"){ie.innerHTML=o?`<div class="msg ${c}">${x(o)}</div>`:""}function de(){const o=f.some(c=>c.status==="uploading");T.disabled=b||o||f.some(c=>c.status==="failed"),X.textContent=o?"Waiting for the upload to finish…":f.some(c=>c.status==="failed")?"Retry or remove failed attachments before sending.":"",g.querySelectorAll(".tool").forEach(c=>{c.disabled=b||f.length>=(r.maxAttachments??5)})}function rt(o){var w;const c=o.el,u=o.kind==="VIDEO"?"Video":"Shot",d=o.kind==="VIDEO"?`<video src="${o.previewUrl}" muted playsinline preload="metadata"></video>`:`<img src="${o.previewUrl}" alt="" />`;let k="";o.status==="uploading"?k=`<div class="veil"><div class="spinner"></div><div class="bar"><i style="width:${Math.round(o.progress*100)}%"></i></div></div>`:o.status==="failed"&&(k=`<div class="veil err"><button type="button" data-act="retry" aria-label="Retry upload">${Q.retry}</button>Failed</div>`),c.innerHTML=`
|
|
869
|
+
${d}
|
|
870
|
+
<span class="kind">${u} · ${Me(o.size)}</span>
|
|
871
|
+
<button class="drop" type="button" data-act="drop" aria-label="Remove ${u.toLowerCase()}">${Q.close}</button>
|
|
872
|
+
${k}`,c.querySelector('[data-act="drop"]').addEventListener("click",()=>Ct(o)),(w=c.querySelector('[data-act="retry"]'))==null||w.addEventListener("click",()=>Qe(o))}function Ct(o){const c=f.indexOf(o);c>=0&&f.splice(c,1),o.previewUrl&&URL.revokeObjectURL(o.previewUrl),o.el.remove(),ae(),de()}async function Qe(o){o.status="uploading",o.progress=0,rt(o),de();try{const{storageKey:c,mime:u}=await a.uploadAttachment(o.blob,o.mime,d=>{o.progress=d;const k=o.el.querySelector(".bar i");k&&(k.style.width=`${Math.round(d*100)}%`)});o.storageKey=c,o.mime=u,o.status="ready"}catch(c){o.status="failed",H(c.message.replace("[BugCatch] ",""))}rt(o),de()}function Ce({blob:o,mime:c,kind:u}){const d=r.maxAttachmentBytes??26214400;if(o.size>d){H(`That file is ${Me(o.size)} — the limit is ${Me(d)}.`);return}const k=Fe(c||o.type,_e);if(!k){H("Only PNG, JPEG, WebP, WebM and MP4 files can be attached to a report.");return}const w={blob:o,kind:u,mime:k,size:o.size,previewUrl:URL.createObjectURL(o),status:"uploading",progress:0,storageKey:null,el:document.createElement("div")};w.el.className="thumb",f.push(w),C.appendChild(w.el),H(""),ae(),Qe(w)}async function $t(o){e.style.opacity="0",e.style.pointerEvents="none",await new Promise(c=>requestAnimationFrame(()=>requestAnimationFrame(c)));try{return await o()}finally{e.style.opacity="",e.style.pointerEvents=""}}(Mn=g.querySelector('[data-act="shot"]'))==null||Mn.addEventListener("click",async()=>{try{const o=await $t(aa);Ce(o)}catch(o){(o==null?void 0:o.name)!=="NotAllowedError"&&H(`Screenshot failed: ${o.message}`)}}),(Ln=g.querySelector('[data-act="file"]'))==null||Ln.addEventListener("click",()=>$.click()),$==null||$.addEventListener("change",()=>{const o=(r.maxAttachments??5)-f.length;[...$.files].slice(0,Math.max(o,0)).forEach(c=>{Ce({blob:c,mime:c.type,kind:c.type.startsWith("video/")?"VIDEO":"SCREENSHOT"})}),$.value=""}),(Bn=g.querySelector('[data-act="rec"]'))==null||Bn.addEventListener("click",async()=>{const o=r.maxRecordingMs??12e4;let c;try{h=await oa({maxMs:o,onTick:u=>{c&&(c.querySelector(".time").textContent=We(u))},onAutoStop:()=>{h&&je({keep:!0})}})}catch(u){(u==null?void 0:u.name)!=="NotAllowedError"&&H(`Recording failed: ${u.message}`);return}g.style.display="none",n.hidden=!0,c=document.createElement("div"),c.className="recbar",c.innerHTML=`
|
|
843
873
|
<span class="dot"></span>
|
|
844
874
|
<span class="time">0:00</span>
|
|
845
|
-
<span class="hint">Recording — up to ${We(Math.round(
|
|
875
|
+
<span class="hint">Recording — up to ${We(Math.round(o/1e3))}</span>
|
|
846
876
|
<button class="stop" type="button">Stop</button>
|
|
847
|
-
<button class="ghost" type="button">Discard</button>`,c.querySelector(".stop").addEventListener("click",()=>je({keep:!0})),c.querySelector(".ghost").addEventListener("click",()=>je({keep:!1})),t.appendChild(c),c.querySelector(".stop").focus()});async function je({keep:
|
|
877
|
+
<button class="ghost" type="button">Discard</button>`,c.querySelector(".stop").addEventListener("click",()=>je({keep:!0})),c.querySelector(".ghost").addEventListener("click",()=>je({keep:!1})),t.appendChild(c),c.querySelector(".stop").focus()});async function je({keep:o}){var u;const c=h;if(c){if(h=null,(u=t.querySelector(".recbar"))==null||u.remove(),g.style.display="",n.hidden=!1,!o){c.cancel(),A.focus();return}try{const d=await c.stop();d.blob.size?Ce(d):H("That recording came back empty — nothing was captured.")}catch(d){H(`Recording failed: ${d.message}`)}A.focus()}}let m={policy:"off",fields:[]},v=null,I="",F="",W=!1,$e=!1;a.referenceFields().then(o=>{m=o}).catch(()=>{});function it(){return m.policy==="off"||!m.fields.length?[]:Pa(m.fields,[A.value,S("#bc-desc").value])}function Ee(){return!v||!I.trim()?[]:[{key:v,value:I.trim().slice(0,120)}]}function ge(){var d,k;if(!v){V.hidden=!0,V.innerHTML="";return}const o=m.fields.find(w=>w.key===v)||m.fields[0],c=m.policy!=="required";V.hidden=!1,V.innerHTML=`
|
|
848
878
|
<p class="why">${x(c?"One more thing, so we can find your record — this helps us answer faster.":"We need one of these to look this up.")}</p>
|
|
849
879
|
<div class="row">
|
|
850
880
|
${m.fields.length>1?`
|
|
851
881
|
<select class="ref-kind" aria-label="Which detail you are giving">
|
|
852
|
-
${m.fields.map(
|
|
853
|
-
<option value="${x(
|
|
882
|
+
${m.fields.map(w=>`
|
|
883
|
+
<option value="${x(w.key)}" ${w.key===o.key?"selected":""}>${x(w.label)}</option>
|
|
854
884
|
`).join("")}
|
|
855
885
|
</select>`:""}
|
|
856
|
-
<input class="ref-value" type="${
|
|
857
|
-
inputmode="${x(
|
|
886
|
+
<input class="ref-value" type="${o.inputMode==="email"?"email":"text"}"
|
|
887
|
+
inputmode="${x(o.inputMode==="numeric"||o.inputMode==="tel"?"numeric":"text")}"
|
|
858
888
|
value="${x(I)}"
|
|
859
|
-
placeholder="${x(
|
|
860
|
-
aria-label="${x(
|
|
889
|
+
placeholder="${x(o.placeholder||"")}"
|
|
890
|
+
aria-label="${x(o.label)}" />
|
|
861
891
|
</div>
|
|
862
|
-
${
|
|
863
|
-
${
|
|
864
|
-
${c?`<button type="button" class="link" data-act="ref-skip">I don't have this</button>`:""}`;const
|
|
892
|
+
${o.hint?`<p class="hint">${x(o.hint)}</p>`:""}
|
|
893
|
+
${F?`<p class="after err">${x(F)}</p>`:""}
|
|
894
|
+
${c?`<button type="button" class="link" data-act="ref-skip">I don't have this</button>`:""}`;const u=V.querySelector(".ref-value");u.addEventListener("input",()=>{I=u.value,F="",$e=!1}),u.addEventListener("keydown",w=>{w.key==="Enter"&&(w.preventDefault(),T.click())}),(d=V.querySelector(".ref-kind"))==null||d.addEventListener("change",w=>{var z;v=w.target.value,F="",ge(),(z=V.querySelector(".ref-value"))==null||z.focus()}),(k=V.querySelector('[data-act="ref-skip"]'))==null||k.addEventListener("click",()=>{W=!0,v=null,I="",F="",$e=!1,ge(),H("")}),u.focus()}function wo(){return m.policy==="off"||!m.fields.length||it().length||Ee().length?!1:!W||m.policy==="required"}T.addEventListener("click",async()=>{const o=A.value;if(!o.trim()){H("Please describe what went wrong."),A.classList.add("invalid"),A.focus(),setTimeout(()=>A.classList.remove("invalid"),500);return}if(wo()){v=v||m.fields[0].key,ge(),H("");return}if(v&&I.trim()){const u=m.fields.find(d=>d.key===v);if(!$e&&u&&!_a(u,I)){F=`That does not look like a ${u.label.toLowerCase()}. Press Send again to use it anyway.`,$e=!0,ge();return}}b=!0,H(""),de();const c=T.innerHTML;T.innerHTML='<span class="spinner"></span>Sending…';try{const u=await a.report({title:o,description:S("#bc-desc").value,priority:y,references:Ee(),attachments:f.filter(d=>d.status==="ready").map(d=>({type:d.kind,storageKey:d.storageKey,mime:d.mime}))});if(u!=null&&u.cancelled){b=!1,T.innerHTML=c,de();return}at=!0,clearTimeout(K),await ke,r.drafts!==!1&&await Xe(De,null).catch(()=>{}),kn(u)}catch(u){b=!1,T.innerHTML=c,H(u.message.replace("[BugCatch] ","")),de(),Z.mode!=="off"&&Mt().catch(()=>{})}}),(An=g.querySelector('[data-act="history"]'))==null||An.addEventListener("click",Cn);let ze=[],st="",Et=null,Ve=null;function bn(){r.knownIssues!==!1&&a.knownIssues().then(o=>{ze=o,Ke()}).catch(()=>{})}let yn=null;function vo(o){if(r.knownIssues===!1)return;clearTimeout(yn),Ve==null||Ve.abort();const c=(o||"").trim();if(c.length<3){bn();return}yn=setTimeout(()=>{Ve=new AbortController,a.matchKnownIssues(c,{signal:Ve.signal}).then(u=>{u.length&&(ze=u,Ke())}).catch(()=>{})},250)}function Ke(){if(!ze.length){E.hidden=!0,E.innerHTML="";return}E.hidden=!1,E.innerHTML=`
|
|
865
895
|
<p class="known-h">Already reported</p>
|
|
866
|
-
${ze.map(
|
|
867
|
-
<div class="issue ${
|
|
896
|
+
${ze.map(o=>`
|
|
897
|
+
<div class="issue ${o.joined?"is-joined":""}">
|
|
868
898
|
<span class="who">
|
|
869
|
-
<span class="t">${x(
|
|
870
|
-
<span class="meta">${x(
|
|
899
|
+
<span class="t">${x(o.title)}</span>
|
|
900
|
+
<span class="meta">${x(xo(o))}</span>
|
|
871
901
|
</span>
|
|
872
|
-
<button class="join" type="button" data-join="${x(
|
|
873
|
-
${
|
|
902
|
+
<button class="join" type="button" data-join="${x(o.id)}"
|
|
903
|
+
${o.joined?"disabled":""}>${o.joined?"Following":"Me too"}</button>
|
|
874
904
|
</div>
|
|
875
|
-
${Et===
|
|
905
|
+
${Et===o.id?`
|
|
876
906
|
<div class="ask">
|
|
877
907
|
<input type="email" class="join-email" placeholder="you@example.com"
|
|
878
908
|
aria-label="Your email, so we can tell you when this is fixed" />
|
|
879
|
-
<button class="ghost" type="button" data-join-confirm="${x(
|
|
909
|
+
<button class="ghost" type="button" data-join-confirm="${x(o.id)}">Follow</button>
|
|
880
910
|
</div>`:""}
|
|
881
911
|
`).join("")}
|
|
882
|
-
${st?`<p class="err">${x(st)}</p>`:""}`}function
|
|
912
|
+
${st?`<p class="err">${x(st)}</p>`:""}`}function xo(o){const c=o.status==="IN_PROGRESS"?"Being worked on now":"Not fixed yet",u=o.affectedCount===0?"":` · ${o.affectedCount} ${o.affectedCount===1?"person has":"people have"} said this is happening to them`;return`${c} · reported ${et(o.since)}${u}`}E.addEventListener("click",async o=>{var w,z,O,q,ee;const c=o.target.closest("[data-join]"),u=o.target.closest("[data-join-confirm]");if(!c&&!u)return;const d=(u||c).getAttribute(u?"data-join-confirm":"data-join");st="";const k=((z=(w=E.querySelector(".join-email"))==null?void 0:w.value)==null?void 0:z.trim())||((O=a.signedInAs())==null?void 0:O.email)||((q=a.config.user)==null?void 0:q.email);if(!k){Et=d,Ke(),(ee=E.querySelector(".join-email"))==null||ee.focus();return}try{const pe=await a.meToo(d,{email:k});Et=null,ze=ze.map(P=>P.id===d?{...P,joined:!0,affectedCount:pe.affectedCount??P.affectedCount}:P),Ke()}catch(pe){st=pe.message.replace("[BugCatch] ",""),Ke()}}),bn(),A.addEventListener("input",()=>vo(A.value));let wn=!1;function vn(){a.callKind().then(o=>{o&&(wn=!0,L.hidden=Tt())}).catch(()=>{})}vn();let Z={mode:a.lastLoginMode||"off",signedIn:null},J="idle",Oe=((Rn=a.config.user)==null?void 0:Rn.email)||"",He="",G=!1,ue="";const Tt=()=>Z.mode==="required"&&!Z.signedIn;function ko(){const o=Tt();U.hidden=o,T.hidden=o,se&&(se.hidden=o),o?L.hidden=!0:wn&&(L.hidden=!1)}function So(){var c;if(Z.mode==="off"){j.hidden=!0,j.innerHTML="";return}j.hidden=!1,j.classList.toggle("asking",J!=="idle");const o=ue?`<div class="after err">${x(ue)}</div>`:"";if(J==="idle"){if(Z.signedIn){j.innerHTML=`<span class="who">Signed in as <strong>${x(Z.signedIn.email)}</strong></span><button type="button" class="link" data-act="signout">Sign out</button>`;return}const u=(c=a.config.user)==null?void 0:c.email;j.innerHTML=`<span class="who">${Z.mode==="required"?"Sign in to report a bug here.":u?`Reporting as <strong>${x(u)}</strong>.`:"Reporting anonymously — sign in and we can tell you what happens next."}</span><button type="button" class="link" data-act="signin">Sign in</button>`;return}if(J==="email"){j.innerHTML=`
|
|
883
913
|
<p class="why">Sign in with any email address — we'll send you a code.
|
|
884
914
|
It's how you hear back about this report${Z.mode==="required"?", and this project asks for it":""}.</p>
|
|
885
915
|
<div class="row">
|
|
@@ -890,8 +920,8 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
890
920
|
${G?"Sending…":"Send code"}
|
|
891
921
|
</button>
|
|
892
922
|
</div>
|
|
893
|
-
${
|
|
894
|
-
${Z.mode==="optional"?'<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>':""}`;return}
|
|
923
|
+
${o}
|
|
924
|
+
${Z.mode==="optional"?'<div class="after"><button type="button" class="link" data-act="skip">Not now</button></div>':""}`;return}j.innerHTML=`
|
|
895
925
|
<p class="why">We sent a code to <strong>${x(Oe)}</strong>. It expires in ten minutes.</p>
|
|
896
926
|
<div class="row">
|
|
897
927
|
<input type="text" class="code" data-fld="code" value="${x(He)}"
|
|
@@ -901,96 +931,108 @@ button.primary .spinner { border-color: rgba(255,255,255,.4); border-top-color:
|
|
|
901
931
|
${G?"Checking…":"Sign in"}
|
|
902
932
|
</button>
|
|
903
933
|
</div>
|
|
904
|
-
${
|
|
934
|
+
${o}
|
|
905
935
|
<div class="after">
|
|
906
936
|
<button type="button" class="link" data-act="resend" ${G?"disabled":""}>Send it again</button>
|
|
907
937
|
<button type="button" class="link" data-act="signin-back" ${G?"disabled":""}>Use another address</button>
|
|
908
|
-
</div>`}function le({focus:
|
|
938
|
+
</div>`}function le({focus:o=!1}={}){var u;if(So(),ko(),!o||G)return;const c=j.querySelector("[data-fld]");c&&(c.focus(),(u=c.setSelectionRange)==null||u.call(c,c.value.length,c.value.length))}j.addEventListener("input",o=>{const c=o.target.closest("[data-fld]");c&&(c.dataset.fld==="email"?Oe=c.value:He=c.value)}),j.addEventListener("keydown",o=>{o.key!=="Enter"||!o.target.closest("[data-fld]")||(o.preventDefault(),J==="email"?It():xn())});async function It({resent:o=!1}={}){const c=Oe.trim();if(!c){ue="Enter the address to send the code to.",le({focus:!0});return}G=!0,ue="",le();try{await a.signIn(c),Oe=c,o||(He=""),J="code"}catch(u){ue=u.message}finally{G=!1,le({focus:!0})}}async function xn(){const o=He.trim();if(!o){ue="Enter the code we emailed you.",le({focus:!0});return}G=!0,ue="",le();try{const c=await a.confirmSignIn(Oe.trim(),o);Z.signedIn=c,J="idle",He="",H(""),vn()}catch(c){ue=c.message}finally{G=!1,le({focus:J!=="idle"})}}j.addEventListener("click",async o=>{const c=o.target.closest("button[data-act]");if(!c)return;const u=c.dataset.act;if(u==="signin"){J="email",ue="",le({focus:!0});return}if(u==="skip"){J="idle",ue="",le();return}if(u==="signin-back"){J="email",ue="",He="",le({focus:!0});return}if(u==="code"){It();return}if(u==="resend"){It({resent:!0});return}if(u==="confirm"){xn();return}if(u==="signout"){G=!0,le();try{await a.signOut()}finally{Z.signedIn=null,G=!1,J=Z.mode==="required"?"email":"idle",le({focus:J!=="idle"})}}});async function Mt({announce:o=!1}={}){const c=await a.loginState();Z={mode:c.mode,signedIn:c.signedIn},a.lastLoginMode=c.mode,Tt()&&J==="idle"&&(J="email"),Z.signedIn&&(J="idle"),o&&c.signedOutReason&&H(c.signedOutReason,"info"),le()}Mt({announce:!0}).catch(()=>{}),L.addEventListener("click",async()=>{b=!0,H(""),de(),L.disabled=!0,L.innerHTML='<span class="spinner"></span>Ringing…';try{const o=await a.startCall();Co(o)}catch(o){b=!1,L.disabled=!1,L.textContent="Talk to the team",de(),o.filed?kn(o.filed,{callFailed:o.reason||"The call could not be started."}):(H(o.message.replace("[BugCatch] ","")),Z.mode!=="off"&&Mt().catch(()=>{}))}});function Co(o){const c=g.querySelector(".panel"),u=o!=null&&o.bugId?String(o.bugId).slice(0,8):null;c.innerHTML=`
|
|
909
939
|
<div class="call">
|
|
910
940
|
<div class="call-head">
|
|
911
941
|
<span class="call-dot" aria-hidden="true"></span>
|
|
912
942
|
<strong class="call-state">Ringing…</strong>
|
|
913
943
|
</div>
|
|
914
944
|
<p class="call-note">
|
|
915
|
-
We're ringing the team now. Someone will pick up if they're free — your report${
|
|
945
|
+
We're ringing the team now. Someone will pick up if they're free — your report${u?` <code>${x(u)}</code>`:""} is already filed either way, so nothing is lost if nobody answers.
|
|
916
946
|
</p>
|
|
917
947
|
<div class="foot">
|
|
918
948
|
<span class="spacer"></span>
|
|
919
949
|
<button class="primary" type="button" data-act="hangup">Cancel</button>
|
|
920
950
|
</div>
|
|
921
|
-
</div>`;const
|
|
951
|
+
</div>`;const d=c.querySelector(".call-state"),k=c.querySelector(".call-dot"),w={ringing:"Ringing the team…",connecting:"Someone answered — connecting…",connected:"Connected",missed:"Nobody was free",ended:"Call ended",failed:"The call dropped"},z=["ended","failed","missed"],O=a.on("call",({state:q})=>{if(d.textContent=w[q]||q,k.classList.toggle("off",z.includes(q)),z.includes(q)&&(c.querySelector('[data-act="hangup"]').textContent="Close",q==="missed")){const ee=c.querySelector(".call-note");ee&&(ee.textContent="Nobody was free to pick up just now. Your report is filed and the team will reply in the chat.")}});c.querySelector('[data-act="hangup"]').addEventListener("click",()=>{O(),a.endCall(),ce()})}function kn(o,{callFailed:c=null}={}){if(o!=null&&o.id&&!c){Lt(o.id,{fresh:!0}).then(u=>{u||Sn(o,{callFailed:c})});return}Sn(o,{callFailed:c})}function Sn(o,{callFailed:c=null}={}){var w;const u=o!=null&&o.id?String(o.id).slice(0,8):null,d=(w=o==null?void 0:o.estimate)!=null&&w.label?String(o.estimate.label):null,k=c?`<p class="eta">${x(c)} Your report is filed, and the team will reply in the chat.</p>`:"";g.querySelector(".panel").innerHTML=`
|
|
922
952
|
<div class="done">
|
|
923
|
-
<div class="tick">${
|
|
953
|
+
<div class="tick">${Q.check}</div>
|
|
924
954
|
<h3>Thanks — that's on its way.</h3>
|
|
925
|
-
<p>${
|
|
926
|
-
${
|
|
927
|
-
${
|
|
928
|
-
</div>`,setTimeout(ce,
|
|
955
|
+
<p>${u?`Filed as <code>${x(u)}</code>.`:"The team has what they need to reproduce it."}</p>
|
|
956
|
+
${k}
|
|
957
|
+
${d?`<p class="eta">Reports like this usually take <strong>${x(d)}</strong>. We'll let you know when it moves.</p>`:""}
|
|
958
|
+
</div>`,setTimeout(ce,k?6e3:d?4e3:2e3)}async function Cn(){const o=g.querySelector(".panel");o.innerHTML=`
|
|
929
959
|
<div class="head">
|
|
930
|
-
<div class="mark">${
|
|
960
|
+
<div class="mark">${Q.bug}</div>
|
|
931
961
|
<div class="titles">
|
|
932
962
|
<h2>Your reports</h2>
|
|
933
963
|
<p>Everything you've reported, and where each one got to.</p>
|
|
934
964
|
</div>
|
|
935
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
965
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${Q.close}</button>
|
|
936
966
|
</div>
|
|
937
|
-
<div class="history"><div class="empty">Loading…</div></div>`,
|
|
938
|
-
<button class="row" type="button" data-report="${x(
|
|
967
|
+
<div class="history"><div class="empty">Loading…</div></div>`,o.querySelector('[data-act="close"]').addEventListener("click",ce);let c=[];try{({reports:c}=await a.myReports())}catch{o.querySelector(".history").innerHTML=`<div class="empty">Couldn't load your reports just now.</div>`;return}const u=o.querySelector(".history");if(u){u.innerHTML=c.length?c.map(d=>`
|
|
968
|
+
<button class="row" type="button" data-report="${x(d.id)}">
|
|
939
969
|
<span class="who">
|
|
940
|
-
<span class="ttl">${x(
|
|
941
|
-
<span class="sub">${x(
|
|
970
|
+
<span class="ttl">${x(d.title)}</span>
|
|
971
|
+
<span class="sub">${x(d.reference)} · ${x(et(d.createdAt))}</span>
|
|
942
972
|
</span>
|
|
943
|
-
<span class="pill ${x(String(
|
|
944
|
-
</button>`).join(""):`<div class="empty">You haven't reported anything yet.</div>`;for(const
|
|
973
|
+
<span class="pill ${x(String(d.status).toLowerCase())}">${x(vt(d.status))}</span>
|
|
974
|
+
</button>`).join(""):`<div class="empty">You haven't reported anything yet.</div>`;for(const d of u.querySelectorAll("[data-report]"))d.addEventListener("click",()=>Lt(d.dataset.report))}}async function Lt(o,{fresh:c=!1}={}){var z;const u=g.querySelector(".panel");u.innerHTML=`
|
|
945
975
|
<div class="head">
|
|
946
|
-
<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${
|
|
976
|
+
<button class="icon-btn back" type="button" data-act="back" aria-label="Back to your reports">${Q.back}</button>
|
|
947
977
|
<div class="titles">
|
|
948
|
-
<h2
|
|
949
|
-
<p
|
|
978
|
+
<h2>${c?"Looking into it":"Your report"}</h2>
|
|
979
|
+
<p>${c?"Our assistant is investigating — it may ask you a question.":"Everything that has happened, and a way to answer."}</p>
|
|
950
980
|
</div>
|
|
951
|
-
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${
|
|
981
|
+
<button class="icon-btn" type="button" data-act="close" aria-label="Close">${Q.close}</button>
|
|
952
982
|
</div>
|
|
953
|
-
<div class="history"><div class="empty">Loading…</div></div>`,
|
|
983
|
+
<div class="history"><div class="empty">Loading…</div></div>`,u.querySelector('[data-act="close"]').addEventListener("click",ce),u.querySelector('[data-act="back"]').addEventListener("click",Cn);let d=null;try{d=await a.myReport(o)}catch{d=null}const k=u.querySelector(".history");if(!k||!u.querySelector('[data-act="back"]'))return!1;if(!d)return c||(k.innerHTML=`<div class="empty">Couldn't load that report just now.</div>`),!1;be=o,a.markReportRead(o),k.classList.add("chatting"),k.innerHTML=`
|
|
954
984
|
<div class="report-head">
|
|
955
985
|
<span class="ttl">${x(d.title)}</span>
|
|
956
986
|
<span class="sub">${x(d.reference)} · ${x(d.project||"")}</span>
|
|
957
|
-
<span class="pill ${x(String(d.status).toLowerCase())}">${x(
|
|
958
|
-
${(
|
|
987
|
+
<span class="pill ${x(String(d.status).toLowerCase())}">${x(vt(d.status))}</span>
|
|
988
|
+
${(z=d.estimate)!=null&&z.label?`<span class="eta-line">Usually takes ${x(String(d.estimate.label))}</span>`:""}
|
|
959
989
|
</div>
|
|
960
|
-
<div class="thread">${
|
|
990
|
+
<div class="thread">${on(d.timeline)}</div>`;const w=k.querySelector(".thread");return wt(w),Tn(k,d),d.canReply&&$o(k,w,o),En(k,d,o),!0}let $n=null;function En(o,c,u){var w,z,O;clearTimeout($n);const d=c.assistant;if((w=o.querySelector(".assistant"))==null||w.remove(),!d)return;const k=document.createElement("div");k.className=`assistant ${x(d.phase)}`,k.setAttribute("role","status"),k.setAttribute("aria-live","polite"),k.innerHTML=`
|
|
991
|
+
<div class="as-top">
|
|
992
|
+
<span class="as-orb" aria-hidden="true">${d.phase==="analyzing"?'<span class="as-spin"></span>':"✦"}</span>
|
|
993
|
+
<div class="as-text">
|
|
994
|
+
<div class="as-title">${x(d.title)}</div>
|
|
995
|
+
<div class="as-detail">${x(d.detail)}</div>
|
|
996
|
+
</div>
|
|
997
|
+
</div>
|
|
998
|
+
<ol class="as-steps">${(d.steps||[]).map(q=>`<li class="${x(q.state)}"><span></span>${x(q.label)}</li>`).join("")}</ol>`,(z=o.querySelector(".report-head"))==null||z.after(k),d.phase==="analyzing"?$n=setTimeout(()=>ct(u),3e3):d.phase==="needs_info"&&((O=o.querySelector(".composer textarea"))==null||O.focus())}function Tn(o,c){var d,k;if((d=o.querySelector(".fix-verification"))==null||d.remove(),!c.resolvedAt||!["RESOLVED","CLOSED"].includes(c.status))return;const u=document.createElement("div");u.className="fix-verification",c.verification?u.textContent=c.verification==="CONFIRMED"?"You confirmed that this fix works.":"Your feedback was recorded.":(u.innerHTML='<p>Does the fix work for you?</p><textarea maxlength="4000" aria-label="Fix feedback" placeholder="What happens when you try again? (optional)"></textarea><button type="button" data-result="CONFIRMED">It works now</button> <button type="button" data-result="STILL_HAPPENING">Still happening</button><p class="feedback-status" role="status"></p>',u.querySelectorAll("[data-result]").forEach(w=>{w.onclick=async()=>{u.querySelectorAll("button").forEach(z=>{z.disabled=!0});try{await a.verifyFix(c.id,{result:w.dataset.result,resolvedAt:c.resolvedAt,note:u.querySelector("textarea").value}),await Lt(c.id)}catch(z){u.querySelector(".feedback-status").textContent=z.message,u.querySelectorAll("button").forEach(O=>{O.disabled=!1})}}})),(k=o.querySelector(".report-head"))==null||k.after(u)}async function ct(o){const c=g.querySelector(".history.chatting"),u=c==null?void 0:c.querySelector(".thread");if(!u||be!==o)return;let d=null;try{d=await a.myReport(o)}catch{}if(!d||be!==o)return;Tn(c,d),En(c,d,o);const k=ao(u);u.innerHTML=on(d.timeline),k&&wt(u);const w=c.querySelector(".report-head .pill");w&&(w.className=`pill ${String(d.status).toLowerCase()}`,w.textContent=vt(d.status))}function $o(o,c,u){const d=document.createElement("div");d.className="composer",d.innerHTML=`
|
|
961
999
|
<div class="staged" hidden></div>
|
|
962
1000
|
<div class="row">
|
|
963
1001
|
<div class="tools">
|
|
964
|
-
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${
|
|
965
|
-
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${
|
|
966
|
-
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${
|
|
1002
|
+
<button class="tool" type="button" data-act="attach" title="Attach a file" aria-label="Attach a file">${Q.paperclip}</button>
|
|
1003
|
+
<button class="tool" type="button" data-act="voice" title="Record a voice note" aria-label="Record a voice note">${Q.mic}</button>
|
|
1004
|
+
<button class="tool" type="button" data-act="livecall" title="Call the team" aria-label="Call the team" hidden>${Q.phone}</button>
|
|
967
1005
|
</div>
|
|
968
1006
|
<textarea rows="1" placeholder="Write a reply…" aria-label="Write a reply"></textarea>
|
|
969
|
-
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${
|
|
1007
|
+
<button class="send" type="button" data-act="send" title="Send" aria-label="Send" disabled>${Q.send}</button>
|
|
970
1008
|
</div>
|
|
971
1009
|
<div class="note" hidden></div>
|
|
972
|
-
<input type="file" hidden multiple accept="${
|
|
973
|
-
<span class="chip ${
|
|
974
|
-
<span class="nm">${x(
|
|
975
|
-
<span class="sz">${
|
|
976
|
-
<button type="button" data-drop="${
|
|
977
|
-
</span>`).join("");for(const
|
|
1010
|
+
<input type="file" hidden multiple accept="${Nt.join(",")}">`,o.appendChild(d);const k=d.querySelector(".staged"),w=d.querySelector("textarea"),z=d.querySelector('[data-act="send"]'),O=d.querySelector('[data-act="voice"]'),q=d.querySelector('[data-act="livecall"]'),ee=d.querySelector("input[type=file]"),pe=d.querySelector(".note"),P=[];let Te=null,Y=!1;function oe(M,R=""){pe.hidden=!M,pe.className=`note ${R}`,pe.textContent=M||""}function Ie(){const M=P.filter(R=>R.storageKey);z.disabled=Y||!w.value.trim()&&!M.length,k.hidden=!P.length,k.innerHTML=P.map((R,he)=>`
|
|
1011
|
+
<span class="chip ${R.storageKey?"":"uploading"}">
|
|
1012
|
+
<span class="nm">${x(R.name)}</span>
|
|
1013
|
+
<span class="sz">${R.storageKey?Me(R.size):"sending…"}</span>
|
|
1014
|
+
<button type="button" data-drop="${he}" aria-label="Remove ${x(R.name)}">${Q.close}</button>
|
|
1015
|
+
</span>`).join("");for(const R of k.querySelectorAll("[data-drop]"))R.addEventListener("click",()=>{P.splice(Number(R.dataset.drop),1),Ie()})}async function Qn(M,R,he){const D={name:he,size:M.size,storageKey:null};P.push(D),Ie();try{const{storageKey:At,mime:To}=await a.uploadAttachment(M,R);D.storageKey=At,D.mime=To}catch(At){P.splice(P.indexOf(D),1),oe(At.message||"That file could not be sent.","err")}Ie()}w.addEventListener("input",()=>{w.style.height="auto",w.style.height=`${Math.min(w.scrollHeight,120)}px`,Ie()}),w.addEventListener("keydown",M=>{M.key==="Enter"&&!M.shiftKey&&!M.isComposing&&(M.preventDefault(),Bt())}),d.querySelector('[data-act="attach"]').addEventListener("click",()=>ee.click()),ee.addEventListener("change",()=>{oe("");for(const M of ee.files){if(M.size>a.config.maxAttachmentBytes){oe(`${M.name} is larger than ${Me(a.config.maxAttachmentBytes)}.`,"err");continue}Qn(M,M.type,M.name)}ee.value=""}),ea()||(O.disabled=!0,O.title="This browser cannot record audio"),O.addEventListener("click",async()=>{if(Te){const M=Te;Te=null,O.classList.remove("recording"),O.innerHTML=Q.mic,oe("");const{blob:R,mime:he}=await M.stop();R.size&&Qn(R,he,"Voice note");return}try{oe(""),Te=await ra({maxMs:a.config.maxRecordingMs,onTick:M=>oe(`Recording — ${We(M)}. Tap the mic to stop.`),onAutoStop:()=>O.click()}),O.classList.add("recording"),O.innerHTML=Q.stopSquare}catch{Te=null,oe("The microphone is not available — check the browser permission.","err")}}),a.canCallTeam(u).then(M=>{M&&(q.hidden=!1)}).catch(()=>{}),q.addEventListener("click",async()=>{q.disabled=!0,oe("");try{const M=await a.startLiveCall(u);Eo(o,c,M)}catch(M){oe(M.message.replace("[BugCatch] ",""),"err")}finally{q.disabled=!1}}),z.addEventListener("click",Bt),c.addEventListener("click",M=>{var he,D;const R=(D=(he=M.target).closest)==null?void 0:D.call(he,"[data-quick]");!R||Y||(w.value=R.dataset.quick,Bt())});async function Bt(){var he;const M=w.value.trim(),R=P.filter(D=>D.storageKey);if(!(Y||!M&&!R.length)){Y=!0,Ie(),oe(""),c.insertAdjacentHTML("beforeend",rn({from:"reporter",body:M,at:new Date().toISOString(),attachments:R.map(D=>({type:"FILE",name:D.name,size:D.size}))},"pending")),wt(c);try{await Pt({apiBase:a.config.apiBase,bugId:u,body:M,attachments:R.map(D=>({storageKey:D.storageKey,mime:D.mime,name:D.name,size:D.size}))}),w.value="",w.style.height="auto",P.length=0,await ct(u)}catch(D){(he=c.querySelector(".msg-row.pending"))==null||he.classList.replace("pending","failed"),oe(D.message||"That could not be sent — try again.","err")}finally{Y=!1,Ie()}}}Ie()}function Eo(o,c,u){const d=document.createElement("div");d.className="livecall",d.innerHTML=`
|
|
978
1016
|
<span class="call-dot" aria-hidden="true"></span>
|
|
979
1017
|
<span class="who" role="status" aria-live="polite">Calling the team…</span>
|
|
980
1018
|
<span class="secs" hidden></span>
|
|
981
1019
|
<button class="act" type="button" data-act="mute" hidden>Mute</button>
|
|
982
|
-
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,
|
|
1020
|
+
<button class="act danger" type="button" data-act="hangup">Cancel</button>`,o.insertBefore(d,c);const k=d.querySelector(".who"),w=d.querySelector(".secs"),z=d.querySelector(".call-dot"),O=d.querySelector('[data-act="mute"]'),q=d.querySelector('[data-act="hangup"]');let ee=null;const pe=()=>{ee&&(clearInterval(ee),ee=null)},P=Y=>{pe(),z.classList.add("off"),d.classList.add("over"),k.textContent=Y,w.hidden=!0,O.hidden=!0,q.textContent="Dismiss",q.classList.remove("danger")},Te=a.on("call",({state:Y})=>{if(Y==="ringing"&&(k.textContent="Calling the team…"),Y==="connecting"&&(k.textContent="Someone answered — connecting…"),Y==="connected"){k.textContent="You're on a call with the team",O.hidden=!1,w.hidden=!1;const oe=Date.now();pe(),ee=setInterval(()=>{w.textContent=We(Math.floor((Date.now()-oe)/1e3))},1e3),w.textContent="0s"}Y==="missed"&&P("Nobody was free. Send a message instead and the team will pick it up."),Y==="ended"&&P("Call ended."),Y==="failed"&&P("The call dropped.")});O.addEventListener("click",()=>{const Y=u.setMuted(!u.isMuted());O.textContent=Y?"Unmute":"Mute",k.textContent=Y?"You're muted":"You're on a call with the team"}),q.addEventListener("click",()=>{Te(),pe(),a.endCall(),d.remove(),ct(be)})}let be=null;return Se=a.on("update",o=>{!be||(o==null?void 0:o.bugId)!==be||(a.markReportRead(be),ct(be))}),t.appendChild(g),de(),A.focus(),{destroy:Ue,close:ce}}function on(t){const e=t||[];return e.length?e.map(n=>{var a,i,r,s;return n.from?rn({from:n.from,author:(a=n.reply)==null?void 0:a.author,automated:(i=n.reply)==null?void 0:i.automated,body:(r=n.reply)==null?void 0:r.body,at:n.at,attachments:(s=n.reply)==null?void 0:s.attachments}):to(n)}).join(""):""}function to(t){return`
|
|
983
1021
|
<div class="sys k-${x(t.kind)}">
|
|
984
1022
|
<span class="dot" aria-hidden="true"></span>${x(t.summary||"")}
|
|
985
1023
|
· ${x(et(t.at))}
|
|
986
|
-
</div>`}function
|
|
1024
|
+
</div>`}function rn(t,e=""){const n=t.from==="reporter",a=t.body||"",i=t.attachments||[],r=!n&&!!t.automated,s=a?`<span class="msg-text">${x(a)}</span>`:"",l=i.length?`<div class="att">${i.map(no).join("")}</div>`:"";let p="";r?p='<span class="msg-who auto">Automatic reply</span>':!n&&t.author&&(p=`<span class="msg-who">${x(t.author)}</span>`);const f=r&&/reply "yes" or "no"/i.test(a)?`<div class="quick" role="group" aria-label="Answer">
|
|
1025
|
+
<button type="button" data-quick="Yes, this is the problem">Yes, that's it</button>
|
|
1026
|
+
<button type="button" data-quick="No, that is not the problem">No, it's something else</button>
|
|
1027
|
+
</div>`:"";return`
|
|
987
1028
|
<div class="msg-row ${n?"mine":"theirs"} ${r?"auto":""} ${e}">
|
|
988
|
-
${
|
|
989
|
-
<div class="bubble ${
|
|
1029
|
+
${p}
|
|
1030
|
+
<div class="bubble ${a?"":"silent"}">${s}${l}</div>
|
|
1031
|
+
${f}
|
|
990
1032
|
<span class="msg-when">${x(et(t.at))}</span>
|
|
991
|
-
</div>`}function
|
|
1033
|
+
</div>`}function no(t){const e=x(t.name||"attachment");if(!t.url)return`<span class="file"><span class="nm">${e}</span></span>`;const n=x(t.url);return t.type==="SCREENSHOT"?`<a href="${n}" target="_blank" rel="noopener noreferrer"><img src="${n}" alt="${e}" loading="lazy"></a>`:t.type==="AUDIO"?`<audio controls preload="metadata" src="${n}"></audio>`:t.type==="VIDEO"?`<video controls preload="metadata" src="${n}"></video>`:`
|
|
992
1034
|
<a class="file" href="${n}" target="_blank" rel="noopener noreferrer" download>
|
|
993
1035
|
<span class="nm">${e}</span>
|
|
994
1036
|
${t.size?`<span class="sz">${x(Me(t.size))}</span>`:""}
|
|
995
|
-
</a>`}function ta(t){return t.scrollHeight-t.scrollTop-t.clientHeight<40}function yt(t){t.scrollTop=t.scrollHeight}function wt(t){return{OPEN:"Open",IN_PROGRESS:"In progress",RESOLVED:"Fixed",CLOSED:"Closed"}[t]||String(t||"").toLowerCase()}function et(t){const e=new Date(t).getTime();if(!Number.isFinite(e))return"";const n=Math.floor((Date.now()-e)/864e5);if(n<=0)return"today";if(n===1)return"yesterday";if(n<30)return`${n} days ago`;const o=Math.floor(n/30);return o===1?"a month ago":`${o} months ago`}function x(t){return String(t).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}const an=8e3;function na(t=an){const e=window.AudioContext||window.webkitAudioContext;try{return new e({sampleRate:t})}catch{return new e}}async function oa(t){if(t.state==="suspended")try{await t.resume()}catch{}}function aa(t,e,n){const o=e/n,i=new Float32Array(Math.floor(t.length/o));for(let r=0;r<i.length;r++){const s=Math.floor(r*o),l=Math.min(Math.floor((r+1)*o),t.length);let u=0;for(let g=s;g<l;g++)u+=t[g];i[r]=l>s?u/(l-s):0}return i}const ra=132,rn=32635;function ia(t){const e=new Uint8Array(t.length);for(let n=0;n<t.length;n++){const o=Math.max(-1,Math.min(1,t[n]));let i=Math.round(o*32767);const r=i<0?128:0;r&&(i=-i),i>rn&&(i=rn),i+=ra;let s=7;for(let u=16384;!(i&u)&&s>0;s--,u>>=1);const l=i>>s+3&15;e[n]=~(r|s<<4|l)&255}return e}const sa=512;function ca(t,e,n,o=an){const i=t.createMediaStreamSource(e),r=t.createScriptProcessor(sa,1,1);r.onaudioprocess=l=>{const u=l.inputBuffer.getChannelData(0),g=t.sampleRate===o?u:aa(u,t.sampleRate,o);n(ia(g))},i.connect(r);const s=t.createGain();return s.gain.value=0,r.connect(s),s.connect(t.destination),{stop(){r.onaudioprocess=null;try{i.disconnect()}catch{}try{r.disconnect()}catch{}try{s.disconnect()}catch{}}}}const la="voiceai.realtime.v1",da=[{urls:"stun:stun.l.google.com:19302"}];function vt(){return navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1}})}function xt(){var t;return typeof window<"u"&&typeof window.RTCPeerConnection=="function"&&!!((t=navigator.mediaDevices)!=null&&t.getUserMedia)}async function sn({realtimeUrl:t,stream:e,ringsUntil:n,onState:o,onAudioBlocked:i,onMicrophone:r}){const s=(m,w)=>{try{o==null||o(m,w)}catch{}},l=m=>{try{i==null||i(m)}catch{}},u=m=>{try{r==null||r(m)}catch{}};if(!xt()){const m=new Error("[BugCatch] this browser cannot make live calls.");throw s("failed",{reason:"unsupported"}),m}let g=e;if(!g)try{g=await vt()}catch(m){throw s("failed",{reason:"microphone",error:String((m==null?void 0:m.name)||m)}),m}let y;try{y=await ua(t)}catch(m){throw ln(g),s("failed",{reason:"connect"}),m}let p=null,b=null,h=!1,k=null,A=null,ie=null,S=!1,E=null,T=null,L=!1;const X=[];let q=!1,Q=!1,D=!1,$=null,se=null,ne=0;const De=2e3,xe=5e3,ot=3e4,ke=4,N=(m,w)=>{if(!h){h=!0,k&&(clearTimeout(k),k=null),ce(),T==null||T(),T=null,at(),E==null||E(),E=null;try{p==null||p.close()}catch{}ln(g),b&&(b.srcObject=null,b.remove(),b=null);try{y.readyState===WebSocket.OPEN&&y.close(1e3,"call over")}catch{}s(m,w)}},oe=m=>{y.readyState===WebSocket.OPEN&&y.send(JSON.stringify(m))},Le=async()=>{if(L||ie||h||!A||!A.audio&&!A.transcript)return;L=!0;const m=A.encoding||"mulaw";if(m!=="mulaw"){cn(`this call is kept as ${m}, which this SDK cannot produce.`);return}const w=Number(A.sample_rate)||8e3;try{const I=na(w);if(await oa(I),h){try{I.close()}catch{}return}const K=ca(I,g,P=>{y.readyState===WebSocket.OPEN&&y.send(P)},w);ie={context:I,tap:K}}catch(I){cn(`could not send the copy this call is keeping: ${String((I==null?void 0:I.message)||I)}`)}};function at(){if(L=!1,!ie)return;const{context:m,tap:w}=ie;ie=null;try{w.stop()}catch{}try{m.close()}catch{}}function Ne(){var w;if(!b||h)return;let m;try{m=(w=b.play)==null?void 0:w.call(b)}catch{Be();return}if(!m||typeof m.then!="function"){ge();return}m.then(ge,Be)}function ge(){E==null||E(),E=null,S&&(S=!1,l(!1))}function Be(){h||(S||(S=!0,l(!0)),kt())}function kt(){if(E||typeof window>"u"||typeof window.addEventListener!="function")return;const m=()=>Ne(),w=["pointerdown","keydown","touchstart"];for(const I of w)window.addEventListener(I,m,{capture:!0,passive:!0});E=()=>{for(const I of w)try{window.removeEventListener(I,m,{capture:!0})}catch{}}}const Ae=m=>{p=new RTCPeerConnection({iceServers:m!=null&&m.length?m:da});for(const w of g.getAudioTracks())p.addTrack(w,g);T=de(),p.onicecandidate=w=>{w.candidate&&oe({type:"signal",signal:{kind:"candidate",payload:w.candidate.toJSON()}})},p.ontrack=w=>{var K;const[I]=w.streams;I&&(b||(b=document.createElement("audio"),b.autoplay=!0,b.playsInline=!0,(K=b.setAttribute)==null||K.call(b,"playsinline",""),b.style.cssText="position:fixed;width:0;height:0;opacity:0;pointer-events:none",document.body.appendChild(b)),b.srcObject=I,Ne())},p.onconnectionstatechange=Se,p.oniceconnectionstatechange=Se};function Se(){if(!p||h)return;const m=p.connectionState||p.iceConnectionState;if(m==="connected"||m==="completed"){Q=!0,ne=0,ce(),D=!1,s("connected");return}if(m==="disconnected"){if(!Q)return;Ue(De);return}if(m==="failed"){if(!Q){N("failed",{reason:"ice"});return}Ue(0)}}function Ue(m){h||(D||(D=!0,s("reconnecting"),se=setTimeout(()=>N("failed",{reason:"network"}),ot)),!$&&($=setTimeout(Re,m)))}function ce(){$&&(clearTimeout($),$=null),se&&(clearTimeout(se),se=null)}async function Re(){if($=null,h||!p)return;const m=p.connectionState||p.iceConnectionState;if(!(m==="connected"||m==="completed")){if(!q){oe({type:"signal",signal:{kind:"restart",payload:{}}}),$=setTimeout(Re,xe);return}ne>=ke||(ne+=1,await z(),$=setTimeout(Re,xe))}}async function z(){if(!(h||!p))try{const m=await p.createOffer({iceRestart:!0});await p.setLocalDescription(m),oe({type:"signal",signal:{kind:"offer",payload:p.localDescription.toJSON()}})}catch{}}function de(){let w=null,I=!1;const K=P=>{if(w&&(clearTimeout(w),w=null),P){if(!I)return;I=!1,u(!0);return}I||(w=setTimeout(()=>{w=null,!h&&(I=!0,u(!1))},600))};for(const P of g.getAudioTracks())P.onmute=()=>K(!1),P.onunmute=()=>K(!0),P.onended=()=>{w&&(clearTimeout(w),w=null),!I&&(I=!0,u(!1))};return()=>{w&&(clearTimeout(w),w=null);for(const P of g.getAudioTracks())P.onmute=null,P.onunmute=null,P.onended=null}}const rt=async()=>{try{const m=await p.createOffer();await p.setLocalDescription(m),oe({type:"signal",signal:{kind:"offer",payload:p.localDescription.toJSON()}})}catch{N("failed",{reason:"negotiation"})}},St=async m=>{try{await p.setRemoteDescription(new RTCSessionDescription(m));const w=await p.createAnswer();await p.setLocalDescription(w),oe({type:"signal",signal:{kind:"answer",payload:p.localDescription.toJSON()}}),await Qe()}catch{N("failed",{reason:"negotiation"})}},Qe=async()=>{for(;X.length;){const m=X.shift();try{await p.addIceCandidate(new RTCIceCandidate(m))}catch{}}};let Ce=Promise.resolve();y.onmessage=m=>{Ce=Ce.then(()=>Ct(m)).catch(()=>{})};const Ct=async m=>{var I,K,P,Ee,it;if(typeof m.data!="string")return;let w;try{w=JSON.parse(m.data)}catch{return}switch(w.type){case"session.created":{if(Ae((I=w.data)==null?void 0:I.ice_servers),A=((K=w.data)==null?void 0:K.capture)||null,(P=w.data)!=null&&P.peer_present){s("connecting"),Le();break}s("ringing"),je();break}case"peer.joined":{k&&(clearTimeout(k),k=null),s("connecting"),q=!!((Ee=w.data)!=null&&Ee.should_offer),q&&await rt(),Le();break}case"signal":{if(!p)break;const{kind:$e,payload:fe}=w.data||{};if($e==="offer")await St(fe);else if($e==="answer")try{await p.setRemoteDescription(new RTCSessionDescription(fe)),await Qe()}catch{N("failed",{reason:"negotiation"})}else if($e==="candidate")if(p.remoteDescription)try{await p.addIceCandidate(new RTCIceCandidate(fe))}catch{}else X.push(fe);else $e==="restart"&&q&&await z();break}case"peer.left":N("ended",{reason:"peer_left"});break;case"error":N("failed",{reason:"server",detail:(it=w.error)==null?void 0:it.detail});break;case"session.ended":N("ended",{reason:"server"});break}};y.onclose=()=>N("ended",{reason:"disconnected"}),y.onerror=()=>N("failed",{reason:"socket"});function je(){if(!n)return;const m=new Date(n).getTime()-Date.now();Number.isFinite(m)&&(k=setTimeout(()=>N("missed"),Math.max(0,m)))}return{hangUp(){oe({type:"session.end"}),N("ended",{reason:"hung_up"})},setMuted(m){for(const w of g.getAudioTracks())w.enabled=!m;return m},isMuted(){return g.getAudioTracks().every(m=>!m.enabled)}}}function ua(t){return new Promise((e,n)=>{let o;try{o=new WebSocket(t,la)}catch(i){n(i);return}o.onopen=()=>{o.onopen=null,o.onerror=null,e(o)},o.onerror=()=>{o.onopen=null,o.onerror=null,n(new Error("[BugCatch] could not connect the call."))}})}function cn(t){try{console.warn(`[BugCatch] ${t}`)}catch{}}function ln(t){var e;for(const n of((e=t==null?void 0:t.getTracks)==null?void 0:e.call(t))??[])try{n.stop()}catch{}}const tt={cycleMs:3e3,peak:.045,bursts:[{at:0,seconds:.4,hz:[440,660]},{at:.55,seconds:.4,hz:[440,660]}]};let dn=!1;if(typeof window<"u"&&window.addEventListener)for(const t of["pointerdown","keydown","touchstart"])window.addEventListener(t,()=>{dn=!0},{once:!0,capture:!0,passive:!0});function pa(){var t;try{return!!((t=navigator.userActivation)!=null&&t.hasBeenActive)}catch{return!1}}function ha(){if(!dn&&!pa())return()=>{};const t=typeof window<"u"&&(window.AudioContext||window.webkitAudioContext);if(!t)return()=>{};let e;try{e=new t}catch{return()=>{}}let n=!1,o=null;const i=[],r=({at:u,seconds:g,hz:y})=>{const p=e.currentTime+u,b=e.createGain();b.connect(e.destination),b.gain.setValueAtTime(0,p),b.gain.linearRampToValueAtTime(tt.peak,p+.02),b.gain.setValueAtTime(tt.peak,p+g-.06),b.gain.linearRampToValueAtTime(0,p+g);for(const h of y){const k=e.createOscillator();k.type="sine",k.frequency.value=h,k.connect(b),k.start(p),k.stop(p+g+.02),i.push(k)}},s=()=>{if(!n)try{tt.bursts.forEach(r)}catch{}},l=()=>{n||(s(),o=setInterval(s,tt.cycleMs))};return e.state==="running"?l():e.resume().then(l).catch(()=>{}),()=>{n=!0,o&&clearInterval(o);for(const u of i)try{u.stop()}catch{}try{e.close()}catch{}}}function fa(t){const e=Date.parse(t||"");return Number.isNaN(e)?0:Math.max(0,Math.round((e-Date.now())/1e3))}const un=["flex:1","padding:9px 12px","border:0","border-radius:8px","font:600 13px/1.4 inherit","cursor:pointer"].join(";");function ga({call:t,accent:e="#5b6ef5",position:n="bottom-right",onAnswer:o,onDecline:i,onExpire:r}){if(typeof document>"u"||!document.body)return()=>{};const[s,l]=String(n).split("-"),u=document.createElement("div");u.setAttribute("role","alertdialog"),u.setAttribute("aria-live","assertive"),u.setAttribute("aria-label",`${t.from||"Support"} is calling about ${t.reference}`),u.style.cssText=["position:fixed",`${s==="top"?"top":"bottom"}:20px`,`${l==="left"?"left":"right"}:20px`,"z-index:2147483647","width:300px","max-width:calc(100vw - 40px)","padding:14px","border-radius:12px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 18px 44px rgba(0,0,0,0.5)",`border:1px solid ${e}`,"opacity:0","transform:translateY(8px)","transition:opacity .2s ease,transform .2s ease"].join(";");const g=document.createElement("div");g.style.cssText="font-weight:600;font-size:14px;margin-bottom:2px",g.textContent=`${t.from||"Support"} is calling`;const y=document.createElement("div");y.style.cssText="color:#a4abba;margin-bottom:10px",y.textContent=t.project?`About your report ${t.reference} · ${t.project}`:`About your report ${t.reference}`;const p=document.createElement("div");p.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px";const b=document.createElement("button");b.type="button",b.textContent="Answer",b.style.cssText=`${un};background:${e};color:#fff`;const h=document.createElement("button");h.type="button",h.textContent="Not now",h.style.cssText=`${un};background:#2b2f3a;color:#c8cedb`;const k=document.createElement("div");if(k.style.cssText="display:flex;gap:8px",k.append(b,h),u.append(g,y,p),t.recorded){const L=document.createElement("div");L.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px",L.textContent="This call will be recorded.",u.append(L)}u.append(k),document.body.appendChild(u);const A=ha();let ie=!1,S=null;const E=()=>{ie||(ie=!0,S&&clearInterval(S),A(),u.style.opacity="0",u.style.transform="translateY(8px)",setTimeout(()=>u.remove(),250))},T=()=>{const L=fa(t.ringsUntil);if(p.textContent=L?`Ringing — ${L}s`:"The call has stopped ringing.",!L){E();try{r==null||r()}catch{}}};return T(),S=setInterval(T,1e3),b.addEventListener("click",()=>{E();try{o==null||o()}catch{}}),h.addEventListener("click",()=>{E();try{i==null||i()}catch{}}),requestAnimationFrame(()=>{u.style.opacity="1",u.style.transform="translateY(0)"}),E}const pn={name:"@sphoro/bugcatch-web-sdk",version:"0.14.2"},nt={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:"#4F46E5",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};class hn{constructor(){Rn(this,B);this.config={...nt},this.started=!1,this.teardown=[],this.consoleBuffer=Pe(nt.consoleLimit),this.networkBuffer=Pe(nt.networkLimit),this.stopWatching=null,this.notifier=null,this.call=null,this.callStarting=!1,this.ringing=null,this.listeners=new Map}init(e={}){if(this.started)return console.warn("[BugCatch] init() called twice — ignoring the second call."),this;if(this.config={...nt,...e},!this.config.apiKey)throw new Error("[BugCatch] apiKey is required.");if(!this.config.projectId)throw new Error("[BugCatch] projectId is required.");return this.consoleBuffer=Pe(this.config.consoleLimit),this.networkBuffer=Pe(this.config.networkLimit),this.config.captureConsole&&this.teardown.push(Pn(this.consoleBuffer)),this.config.captureNetwork&&this.teardown.push(_n(this.networkBuffer)),this.config.captureErrors&&this.teardown.push(Fn(this.consoleBuffer)),this.config.widget&&this.teardown.push(Xo(this)),this.config.updates&&re()&&(this.startWatching(),queueMicrotask(()=>V(this,B,ye).call(this))),this.started=!0,this}startWatching(){if(this.stopWatching)return this;this.stopWatching=Mo({apiBase:this.config.apiBase,onUpdate:n=>{if(n!=null&&n.incomingCall){V(this,B,zn).call(this,n);return}if(n!=null&&n.callWithdrawn){V(this,B,lt).call(this,n.callWithdrawn.callId);return}const o=yo(n);typeof this.config.onUpdate=="function"&&this.config.onUpdate(o),this.emit("update",o),V(this,B,ye).call(this)}}),this.teardown.push(()=>{var n;return(n=this.stopWatching)==null?void 0:n.call(this)}),this.teardown.push(()=>V(this,B,lt).call(this));const e=n=>{(n.key===Je||n.key===null)&&V(this,B,ye).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(i){console.error("[BugCatch] an update listener threw:",i)}}unreadUpdates(){return qe()}markUpdateRead(e){return wo(e),V(this,B,ye).call(this),this}markReportRead(e){return vo(e),V(this,B,ye).call(this),this}markUpdatesRead(){return Ut(),V(this,B,ye).call(this),this}async verifyFix(e,{result:n,resolvedAt:o,note:i}){const r=n==="STILL_HAPPENING"?await V(this,B,ct).call(this,{}):{};return Do({apiBase:this.config.apiBase,bugId:e,result:n,resolvedAt:o,note:i,metadata:r.metadata,logs:r.logs})}myReport(e){return So({apiBase:this.config.apiBase,bugId:e})}replyToReport(e,{body:n,attachments:o}={}){return Vt({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 Co({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.kinds)}canCall(e){return this.config.voice?Kt({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 V(this,B,jn).call(this,e)}finally{this.callStarting=!1}}startLiveCall(e){return this.startCall(e)}canCallTeam(e){return this.config.voice?Kt({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 ko({apiBase:this.config.apiBase})}hasReports(){return!!re()}forgetReports(){var e;return(e=this.stopWatching)==null||e.call(this),this.stopWatching=null,this.endCall(),ve(),V(this,B,ye).call(this),this}identify(e){return this.config.user=e,this}async uploadAttachment(e,n,o){if(!this.started)throw new Error("[BugCatch] call init() first.");return oo({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:i={},attachments:r=[],references:s=[]}={}){if(!this.started)throw new Error("[BugCatch] call init() first.");if(!e||!e.trim())throw new Error("[BugCatch] a title is required.");const l=(r||[]).filter(b=>(b==null?void 0:b.storageKey)&&Fe(b.mime,_e)).map(b=>({type:b.type==="VIDEO"?"VIDEO":"SCREENSHOT",storageKey:b.storageKey,mime:Fe(b.mime,_e)}));let u=await V(this,B,ct).call(this,{title:e.trim(),description:n,priority:o,metadata:i,media:l,references:s});if(typeof this.config.beforeSend=="function"){const b=this.config.beforeSend(u);if(b===!1)return{cancelled:!0};b&&typeof b=="object"&&(u=b)}const g=he(this.config.projectId),y=await fetch(`${this.config.apiBase}/ingest/bugs`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey,...g!=null&&g.token?{"X-BugCatch-Session":g.token}:{}},body:JSON.stringify(u)});if(y.status===401&&g&&ft(this.config.projectId),!y.ok){let b="";try{const h=await y.json();b=Array.isArray(h.message)?h.message.join(", "):h.message||""}catch{}throw new Error(`[BugCatch] report failed (HTTP ${y.status})${b?": "+b:""}`)}const p=await y.json();return p.watchToken&&(mt(p.watchToken),this.config.updates&&this.startWatching()),p}loginState(){var e;return po({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:(e=he(this.config.projectId))==null?void 0:e.token})}referenceFields(){return this.refFields?this.refFields:(this.refFields=Po({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.refFields)}signedInAs(){const e=he(this.config.projectId);return e?{email:e.email,name:e.name}:null}signIn(e,{name:n}={}){var o;return ho({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 i;const o=await fo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,code:n});return(i=this.config.user)!=null&&i.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=he(this.config.projectId),n=await go({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 zo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,sessionToken:(e=he(this.config.projectId))==null?void 0:e.token})}matchKnownIssues(e,{signal:n}={}){var o;return Oo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,q:e||"",sessionToken:(o=he(this.config.projectId))==null?void 0:o.token,signal:n})}async meToo(e,{email:n,name:o}={}){var s,l;const i=he(this.config.projectId),r=await zt();return Ho({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||((l=this.config.user)==null?void 0:l.name),metadata:{...r,user:this.config.user||void 0,sdk:pn},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},sessionToken:i==null?void 0:i.token})}snapshot(){return{console:this.consoleBuffer.all(),network:this.networkBuffer.all(),environment:Ot()}}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}}B=new WeakSet,ye=function(){const e=qe();if(this.emit("unread",{count:e.length,updates:e}),!!this.config.updateToast){if(!this.notifier){if(!e.length)return;this.notifier=jo({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)}},ct=async function({title:e,description:n="",priority:o="MEDIUM",metadata:i={},media:r=[],references:s=[]}){var l,u;return{projectId:this.config.projectId,...e?{title:e}:{},description:n,priority:o,url:window.location.href,reporterEmail:(l=this.config.user)==null?void 0:l.email,reporterName:(u=this.config.user)==null?void 0:u.name,metadata:{...await zt(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,...i,user:this.config.user||void 0,sdk:pn},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},...r.length?{attachments:r}:{},...s.length?{references:s}:{}}},Qn=async function(){const e=he(this.config.projectId);let n;try{n=await Eo({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:e==null?void 0:e.token,payload:await V(this,B,ct).call(this,{})})}catch(o){throw o.status===401&&e&&ft(this.config.projectId),o}return n.watchToken&&(mt(n.watchToken),this.config.updates&&this.startWatching()),n},jn=async function(e){if(!xt())throw new Error("[BugCatch] this browser cannot make live calls.");const n=await vt();let o,i=null;try{if(e)o=await $o({apiBase:this.config.apiBase,bugId:e});else if(i=await V(this,B,Qn).call(this),e=i.id,o=i.live_call,!(o!=null&&o.realtime_url)){const s=new Error(`[BugCatch] the report was filed, but the team could not be rung${i.call_error?`: ${i.call_error}`:"."}`);throw s.filed=i,s.reason=i.call_error||null,s}}catch(s){for(const l of n.getTracks())l.stop();throw s}const r=await sn({realtimeUrl:o.realtime_url,stream:n,ringsUntil:o.rings_until,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),s==="missed"&&To({apiBase:this.config.apiBase,bugId:e,callId:o.call_id}),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,...l}),this.emit("call",{bugId:e,live:!0,state:s,...l})}});return this.call=r,Object.assign(r,{bugId:e,callId:o.call_id,live:!0,filed:i})},zn=function(e){var i;const n=e.incomingCall;if(!this.config.voice||!xt()||((i=this.ringing)==null?void 0:i.callId)===n.callId||this.call||this.callStarting)return;V(this,B,lt).call(this);const o=ga({call:n,accent:this.config.accent,position:this.config.widgetPosition,onAnswer:()=>{V(this,B,On).call(this,e.bugId,n)},onDecline:()=>{this.ringing=null,Pt({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:o},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"})},lt=function(e){if(this.ringing&&!(e&&this.ringing.callId!==e)){try{this.ringing.dismiss()}catch{}this.ringing=null}},On=async function(e,n){if(this.ringing=null,this.call||this.callStarting)return;this.callStarting=!0;let o;try{o=await vt()}catch(r){this.callStarting=!1,Pt({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 Io({apiBase:this.config.apiBase,bugId:e,callId:n.callId})}catch(r){for(const s of o.getTracks())s.stop();this.callStarting=!1,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"missed",error:r});return}try{const r=await sn({realtimeUrl:i.realtime_url,stream:o,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,incoming:!0,...l}),this.emit("call",{bugId:e,live:!0,incoming:!0,state:s,...l})}});this.call=r,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"answered"})}catch(r){for(const s of o.getTracks())s.stop();this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:r})}finally{this.callStarting=!1}};const fn=new hn;return fn.Client=hn,fn});
|
|
1037
|
+
</a>`}function ao(t){return t.scrollHeight-t.scrollTop-t.clientHeight<40}function wt(t){t.scrollTop=t.scrollHeight}function vt(t){return{OPEN:"Open",IN_PROGRESS:"In progress",RESOLVED:"Fixed",CLOSED:"Closed"}[t]||String(t||"").toLowerCase()}function et(t){const e=new Date(t).getTime();if(!Number.isFinite(e))return"";const n=Math.floor((Date.now()-e)/864e5);if(n<=0)return"today";if(n===1)return"yesterday";if(n<30)return`${n} days ago`;const a=Math.floor(n/30);return a===1?"a month ago":`${a} months ago`}function x(t){return String(t).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}const sn=8e3;function oo(t=sn){const e=window.AudioContext||window.webkitAudioContext;try{return new e({sampleRate:t})}catch{return new e}}async function ro(t){if(t.state==="suspended")try{await t.resume()}catch{}}function io(t,e,n){const a=e/n,i=new Float32Array(Math.floor(t.length/a));for(let r=0;r<i.length;r++){const s=Math.floor(r*a),l=Math.min(Math.floor((r+1)*a),t.length);let p=0;for(let f=s;f<l;f++)p+=t[f];i[r]=l>s?p/(l-s):0}return i}const so=132,cn=32635;function co(t){const e=new Uint8Array(t.length);for(let n=0;n<t.length;n++){const a=Math.max(-1,Math.min(1,t[n]));let i=Math.round(a*32767);const r=i<0?128:0;r&&(i=-i),i>cn&&(i=cn),i+=so;let s=7;for(let p=16384;!(i&p)&&s>0;s--,p>>=1);const l=i>>s+3&15;e[n]=~(r|s<<4|l)&255}return e}const lo=512;function uo(t,e,n,a=sn){const i=t.createMediaStreamSource(e),r=t.createScriptProcessor(lo,1,1);r.onaudioprocess=l=>{const p=l.inputBuffer.getChannelData(0),f=t.sampleRate===a?p:io(p,t.sampleRate,a);n(co(f))},i.connect(r);const s=t.createGain();return s.gain.value=0,r.connect(s),s.connect(t.destination),{stop(){r.onaudioprocess=null;try{i.disconnect()}catch{}try{r.disconnect()}catch{}try{s.disconnect()}catch{}}}}const po="voiceai.realtime.v1",ho=[{urls:"stun:stun.l.google.com:19302"}];function xt(){return navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1}})}function kt(){var t;return typeof window<"u"&&typeof window.RTCPeerConnection=="function"&&!!((t=navigator.mediaDevices)!=null&&t.getUserMedia)}async function ln({realtimeUrl:t,stream:e,ringsUntil:n,onState:a,onAudioBlocked:i,onMicrophone:r}){const s=(m,v)=>{try{a==null||a(m,v)}catch{}},l=m=>{try{i==null||i(m)}catch{}},p=m=>{try{r==null||r(m)}catch{}};if(!kt()){const m=new Error("[BugCatch] this browser cannot make live calls.");throw s("failed",{reason:"unsupported"}),m}let f=e;if(!f)try{f=await xt()}catch(m){throw s("failed",{reason:"microphone",error:String((m==null?void 0:m.name)||m)}),m}let y;try{y=await fo(t)}catch(m){throw un(f),s("failed",{reason:"connect"}),m}let h=null,b=null,g=!1,S=null,A=null,ie=null,C=!1,$=null,T=null,L=!1;const X=[];let U=!1,j=!1,V=!1,E=null,se=null,ne=0;const De=2e3,xe=5e3,at=3e4,ke=4,K=(m,v)=>{if(!g){g=!0,S&&(clearTimeout(S),S=null),ce(),T==null||T(),T=null,ot(),$==null||$(),$=null;try{h==null||h.close()}catch{}un(f),b&&(b.srcObject=null,b.remove(),b=null);try{y.readyState===WebSocket.OPEN&&y.close(1e3,"call over")}catch{}s(m,v)}},ae=m=>{y.readyState===WebSocket.OPEN&&y.send(JSON.stringify(m))},Le=async()=>{if(L||ie||g||!A||!A.audio&&!A.transcript)return;L=!0;const m=A.encoding||"mulaw";if(m!=="mulaw"){dn(`this call is kept as ${m}, which this SDK cannot produce.`);return}const v=Number(A.sample_rate)||8e3;try{const I=oo(v);if(await ro(I),g){try{I.close()}catch{}return}const F=uo(I,f,W=>{y.readyState===WebSocket.OPEN&&y.send(W)},v);ie={context:I,tap:F}}catch(I){dn(`could not send the copy this call is keeping: ${String((I==null?void 0:I.message)||I)}`)}};function ot(){if(L=!1,!ie)return;const{context:m,tap:v}=ie;ie=null;try{v.stop()}catch{}try{m.close()}catch{}}function Ne(){var v;if(!b||g)return;let m;try{m=(v=b.play)==null?void 0:v.call(b)}catch{Be();return}if(!m||typeof m.then!="function"){me();return}m.then(me,Be)}function me(){$==null||$(),$=null,C&&(C=!1,l(!1))}function Be(){g||(C||(C=!0,l(!0)),St())}function St(){if($||typeof window>"u"||typeof window.addEventListener!="function")return;const m=()=>Ne(),v=["pointerdown","keydown","touchstart"];for(const I of v)window.addEventListener(I,m,{capture:!0,passive:!0});$=()=>{for(const I of v)try{window.removeEventListener(I,m,{capture:!0})}catch{}}}const Ae=m=>{h=new RTCPeerConnection({iceServers:m!=null&&m.length?m:ho});for(const v of f.getAudioTracks())h.addTrack(v,f);T=de(),h.onicecandidate=v=>{v.candidate&&ae({type:"signal",signal:{kind:"candidate",payload:v.candidate.toJSON()}})},h.ontrack=v=>{var F;const[I]=v.streams;I&&(b||(b=document.createElement("audio"),b.autoplay=!0,b.playsInline=!0,(F=b.setAttribute)==null||F.call(b,"playsinline",""),b.style.cssText="position:fixed;width:0;height:0;opacity:0;pointer-events:none",document.body.appendChild(b)),b.srcObject=I,Ne())},h.onconnectionstatechange=Se,h.oniceconnectionstatechange=Se};function Se(){if(!h||g)return;const m=h.connectionState||h.iceConnectionState;if(m==="connected"||m==="completed"){j=!0,ne=0,ce(),V=!1,s("connected");return}if(m==="disconnected"){if(!j)return;Ue(De);return}if(m==="failed"){if(!j){K("failed",{reason:"ice"});return}Ue(0)}}function Ue(m){g||(V||(V=!0,s("reconnecting"),se=setTimeout(()=>K("failed",{reason:"network"}),at)),!E&&(E=setTimeout(Re,m)))}function ce(){E&&(clearTimeout(E),E=null),se&&(clearTimeout(se),se=null)}async function Re(){if(E=null,g||!h)return;const m=h.connectionState||h.iceConnectionState;if(!(m==="connected"||m==="completed")){if(!U){ae({type:"signal",signal:{kind:"restart",payload:{}}}),E=setTimeout(Re,xe);return}ne>=ke||(ne+=1,await H(),E=setTimeout(Re,xe))}}async function H(){if(!(g||!h))try{const m=await h.createOffer({iceRestart:!0});await h.setLocalDescription(m),ae({type:"signal",signal:{kind:"offer",payload:h.localDescription.toJSON()}})}catch{}}function de(){let v=null,I=!1;const F=W=>{if(v&&(clearTimeout(v),v=null),W){if(!I)return;I=!1,p(!0);return}I||(v=setTimeout(()=>{v=null,!g&&(I=!0,p(!1))},600))};for(const W of f.getAudioTracks())W.onmute=()=>F(!1),W.onunmute=()=>F(!0),W.onended=()=>{v&&(clearTimeout(v),v=null),!I&&(I=!0,p(!1))};return()=>{v&&(clearTimeout(v),v=null);for(const W of f.getAudioTracks())W.onmute=null,W.onunmute=null,W.onended=null}}const rt=async()=>{try{const m=await h.createOffer();await h.setLocalDescription(m),ae({type:"signal",signal:{kind:"offer",payload:h.localDescription.toJSON()}})}catch{K("failed",{reason:"negotiation"})}},Ct=async m=>{try{await h.setRemoteDescription(new RTCSessionDescription(m));const v=await h.createAnswer();await h.setLocalDescription(v),ae({type:"signal",signal:{kind:"answer",payload:h.localDescription.toJSON()}}),await Qe()}catch{K("failed",{reason:"negotiation"})}},Qe=async()=>{for(;X.length;){const m=X.shift();try{await h.addIceCandidate(new RTCIceCandidate(m))}catch{}}};let Ce=Promise.resolve();y.onmessage=m=>{Ce=Ce.then(()=>$t(m)).catch(()=>{})};const $t=async m=>{var I,F,W,$e,it;if(typeof m.data!="string")return;let v;try{v=JSON.parse(m.data)}catch{return}switch(v.type){case"session.created":{if(Ae((I=v.data)==null?void 0:I.ice_servers),A=((F=v.data)==null?void 0:F.capture)||null,(W=v.data)!=null&&W.peer_present){s("connecting"),Le();break}s("ringing"),je();break}case"peer.joined":{S&&(clearTimeout(S),S=null),s("connecting"),U=!!(($e=v.data)!=null&&$e.should_offer),U&&await rt(),Le();break}case"signal":{if(!h)break;const{kind:Ee,payload:ge}=v.data||{};if(Ee==="offer")await Ct(ge);else if(Ee==="answer")try{await h.setRemoteDescription(new RTCSessionDescription(ge)),await Qe()}catch{K("failed",{reason:"negotiation"})}else if(Ee==="candidate")if(h.remoteDescription)try{await h.addIceCandidate(new RTCIceCandidate(ge))}catch{}else X.push(ge);else Ee==="restart"&&U&&await H();break}case"peer.left":K("ended",{reason:"peer_left"});break;case"error":K("failed",{reason:"server",detail:(it=v.error)==null?void 0:it.detail});break;case"session.ended":K("ended",{reason:"server"});break}};y.onclose=()=>K("ended",{reason:"disconnected"}),y.onerror=()=>K("failed",{reason:"socket"});function je(){if(!n)return;const m=new Date(n).getTime()-Date.now();Number.isFinite(m)&&(S=setTimeout(()=>K("missed"),Math.max(0,m)))}return{hangUp(){ae({type:"session.end"}),K("ended",{reason:"hung_up"})},setMuted(m){for(const v of f.getAudioTracks())v.enabled=!m;return m},isMuted(){return f.getAudioTracks().every(m=>!m.enabled)}}}function fo(t){return new Promise((e,n)=>{let a;try{a=new WebSocket(t,po)}catch(i){n(i);return}a.onopen=()=>{a.onopen=null,a.onerror=null,e(a)},a.onerror=()=>{a.onopen=null,a.onerror=null,n(new Error("[BugCatch] could not connect the call."))}})}function dn(t){try{console.warn(`[BugCatch] ${t}`)}catch{}}function un(t){var e;for(const n of((e=t==null?void 0:t.getTracks)==null?void 0:e.call(t))??[])try{n.stop()}catch{}}const tt={cycleMs:3e3,peak:.045,bursts:[{at:0,seconds:.4,hz:[440,660]},{at:.55,seconds:.4,hz:[440,660]}]};let pn=!1;if(typeof window<"u"&&window.addEventListener)for(const t of["pointerdown","keydown","touchstart"])window.addEventListener(t,()=>{pn=!0},{once:!0,capture:!0,passive:!0});function go(){var t;try{return!!((t=navigator.userActivation)!=null&&t.hasBeenActive)}catch{return!1}}function mo(){if(!pn&&!go())return()=>{};const t=typeof window<"u"&&(window.AudioContext||window.webkitAudioContext);if(!t)return()=>{};let e;try{e=new t}catch{return()=>{}}let n=!1,a=null;const i=[],r=({at:p,seconds:f,hz:y})=>{const h=e.currentTime+p,b=e.createGain();b.connect(e.destination),b.gain.setValueAtTime(0,h),b.gain.linearRampToValueAtTime(tt.peak,h+.02),b.gain.setValueAtTime(tt.peak,h+f-.06),b.gain.linearRampToValueAtTime(0,h+f);for(const g of y){const S=e.createOscillator();S.type="sine",S.frequency.value=g,S.connect(b),S.start(h),S.stop(h+f+.02),i.push(S)}},s=()=>{if(!n)try{tt.bursts.forEach(r)}catch{}},l=()=>{n||(s(),a=setInterval(s,tt.cycleMs))};return e.state==="running"?l():e.resume().then(l).catch(()=>{}),()=>{n=!0,a&&clearInterval(a);for(const p of i)try{p.stop()}catch{}try{e.close()}catch{}}}function bo(t){const e=Date.parse(t||"");return Number.isNaN(e)?0:Math.max(0,Math.round((e-Date.now())/1e3))}const hn=["flex:1","padding:9px 12px","border:0","border-radius:8px","font:600 13px/1.4 inherit","cursor:pointer"].join(";");function yo({call:t,accent:e="#5b6ef5",position:n="bottom-right",onAnswer:a,onDecline:i,onExpire:r}){if(typeof document>"u"||!document.body)return()=>{};const[s,l]=String(n).split("-"),p=document.createElement("div");p.setAttribute("role","alertdialog"),p.setAttribute("aria-live","assertive"),p.setAttribute("aria-label",`${t.from||"Support"} is calling about ${t.reference}`),p.style.cssText=["position:fixed",`${s==="top"?"top":"bottom"}:20px`,`${l==="left"?"left":"right"}:20px`,"z-index:2147483647","width:300px","max-width:calc(100vw - 40px)","padding:14px","border-radius:12px","background:#1b1e26","color:#eceef2",'font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif',"box-shadow:0 18px 44px rgba(0,0,0,0.5)",`border:1px solid ${e}`,"opacity:0","transform:translateY(8px)","transition:opacity .2s ease,transform .2s ease"].join(";");const f=document.createElement("div");f.style.cssText="font-weight:600;font-size:14px;margin-bottom:2px",f.textContent=`${t.from||"Support"} is calling`;const y=document.createElement("div");y.style.cssText="color:#a4abba;margin-bottom:10px",y.textContent=t.project?`About your report ${t.reference} · ${t.project}`:`About your report ${t.reference}`;const h=document.createElement("div");h.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px";const b=document.createElement("button");b.type="button",b.textContent="Answer",b.style.cssText=`${hn};background:${e};color:#fff`;const g=document.createElement("button");g.type="button",g.textContent="Not now",g.style.cssText=`${hn};background:#2b2f3a;color:#c8cedb`;const S=document.createElement("div");if(S.style.cssText="display:flex;gap:8px",S.append(b,g),p.append(f,y,h),t.recorded){const L=document.createElement("div");L.style.cssText="color:#7d8598;font-size:12px;margin-bottom:10px",L.textContent="This call will be recorded.",p.append(L)}p.append(S),document.body.appendChild(p);const A=mo();let ie=!1,C=null;const $=()=>{ie||(ie=!0,C&&clearInterval(C),A(),p.style.opacity="0",p.style.transform="translateY(8px)",setTimeout(()=>p.remove(),250))},T=()=>{const L=bo(t.ringsUntil);if(h.textContent=L?`Ringing — ${L}s`:"The call has stopped ringing.",!L){$();try{r==null||r()}catch{}}};return T(),C=setInterval(T,1e3),b.addEventListener("click",()=>{$();try{a==null||a()}catch{}}),g.addEventListener("click",()=>{$();try{i==null||i()}catch{}}),requestAnimationFrame(()=>{p.style.opacity="1",p.style.transform="translateY(0)"}),$}const fn={name:"@sphoro/bugcatch-web-sdk",version:"0.14.4"},nt={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:"#4F46E5",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};class gn{constructor(){zn(this,B);this.config={...nt},this.started=!1,this.teardown=[],this.consoleBuffer=Pe(nt.consoleLimit),this.networkBuffer=Pe(nt.networkLimit),this.stopWatching=null,this.notifier=null,this.call=null,this.callStarting=!1,this.ringing=null,this.listeners=new Map}init(e={}){if(this.started)return console.warn("[BugCatch] init() called twice — ignoring the second call."),this;if(this.config={...nt,...e},!this.config.apiKey)throw new Error("[BugCatch] apiKey is required.");if(!this.config.projectId)throw new Error("[BugCatch] projectId is required.");return this.consoleBuffer=Pe(this.config.consoleLimit),this.networkBuffer=Pe(this.config.networkLimit),this.config.captureConsole&&this.teardown.push(Wn(this.consoleBuffer)),this.config.captureNetwork&&this.teardown.push(Yn(this.networkBuffer)),this.config.captureErrors&&this.teardown.push(Xn(this.consoleBuffer)),this.config.widget&&this.teardown.push(Ja(this)),this.config.updates&&re()&&(this.startWatching(),queueMicrotask(()=>_(this,B,ye).call(this))),this.started=!0,this}startWatching(){if(this.stopWatching)return this;this.stopWatching=Ba({apiBase:this.config.apiBase,onUpdate:n=>{if(n!=null&&n.incomingCall){_(this,B,qn).call(this,n);return}if(n!=null&&n.callWithdrawn){_(this,B,dt).call(this,n.callWithdrawn.callId);return}const a=va(n);typeof this.config.onUpdate=="function"&&this.config.onUpdate(a),this.emit("update",a),_(this,B,ye).call(this)}}),this.teardown.push(()=>{var n;return(n=this.stopWatching)==null?void 0:n.call(this)}),this.teardown.push(()=>_(this,B,dt).call(this));const e=n=>{(n.key===Je||n.key===null)&&_(this,B,ye).call(this)};return window.addEventListener("storage",e),this.teardown.push(()=>window.removeEventListener("storage",e)),this}on(e,n){if(typeof n!="function")return()=>{};const a=this.listeners.get(e)||new Set;return a.add(n),this.listeners.set(e,a),()=>this.off(e,n)}off(e,n){var a;return(a=this.listeners.get(e))==null||a.delete(n),this}emit(e,n){for(const a of this.listeners.get(e)||[])try{a(n)}catch(i){console.error("[BugCatch] an update listener threw:",i)}}unreadUpdates(){return qe()}markUpdateRead(e){return xa(e),_(this,B,ye).call(this),this}markReportRead(e){return ka(e),_(this,B,ye).call(this),this}markUpdatesRead(){return Kt(),_(this,B,ye).call(this),this}async verifyFix(e,{result:n,resolvedAt:a,note:i}){const r=n==="STILL_HAPPENING"?await _(this,B,lt).call(this,{}):{};return Ua({apiBase:this.config.apiBase,bugId:e,result:n,resolvedAt:a,note:i,metadata:r.metadata,logs:r.logs})}myReport(e){return $a({apiBase:this.config.apiBase,bugId:e})}replyToReport(e,{body:n,attachments:a}={}){return Pt({apiBase:this.config.apiBase,bugId:e,body:n,attachments:a})}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 Ea({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.kinds)}canCall(e){return this.config.voice?_t({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 _(this,B,Hn).call(this,e)}finally{this.callStarting=!1}}startLiveCall(e){return this.startCall(e)}canCallTeam(e){return this.config.voice?_t({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 Ca({apiBase:this.config.apiBase})}hasReports(){return!!re()}forgetReports(){var e;return(e=this.stopWatching)==null||e.call(this),this.stopWatching=null,this.endCall(),ve(),_(this,B,ye).call(this),this}identify(e){return this.config.user=e,this}async uploadAttachment(e,n,a){if(!this.started)throw new Error("[BugCatch] call init() first.");return ia({apiBase:this.config.apiBase,apiKey:this.config.apiKey,blob:e,mime:n||(e==null?void 0:e.type),onProgress:a})}async report({title:e,description:n="",priority:a="MEDIUM",metadata:i={},attachments:r=[],references:s=[]}={}){if(!this.started)throw new Error("[BugCatch] call init() first.");if(!e||!e.trim())throw new Error("[BugCatch] a title is required.");const l=(r||[]).filter(b=>(b==null?void 0:b.storageKey)&&Fe(b.mime,_e)).map(b=>({type:b.type==="VIDEO"?"VIDEO":"SCREENSHOT",storageKey:b.storageKey,mime:Fe(b.mime,_e)}));let p=await _(this,B,lt).call(this,{title:e.trim(),description:n,priority:a,metadata:i,media:l,references:s});if(typeof this.config.beforeSend=="function"){const b=this.config.beforeSend(p);if(b===!1)return{cancelled:!0};b&&typeof b=="object"&&(p=b)}const f=fe(this.config.projectId),y=await fetch(`${this.config.apiBase}/ingest/bugs`,{method:"POST",headers:{"Content-Type":"application/json","X-BugCatch-Key":this.config.apiKey,...f!=null&&f.token?{"X-BugCatch-Session":f.token}:{}},body:JSON.stringify(p)});if(y.status===401&&f&>(this.config.projectId),!y.ok){let b="";try{const g=await y.json();b=Array.isArray(g.message)?g.message.join(", "):g.message||""}catch{}throw new Error(`[BugCatch] report failed (HTTP ${y.status})${b?": "+b:""}`)}const h=await y.json();return h.watchToken&&(bt(h.watchToken),this.config.updates&&this.startWatching()),h}loginState(){var e;return fa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:(e=fe(this.config.projectId))==null?void 0:e.token})}referenceFields(){return this.refFields?this.refFields:(this.refFields=Fa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId}),this.refFields)}signedInAs(){const e=fe(this.config.projectId);return e?{email:e.email,name:e.name}:null}signIn(e,{name:n}={}){var a;return ga({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,name:n??((a=this.config.user)==null?void 0:a.name)??null})}async confirmSignIn(e,n){var i;const a=await ma({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,email:e,code:n});return(i=this.config.user)!=null&&i.email||(this.config.user={email:a.email,name:a.name||void 0}),this.emit("signin",{email:a.email,name:a.name}),{email:a.email,name:a.name}}async signOut(){var a;const e=fe(this.config.projectId),n=await ba({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,token:e==null?void 0:e.token});return e!=null&&e.email&&((a=this.config.user)==null?void 0:a.email)===e.email&&(this.config.user=null),this.emit("signout",{email:(e==null?void 0:e.email)||null}),n}knownIssues(){var e;return Ha({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,sessionToken:(e=fe(this.config.projectId))==null?void 0:e.token})}matchKnownIssues(e,{signal:n}={}){var a;return qa({apiBase:this.config.apiBase,apiKey:this.config.apiKey,projectId:this.config.projectId,q:e||"",sessionToken:(a=fe(this.config.projectId))==null?void 0:a.token,signal:n})}async meToo(e,{email:n,name:a}={}){var s,l;const i=fe(this.config.projectId),r=await Ht();return Da({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:a||((l=this.config.user)==null?void 0:l.name),metadata:{...r,user:this.config.user||void 0,sdk:fn},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},sessionToken:i==null?void 0:i.token})}snapshot(){return{console:this.consoleBuffer.all(),network:this.networkBuffer.all(),environment:qt()}}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}}B=new WeakSet,ye=function(){const e=qe();if(this.emit("unread",{count:e.length,updates:e}),!!this.config.updateToast){if(!this.notifier){if(!e.length)return;this.notifier=Oa({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)}},lt=async function({title:e,description:n="",priority:a="MEDIUM",metadata:i={},media:r=[],references:s=[]}){var l,p;return{projectId:this.config.projectId,...e?{title:e}:{},description:n,priority:a,url:window.location.href,reporterEmail:(l=this.config.user)==null?void 0:l.email,reporterName:(p=this.config.user)==null?void 0:p.name,metadata:{...await Ht(),release:this.config.release,environment:this.config.environment,buildId:this.config.buildId,...i,user:this.config.user||void 0,sdk:fn},logs:{console:{entries:this.consoleBuffer.all()},network:{entries:this.networkBuffer.all()}},...r.length?{attachments:r}:{},...s.length?{references:s}:{}}},On=async function(){const e=fe(this.config.projectId);let n;try{n=await Ta({apiBase:this.config.apiBase,apiKey:this.config.apiKey,token:e==null?void 0:e.token,payload:await _(this,B,lt).call(this,{})})}catch(a){throw a.status===401&&e&>(this.config.projectId),a}return n.watchToken&&(bt(n.watchToken),this.config.updates&&this.startWatching()),n},Hn=async function(e){if(!kt())throw new Error("[BugCatch] this browser cannot make live calls.");const n=await xt();let a,i=null;try{if(e)a=await Ia({apiBase:this.config.apiBase,bugId:e});else if(i=await _(this,B,On).call(this),e=i.id,a=i.live_call,!(a!=null&&a.realtime_url)){const s=new Error(`[BugCatch] the report was filed, but the team could not be rung${i.call_error?`: ${i.call_error}`:"."}`);throw s.filed=i,s.reason=i.call_error||null,s}}catch(s){for(const l of n.getTracks())l.stop();throw s}const r=await ln({realtimeUrl:a.realtime_url,stream:n,ringsUntil:a.rings_until,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),s==="missed"&&Ma({apiBase:this.config.apiBase,bugId:e,callId:a.call_id}),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,...l}),this.emit("call",{bugId:e,live:!0,state:s,...l})}});return this.call=r,Object.assign(r,{bugId:e,callId:a.call_id,live:!0,filed:i})},qn=function(e){var i;const n=e.incomingCall;if(!this.config.voice||!kt()||((i=this.ringing)==null?void 0:i.callId)===n.callId||this.call||this.callStarting)return;_(this,B,dt).call(this);const a=yo({call:n,accent:this.config.accent,position:this.config.widgetPosition,onAnswer:()=>{_(this,B,Dn).call(this,e.bugId,n)},onDecline:()=>{this.ringing=null,Ft({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"})},dt=function(e){if(this.ringing&&!(e&&this.ringing.callId!==e)){try{this.ringing.dismiss()}catch{}this.ringing=null}},Dn=async function(e,n){if(this.ringing=null,this.call||this.callStarting)return;this.callStarting=!0;let a;try{a=await xt()}catch(r){this.callStarting=!1,Ft({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 La({apiBase:this.config.apiBase,bugId:e,callId:n.callId})}catch(r){for(const s of a.getTracks())s.stop();this.callStarting=!1,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"missed",error:r});return}try{const r=await ln({realtimeUrl:i.realtime_url,stream:a,onState:(s,l)=>{(s==="ended"||s==="failed"||s==="missed")&&(this.call=null),typeof this.config.onCallState=="function"&&this.config.onCallState(s,{bugId:e,live:!0,incoming:!0,...l}),this.emit("call",{bugId:e,live:!0,incoming:!0,state:s,...l})}});this.call=r,this.emit("incoming-call",{bugId:e,callId:n.callId,state:"answered"})}catch(r){for(const s of a.getTracks())s.stop();this.emit("incoming-call",{bugId:e,callId:n.callId,state:"failed",error:r})}finally{this.callStarting=!1}};const mn=new gn;return mn.Client=gn,mn});
|
|
996
1038
|
//# sourceMappingURL=bugcatch.umd.js.map
|