bugstash 0.1.10 → 0.1.12

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/index.js CHANGED
@@ -1,13 +1,18 @@
1
- var Pe=[],es=50,ze=null,Ae=null,Ie=null,He=null;function Ve(e){if(e.id)return`#${e.id}`;let t=e.tagName.toLowerCase(),s=e.className&&typeof e.className=="string"?"."+e.className.trim().split(/\s+/).slice(0,2).join("."):"",n=(e.textContent||"").trim().slice(0,30),r=n?` "${n}"`:"";return`${t}${s}${r}`}function q(e){Pe.push(e),Pe.length>es&&Pe.shift()}function ts(e){e&&(es=e),ze=s=>{let n=s.target;!n||!n.tagName||q({type:"click",category:"ui",message:`Clicked ${Ve(n)}`,timestamp:Date.now(),data:{x:s.clientX,y:s.clientY,selector:Ve(n)}})},document.addEventListener("click",ze,!0);let t=new WeakMap;Ae=s=>{let n=s.target;if(!n||!n.tagName)return;let r=n.tagName.toLowerCase();if(r!=="input"&&r!=="textarea"&&r!=="select")return;let i=t.get(n);i&&clearTimeout(i),t.set(n,window.setTimeout(()=>{let c=n instanceof HTMLInputElement&&n.type==="password";q({type:"input",category:"ui",message:`Input ${Ve(n)}`,timestamp:Date.now(),data:{selector:Ve(n),value:c?"[redacted]":void 0}})},300))},document.addEventListener("input",Ae,!0),Ie=()=>{q({type:"navigation",category:"navigation",message:`Navigated to ${window.location.pathname}`,timestamp:Date.now(),data:{url:window.location.href}})},window.addEventListener("popstate",Ie),He=()=>{q({type:"navigation",category:"navigation",message:`Hash changed to ${window.location.hash}`,timestamp:Date.now(),data:{url:window.location.href}})},window.addEventListener("hashchange",He),q({type:"navigation",category:"navigation",message:`Page loaded: ${window.location.pathname}`,timestamp:Date.now(),data:{url:window.location.href}})}function ue(){return[...Pe]}function ss(){Pe=[]}function ns(){ze&&document.removeEventListener("click",ze,!0),Ae&&document.removeEventListener("input",Ae,!0),Ie&&window.removeEventListener("popstate",Ie),He&&window.removeEventListener("hashchange",He),ze=null,Ae=null,Ie=null,He=null}var Pt="[REDACTED]",dn=[[/\b(?:\d[ -]*?){13,19}\b/g,"[CC_REDACTED]"],[/\b\d{3}-\d{2}-\d{4}\b/g,"[SSN_REDACTED]"],[/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,"Bearer [TOKEN_REDACTED]"],[/eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,"[JWT_REDACTED]"],[/(?:api[_-]?key|apikey|secret|token|password|passwd|authorization)['":\s=]+['"]?([A-Za-z0-9\-._~+/]{20,})['"]?/gi,e=>{let t=e.search(/[=:]/);return e.slice(0,t+1)+" "+Pt}],[/AKIA[0-9A-Z]{16}/g,"[AWS_KEY_REDACTED]"],[/"(?:password|passwd|secret|token|access_token|refresh_token|api_key|apiKey|private_key)":\s*"[^"]*"/gi,e=>{let t=e.indexOf(":");return e.slice(0,t+1)+' "'+Pt+'"'}]];function fe(e){let t=e;for(let[s,n]of dn)t=t.replace(s,n);return t}function rs(e){return e.map(fe)}function Ke(e){if(typeof e=="string")return fe(e);if(Array.isArray(e))return e.map(Ke);if(e&&typeof e=="object"){let t={};for(let[s,n]of Object.entries(e)){let r=s.toLowerCase();r.includes("password")||r.includes("secret")||r.includes("token")||r.includes("apikey")||r.includes("api_key")||r.includes("private")?t[s]=Pt:t[s]=Ke(n)}return t}return e}var Ze={log:console.log,warn:console.warn,error:console.error,debug:console.debug,info:console.info},Re=[],os=50;function bn(e){return e.map(t=>{if(t instanceof Error)return`${t.name}: ${t.message}
2
- ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{return String(t)}return String(t)})}function pn(e,t){let s={level:e,args:rs(bn(t)),timestamp:Date.now()};e==="error"&&(s.stack=new Error().stack?.split(`
1
+ var Ie=[],sn=50,He=null,Re=null,Be=null,Ne=null;function nt(e){if(e.id)return`#${e.id}`;let t=e.tagName.toLowerCase(),n=e.className&&typeof e.className=="string"?"."+e.className.trim().split(/\s+/).slice(0,2).join("."):"",s=(e.textContent||"").trim().slice(0,30),r=s?` "${s}"`:"";return`${t}${n}${r}`}function _(e){Ie.push(e),Ie.length>sn&&Ie.shift()}function rn(e){e&&(sn=e),He=n=>{let s=n.target;!s||!s.tagName||_({type:"click",category:"ui",message:`Clicked ${nt(s)}`,timestamp:Date.now(),data:{x:n.clientX,y:n.clientY,selector:nt(s)}})},document.addEventListener("click",He,!0);let t=new WeakMap;Re=n=>{let s=n.target;if(!s||!s.tagName)return;let r=s.tagName.toLowerCase();if(r!=="input"&&r!=="textarea"&&r!=="select")return;let a=t.get(s);a&&clearTimeout(a),t.set(s,window.setTimeout(()=>{let l=s instanceof HTMLInputElement&&s.type==="password";_({type:"input",category:"ui",message:`Input ${nt(s)}`,timestamp:Date.now(),data:{selector:nt(s),value:l?"[redacted]":void 0}})},300))},document.addEventListener("input",Re,!0),Be=()=>{_({type:"navigation",category:"navigation",message:`Navigated to ${window.location.pathname}`,timestamp:Date.now(),data:{url:window.location.href}})},window.addEventListener("popstate",Be),Ne=()=>{_({type:"navigation",category:"navigation",message:`Hash changed to ${window.location.hash}`,timestamp:Date.now(),data:{url:window.location.href}})},window.addEventListener("hashchange",Ne),_({type:"navigation",category:"navigation",message:`Page loaded: ${window.location.pathname}`,timestamp:Date.now(),data:{url:window.location.href}})}function he(){return[...Ie]}function on(){Ie=[]}function an(){He&&document.removeEventListener("click",He,!0),Re&&document.removeEventListener("input",Re,!0),Be&&window.removeEventListener("popstate",Be),Ne&&window.removeEventListener("hashchange",Ne),He=null,Re=null,Be=null,Ne=null}var It="[REDACTED]",ms=[[/\b(?:\d[ -]*?){13,19}\b/g,"[CC_REDACTED]"],[/\b\d{3}-\d{2}-\d{4}\b/g,"[SSN_REDACTED]"],[/Bearer\s+[A-Za-z0-9\-._~+/]+=*/g,"Bearer [TOKEN_REDACTED]"],[/eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,"[JWT_REDACTED]"],[/(?:api[_-]?key|apikey|secret|token|password|passwd|authorization)['":\s=]+['"]?([A-Za-z0-9\-._~+/]{20,})['"]?/gi,e=>{let t=e.search(/[=:]/);return e.slice(0,t+1)+" "+It}],[/AKIA[0-9A-Z]{16}/g,"[AWS_KEY_REDACTED]"],[/"(?:password|passwd|secret|token|access_token|refresh_token|api_key|apiKey|private_key)":\s*"[^"]*"/gi,e=>{let t=e.indexOf(":");return e.slice(0,t+1)+' "'+It+'"'}]];function ve(e){let t=e;for(let[n,s]of ms)t=t.replace(n,s);return t}function ln(e){return e.map(ve)}function st(e){if(typeof e=="string")return ve(e);if(Array.isArray(e))return e.map(st);if(e&&typeof e=="object"){let t={};for(let[n,s]of Object.entries(e)){let r=n.toLowerCase();r.includes("password")||r.includes("secret")||r.includes("token")||r.includes("apikey")||r.includes("api_key")||r.includes("private")?t[n]=It:t[n]=st(s)}return t}return e}var rt={log:console.log,warn:console.warn,error:console.error,debug:console.debug,info:console.info},De=[],cn=50;function gs(e){return e.map(t=>{if(t instanceof Error)return`${t.name}: ${t.message}
2
+ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{return String(t)}return String(t)})}function fs(e,t){let n={level:e,args:ln(gs(t)),timestamp:Date.now()};e==="error"&&(n.stack=new Error().stack?.split(`
3
3
  `).slice(2).join(`
4
- `)),Re.push(s),Re.length>os&&Re.shift(),q({type:"console",category:`console.${e}`,message:s.args.join(" ").slice(0,200),timestamp:s.timestamp})}function as(e){e&&(os=e);for(let t of Object.keys(Ze))console[t]=function(...s){pn(t,s),Ze[t].apply(console,s)}}function G(){return[...Re]}function is(){Re=[]}function ls(){for(let e of Object.keys(Ze))console[e]=Ze[e]}var ge=[],cs=50,Qe,Ge,et;function zt(e){ge.push(e),ge.length>cs&&ge.shift(),q({type:"network",category:e.failed?"network.error":"network.ok",message:`${e.method} ${e.url} \u2192 ${e.status} (${e.duration}ms)`,timestamp:e.timestamp,data:{status:e.status,duration:e.duration}})}function ds(e){try{let t=new URL(e,window.location.origin),s=new URLSearchParams(t.search);for(let r of s.keys()){let i=r.toLowerCase();(i.includes("token")||i.includes("key")||i.includes("secret")||i.includes("password")||i.includes("auth"))&&s.set(r,"[REDACTED]")}let n=s.toString();return t.pathname+(n?"?"+n:"")}catch{return fe(e)}}function un(){Qe=window.fetch,window.fetch=async function(e,t){let s=t?.method?.toUpperCase()??"GET",n=typeof e=="string"?e:e instanceof URL?e.href:e.url,r=ds(n),i=Date.now();try{let c=await Qe.call(window,e,t);return zt({method:s,url:r,status:c.status,statusText:c.statusText,duration:Date.now()-i,responseType:c.headers.get("content-type")??void 0,timestamp:i,failed:c.status>=400}),c}catch(c){throw zt({method:s,url:r,status:0,statusText:"Network Error",duration:Date.now()-i,timestamp:i,failed:!0}),c}}}function fn(){Ge=XMLHttpRequest.prototype.open,et=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(e,t,...s){return this.__bs_method=e.toUpperCase(),this.__bs_url=ds(typeof t=="string"?t:t.href),Ge.apply(this,[e,t,...s])},XMLHttpRequest.prototype.send=function(e){let t=Date.now();return this.addEventListener("loadend",function(){zt({method:this.__bs_method??"GET",url:this.__bs_url??"",status:this.status,statusText:this.statusText,duration:Date.now()-t,responseType:this.getResponseHeader("content-type")??void 0,timestamp:t,failed:this.status>=400||this.status===0})}),et.call(this,e)}}function bs(e){e&&(cs=e),un(),fn()}function me(){return[...ge]}function ae(){return ge.filter(e=>e.failed)}function ps(){ge=[]}function us(){Qe&&(window.fetch=Qe),Ge&&(XMLHttpRequest.prototype.open=Ge),et&&(XMLHttpRequest.prototype.send=et)}var tt=[],Be=null,Ne=null;function fs(){Be=e=>{let t={message:e.message||"Unknown error",source:e.filename,lineno:e.lineno,colno:e.colno,stack:e.error?.stack,type:"error",timestamp:Date.now()};tt.push(t),q({type:"error",category:"exception",message:t.message,timestamp:t.timestamp,data:{source:t.source,lineno:t.lineno}})},Ne=e=>{let t=e.reason,s=t instanceof Error?t.message:typeof t=="string"?t:"Unhandled promise rejection",n={message:s,stack:t instanceof Error?t.stack:void 0,type:"unhandledrejection",timestamp:Date.now()};tt.push(n),q({type:"error",category:"promise",message:s,timestamp:n.timestamp})},window.addEventListener("error",Be),window.addEventListener("unhandledrejection",Ne)}function ee(){return[...tt]}function gs(){tt=[]}function ms(){Be&&window.removeEventListener("error",Be),Ne&&window.removeEventListener("unhandledrejection",Ne),Be=null,Ne=null}var $=null,st=null,nt=null,rt=null;function hs(){if($={timestamp:Date.now()},performance.getEntriesByType){let e=()=>{let[t]=performance.getEntriesByType("navigation");t&&$&&($.pageLoadTime=Math.round(t.loadEventEnd-t.startTime),$.domContentLoaded=Math.round(t.domContentLoadedEventEnd-t.startTime));let s=performance.getEntriesByType("paint");for(let r of s)r.name==="first-paint"&&$&&($.firstPaint=Math.round(r.startTime)),r.name==="first-contentful-paint"&&$&&($.firstContentfulPaint=Math.round(r.startTime));$&&($.resourceCount=performance.getEntriesByType("resource").length);let n=performance.memory;n&&$&&($.memoryUsage={usedJSHeapSize:n.usedJSHeapSize,totalJSHeapSize:n.totalJSHeapSize})};document.readyState==="complete"?setTimeout(e,0):window.addEventListener("load",()=>setTimeout(e,100))}if(typeof PerformanceObserver<"u"){try{st=new PerformanceObserver(e=>{let t=e.getEntries(),s=t[t.length-1];s&&$&&($.largestContentfulPaint=Math.round(s.startTime))}),st.observe({type:"largest-contentful-paint",buffered:!0})}catch{}try{let e=0;nt=new PerformanceObserver(t=>{for(let s of t.getEntries())s.hadRecentInput||(e+=s.value);$&&($.cumulativeLayoutShift=Math.round(e*1e3)/1e3)}),nt.observe({type:"layout-shift",buffered:!0})}catch{}try{rt=new PerformanceObserver(e=>{let[t]=e.getEntries();t&&$&&($.firstInputDelay=Math.round(t.processingStart-t.startTime))}),rt.observe({type:"first-input",buffered:!0})}catch{}}}function he(){return $&&($.timestamp=Date.now()),$?{...$}:null}function xs(){st?.disconnect(),nt?.disconnect(),rt?.disconnect(),st=null,nt=null,rt=null,$=null}async function ot(){try{let e=await gn();if(e)return e}catch{}try{let e=await mn();if(e)return e}catch{}return null}async function gn(){let e=window.innerWidth,t=window.innerHeight,s=document.documentElement.cloneNode(!0),n=document.documentElement.querySelectorAll("*"),r=s.querySelectorAll("*");for(let g=0;g<n.length&&g<r.length;g++){let h=window.getComputedStyle(n[g]),y=r[g];if(y.style){let M=["background","background-color","background-image","color","font","font-size","font-family","font-weight","border","border-radius","padding","margin","display","flex-direction","align-items","justify-content","gap","width","height","max-width","max-height","overflow","position","top","left","right","bottom","box-shadow","text-shadow","opacity","transform","text-align","line-height","letter-spacing","text-decoration","visibility","z-index","grid-template-columns","grid-template-rows","box-sizing"];for(let re of M)try{y.style.setProperty(re,h.getPropertyValue(re))}catch{}}}s.querySelectorAll("script, [data-bugstash], .bs-fab, .bs-modal, .bs-backdrop").forEach(g=>g.remove());let c=new XMLSerializer().serializeToString(s),p=`
5
- <svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${t}">
6
- <foreignObject width="100%" height="100%">
7
- ${c}
8
- </foreignObject>
9
- </svg>
10
- `,l=new Blob([p],{type:"image/svg+xml;charset=utf-8"}),x=URL.createObjectURL(l);return new Promise(g=>{let h=new Image;h.onload=()=>{let y=document.createElement("canvas");y.width=e*.5,y.height=t*.5;let M=y.getContext("2d");if(!M){URL.revokeObjectURL(x),g(null);return}M.scale(.5,.5),M.drawImage(h,0,0),URL.revokeObjectURL(x),g(y.toDataURL("image/jpeg",.6))},h.onerror=()=>{URL.revokeObjectURL(x),g(null)},h.src=x})}async function mn(){if(!navigator.mediaDevices?.getDisplayMedia)return null;let e=await navigator.mediaDevices.getDisplayMedia({video:{displaySurface:"browser"}}),t=e.getVideoTracks()[0],s=document.createElement("video");return new Promise(n=>{s.onloadedmetadata=()=>{s.play();let r=document.createElement("canvas");r.width=s.videoWidth*.5,r.height=s.videoHeight*.5;let i=r.getContext("2d");if(!i){t.stop(),n(null);return}i.scale(.5,.5),i.drawImage(s,0,0),t.stop(),n(r.toDataURL("image/jpeg",.6))},s.onerror=()=>{t.stop(),n(null)},s.srcObject=e})}var hn="https://bugstash-backend.vercel.app",vs="https://bugstash-backend.vercel.app",U=hn,At=!1;function ys(e){U=e.replace(/\/$/,""),At=!1}function ws(){return U}async function X(e,t){try{return await fetch(e,t)}catch(s){if(At)throw s;At=!0;let n=U;U=vs;let r=e.replace(n,vs);return fetch(r,t)}}var It="bugstash_auth";function Ht(){try{let e=localStorage.getItem(It);if(!e)return null;let t=JSON.parse(e);return t.tokens.expiresAt<Date.now(),t}catch{return null}}function ks(e){localStorage.setItem(It,JSON.stringify(e))}function xn(){localStorage.removeItem(It)}function J(){return Ht()?.user||null}function Es(){return Ht()?.tokens.accessToken||null}async function ie(){let e=Ht();if(!e)return{"Content-Type":"application/json"};if(e.tokens.expiresAt<Date.now()+6e4)try{let t=await X(`${U}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e.tokens.refreshToken})});if(t.ok){let s=await t.json();s.success&&(e.tokens=s.data,ks(e))}}catch{}return{"Content-Type":"application/json",Authorization:`Bearer ${e.tokens.accessToken}`}}async function at(e,t,s){try{let r=await(await X(`${U}/api/auth/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:t,projectId:s})})).json();return r.success&&ks({user:r.data.user,tokens:r.data.tokens}),r}catch{return{success:!1,error:"Network error"}}}async function it(){xn()}async function Rt(e){try{let t=await ie();return await(await X(`${U}/api/reports`,{method:"POST",headers:t,body:JSON.stringify(e)})).json()}catch{return{success:!1,error:"Network error - could not reach BugStash"}}}async function Ls(e,t){try{let s=await ie();return await(await X(`${U}/api/pins/by-page?projectId=${e}&pathname=${encodeURIComponent(t)}`,{headers:s})).json()}catch{return{success:!1,error:"Network error"}}}async function Bt(e){try{let t=await ie();return await(await X(`${U}/api/pins`,{method:"POST",headers:t,body:JSON.stringify(e)})).json()}catch{return{success:!1,error:"Network error"}}}async function lt(e,t){try{let s=await ie();return await(await X(`${U}/api/pins/${e}`,{method:"PUT",headers:s,body:JSON.stringify(t)})).json()}catch{return{success:!1,error:"Network error"}}}async function Ss(e){try{let t=await ie();return await(await X(`${U}/api/pins/${e}`,{method:"DELETE",headers:t})).json()}catch{return{success:!1,error:"Network error"}}}async function Cs(e){try{let t=await ie();return await(await X(`${U}/api/pins/${e}/comments`,{headers:t})).json()}catch{return{success:!1,error:"Network error"}}}async function Nt(e,t,s=[]){try{let n=await ie();return await(await X(`${U}/api/pins/${e}/comments`,{method:"POST",headers:n,body:JSON.stringify({body:t,mentions:s})})).json()}catch{return{success:!1,error:"Network error"}}}async function Ts(e){try{let t=await ie();return await(await X(`${U}/api/members/for-project/${e}`,{headers:t})).json()}catch{return{success:!1,error:"Network error"}}}var Dt="bugstash_offline_queue";function jt(e){let t=$s();t.push({...e,id:Math.random().toString(36).slice(2),timestamp:Date.now()}),localStorage.setItem(Dt,JSON.stringify(t))}function $s(){try{return JSON.parse(localStorage.getItem(Dt)||"[]")}catch{return[]}}async function vn(){let e=$s();if(e.length===0)return 0;let t=0,s=[];for(let n of e)try{let r;switch(n.type){case"create_pin":r=await Bt(n.data);break;case"create_comment":r=await Nt(n.data.pinId,n.data.body,n.data.mentions);break;case"update_pin":r=await lt(n.data.pinId,n.data.updates);break;case"submit_report":r=await Rt(n.data);break;default:r={success:!1,error:"Unknown action"}}r.success?t++:s.push(n)}catch{s.push(n)}return localStorage.setItem(Dt,JSON.stringify(s)),t}typeof window<"u"&&window.addEventListener("online",()=>{vn().catch(()=>{})});var Ot=[{id:"midnight",name:"Midnight",preview:["#1a1d2e","#6E9ED0"],vars:{"--bs-bg":"#1a1d2e","--bs-bg2":"#222639","--bs-bg3":"#2a2e42","--bs-text":"#e2e5ed","--bs-muted":"#7c82a0","--bs-border":"#333754","--bs-accent":"#6E9ED0","--bs-accent2":"#8FAFD6","--bs-fab1":"#6E9ED0","--bs-fab2":"#8FAFD6","--bs-radius":"16px","--bs-radius-sm":"10px","--bs-red":"#f87171","--bs-green":"#4ade80","--bs-orange":"#fb923c","--bs-yellow":"#fbbf24"}},{id:"purple",name:"Deep Purple",preview:["#1c1628","#a78bfa"],vars:{"--bs-bg":"#1c1628","--bs-bg2":"#241e34","--bs-bg3":"#2e2640","--bs-text":"#e8e0f5","--bs-muted":"#8b7faa","--bs-border":"#3b3255","--bs-accent":"#a78bfa","--bs-accent2":"#c4b5fd","--bs-fab1":"#a78bfa","--bs-fab2":"#c084fc","--bs-radius":"16px","--bs-radius-sm":"10px","--bs-red":"#fb7185","--bs-green":"#6ee7b7","--bs-orange":"#fdba74","--bs-yellow":"#fde68a"}},{id:"cyberpunk",name:"Cyberpunk",preview:["#0a0a12","#00fff0"],vars:{"--bs-bg":"#0a0a12","--bs-bg2":"#12121f","--bs-bg3":"#1a1a2c","--bs-text":"#e0f7fa","--bs-muted":"#5e7f88","--bs-border":"#1e3a3f","--bs-accent":"#00fff0","--bs-accent2":"#00c8ff","--bs-fab1":"#00fff0","--bs-fab2":"#ff00c8","--bs-radius":"4px","--bs-radius-sm":"2px","--bs-red":"#ff3860","--bs-green":"#00ff88","--bs-orange":"#ffaa00","--bs-yellow":"#ffe600"}},{id:"sunset",name:"Sunset",preview:["#1f1318","#f97316"],vars:{"--bs-bg":"#1f1318","--bs-bg2":"#291a20","--bs-bg3":"#33212a","--bs-text":"#f5e6ea","--bs-muted":"#a07880","--bs-border":"#4a2a34","--bs-accent":"#f97316","--bs-accent2":"#fb923c","--bs-fab1":"#f97316","--bs-fab2":"#ef4444","--bs-radius":"14px","--bs-radius-sm":"8px","--bs-red":"#ef4444","--bs-green":"#4ade80","--bs-orange":"#fb923c","--bs-yellow":"#fbbf24"}},{id:"ocean",name:"Ocean",preview:["#0d1b2a","#2dd4bf"],vars:{"--bs-bg":"#0d1b2a","--bs-bg2":"#132638","--bs-bg3":"#1a3146","--bs-text":"#d6f0ee","--bs-muted":"#5c8a8e","--bs-border":"#1f4050","--bs-accent":"#2dd4bf","--bs-accent2":"#5eead4","--bs-fab1":"#2dd4bf","--bs-fab2":"#22d3ee","--bs-radius":"16px","--bs-radius-sm":"10px","--bs-red":"#fca5a5","--bs-green":"#6ee7b7","--bs-orange":"#fdba74","--bs-yellow":"#fde68a"}},{id:"rose",name:"Rose Gold",preview:["#1f1520","#f472b6"],vars:{"--bs-bg":"#1f1520","--bs-bg2":"#2a1c2a","--bs-bg3":"#352434","--bs-text":"#f5e0ec","--bs-muted":"#a07090","--bs-border":"#4a2a44","--bs-accent":"#f472b6","--bs-accent2":"#f9a8d4","--bs-fab1":"#f472b6","--bs-fab2":"#e879f9","--bs-radius":"20px","--bs-radius-sm":"12px","--bs-red":"#fb7185","--bs-green":"#86efac","--bs-orange":"#fdba74","--bs-yellow":"#fde68a"}},{id:"arctic",name:"Arctic Light",preview:["#f0f4f8","#3b82f6"],vars:{"--bs-bg":"#f0f4f8","--bs-bg2":"#e2e8f0","--bs-bg3":"#ffffff","--bs-text":"#1e293b","--bs-muted":"#64748b","--bs-border":"#cbd5e1","--bs-accent":"#3b82f6","--bs-accent2":"#60a5fa","--bs-fab1":"#3b82f6","--bs-fab2":"#6366f1","--bs-radius":"16px","--bs-radius-sm":"10px","--bs-red":"#ef4444","--bs-green":"#22c55e","--bs-orange":"#f97316","--bs-yellow":"#eab308"}},{id:"glass",name:"Glassmorphism",preview:["rgba(30,30,50,0.6)","#a5b4fc"],vars:{"--bs-bg":"rgba(22,22,40,0.75)","--bs-bg2":"rgba(35,35,60,0.6)","--bs-bg3":"rgba(45,45,75,0.5)","--bs-text":"#e8eaff","--bs-muted":"#8888bb","--bs-border":"rgba(255,255,255,0.1)","--bs-accent":"#a5b4fc","--bs-accent2":"#c7d2fe","--bs-fab1":"#818cf8","--bs-fab2":"#a78bfa","--bs-radius":"20px","--bs-radius-sm":"12px","--bs-red":"#fca5a5","--bs-green":"#86efac","--bs-orange":"#fdba74","--bs-yellow":"#fde68a"}},{id:"neon",name:"Neon",preview:["#080c08","#39ff14"],vars:{"--bs-bg":"#080c08","--bs-bg2":"#0f150f","--bs-bg3":"#161e16","--bs-text":"#d0f0c0","--bs-muted":"#5a7a50","--bs-border":"#1e3018","--bs-accent":"#39ff14","--bs-accent2":"#7dff5e","--bs-fab1":"#39ff14","--bs-fab2":"#00ff88","--bs-radius":"8px","--bs-radius-sm":"4px","--bs-red":"#ff4444","--bs-green":"#39ff14","--bs-orange":"#ffaa00","--bs-yellow":"#e6ff00"}},{id:"forest",name:"Forest",preview:["#111c15","#34d399"],vars:{"--bs-bg":"#111c15","--bs-bg2":"#18261d","--bs-bg3":"#203026","--bs-text":"#d1f0dd","--bs-muted":"#6a9a7a","--bs-border":"#2a4a33","--bs-accent":"#34d399","--bs-accent2":"#6ee7b7","--bs-fab1":"#34d399","--bs-fab2":"#2dd4bf","--bs-radius":"14px","--bs-radius-sm":"8px","--bs-red":"#fca5a5","--bs-green":"#4ade80","--bs-orange":"#fdba74","--bs-yellow":"#fde68a"}},{id:"minimal-dark",name:"Minimal Dark",preview:["#18181b","#a1a1aa"],vars:{"--bs-bg":"#18181b","--bs-bg2":"#212124","--bs-bg3":"#2a2a2e","--bs-text":"#e4e4e7","--bs-muted":"#71717a","--bs-border":"#333338","--bs-accent":"#a1a1aa","--bs-accent2":"#d4d4d8","--bs-fab1":"#52525b","--bs-fab2":"#71717a","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#f87171","--bs-green":"#4ade80","--bs-orange":"#fb923c","--bs-yellow":"#fbbf24"}},{id:"minimal-light",name:"Minimal Light",preview:["#fafafa","#52525b"],vars:{"--bs-bg":"#fafafa","--bs-bg2":"#f0f0f0","--bs-bg3":"#ffffff","--bs-text":"#18181b","--bs-muted":"#71717a","--bs-border":"#e4e4e7","--bs-accent":"#18181b","--bs-accent2":"#3f3f46","--bs-fab1":"#18181b","--bs-fab2":"#3f3f46","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#dc2626","--bs-green":"#16a34a","--bs-orange":"#ea580c","--bs-yellow":"#ca8a04"}},{id:"dracula",name:"Dracula",preview:["#282a36","#bd93f9"],vars:{"--bs-bg":"#282a36","--bs-bg2":"#2e303e","--bs-bg3":"#363848","--bs-text":"#f8f8f2","--bs-muted":"#6272a4","--bs-border":"#44475a","--bs-accent":"#bd93f9","--bs-accent2":"#caa9fa","--bs-fab1":"#bd93f9","--bs-fab2":"#ff79c6","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#ff5555","--bs-green":"#50fa7b","--bs-orange":"#ffb86c","--bs-yellow":"#f1fa8c"}},{id:"nord",name:"Nord",preview:["#2e3440","#88c0d0"],vars:{"--bs-bg":"#2e3440","--bs-bg2":"#3b4252","--bs-bg3":"#434c5e","--bs-text":"#eceff4","--bs-muted":"#7b88a1","--bs-border":"#4c566a","--bs-accent":"#88c0d0","--bs-accent2":"#8fbcbb","--bs-fab1":"#88c0d0","--bs-fab2":"#81a1c1","--bs-radius":"10px","--bs-radius-sm":"6px","--bs-red":"#bf616a","--bs-green":"#a3be8c","--bs-orange":"#d08770","--bs-yellow":"#ebcb8b"}},{id:"monokai",name:"Monokai",preview:["#272822","#a6e22e"],vars:{"--bs-bg":"#272822","--bs-bg2":"#2f302a","--bs-bg3":"#383930","--bs-text":"#f8f8f2","--bs-muted":"#75715e","--bs-border":"#49483e","--bs-accent":"#a6e22e","--bs-accent2":"#c4f060","--bs-fab1":"#a6e22e","--bs-fab2":"#66d9ef","--bs-radius":"8px","--bs-radius-sm":"4px","--bs-red":"#f92672","--bs-green":"#a6e22e","--bs-orange":"#fd971f","--bs-yellow":"#e6db74"}},{id:"solarized",name:"Solarized Dark",preview:["#002b36","#268bd2"],vars:{"--bs-bg":"#002b36","--bs-bg2":"#073642","--bs-bg3":"#0e4050","--bs-text":"#eee8d5","--bs-muted":"#839496","--bs-border":"#1a4f5c","--bs-accent":"#268bd2","--bs-accent2":"#2aa198","--bs-fab1":"#268bd2","--bs-fab2":"#2aa198","--bs-radius":"10px","--bs-radius-sm":"6px","--bs-red":"#dc322f","--bs-green":"#859900","--bs-orange":"#cb4b16","--bs-yellow":"#b58900"}},{id:"candy",name:"Candy",preview:["#fef1f8","#ec4899"],vars:{"--bs-bg":"#fef1f8","--bs-bg2":"#fce7f3","--bs-bg3":"#ffffff","--bs-text":"#4a1942","--bs-muted":"#9f5090","--bs-border":"#f0c6e0","--bs-accent":"#ec4899","--bs-accent2":"#f472b6","--bs-fab1":"#ec4899","--bs-fab2":"#a855f7","--bs-radius":"20px","--bs-radius-sm":"14px","--bs-red":"#e11d48","--bs-green":"#059669","--bs-orange":"#ea580c","--bs-yellow":"#ca8a04"}},{id:"slate",name:"Slate",preview:["#1e2432","#94a3b8"],vars:{"--bs-bg":"#1e2432","--bs-bg2":"#263040","--bs-bg3":"#2e384a","--bs-text":"#e2e8f0","--bs-muted":"#64748b","--bs-border":"#374462","--bs-accent":"#94a3b8","--bs-accent2":"#cbd5e1","--bs-fab1":"#475569","--bs-fab2":"#64748b","--bs-radius":"14px","--bs-radius-sm":"8px","--bs-red":"#f87171","--bs-green":"#4ade80","--bs-orange":"#fb923c","--bs-yellow":"#fbbf24"}},{id:"ember",name:"Ember",preview:["#1a0f0f","#ef4444"],vars:{"--bs-bg":"#1a0f0f","--bs-bg2":"#241515","--bs-bg3":"#2e1c1c","--bs-text":"#fde8e8","--bs-muted":"#a06060","--bs-border":"#4a2222","--bs-accent":"#ef4444","--bs-accent2":"#f87171","--bs-fab1":"#ef4444","--bs-fab2":"#f97316","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#fca5a5","--bs-green":"#86efac","--bs-orange":"#fdba74","--bs-yellow":"#fde68a"}},{id:"lavender",name:"Lavender",preview:["#f5f0ff","#7c3aed"],vars:{"--bs-bg":"#f5f0ff","--bs-bg2":"#ede5ff","--bs-bg3":"#ffffff","--bs-text":"#2e1065","--bs-muted":"#7c6a9a","--bs-border":"#d8c8f0","--bs-accent":"#7c3aed","--bs-accent2":"#8b5cf6","--bs-fab1":"#7c3aed","--bs-fab2":"#a855f7","--bs-radius":"18px","--bs-radius-sm":"12px","--bs-red":"#dc2626","--bs-green":"#16a34a","--bs-orange":"#ea580c","--bs-yellow":"#ca8a04"}}];function ct(){return Ot}function dt(e){return Ot.find(t=>t.id===e)}function Ms(){return Ot[0]}var qt=[{id:"classic",name:"Classic Center",description:"Centered modal, top tabs",tabPosition:"top"},{id:"drawer-right",name:"Right Drawer",description:"Slides in from the right",tabPosition:"top"},{id:"drawer-left",name:"Left Drawer",description:"Slides in from the left",tabPosition:"top"},{id:"bottom-sheet",name:"Bottom Sheet",description:"Slides up from the bottom",tabPosition:"top"},{id:"top-bar",name:"Top Drop",description:"Drops down from the top",tabPosition:"top"},{id:"compact",name:"Compact",description:"Small centered popup",tabPosition:"top"},{id:"wide",name:"Wide",description:"Wide horizontal modal",tabPosition:"top"},{id:"fullscreen",name:"Fullscreen",description:"Full screen overlay",tabPosition:"top"},{id:"corner-br",name:"Corner Card",description:"Bottom-right corner card",tabPosition:"top"},{id:"corner-bl",name:"Corner Left",description:"Bottom-left corner card",tabPosition:"top"},{id:"pill-tabs",name:"Pill Tabs",description:"Centered with pill-style tabs",tabPosition:"top"},{id:"sidebar-tabs",name:"Sidebar Tabs",description:"Vertical tabs on the left",tabPosition:"left"},{id:"segmented",name:"Segmented",description:"Tabs as segmented control",tabPosition:"top"},{id:"minimal",name:"Minimal",description:"Ultra clean, spacious",tabPosition:"top"},{id:"dense",name:"Dense",description:"Compact, tight spacing",tabPosition:"top"},{id:"rounded",name:"Bubble",description:"Extra rounded, playful",tabPosition:"top"},{id:"sharp",name:"Sharp",description:"Square corners, industrial",tabPosition:"top"},{id:"split",name:"Split View",description:"Two-column layout",tabPosition:"left"},{id:"floating",name:"Floating",description:"Heavy shadow, borderless",tabPosition:"top"},{id:"bottom-tabs",name:"Bottom Tabs",description:"Tabs at the bottom",tabPosition:"bottom"}];function bt(){return qt}function De(e){return qt.find(t=>t.id===e)}function Ps(){return qt[0]}var zs=`
4
+ `)),De.push(n),De.length>cn&&De.shift(),_({type:"console",category:`console.${e}`,message:n.args.join(" ").slice(0,200),timestamp:n.timestamp})}function dn(e){e&&(cn=e);for(let t of Object.keys(rt))console[t]=function(...n){fs(t,n),rt[t].apply(console,n)}}function te(){return[...De]}function pn(){De=[]}function bn(){for(let e of Object.keys(rt))console[e]=rt[e]}var xe=[],un=50,ot,at,it;function Ht(e){xe.push(e),xe.length>un&&xe.shift(),_({type:"network",category:e.failed?"network.error":"network.ok",message:`${e.method} ${e.url} \u2192 ${e.status} (${e.duration}ms)`,timestamp:e.timestamp,data:{status:e.status,duration:e.duration}})}function mn(e){try{let t=new URL(e,window.location.origin),n=new URLSearchParams(t.search);for(let r of n.keys()){let a=r.toLowerCase();(a.includes("token")||a.includes("key")||a.includes("secret")||a.includes("password")||a.includes("auth"))&&n.set(r,"[REDACTED]")}let s=n.toString();return t.pathname+(s?"?"+s:"")}catch{return ve(e)}}function hs(){ot=window.fetch,window.fetch=async function(e,t){let n=t?.method?.toUpperCase()??"GET",s=typeof e=="string"?e:e instanceof URL?e.href:e.url,r=mn(s),a=Date.now();try{let l=await ot.call(window,e,t);return Ht({method:n,url:r,status:l.status,statusText:l.statusText,duration:Date.now()-a,responseType:l.headers.get("content-type")??void 0,timestamp:a,failed:l.status>=400}),l}catch(l){throw Ht({method:n,url:r,status:0,statusText:"Network Error",duration:Date.now()-a,timestamp:a,failed:!0}),l}}}function vs(){at=XMLHttpRequest.prototype.open,it=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(e,t,...n){return this.__bs_method=e.toUpperCase(),this.__bs_url=mn(typeof t=="string"?t:t.href),at.apply(this,[e,t,...n])},XMLHttpRequest.prototype.send=function(e){let t=Date.now();return this.addEventListener("loadend",function(){Ht({method:this.__bs_method??"GET",url:this.__bs_url??"",status:this.status,statusText:this.statusText,duration:Date.now()-t,responseType:this.getResponseHeader("content-type")??void 0,timestamp:t,failed:this.status>=400||this.status===0})}),it.call(this,e)}}function gn(e){e&&(un=e),hs(),vs()}function ye(){return[...xe]}function ce(){return xe.filter(e=>e.failed)}function fn(){xe=[]}function hn(){ot&&(window.fetch=ot),at&&(XMLHttpRequest.prototype.open=at),it&&(XMLHttpRequest.prototype.send=it)}var lt=[],je=null,Oe=null;function vn(){je=e=>{let t={message:e.message||"Unknown error",source:e.filename,lineno:e.lineno,colno:e.colno,stack:e.error?.stack,type:"error",timestamp:Date.now()};lt.push(t),_({type:"error",category:"exception",message:t.message,timestamp:t.timestamp,data:{source:t.source,lineno:t.lineno}})},Oe=e=>{let t=e.reason,n=t instanceof Error?t.message:typeof t=="string"?t:"Unhandled promise rejection",s={message:n,stack:t instanceof Error?t.stack:void 0,type:"unhandledrejection",timestamp:Date.now()};lt.push(s),_({type:"error",category:"promise",message:n,timestamp:s.timestamp})},window.addEventListener("error",je),window.addEventListener("unhandledrejection",Oe)}function ne(){return[...lt]}function xn(){lt=[]}function yn(){je&&window.removeEventListener("error",je),Oe&&window.removeEventListener("unhandledrejection",Oe),je=null,Oe=null}var $=null,ct=null,dt=null,pt=null;function wn(){if($={timestamp:Date.now()},performance.getEntriesByType){let e=()=>{let[t]=performance.getEntriesByType("navigation");t&&$&&($.pageLoadTime=Math.round(t.loadEventEnd-t.startTime),$.domContentLoaded=Math.round(t.domContentLoadedEventEnd-t.startTime));let n=performance.getEntriesByType("paint");for(let r of n)r.name==="first-paint"&&$&&($.firstPaint=Math.round(r.startTime)),r.name==="first-contentful-paint"&&$&&($.firstContentfulPaint=Math.round(r.startTime));$&&($.resourceCount=performance.getEntriesByType("resource").length);let s=performance.memory;s&&$&&($.memoryUsage={usedJSHeapSize:s.usedJSHeapSize,totalJSHeapSize:s.totalJSHeapSize})};document.readyState==="complete"?setTimeout(e,0):window.addEventListener("load",()=>setTimeout(e,100))}if(typeof PerformanceObserver<"u"){try{ct=new PerformanceObserver(e=>{let t=e.getEntries(),n=t[t.length-1];n&&$&&($.largestContentfulPaint=Math.round(n.startTime))}),ct.observe({type:"largest-contentful-paint",buffered:!0})}catch{}try{let e=0;dt=new PerformanceObserver(t=>{for(let n of t.getEntries())n.hadRecentInput||(e+=n.value);$&&($.cumulativeLayoutShift=Math.round(e*1e3)/1e3)}),dt.observe({type:"layout-shift",buffered:!0})}catch{}try{pt=new PerformanceObserver(e=>{let[t]=e.getEntries();t&&$&&($.firstInputDelay=Math.round(t.processingStart-t.startTime))}),pt.observe({type:"first-input",buffered:!0})}catch{}}}function we(){return $&&($.timestamp=Date.now()),$?{...$}:null}function kn(){ct?.disconnect(),dt?.disconnect(),pt?.disconnect(),ct=null,dt=null,pt=null,$=null}function xs(){let e=document.createElement("div");if(e.style.cssText=`
5
+ position: fixed; inset: 0; z-index: 2147483647;
6
+ background: white; opacity: 0;
7
+ pointer-events: none;
8
+ animation: bs-flash 0.4s ease-out forwards;
9
+ `,!document.getElementById("bs-flash-style")){let t=document.createElement("style");t.id="bs-flash-style",t.textContent=`
10
+ @keyframes bs-flash {
11
+ 0% { opacity: 0; }
12
+ 15% { opacity: 0.7; }
13
+ 100% { opacity: 0; }
14
+ }
15
+ `,document.head.appendChild(t)}document.body.appendChild(e),e.addEventListener("animationend",()=>e.remove())}async function qe(){xs();try{let e=await ys();if(e)return e}catch{}try{let e=await ws();if(e)return e}catch{}try{let e=await ks();if(e)return e}catch{}return null}async function ys(){let e=window.innerWidth,t=window.innerHeight,n=document.documentElement.cloneNode(!0),s=document.documentElement.querySelectorAll("*"),r=n.querySelectorAll("*");for(let p=0;p<s.length&&p<r.length;p++){let v=window.getComputedStyle(s[p]),w=r[p];if(w.style){let M=["background","background-color","background-image","color","font","font-size","font-family","font-weight","border","border-radius","padding","margin","display","flex-direction","align-items","justify-content","gap","width","height","max-width","max-height","overflow","position","top","left","right","bottom","box-shadow","text-shadow","opacity","transform","text-align","line-height","letter-spacing","text-decoration","visibility","z-index","grid-template-columns","grid-template-rows","box-sizing"];for(let ie of M)try{w.style.setProperty(ie,v.getPropertyValue(ie))}catch{}}}n.querySelectorAll('script, [data-bugstash], .bs-fab, .bs-toolbar, .bs-modal, .bs-backdrop, [id="bs-flash-style"]').forEach(p=>p.remove()),n.querySelectorAll("img").forEach(p=>{try{let v=p.getAttribute("src")||"";v&&!v.startsWith("data:")&&!v.startsWith(window.location.origin)&&(p.removeAttribute("src"),p.style.backgroundColor="#e5e7eb")}catch{}}),n.querySelectorAll("iframe").forEach(p=>p.remove()),n.querySelectorAll("canvas").forEach(p=>p.remove()),n.querySelectorAll("video, audio").forEach(p=>p.remove());let l=new XMLSerializer().serializeToString(n),d=`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${t}"><foreignObject width="100%" height="100%">${l}</foreignObject></svg>`,c=new Blob([d],{type:"image/svg+xml;charset=utf-8"}),h=URL.createObjectURL(c);return new Promise(p=>{let v=new Image;v.crossOrigin="anonymous",v.onload=()=>{let w=document.createElement("canvas");w.width=e*.5,w.height=t*.5;let M=w.getContext("2d");if(!M){URL.revokeObjectURL(h),p(null);return}M.scale(.5,.5),M.drawImage(v,0,0),URL.revokeObjectURL(h);try{p(w.toDataURL("image/jpeg",.6))}catch{p(null)}},v.onerror=()=>{URL.revokeObjectURL(h),p(null)},v.src=h})}async function ws(){let e=window;if(e.html2canvas||await new Promise((n,s)=>{let r=document.createElement("script");r.src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js",r.onload=()=>n(),r.onerror=()=>s(new Error("Failed to load html2canvas")),document.head.appendChild(r)}),!e.html2canvas)return null;let t=await e.html2canvas(document.body,{scale:.5,useCORS:!0,allowTaint:!1,logging:!1,backgroundColor:null,ignoreElements:n=>n.classList?.contains("bs-fab")||n.classList?.contains("bs-toolbar")||n.classList?.contains("bs-modal")||n.classList?.contains("bs-backdrop")||n.id==="bs-flash-style"});try{return t.toDataURL("image/jpeg",.6)}catch{return null}}async function ks(){let e=window.innerWidth,t=window.innerHeight,n=document.createElement("canvas");n.width=e*.5,n.height=t*.5;let s=n.getContext("2d");if(!s)return null;s.scale(.5,.5);let r=window.getComputedStyle(document.body).backgroundColor;s.fillStyle=r||"#ffffff",s.fillRect(0,0,e,t),s.fillStyle="#888888",s.font="14px sans-serif",s.fillText(`Screenshot of: ${document.title||window.location.href}`,20,30),s.fillText(`Viewport: ${e}x${t}`,20,54),s.fillText(`Time: ${new Date().toLocaleString()}`,20,78);let a=document.querySelectorAll('main, header, footer, section, article, nav, aside, .card, [class*="container"]');s.strokeStyle="rgba(128,128,128,0.3)",s.lineWidth=1,a.forEach(l=>{let d=l.getBoundingClientRect();d.width>10&&d.height>10&&s.strokeRect(d.left,d.top,d.width,d.height)});try{return n.toDataURL("image/jpeg",.6)}catch{return null}}var Es="https://bugstash-backend.vercel.app",En="https://bugstash-backend.vercel.app",W=Es,Rt=!1;function Ln(e){W=e.replace(/\/$/,""),Rt=!1}function Sn(){return W}async function Q(e,t){try{return await fetch(e,t)}catch(n){if(Rt)throw n;Rt=!0;let s=W;W=En;let r=e.replace(s,En);return fetch(r,t)}}var Bt="bugstash_auth";function Nt(){try{let e=localStorage.getItem(Bt);if(!e)return null;let t=JSON.parse(e);return t.tokens.expiresAt<Date.now(),t}catch{return null}}function Cn(e){localStorage.setItem(Bt,JSON.stringify(e))}function Ls(){localStorage.removeItem(Bt)}function V(){return Nt()?.user||null}function Tn(){return Nt()?.tokens.accessToken||null}async function de(){let e=Nt();if(!e)return{"Content-Type":"application/json"};if(e.tokens.expiresAt<Date.now()+6e4)try{let t=await Q(`${W}/api/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e.tokens.refreshToken})});if(t.ok){let n=await t.json();n.success&&(e.tokens=n.data,Cn(e))}}catch{}return{"Content-Type":"application/json",Authorization:`Bearer ${e.tokens.accessToken}`}}async function bt(e,t,n){try{let r=await(await Q(`${W}/api/auth/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:t,projectId:n})})).json();return r.success&&Cn({user:r.data.user,tokens:r.data.tokens}),r}catch{return{success:!1,error:"Network error"}}}async function ut(){Ls()}async function Dt(e){try{let t=await de();return await(await Q(`${W}/api/reports`,{method:"POST",headers:t,body:JSON.stringify(e)})).json()}catch{return{success:!1,error:"Network error - could not reach BugStash"}}}async function $n(e,t){try{let n=await de();return await(await Q(`${W}/api/pins/by-page?projectId=${e}&pathname=${encodeURIComponent(t)}`,{headers:n})).json()}catch{return{success:!1,error:"Network error"}}}async function jt(e){try{let t=await de();return await(await Q(`${W}/api/pins`,{method:"POST",headers:t,body:JSON.stringify(e)})).json()}catch{return{success:!1,error:"Network error"}}}async function mt(e,t){try{let n=await de();return await(await Q(`${W}/api/pins/${e}`,{method:"PUT",headers:n,body:JSON.stringify(t)})).json()}catch{return{success:!1,error:"Network error"}}}async function Mn(e){try{let t=await de();return await(await Q(`${W}/api/pins/${e}`,{method:"DELETE",headers:t})).json()}catch{return{success:!1,error:"Network error"}}}async function Pn(e){try{let t=await de();return await(await Q(`${W}/api/pins/${e}/comments`,{headers:t})).json()}catch{return{success:!1,error:"Network error"}}}async function Ot(e,t,n=[]){try{let s=await de();return await(await Q(`${W}/api/pins/${e}/comments`,{method:"POST",headers:s,body:JSON.stringify({body:t,mentions:n})})).json()}catch{return{success:!1,error:"Network error"}}}async function zn(e){try{let t=await de();return await(await Q(`${W}/api/members/for-project/${e}`,{headers:t})).json()}catch{return{success:!1,error:"Network error"}}}var qt="bugstash_offline_queue";function Ut(e){let t=An();t.push({...e,id:Math.random().toString(36).slice(2),timestamp:Date.now()}),localStorage.setItem(qt,JSON.stringify(t))}function An(){try{return JSON.parse(localStorage.getItem(qt)||"[]")}catch{return[]}}async function Ss(){let e=An();if(e.length===0)return 0;let t=0,n=[];for(let s of e)try{let r;switch(s.type){case"create_pin":r=await jt(s.data);break;case"create_comment":r=await Ot(s.data.pinId,s.data.body,s.data.mentions);break;case"update_pin":r=await mt(s.data.pinId,s.data.updates);break;case"submit_report":r=await Dt(s.data);break;default:r={success:!1,error:"Unknown action"}}r.success?t++:n.push(s)}catch{n.push(s)}return localStorage.setItem(qt,JSON.stringify(n)),t}typeof window<"u"&&window.addEventListener("online",()=>{Ss().catch(()=>{})});var _t=[{id:"slate",name:"Slate",preview:["#0f1117","#6E9ED0"],vars:{"--bs-bg":"#0f1117","--bs-bg2":"#1a1d27","--bs-bg3":"#2a2d37","--bs-text":"#e8eaed","--bs-muted":"#9ca3af","--bs-border":"#2a2d37","--bs-accent":"#6E9ED0","--bs-accent2":"#C3CAD6","--bs-fab1":"#6E9ED0","--bs-fab2":"#4a7ba8","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#ef4444","--bs-green":"#22c55e","--bs-orange":"#f97316","--bs-yellow":"#eab308"}},{id:"black",name:"Dark",preview:["#0a0a0a","#ffffff"],vars:{"--bs-bg":"#0a0a0a","--bs-bg2":"#141414","--bs-bg3":"#1e1e1e","--bs-text":"#f5f5f5","--bs-muted":"#737373","--bs-border":"#262626","--bs-accent":"#f5f5f5","--bs-accent2":"#d4d4d4","--bs-fab1":"#262626","--bs-fab2":"#171717","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#ef4444","--bs-green":"#22c55e","--bs-orange":"#f97316","--bs-yellow":"#eab308"}},{id:"white",name:"Light",preview:["#ffffff","#0a0a0a"],vars:{"--bs-bg":"#ffffff","--bs-bg2":"#f5f5f5","--bs-bg3":"#e5e5e5","--bs-text":"#0a0a0a","--bs-muted":"#737373","--bs-border":"#e5e5e5","--bs-accent":"#0a0a0a","--bs-accent2":"#404040","--bs-fab1":"#0a0a0a","--bs-fab2":"#262626","--bs-radius":"12px","--bs-radius-sm":"8px","--bs-red":"#dc2626","--bs-green":"#16a34a","--bs-orange":"#ea580c","--bs-yellow":"#ca8a04"}}];function gt(){return _t}function ft(e){return _t.find(t=>t.id===e)}function In(){return _t[0]}var Wt=[{id:"classic",name:"Center",description:"Centered modal",tabPosition:"top"},{id:"drawer-right",name:"Right Drawer",description:"Slides from right",tabPosition:"top"},{id:"bottom-sheet",name:"Bottom Sheet",description:"Slides from bottom",tabPosition:"top"},{id:"sidebar-tabs",name:"Sidebar",description:"Side navigation",tabPosition:"left"}];function ht(){return Wt}function Ue(e){return Wt.find(t=>t.id===e)}function Hn(){return Wt[0]}var Rn=`
11
16
  /* \u2500\u2500 1. Classic (default \u2014 no overrides) \u2500\u2500 */
12
17
 
13
18
  /* \u2500\u2500 2. Drawer Right \u2500\u2500 */
@@ -24,21 +29,7 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
24
29
  opacity: 1;
25
30
  }
26
31
 
27
- /* \u2500\u2500 3. Drawer Left \u2500\u2500 */
28
- .bs-ly-drawer-left.bs-modal {
29
- top: 0; left: 0; right: auto; bottom: 0;
30
- width: 420px; max-width: 100vw; max-height: 100vh;
31
- height: 100vh;
32
- border-radius: 0;
33
- transform: translateX(-100%);
34
- transition: transform 0.4s cubic-bezier(0.22,1,0.36,1), opacity 0.3s ease;
35
- }
36
- .bs-ly-drawer-left.bs-modal.bs-in {
37
- transform: translateX(0);
38
- opacity: 1;
39
- }
40
-
41
- /* \u2500\u2500 4. Bottom Sheet \u2500\u2500 */
32
+ /* \u2500\u2500 3. Bottom Sheet \u2500\u2500 */
42
33
  .bs-ly-bottom-sheet.bs-modal {
43
34
  top: auto; left: 50%; right: auto; bottom: 0;
44
35
  width: 600px; max-width: 100vw;
@@ -52,105 +43,7 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
52
43
  opacity: 1;
53
44
  }
54
45
 
55
- /* \u2500\u2500 5. Top Drop \u2500\u2500 */
56
- .bs-ly-top-bar.bs-modal {
57
- top: 0; left: 50%; bottom: auto;
58
- width: 700px; max-width: 100vw;
59
- max-height: 75vh;
60
- border-radius: 0 0 var(--bs-radius) var(--bs-radius);
61
- transform: translate(-50%, -100%);
62
- transition: transform 0.45s cubic-bezier(0.22,1,0.36,1), opacity 0.3s ease;
63
- }
64
- .bs-ly-top-bar.bs-modal.bs-in {
65
- transform: translate(-50%, 0);
66
- opacity: 1;
67
- }
68
-
69
- /* \u2500\u2500 6. Compact \u2500\u2500 */
70
- .bs-ly-compact.bs-modal {
71
- width: 380px;
72
- }
73
- .bs-ly-compact .bs-scroll { padding: 12px 16px 16px; }
74
- .bs-ly-compact .bs-hdr { padding: 14px 16px 0; }
75
- .bs-ly-compact .bs-tabs { padding: 8px 16px 0; }
76
- .bs-ly-compact .bs-tab { padding: 7px 10px; font-size: 11px; }
77
- .bs-ly-compact .bs-field { margin-bottom: 10px; }
78
- .bs-ly-compact .bs-input, .bs-ly-compact .bs-textarea { padding: 8px 10px; font-size: 13px; }
79
- .bs-ly-compact .bs-submit-btn { padding: 10px; font-size: 13px; }
80
-
81
- /* \u2500\u2500 7. Wide \u2500\u2500 */
82
- .bs-ly-wide.bs-modal {
83
- width: 720px;
84
- }
85
- .bs-ly-wide .bs-scroll { padding: 20px 32px 28px; }
86
- .bs-ly-wide .bs-hdr { padding: 22px 32px 0; }
87
- .bs-ly-wide .bs-tabs { padding: 14px 32px 0; }
88
-
89
- /* \u2500\u2500 8. Fullscreen \u2500\u2500 */
90
- .bs-ly-fullscreen.bs-modal {
91
- top: 0; left: 0; width: 100vw; max-width: 100vw;
92
- height: 100vh; max-height: 100vh;
93
- border-radius: 0;
94
- transform: scale(0.95);
95
- transition: transform 0.35s cubic-bezier(0.22,1,0.36,1), opacity 0.3s ease;
96
- }
97
- .bs-ly-fullscreen.bs-modal.bs-in {
98
- transform: scale(1);
99
- opacity: 1;
100
- }
101
- .bs-ly-fullscreen .bs-scroll { padding: 24px 15%; }
102
- .bs-ly-fullscreen .bs-hdr { padding: 24px 15% 0; }
103
- .bs-ly-fullscreen .bs-tabs { padding: 16px 15% 0; }
104
-
105
- /* \u2500\u2500 9. Corner Bottom-Right \u2500\u2500 */
106
- .bs-ly-corner-br.bs-modal {
107
- top: auto; left: auto; right: 24px; bottom: 88px;
108
- width: 400px;
109
- max-height: 70vh;
110
- transform: translateY(20px) scale(0.95);
111
- transition: transform 0.35s cubic-bezier(0.34,1.56,0.64,1), opacity 0.3s ease;
112
- }
113
- .bs-ly-corner-br.bs-modal.bs-in {
114
- transform: translateY(0) scale(1);
115
- opacity: 1;
116
- }
117
-
118
- /* \u2500\u2500 10. Corner Bottom-Left \u2500\u2500 */
119
- .bs-ly-corner-bl.bs-modal {
120
- top: auto; left: 24px; right: auto; bottom: 88px;
121
- width: 400px;
122
- max-height: 70vh;
123
- transform: translateY(20px) scale(0.95);
124
- transition: transform 0.35s cubic-bezier(0.34,1.56,0.64,1), opacity 0.3s ease;
125
- }
126
- .bs-ly-corner-bl.bs-modal.bs-in {
127
- transform: translateY(0) scale(1);
128
- opacity: 1;
129
- }
130
-
131
- /* \u2500\u2500 11. Pill Tabs \u2500\u2500 */
132
- .bs-ly-pill-tabs .bs-tabs {
133
- background: var(--bs-bg2);
134
- margin: 12px 22px 0;
135
- border-radius: 999px;
136
- padding: 4px;
137
- gap: 4px;
138
- }
139
- .bs-ly-pill-tabs .bs-tab {
140
- border-radius: 999px;
141
- padding: 8px 14px;
142
- justify-content: center;
143
- flex: 1;
144
- }
145
- .bs-ly-pill-tabs .bs-tab.bs-active {
146
- background: var(--bs-accent);
147
- color: #fff;
148
- }
149
- .bs-ly-pill-tabs .bs-tab.bs-active::after { display: none; }
150
- .bs-ly-pill-tabs .bs-tab.bs-active .bs-tab-badge { background: rgba(255,255,255,0.25); color: #fff; }
151
- .bs-ly-pill-tabs .bs-tab-divider { display: none; }
152
-
153
- /* \u2500\u2500 12. Sidebar Tabs \u2500\u2500 */
46
+ /* \u2500\u2500 4. Sidebar Tabs \u2500\u2500 */
154
47
  .bs-ly-sidebar-tabs.bs-modal {
155
48
  width: 620px;
156
49
  }
@@ -179,222 +72,89 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
179
72
  }
180
73
  .bs-ly-sidebar-tabs .bs-tab-divider { display: none; }
181
74
  .bs-ly-sidebar-tabs .bs-scroll { flex: 1; }
182
-
183
- /* \u2500\u2500 13. Segmented \u2500\u2500 */
184
- .bs-ly-segmented .bs-tabs {
185
- background: var(--bs-bg2);
186
- margin: 12px 22px 0;
187
- border-radius: var(--bs-radius-sm);
188
- padding: 3px;
189
- gap: 3px;
190
- border: 1px solid var(--bs-border);
191
- }
192
- .bs-ly-segmented .bs-tab {
193
- border-radius: calc(var(--bs-radius-sm) - 2px);
194
- padding: 8px 12px;
195
- justify-content: center;
196
- flex: 1;
197
- font-size: 11px;
198
- }
199
- .bs-ly-segmented .bs-tab.bs-active { background: var(--bs-bg); box-shadow: 0 1px 3px rgba(0,0,0,0.2); }
200
- .bs-ly-segmented .bs-tab.bs-active::after { display: none; }
201
- .bs-ly-segmented .bs-tab-divider { display: none; }
202
-
203
- /* \u2500\u2500 14. Minimal \u2500\u2500 */
204
- .bs-ly-minimal.bs-modal {
205
- border: none;
206
- box-shadow: 0 40px 100px rgba(0,0,0,0.5);
207
- }
208
- .bs-ly-minimal .bs-hdr { padding: 28px 32px 0; }
209
- .bs-ly-minimal .bs-tabs { padding: 16px 32px 0; }
210
- .bs-ly-minimal .bs-scroll { padding: 24px 32px 32px; }
211
- .bs-ly-minimal .bs-field { margin-bottom: 22px; }
212
- .bs-ly-minimal .bs-input, .bs-ly-minimal .bs-textarea {
213
- border-color: transparent;
214
- background: var(--bs-bg2);
215
- }
216
- .bs-ly-minimal .bs-input:focus, .bs-ly-minimal .bs-textarea:focus { border-color: var(--bs-accent); }
217
- .bs-ly-minimal .bs-tab { font-weight: 400; letter-spacing: 0.5px; }
218
- .bs-ly-minimal .bs-tab.bs-active { font-weight: 700; }
219
-
220
- /* \u2500\u2500 15. Dense \u2500\u2500 */
221
- .bs-ly-dense.bs-modal { width: 480px; }
222
- .bs-ly-dense .bs-hdr { padding: 10px 14px 0; }
223
- .bs-ly-dense .bs-logo { font-size: 14px; }
224
- .bs-ly-dense .bs-tabs { padding: 6px 14px 0; }
225
- .bs-ly-dense .bs-tab { padding: 6px 8px; font-size: 10px; gap: 4px; }
226
- .bs-ly-dense .bs-tab svg { width: 12px; height: 12px; }
227
- .bs-ly-dense .bs-tab-divider { margin: 0; }
228
- .bs-ly-dense .bs-scroll { padding: 10px 14px 14px; }
229
- .bs-ly-dense .bs-field { margin-bottom: 8px; }
230
- .bs-ly-dense .bs-field-label { font-size: 11px; margin-bottom: 4px; }
231
- .bs-ly-dense .bs-input, .bs-ly-dense .bs-textarea { padding: 7px 10px; font-size: 12px; }
232
- .bs-ly-dense .bs-textarea { min-height: 50px; }
233
- .bs-ly-dense .bs-sev-btn { padding: 6px 0; font-size: 10px; }
234
- .bs-ly-dense .bs-shot-area { padding: 8px 10px; }
235
- .bs-ly-dense .bs-submit-btn { padding: 10px; font-size: 13px; }
236
-
237
- /* \u2500\u2500 16. Bubble / Rounded \u2500\u2500 */
238
- .bs-ly-rounded.bs-modal { border-radius: 28px; }
239
- .bs-ly-rounded .bs-hdr { padding: 22px 26px 0; }
240
- .bs-ly-rounded .bs-tabs { padding: 14px 26px 0; }
241
- .bs-ly-rounded .bs-tab { border-radius: 16px 16px 0 0; }
242
- .bs-ly-rounded .bs-scroll { padding: 18px 26px 26px; }
243
- .bs-ly-rounded .bs-input, .bs-ly-rounded .bs-textarea { border-radius: 16px; }
244
- .bs-ly-rounded .bs-sev-btn { border-radius: 16px; }
245
- .bs-ly-rounded .bs-submit-btn { border-radius: 20px; }
246
- .bs-ly-rounded .bs-shot-area { border-radius: 18px; }
247
- .bs-ly-rounded .bs-log, .bs-ly-rounded .bs-net { border-radius: 14px; }
248
- .bs-ly-rounded .bs-err-card { border-radius: 16px; }
249
-
250
- /* \u2500\u2500 17. Sharp \u2500\u2500 */
251
- .bs-ly-sharp.bs-modal { border-radius: 0; }
252
- .bs-ly-sharp .bs-tab { border-radius: 0; }
253
- .bs-ly-sharp .bs-tab.bs-active::after { border-radius: 0; }
254
- .bs-ly-sharp .bs-input, .bs-ly-sharp .bs-textarea { border-radius: 0; }
255
- .bs-ly-sharp .bs-sev-btn { border-radius: 0; }
256
- .bs-ly-sharp .bs-submit-btn { border-radius: 0; }
257
- .bs-ly-sharp .bs-shot-area { border-radius: 0; }
258
- .bs-ly-sharp .bs-log, .bs-ly-sharp .bs-net { border-radius: 0; }
259
- .bs-ly-sharp .bs-err-card { border-radius: 0; }
260
- .bs-ly-sharp .bs-msg { border-radius: 0; }
261
- .bs-ly-sharp .bs-ann-wrap { border-radius: 0; }
262
- .bs-ly-sharp .bs-fab { border-radius: 0; }
263
-
264
- /* \u2500\u2500 18. Split View \u2500\u2500 */
265
- .bs-ly-split.bs-modal {
266
- width: 700px;
267
- }
268
- .bs-ly-split .bs-body-wrap {
269
- display: flex;
270
- flex: 1;
271
- overflow: hidden;
272
- }
273
- .bs-ly-split .bs-tabs {
274
- flex-direction: column;
275
- padding: 16px 0 16px 16px;
276
- gap: 6px;
277
- min-width: 160px;
278
- border-right: 1px solid var(--bs-border);
279
- overflow-y: auto;
280
- }
281
- .bs-ly-split .bs-tab {
282
- border-radius: var(--bs-radius-sm);
283
- padding: 12px 14px;
284
- width: 100%;
285
- font-size: 13px;
286
- }
287
- .bs-ly-split .bs-tab.bs-active { background: var(--bs-accent); color: #fff; }
288
- .bs-ly-split .bs-tab.bs-active::after { display: none; }
289
- .bs-ly-split .bs-tab.bs-active .bs-tab-badge { background: rgba(255,255,255,0.25); color: #fff; }
290
- .bs-ly-split .bs-tab-divider { display: none; }
291
- .bs-ly-split .bs-scroll { flex: 1; }
292
-
293
- /* \u2500\u2500 19. Floating \u2500\u2500 */
294
- .bs-ly-floating.bs-modal {
295
- border: none;
296
- box-shadow: 0 50px 120px rgba(0,0,0,0.7), 0 20px 50px rgba(0,0,0,0.4);
297
- border-radius: 24px;
298
- }
299
- .bs-ly-floating .bs-hdr { padding: 22px 26px 0; }
300
- .bs-ly-floating .bs-tabs {
301
- padding: 14px 26px 0;
302
- background: transparent;
303
- }
304
- .bs-ly-floating .bs-tab {
305
- background: var(--bs-bg2);
306
- border-radius: var(--bs-radius-sm);
307
- margin-right: 4px;
308
- }
309
- .bs-ly-floating .bs-tab.bs-active {
310
- background: var(--bs-bg3);
311
- box-shadow: 0 2px 8px rgba(0,0,0,0.2);
312
- }
313
- .bs-ly-floating .bs-tab.bs-active::after { display: none; }
314
- .bs-ly-floating .bs-tab-divider { display: none; }
315
- .bs-ly-floating .bs-scroll { padding: 18px 26px 26px; }
316
-
317
- /* \u2500\u2500 20. Bottom Tabs \u2500\u2500 */
318
- .bs-ly-bottom-tabs .bs-tabs {
319
- order: 99;
320
- padding: 0 22px 12px;
321
- border-top: 1px solid var(--bs-border);
322
- border-bottom: none;
323
- background: var(--bs-bg);
324
- }
325
- .bs-ly-bottom-tabs .bs-tab {
326
- border-radius: 0 0 var(--bs-radius-sm) var(--bs-radius-sm);
327
- flex: 1;
328
- justify-content: center;
329
- padding: 12px 8px;
330
- }
331
- .bs-ly-bottom-tabs .bs-tab.bs-active::after {
332
- top: 0; bottom: auto;
333
- border-radius: 0 0 2px 2px;
334
- }
335
- .bs-ly-bottom-tabs .bs-tab-divider { order: 98; }
336
- .bs-ly-bottom-tabs .bs-scroll { order: 1; }
337
- `;var ye=null,pt=0,yn=5e3,xe=new Map,ve=null,ut=new Set;function ft(e){ve=e,pt=Date.now(),wn()}function wn(){ye||(ye=setInterval(kn,yn))}async function kn(){if(!ve)return;let e=Es();if(e)try{let t=ws(),s=window.location.pathname,n=await fetch(`${t}/api/pins/poll?projectId=${ve}&pathname=${encodeURIComponent(s)}&since=${pt}`,{headers:{Authorization:`Bearer ${e}`}});if(!n.ok)return;let r=await n.json();if(!r.success)return;let{pins:i,serverTime:c}=r.data;pt=c;for(let p of i)ut.has(p.id)?As("pin:updated",{type:"pin:updated",projectId:ve,data:p,userId:"",timestamp:Date.now()}):(ut.add(p.id),As("pin:created",{type:"pin:created",projectId:ve,data:p,userId:"",timestamp:Date.now()}))}catch{}}function Is(){ye&&(clearInterval(ye),ye=null),ve=null,ut.clear(),pt=0}function je(e,t){return xe.has(e)||xe.set(e,new Set),xe.get(e).add(t),()=>{xe.get(e)?.delete(t)}}function As(e,t){xe.get(e)?.forEach(s=>s(t)),xe.get("*")?.forEach(s=>s(t))}function Hs(e){ut=new Set(e)}function Rs(){return ye!==null}var gt,A=null,j=[],js=[],we=!1,Oe=null,En="",Bs={open:"#f97316",in_progress:"#3b82f6",resolved:"#22c55e",closed:"#6b7280"};function mt(e){gt=e,En=window.location.pathname,Ln(),qs(),Sn(),Mn(),Pn()}function Os(){A&&(A.remove(),A=null),j=[]}function ht(e){return we=e!==void 0?e:!we,A&&A.classList.toggle("bs-pin-mode",we),we}function xt(){return we}function Ln(){if(A)return;A=document.createElement("div"),A.id="bugstash-live-pins";let e=document.createElement("style");e.textContent=`
75
+ `;var Le=null,vt=0,Cs=5e3,ke=new Map,Ee=null,xt=new Set;function _e(e){Ee=e,vt=Date.now(),Ts()}function Ts(){Le||(Le=setInterval($s,Cs))}async function $s(){if(!Ee)return;let e=Tn();if(e)try{let t=Sn(),n=window.location.pathname,s=await fetch(`${t}/api/pins/poll?projectId=${Ee}&pathname=${encodeURIComponent(n)}&since=${vt}`,{headers:{Authorization:`Bearer ${e}`}});if(!s.ok)return;let r=await s.json();if(!r.success)return;let{pins:a,serverTime:l}=r.data;vt=l;for(let d of a)xt.has(d.id)?Bn("pin:updated",{type:"pin:updated",projectId:Ee,data:d,userId:"",timestamp:Date.now()}):(xt.add(d.id),Bn("pin:created",{type:"pin:created",projectId:Ee,data:d,userId:"",timestamp:Date.now()}))}catch{}}function Nn(){Le&&(clearInterval(Le),Le=null),Ee=null,xt.clear(),vt=0}function We(e,t){return ke.has(e)||ke.set(e,new Set),ke.get(e).add(t),()=>{ke.get(e)?.delete(t)}}function Bn(e,t){ke.get(e)?.forEach(n=>n(t)),ke.get("*")?.forEach(n=>n(t))}function Dn(e){xt=new Set(e)}function jn(){return Le!==null}var yt,A=null,U=[],_n=[],Se=!1,Fe=null,Ms="",On={open:"#f97316",in_progress:"#3b82f6",resolved:"#22c55e",closed:"#6b7280"};function Ye(e){yt=e,Ms=window.location.pathname,Ps(),Fn(),zs(),Rs(),Bs()}function Wn(){A&&(A.remove(),A=null),U=[]}function Xe(e){return Se=e!==void 0?e:!Se,A&&A.classList.toggle("bs-pin-mode",Se),Se}function wt(){return Se}function Ps(){if(A)return;A=document.createElement("div"),A.id="bugstash-live-pins";let e=document.createElement("style");e.textContent=`
76
+ /* Container scrolls with page so pins stick to their position */
338
77
  #bugstash-live-pins {
339
- position: fixed;
340
- inset: 0;
78
+ position: absolute;
79
+ top: 0;
80
+ left: 0;
81
+ width: 100%;
82
+ min-height: 100%;
341
83
  z-index: 2147483640;
342
84
  pointer-events: none;
343
85
  }
344
86
  #bugstash-live-pins.bs-pin-mode {
345
87
  pointer-events: auto;
346
88
  cursor: crosshair;
89
+ position: fixed;
90
+ inset: 0;
91
+ width: auto;
92
+ min-height: auto;
347
93
  }
94
+
95
+ /* \u2500\u2500 Pin Marker \u2014 clean numbered dot \u2500\u2500 */
348
96
  .bs-lp {
349
97
  position: absolute;
350
98
  pointer-events: auto;
351
99
  cursor: pointer;
352
- transition: transform 0.15s ease;
100
+ transform: translate(-50%, -50%);
101
+ transition: transform 0.2s cubic-bezier(0.34,1.56,0.64,1);
102
+ z-index: 1;
353
103
  }
354
- .bs-lp:hover { transform: scale(1.15); }
104
+ .bs-lp:hover { transform: translate(-50%, -50%) scale(1.2); z-index: 5; }
355
105
  .bs-lp-dot {
356
- width: 28px;
357
- height: 28px;
358
- border-radius: 50% 50% 50% 0;
359
- transform: rotate(-45deg);
106
+ width: 24px;
107
+ height: 24px;
108
+ border-radius: 50%;
360
109
  display: flex;
361
110
  align-items: center;
362
111
  justify-content: center;
363
- box-shadow: 0 2px 8px rgba(0,0,0,0.3);
364
- border: 2px solid #fff;
365
112
  font-size: 11px;
366
- font-weight: 700;
113
+ font-weight: 800;
114
+ font-family: -apple-system, system-ui, sans-serif;
367
115
  color: #fff;
116
+ box-shadow: 0 2px 12px rgba(0,0,0,0.35), 0 0 0 2px rgba(255,255,255,0.9);
117
+ position: relative;
368
118
  }
369
- .bs-lp-dot span {
370
- transform: rotate(45deg);
371
- display: block;
119
+ .bs-lp-ring {
120
+ position: absolute;
121
+ inset: -4px;
122
+ border-radius: 50%;
123
+ border: 2px solid currentColor;
124
+ opacity: 0;
125
+ animation: bs-lp-pulse 2s ease-out infinite;
372
126
  }
127
+ @keyframes bs-lp-pulse {
128
+ 0% { opacity: 0.6; transform: scale(0.8); }
129
+ 100% { opacity: 0; transform: scale(1.6); }
130
+ }
131
+
132
+ /* \u2500\u2500 Popup \u2500\u2500 */
373
133
  .bs-lp-popup {
374
134
  position: absolute;
375
- left: 36px;
376
- top: -8px;
377
- width: 320px;
378
- background: #1a1d2e;
379
- border: 1px solid #333754;
380
- border-radius: 12px;
381
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);
135
+ left: 32px;
136
+ top: -12px;
137
+ width: 300px;
138
+ background: #111318;
139
+ border: 1px solid #2a2d37;
140
+ border-radius: 10px;
141
+ box-shadow: 0 12px 40px rgba(0,0,0,0.5);
382
142
  z-index: 10;
383
143
  pointer-events: auto;
384
144
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
385
- color: #e2e5ed;
145
+ color: #e8eaed;
386
146
  overflow: hidden;
387
147
  }
388
148
  .bs-lp-popup-header {
389
- padding: 12px 14px;
390
- border-bottom: 1px solid #333754;
149
+ padding: 10px 12px;
150
+ border-bottom: 1px solid #1e2028;
391
151
  display: flex;
392
152
  align-items: center;
393
153
  justify-content: space-between;
394
- gap: 8px;
154
+ gap: 6px;
395
155
  }
396
156
  .bs-lp-popup-title {
397
- font-size: 14px;
157
+ font-size: 13px;
398
158
  font-weight: 600;
399
159
  flex: 1;
400
160
  overflow: hidden;
@@ -402,189 +162,199 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
402
162
  white-space: nowrap;
403
163
  }
404
164
  .bs-lp-popup-status {
405
- font-size: 10px;
406
- padding: 2px 8px;
165
+ font-size: 9px;
166
+ padding: 2px 7px;
407
167
  border-radius: 4px;
408
- font-weight: 600;
168
+ font-weight: 700;
409
169
  text-transform: uppercase;
170
+ letter-spacing: 0.3px;
410
171
  }
411
172
  .bs-lp-popup-body {
412
- padding: 12px 14px;
413
- font-size: 13px;
173
+ padding: 10px 12px;
174
+ font-size: 12px;
414
175
  line-height: 1.5;
415
- color: #a0a4b8;
416
- max-height: 120px;
176
+ color: #9ca3af;
177
+ max-height: 100px;
417
178
  overflow-y: auto;
418
179
  }
419
180
  .bs-lp-popup-meta {
420
- padding: 8px 14px;
421
- font-size: 11px;
422
- color: #7c82a0;
423
- border-top: 1px solid #2a2e42;
181
+ padding: 6px 12px;
182
+ font-size: 10px;
183
+ color: #6b7280;
184
+ border-top: 1px solid #1e2028;
424
185
  display: flex;
425
186
  justify-content: space-between;
426
187
  }
427
188
  .bs-lp-comments {
428
- max-height: 200px;
189
+ max-height: 180px;
429
190
  overflow-y: auto;
430
- border-top: 1px solid #2a2e42;
191
+ border-top: 1px solid #1e2028;
431
192
  }
432
193
  .bs-lp-comment {
433
- padding: 8px 14px;
434
- border-bottom: 1px solid #222639;
194
+ padding: 8px 12px;
195
+ border-bottom: 1px solid #1a1d24;
435
196
  font-size: 12px;
436
197
  }
437
198
  .bs-lp-comment-author {
438
199
  font-weight: 600;
439
- color: #e2e5ed;
200
+ color: #e8eaed;
440
201
  margin-bottom: 2px;
202
+ font-size: 11px;
441
203
  }
442
204
  .bs-lp-comment-body {
443
- color: #a0a4b8;
205
+ color: #9ca3af;
444
206
  line-height: 1.4;
445
207
  }
446
208
  .bs-lp-comment-time {
447
209
  font-size: 10px;
448
- color: #7c82a0;
210
+ color: #6b7280;
449
211
  margin-top: 2px;
450
212
  }
451
213
  .bs-lp-input-row {
452
214
  display: flex;
453
- border-top: 1px solid #333754;
215
+ border-top: 1px solid #2a2d37;
454
216
  }
455
217
  .bs-lp-input-row input {
456
218
  flex: 1;
457
219
  background: transparent;
458
220
  border: none;
459
- padding: 10px 14px;
460
- color: #e2e5ed;
461
- font-size: 13px;
221
+ padding: 8px 12px;
222
+ color: #e8eaed;
223
+ font-size: 12px;
462
224
  outline: none;
463
225
  }
464
- .bs-lp-input-row input::placeholder { color: #555; }
226
+ .bs-lp-input-row input::placeholder { color: #4b5563; }
465
227
  .bs-lp-input-row button {
466
- background: linear-gradient(135deg, #6E9ED0, #8FAFD6);
228
+ background: #6E9ED0;
467
229
  border: none;
468
230
  color: #fff;
469
- padding: 0 16px;
470
- font-size: 12px;
231
+ padding: 0 14px;
232
+ font-size: 11px;
471
233
  font-weight: 600;
472
234
  cursor: pointer;
473
235
  }
474
- .bs-lp-input-row button:hover { opacity: 0.9; }
236
+ .bs-lp-input-row button:hover { opacity: 0.85; }
475
237
  .bs-lp-actions {
476
- padding: 8px 14px;
238
+ padding: 6px 12px;
477
239
  display: flex;
478
- gap: 6px;
479
- border-top: 1px solid #2a2e42;
240
+ gap: 4px;
241
+ border-top: 1px solid #1e2028;
480
242
  }
481
243
  .bs-lp-btn {
482
244
  padding: 4px 10px;
483
245
  border-radius: 6px;
484
- border: 1px solid #333754;
485
- background: #222639;
486
- color: #a0a4b8;
487
- font-size: 11px;
246
+ border: 1px solid #2a2d37;
247
+ background: #1a1d24;
248
+ color: #9ca3af;
249
+ font-size: 10px;
250
+ font-weight: 500;
488
251
  cursor: pointer;
252
+ transition: all 0.15s;
489
253
  }
490
- .bs-lp-btn:hover { background: #2a2e42; color: #e2e5ed; }
491
- .bs-lp-btn.resolve { border-color: #22c55e44; color: #4ade80; }
492
- .bs-lp-btn.resolve:hover { background: #22c55e22; }
493
- .bs-lp-btn.delete { border-color: #ef444444; color: #f87171; }
494
- .bs-lp-btn.delete:hover { background: #ef444422; }
254
+ .bs-lp-btn:hover { background: #222630; color: #e8eaed; }
255
+ .bs-lp-btn.resolve { border-color: #22c55e33; color: #4ade80; }
256
+ .bs-lp-btn.resolve:hover { background: #22c55e18; }
257
+ .bs-lp-btn.delete { border-color: #ef444433; color: #f87171; }
258
+ .bs-lp-btn.delete:hover { background: #ef444418; }
495
259
  .bs-lp-close {
496
260
  background: none;
497
261
  border: none;
498
- color: #7c82a0;
499
- font-size: 18px;
262
+ color: #6b7280;
263
+ font-size: 16px;
500
264
  cursor: pointer;
501
- padding: 0 4px;
265
+ padding: 0 2px;
502
266
  line-height: 1;
267
+ transition: color 0.15s;
503
268
  }
504
- .bs-lp-close:hover { color: #e2e5ed; }
269
+ .bs-lp-close:hover { color: #e8eaed; }
505
270
 
506
- /* New pin form */
271
+ /* \u2500\u2500 New pin form \u2500\u2500 */
507
272
  .bs-lp-newform {
508
273
  position: absolute;
509
- width: 320px;
510
- background: #1a1d2e;
511
- border: 1px solid #333754;
512
- border-radius: 12px;
513
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);
274
+ width: 300px;
275
+ background: #111318;
276
+ border: 1px solid #2a2d37;
277
+ border-radius: 10px;
278
+ box-shadow: 0 12px 40px rgba(0,0,0,0.5);
514
279
  z-index: 2147483645;
515
280
  pointer-events: auto;
516
281
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
517
- color: #e2e5ed;
518
- padding: 14px;
282
+ color: #e8eaed;
283
+ padding: 12px;
519
284
  }
520
285
  .bs-lp-newform label {
521
286
  display: block;
522
- font-size: 11px;
523
- color: #7c82a0;
287
+ font-size: 10px;
288
+ color: #6b7280;
524
289
  margin-bottom: 4px;
525
- margin-top: 10px;
290
+ margin-top: 8px;
526
291
  font-weight: 600;
292
+ text-transform: uppercase;
293
+ letter-spacing: 0.3px;
527
294
  }
528
295
  .bs-lp-newform label:first-child { margin-top: 0; }
529
296
  .bs-lp-newform input, .bs-lp-newform textarea, .bs-lp-newform select {
530
297
  width: 100%;
531
- background: #222639;
532
- border: 1px solid #333754;
533
- border-radius: 8px;
534
- padding: 8px 10px;
535
- color: #e2e5ed;
536
- font-size: 13px;
298
+ background: #1a1d24;
299
+ border: 1px solid #2a2d37;
300
+ border-radius: 6px;
301
+ padding: 7px 10px;
302
+ color: #e8eaed;
303
+ font-size: 12px;
537
304
  outline: none;
538
305
  font-family: inherit;
539
306
  box-sizing: border-box;
540
307
  }
541
- .bs-lp-newform textarea { resize: vertical; min-height: 60px; }
308
+ .bs-lp-newform textarea { resize: vertical; min-height: 50px; }
542
309
  .bs-lp-newform input:focus, .bs-lp-newform textarea:focus, .bs-lp-newform select:focus {
543
310
  border-color: #6E9ED0;
544
311
  }
545
312
  .bs-lp-newform-actions {
546
313
  display: flex;
547
- gap: 8px;
548
- margin-top: 12px;
314
+ gap: 6px;
315
+ margin-top: 10px;
549
316
  }
550
317
  .bs-lp-newform-actions button {
551
318
  flex: 1;
552
- padding: 8px;
553
- border-radius: 8px;
319
+ padding: 7px;
320
+ border-radius: 6px;
554
321
  border: none;
555
- font-size: 13px;
322
+ font-size: 12px;
556
323
  font-weight: 600;
557
324
  cursor: pointer;
558
325
  }
559
326
  .bs-lp-newform-submit {
560
- background: linear-gradient(135deg, #6E9ED0, #8FAFD6);
327
+ background: #6E9ED0;
561
328
  color: #fff;
562
329
  }
330
+ .bs-lp-newform-submit:hover { opacity: 0.85; }
563
331
  .bs-lp-newform-cancel {
564
- background: #333754;
565
- color: #a0a4b8;
332
+ background: #2a2d37;
333
+ color: #9ca3af;
566
334
  }
567
- `,A.appendChild(e),document.body.appendChild(A),A.addEventListener("click",t=>{if(!we||t.target.closest(".bs-lp, .bs-lp-popup, .bs-lp-newform"))return;let s=t.clientX+window.scrollX,n=t.clientY+window.scrollY;A.style.pointerEvents="none";let r=document.elementFromPoint(t.clientX,t.clientY);A.style.pointerEvents="",$n(s,n,r)})}async function qs(){let e=await Ls(gt,window.location.pathname);e.success&&e.data&&(j=e.data,Hs(j.map(t=>t.id)),se())}async function Sn(){let e=await Ts(gt);e.success&&e.data&&(js=e.data)}function se(){A&&(A.querySelectorAll(".bs-lp").forEach(e=>e.remove()),j.forEach((e,t)=>{let s=document.createElement("div");s.className="bs-lp",s.style.left=`${e.pageX}px`,s.style.top=`${e.pageY}px`,s.dataset.pinId=e.id;let n=Bs[e.status]||Bs.open;s.innerHTML=`
568
- <div class="bs-lp-dot" style="background:${n}">
569
- <span>${t+1}</span>
335
+ .bs-lp-newform-cancel:hover { background: #333; }
336
+ `,A.appendChild(e),document.body.appendChild(A),A.addEventListener("click",t=>{if(!Se||t.target.closest(".bs-lp, .bs-lp-popup, .bs-lp-newform"))return;let n=t.clientX+window.scrollX,s=t.clientY+window.scrollY;A.style.pointerEvents="none";let r=document.elementFromPoint(t.clientX,t.clientY);A.style.pointerEvents="",Hs(n,s,r)})}async function Fn(){let e=await $n(yt,window.location.pathname);e.success&&e.data&&(U=e.data,Dn(U.map(t=>t.id)),re())}async function zs(){let e=await zn(yt);e.success&&e.data&&(_n=e.data)}function re(){A&&(A.querySelectorAll(".bs-lp").forEach(e=>e.remove()),U.forEach((e,t)=>{let n=document.createElement("div");n.className="bs-lp",n.style.left=`${e.pageX}px`,n.style.top=`${e.pageY}px`,n.dataset.pinId=e.id;let s=On[e.status]||On.open;n.innerHTML=`
337
+ <div class="bs-lp-dot" style="background:${s};color:${s}">
338
+ ${t+1}
339
+ <span class="bs-lp-ring"></span>
570
340
  </div>
571
- `,s.addEventListener("click",r=>{r.stopPropagation(),Cn(e,s)}),A.appendChild(s)}))}function Ns(e){let t=Date.now()-e,s=Math.floor(t/6e4);if(s<1)return"just now";if(s<60)return`${s}m ago`;let n=Math.floor(s/60);return n<24?`${n}h ago`:`${Math.floor(n/24)}d ago`}function Ds(e){return{open:"#f97316",in_progress:"#3b82f6",resolved:"#22c55e",closed:"#6b7280"}[e]||"#6b7280"}async function Cn(e,t){ce();let s=document.createElement("div");s.className="bs-lp-popup";let n=await Cs(e.id),r=n.success&&n.data?n.data:[],i=J(),c=i&&(i.role==="owner"||i.role==="admin"||i.id===e.createdBy);s.innerHTML=`
341
+ `,n.addEventListener("click",r=>{r.stopPropagation(),As(e,n)}),A.appendChild(n)}))}function qn(e){let t=Date.now()-e,n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;let s=Math.floor(n/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function Un(e){return{open:"#f97316",in_progress:"#3b82f6",resolved:"#22c55e",closed:"#6b7280"}[e]||"#6b7280"}async function As(e,t){ue();let n=document.createElement("div");n.className="bs-lp-popup";let s=await Pn(e.id),r=s.success&&s.data?s.data:[],a=V(),l=a&&(a.role==="owner"||a.role==="admin"||a.id===e.createdBy);n.innerHTML=`
572
342
  <div class="bs-lp-popup-header">
573
- <div class="bs-lp-popup-title">${te(e.title)}</div>
574
- <span class="bs-lp-popup-status" style="background:${Ds(e.status)}22;color:${Ds(e.status)}">${e.status.replace("_"," ")}</span>
343
+ <div class="bs-lp-popup-title">${se(e.title)}</div>
344
+ <span class="bs-lp-popup-status" style="background:${Un(e.status)}22;color:${Un(e.status)}">${e.status.replace("_"," ")}</span>
575
345
  <button class="bs-lp-close">&times;</button>
576
346
  </div>
577
- ${e.description?`<div class="bs-lp-popup-body">${te(e.description)}</div>`:""}
347
+ ${e.description?`<div class="bs-lp-popup-body">${se(e.description)}</div>`:""}
578
348
  <div class="bs-lp-popup-meta">
579
- <span>${e.creatorName||"Unknown"} &middot; ${Ns(e.createdAt)}</span>
349
+ <span>${e.creatorName||"Unknown"} &middot; ${qn(e.createdAt)}</span>
580
350
  <span>${e.assigneeName?`Assigned: ${e.assigneeName}`:"Unassigned"}</span>
581
351
  </div>
582
352
  <div class="bs-lp-comments" id="bs-lp-comments">
583
- ${r.map(l=>`
353
+ ${r.map(c=>`
584
354
  <div class="bs-lp-comment">
585
- <div class="bs-lp-comment-author">${te(l.author?.name||l.authorName||"Unknown")}</div>
586
- <div class="bs-lp-comment-body">${te(l.body)}</div>
587
- <div class="bs-lp-comment-time">${Ns(new Date(l.createdAt).getTime())}</div>
355
+ <div class="bs-lp-comment-author">${se(c.author?.name||c.authorName||"Unknown")}</div>
356
+ <div class="bs-lp-comment-body">${se(c.body)}</div>
357
+ <div class="bs-lp-comment-time">${qn(new Date(c.createdAt).getTime())}</div>
588
358
  </div>
589
359
  `).join("")}
590
360
  </div>
@@ -594,15 +364,15 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
594
364
  </div>
595
365
  <div class="bs-lp-actions">
596
366
  ${e.status!=="resolved"?'<button class="bs-lp-btn resolve" id="bs-lp-resolve">Resolve</button>':'<button class="bs-lp-btn" id="bs-lp-reopen">Reopen</button>'}
597
- ${c?'<button class="bs-lp-btn delete" id="bs-lp-delete">Delete</button>':""}
367
+ ${l?'<button class="bs-lp-btn delete" id="bs-lp-delete">Delete</button>':""}
598
368
  </div>
599
- `,t.appendChild(s),Oe=s,s.querySelector(".bs-lp-close").addEventListener("click",l=>{l.stopPropagation(),ce()}),s.querySelector("#bs-lp-comment-send")?.addEventListener("click",async()=>{let l=s.querySelector("#bs-lp-comment-input"),x=l.value.trim();if(x)if(l.value="",navigator.onLine){let g=await Nt(e.id,x);if(g.success&&g.data){let h=s.querySelector("#bs-lp-comments"),y=g.data;h.innerHTML+=`
369
+ `,t.appendChild(n),Fe=n,n.querySelector(".bs-lp-close").addEventListener("click",c=>{c.stopPropagation(),ue()}),n.querySelector("#bs-lp-comment-send")?.addEventListener("click",async()=>{let c=n.querySelector("#bs-lp-comment-input"),h=c.value.trim();if(h)if(c.value="",navigator.onLine){let p=await Ot(e.id,h);if(p.success&&p.data){let v=n.querySelector("#bs-lp-comments"),w=p.data;v.innerHTML+=`
600
370
  <div class="bs-lp-comment">
601
- <div class="bs-lp-comment-author">${te(y.authorName||i?.name||"You")}</div>
602
- <div class="bs-lp-comment-body">${te(y.body)}</div>
371
+ <div class="bs-lp-comment-author">${se(w.authorName||a?.name||"You")}</div>
372
+ <div class="bs-lp-comment-body">${se(w.body)}</div>
603
373
  <div class="bs-lp-comment-time">just now</div>
604
374
  </div>
605
- `,h.scrollTop=h.scrollHeight}}else jt({type:"create_comment",data:{pinId:e.id,body:x}})}),s.querySelector("#bs-lp-comment-input")?.addEventListener("keydown",l=>{l.key==="Enter"&&s.querySelector("#bs-lp-comment-send")?.dispatchEvent(new Event("click"))}),s.querySelector("#bs-lp-resolve")?.addEventListener("click",async()=>{await lt(e.id,{status:"resolved"}),e.status="resolved",ce(),se()}),s.querySelector("#bs-lp-reopen")?.addEventListener("click",async()=>{await lt(e.id,{status:"open"}),e.status="open",ce(),se()}),s.querySelector("#bs-lp-delete")?.addEventListener("click",async()=>{confirm("Delete this pin?")&&(await Ss(e.id),j=j.filter(l=>l.id!==e.id),ce(),se())}),s.addEventListener("click",l=>l.stopPropagation())}function ce(){Oe?.remove(),Oe=null}function Us(e){if(!e||e===document.body||e===document.documentElement)return"body";if(e.id)return`#${e.id}`;let t=e.tagName.toLowerCase();if(e.className&&typeof e.className=="string"){let n=e.className.trim().split(/\s+/).filter(r=>!r.startsWith("bs-")).slice(0,3);n.length&&(t+="."+n.join("."))}let s=e.parentElement;if(s&&s!==document.body){let n=Array.from(s.children).filter(r=>r.tagName===e.tagName);if(n.length>1){let r=n.indexOf(e);t+=`:nth-child(${r+1})`}return Us(s)+" > "+t}return t}function Tn(e){if(!e)return"";let t=[],s=e;for(;s&&s!==document.body;){let n=1,r=s.previousElementSibling;for(;r;)r.tagName===s.tagName&&n++,r=r.previousElementSibling;t.unshift(`${s.tagName.toLowerCase()}[${n}]`),s=s.parentElement}return"/body/"+t.join("/")}function $n(e,t,s){ce(),A?.querySelectorAll(".bs-lp-newform").forEach(i=>i.remove());let n=document.createElement("div");n.className="bs-lp-newform",n.style.left=`${e+16}px`,n.style.top=`${t-8}px`,requestAnimationFrame(()=>{let i=n.getBoundingClientRect();i.right>window.innerWidth-16&&(n.style.left=`${e-336}px`),i.bottom>window.innerHeight-16&&(n.style.top=`${t-i.height}px`)});let r=js.filter(i=>i.userId!==J()?.id).map(i=>`<option value="${i.userId}">${te(i.name)}</option>`).join("");n.innerHTML=`
375
+ `,v.scrollTop=v.scrollHeight}}else Ut({type:"create_comment",data:{pinId:e.id,body:h}})}),n.querySelector("#bs-lp-comment-input")?.addEventListener("keydown",c=>{c.key==="Enter"&&n.querySelector("#bs-lp-comment-send")?.dispatchEvent(new Event("click"))}),n.querySelector("#bs-lp-resolve")?.addEventListener("click",async()=>{await mt(e.id,{status:"resolved"}),e.status="resolved",ue(),re()}),n.querySelector("#bs-lp-reopen")?.addEventListener("click",async()=>{await mt(e.id,{status:"open"}),e.status="open",ue(),re()}),n.querySelector("#bs-lp-delete")?.addEventListener("click",async()=>{confirm("Delete this pin?")&&(await Mn(e.id),U=U.filter(c=>c.id!==e.id),ue(),re())}),n.addEventListener("click",c=>c.stopPropagation())}function ue(){Fe?.remove(),Fe=null}function Yn(e){if(!e||e===document.body||e===document.documentElement)return"body";if(e.id)return`#${e.id}`;let t=e.tagName.toLowerCase();if(e.className&&typeof e.className=="string"){let s=e.className.trim().split(/\s+/).filter(r=>!r.startsWith("bs-")).slice(0,3);s.length&&(t+="."+s.join("."))}let n=e.parentElement;if(n&&n!==document.body){let s=Array.from(n.children).filter(r=>r.tagName===e.tagName);if(s.length>1){let r=s.indexOf(e);t+=`:nth-child(${r+1})`}return Yn(n)+" > "+t}return t}function Is(e){if(!e)return"";let t=[],n=e;for(;n&&n!==document.body;){let s=1,r=n.previousElementSibling;for(;r;)r.tagName===n.tagName&&s++,r=r.previousElementSibling;t.unshift(`${n.tagName.toLowerCase()}[${s}]`),n=n.parentElement}return"/body/"+t.join("/")}function Hs(e,t,n){ue(),A?.querySelectorAll(".bs-lp-newform").forEach(a=>a.remove());let s=document.createElement("div");s.className="bs-lp-newform",s.style.left=`${e+16}px`,s.style.top=`${t-8}px`,requestAnimationFrame(()=>{let a=s.getBoundingClientRect();a.right>window.innerWidth-16&&(s.style.left=`${e-336}px`),a.bottom>window.innerHeight-16&&(s.style.top=`${t-a.height}px`)});let r=_n.filter(a=>a.userId!==V()?.id).map(a=>`<option value="${a.userId}">${se(a.name)}</option>`).join("");s.innerHTML=`
606
376
  <label>Title *</label>
607
377
  <input type="text" id="bs-np-title" placeholder="What's the issue?" autofocus />
608
378
  <label>Description</label>
@@ -633,13 +403,13 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
633
403
  <button class="bs-lp-newform-cancel" id="bs-np-cancel">Cancel</button>
634
404
  <button class="bs-lp-newform-submit" id="bs-np-submit">Create Pin</button>
635
405
  </div>
636
- `,A.appendChild(n),n.addEventListener("click",i=>i.stopPropagation()),n.querySelector("#bs-np-cancel").addEventListener("click",()=>n.remove()),n.querySelector("#bs-np-submit").addEventListener("click",async()=>{let i=n.querySelector("#bs-np-title").value.trim();if(!i){n.querySelector("#bs-np-title").style.borderColor="#ef4444";return}let c=n.querySelector("#bs-np-desc").value.trim(),p=n.querySelector("#bs-np-priority").value,l=n.querySelector("#bs-np-category").value,g=n.querySelector("#bs-np-assignee")?.value||void 0,h=Us(s),y=Tn(s),M=G().slice(-20).map(k=>`[${k.level}] ${k.args.join(" ")}`),re=ee().slice(-10).map(k=>`${k.message} at ${k.source}:${k.lineno}`),Ce=ae().slice(-10).map(k=>`${k.method} ${k.url} \u2192 ${k.status}`),R;try{n.style.display="none",A.style.display="none",R=await ot()??void 0,A.style.display="",n.style.display=""}catch{}let P={projectId:gt,pageUrl:window.location.href,pathname:window.location.pathname,elementSelector:h,elementXPath:y,xPercent:0,yPercent:0,pageX:e,pageY:t,title:i,description:c,screenshot:R,priority:p,category:l,assigneeId:g,browserInfo:navigator.userAgent,screenSize:`${screen.width}x${screen.height}`,viewportSize:`${window.innerWidth}x${window.innerHeight}`,devicePixelRatio:window.devicePixelRatio,consoleLogs:M,networkErrors:Ce,jsErrors:re};if(n.remove(),navigator.onLine){let k=await Bt(P);k.success&&k.data&&(j.push(k.data),se())}else jt({type:"create_pin",data:P}),j.push({...P,id:"local-"+Date.now(),orgId:"",status:"open",tags:[],createdById:J()?.id||"",creatorName:J()?.name||"",commentCount:0,createdAt:Date.now(),updatedAt:Date.now()}),se()}),setTimeout(()=>n.querySelector("#bs-np-title")?.focus(),50)}function Mn(){je("pin:created",e=>{let t=e.data;t.pathname===window.location.pathname&&(j.find(s=>s.id===t.id)||(j.push(t),se()))}),je("pin:updated",e=>{let t=e.data,s=j.findIndex(n=>n.id===t.id);s>=0&&(j[s]={...j[s],...t},se())}),je("pin:deleted",e=>{let{id:t}=e.data;j=j.filter(s=>s.id!==t),ce(),se()}),je("comment:created",e=>{let t=e.data;if(Oe){let s=Oe.querySelector("#bs-lp-comments");s&&(s.innerHTML+=`
406
+ `,A.appendChild(s),s.addEventListener("click",a=>a.stopPropagation()),s.querySelector("#bs-np-cancel").addEventListener("click",()=>s.remove()),s.querySelector("#bs-np-submit").addEventListener("click",async()=>{let a=s.querySelector("#bs-np-title").value.trim();if(!a){s.querySelector("#bs-np-title").style.borderColor="#ef4444";return}let l=s.querySelector("#bs-np-desc").value.trim(),d=s.querySelector("#bs-np-priority").value,c=s.querySelector("#bs-np-category").value,p=s.querySelector("#bs-np-assignee")?.value||void 0,v=Yn(n),w=Is(n),M=te().slice(-20).map(k=>`[${k.level}] ${k.args.join(" ")}`),ie=ne().slice(-10).map(k=>`${k.message} at ${k.source}:${k.lineno}`),Me=ce().slice(-10).map(k=>`${k.method} ${k.url} \u2192 ${k.status}`),R;try{s.style.display="none",A.style.display="none",R=await qe()??void 0,A.style.display="",s.style.display=""}catch{}let P={projectId:yt,pageUrl:window.location.href,pathname:window.location.pathname,elementSelector:v,elementXPath:w,xPercent:0,yPercent:0,pageX:e,pageY:t,title:a,description:l,screenshot:R,priority:d,category:c,assigneeId:p,browserInfo:navigator.userAgent,screenSize:`${screen.width}x${screen.height}`,viewportSize:`${window.innerWidth}x${window.innerHeight}`,devicePixelRatio:window.devicePixelRatio,consoleLogs:M,networkErrors:Me,jsErrors:ie};if(s.remove(),navigator.onLine){let k=await jt(P);k.success&&k.data&&(U.push(k.data),re())}else Ut({type:"create_pin",data:P}),U.push({...P,id:"local-"+Date.now(),orgId:"",status:"open",tags:[],createdById:V()?.id||"",creatorName:V()?.name||"",commentCount:0,createdAt:Date.now(),updatedAt:Date.now()}),re()}),setTimeout(()=>s.querySelector("#bs-np-title")?.focus(),50)}function Rs(){We("pin:created",e=>{let t=e.data;t.pathname===window.location.pathname&&(U.find(n=>n.id===t.id)||(U.push(t),re()))}),We("pin:updated",e=>{let t=e.data,n=U.findIndex(s=>s.id===t.id);n>=0&&(U[n]={...U[n],...t},re())}),We("pin:deleted",e=>{let{id:t}=e.data;U=U.filter(n=>n.id!==t),ue(),re()}),We("comment:created",e=>{let t=e.data;if(Fe){let n=Fe.querySelector("#bs-lp-comments");n&&(n.innerHTML+=`
637
407
  <div class="bs-lp-comment">
638
- <div class="bs-lp-comment-author">${te(t.author?.name||"Someone")}</div>
639
- <div class="bs-lp-comment-body">${te(t.body)}</div>
408
+ <div class="bs-lp-comment-author">${se(t.author?.name||"Someone")}</div>
409
+ <div class="bs-lp-comment-body">${se(t.body)}</div>
640
410
  <div class="bs-lp-comment-time">just now</div>
641
411
  </div>
642
- `,s.scrollTop=s.scrollHeight)}})}function Pn(){let e=window.location.pathname,t=()=>{window.location.pathname!==e&&(e=window.location.pathname,window.location.href,qs())},s=history.pushState,n=history.replaceState;history.pushState=function(...r){s.apply(this,r),t()},history.replaceState=function(...r){n.apply(this,r),t()},window.addEventListener("popstate",t)}function te(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}var W,O=null,m=null,F=null,qe=null,Ue=null,be=!1,ke="report";var wt=Ms(),de=Ps(),V={bug:'<svg width="28" height="28" viewBox="55 38 60 105" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M95.8 44h-29c-3 0-5.4 2.4-5.4 5.4v29c0 3 2.4 5.4 5.4 5.4h19.5c13 0 23.5-10.5 23.5-23.5v-2.8c0-7.5-6-13.5-13.5-13.5h-.5zm-6.2 28.2H74.8V57.4h14.8c5.8 0 10.4 4.7 10.4 10.4s-4.7 10.4-10.4 10.4z" fill="rgba(255,255,255,0.85)"/><path d="M100.4 96h-33.6c-3 0-5.4 2.4-5.4 5.4v33.6c0 3 2.4 5.4 5.4 5.4h22c15 0 27-12 27-27v-3.9c0-7.5-6-13.5-13.5-13.5h-1.9zm-7.8 32.2H74.8v-20h17.8c6.7 0 12.2 5.5 12.2 12.2 0 4.3-3.5 7.8-7.8 7.8h-4.6z" fill="rgba(255,255,255,1)"/></svg>',x:'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',cam:'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>',check:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg>',report:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>',console:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>',network:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>',ctx:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',settings:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/></svg>',history:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>'},zn=`
412
+ `,n.scrollTop=n.scrollHeight)}})}function Bs(){let e=window.location.pathname,t=()=>{window.location.pathname!==e&&(e=window.location.pathname,window.location.href,Fn())},n=history.pushState,s=history.replaceState;history.pushState=function(...r){n.apply(this,r),t()},history.replaceState=function(...r){s.apply(this,r),t()},window.addEventListener("popstate",t)}function se(e){let t=document.createElement("div");return t.textContent=e,t.innerHTML}var F,D=null,B=null,f=null,X=null,Je=null,Ke=null,J=!1,Et=!1,Ce="report";var pe=In(),me=Hn(),N={bug:'<svg width="28" height="28" viewBox="55 38 60 105" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M95.8 44h-29c-3 0-5.4 2.4-5.4 5.4v29c0 3 2.4 5.4 5.4 5.4h19.5c13 0 23.5-10.5 23.5-23.5v-2.8c0-7.5-6-13.5-13.5-13.5h-.5zm-6.2 28.2H74.8V57.4h14.8c5.8 0 10.4 4.7 10.4 10.4s-4.7 10.4-10.4 10.4z" fill="rgba(255,255,255,0.85)"/><path d="M100.4 96h-33.6c-3 0-5.4 2.4-5.4 5.4v33.6c0 3 2.4 5.4 5.4 5.4h22c15 0 27-12 27-27v-3.9c0-7.5-6-13.5-13.5-13.5h-1.9zm-7.8 32.2H74.8v-20h17.8c6.7 0 12.2 5.5 12.2 12.2 0 4.3-3.5 7.8-7.8 7.8h-4.6z" fill="rgba(255,255,255,1)"/></svg>',x:'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',cam:'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>',check:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg>',report:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>',console:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>',network:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>',ctx:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>',settings:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/></svg>',history:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>',pin:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>',sun:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>',moon:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>',keyboard:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="4" width="20" height="16" rx="2"/><line x1="6" y1="8" x2="6" y2="8"/><line x1="10" y1="8" x2="10" y2="8"/><line x1="14" y1="8" x2="14" y2="8"/><line x1="18" y1="8" x2="18" y2="8"/><line x1="8" y1="12" x2="16" y2="12"/><line x1="6" y1="16" x2="18" y2="16"/></svg>'},Ns=`
643
413
  @import url('https://fonts.googleapis.com/css2?family=Comfortaa:wght@400;600;700&family=Inter:wght@300;400;500;600;700&display=swap');
644
414
 
645
415
  /* \u2500\u2500 FAB \u2500\u2500 */
@@ -706,6 +476,65 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
706
476
  border-right: none;
707
477
  }
708
478
 
479
+ /* \u2500\u2500 Quick Action Toolbar \u2500\u2500 */
480
+ .bs-toolbar {
481
+ position: fixed;
482
+ z-index: 2147483646;
483
+ display: flex;
484
+ flex-direction: column;
485
+ gap: 6px;
486
+ bottom: 88px;
487
+ opacity: 0;
488
+ transform: translateY(10px);
489
+ transition: all 0.3s cubic-bezier(0.34,1.56,0.64,1);
490
+ pointer-events: none;
491
+ }
492
+ .bs-toolbar.bs-show {
493
+ opacity: 1;
494
+ transform: translateY(0);
495
+ pointer-events: all;
496
+ }
497
+ .bs-toolbar-btn {
498
+ all: unset;
499
+ width: 40px;
500
+ height: 40px;
501
+ border-radius: var(--bs-radius-sm);
502
+ background: var(--bs-bg2);
503
+ border: 1px solid var(--bs-border);
504
+ color: var(--bs-muted);
505
+ cursor: pointer;
506
+ display: flex;
507
+ align-items: center;
508
+ justify-content: center;
509
+ transition: all 0.2s;
510
+ position: relative;
511
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
512
+ }
513
+ .bs-toolbar-btn:hover { color: var(--bs-text); border-color: var(--bs-accent); background: var(--bs-bg3); }
514
+ .bs-toolbar-btn.bs-active { color: var(--bs-accent); border-color: var(--bs-accent); }
515
+ .bs-toolbar-tip {
516
+ position: absolute;
517
+ right: calc(100% + 8px);
518
+ background: var(--bs-bg2);
519
+ color: var(--bs-text);
520
+ font-family: 'Inter', sans-serif;
521
+ font-size: 11px;
522
+ font-weight: 500;
523
+ padding: 4px 8px;
524
+ border-radius: 6px;
525
+ white-space: nowrap;
526
+ box-shadow: 0 2px 8px rgba(0,0,0,0.2);
527
+ opacity: 0;
528
+ pointer-events: none;
529
+ transition: opacity 0.15s;
530
+ }
531
+ .bs-toolbar-btn:hover .bs-toolbar-tip { opacity: 1; }
532
+ .bs-toolbar-kbd {
533
+ font-size: 9px;
534
+ color: var(--bs-muted);
535
+ margin-left: 4px;
536
+ }
537
+
709
538
  /* \u2500\u2500 Backdrop \u2500\u2500 */
710
539
  .bs-backdrop {
711
540
  position: fixed;
@@ -1136,6 +965,46 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
1136
965
  letter-spacing: 0.3px;
1137
966
  color: var(--bs-muted);
1138
967
  }
968
+
969
+ /* \u2500\u2500 Report Summary Bar \u2500\u2500 */
970
+ .bs-report-summary {
971
+ display: flex;
972
+ align-items: center;
973
+ justify-content: space-between;
974
+ padding: 10px 14px;
975
+ border-radius: var(--bs-radius-sm);
976
+ background: var(--bs-bg2);
977
+ border: 1px solid var(--bs-border);
978
+ margin-bottom: 16px;
979
+ font-size: 12px;
980
+ color: var(--bs-muted);
981
+ }
982
+ .bs-report-summary.bs-alert {
983
+ background: color-mix(in srgb, var(--bs-red) 6%, transparent);
984
+ border-color: color-mix(in srgb, var(--bs-red) 15%, transparent);
985
+ color: var(--bs-red);
986
+ }
987
+ .bs-report-summary.bs-has { color: var(--bs-text); }
988
+ .bs-report-summary-left { display: flex; align-items: center; gap: 8px; }
989
+ .bs-report-summary-icon {
990
+ width: 22px; height: 22px;
991
+ border-radius: 50%;
992
+ background: color-mix(in srgb, var(--bs-green) 12%, transparent);
993
+ color: var(--bs-green);
994
+ display: flex; align-items: center; justify-content: center;
995
+ font-size: 10px; flex-shrink: 0;
996
+ }
997
+ .bs-report-summary-icon.bs-warn {
998
+ background: color-mix(in srgb, var(--bs-red) 12%, transparent);
999
+ color: var(--bs-red);
1000
+ font-weight: 800; font-size: 12px;
1001
+ }
1002
+ .bs-input-title {
1003
+ font-size: 16px !important;
1004
+ font-weight: 600;
1005
+ padding: 14px !important;
1006
+ }
1007
+
1139
1008
  .bs-auto-step-n {
1140
1009
  width: 20px;
1141
1010
  height: 20px;
@@ -1176,18 +1045,16 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
1176
1045
  .bs-submit-btn:hover { box-shadow: 0 8px 28px rgba(0,0,0,0.3); transform: translateY(-1px); }
1177
1046
  .bs-submit-btn:active { transform: translateY(0) scale(0.98); }
1178
1047
  .bs-submit-btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none !important; box-shadow: none !important; }
1179
-
1180
- .bs-msg {
1181
- text-align: center;
1182
- padding: 12px;
1183
- border-radius: var(--bs-radius-sm);
1048
+ .bs-submit-btn.bs-submit-ok {
1049
+ background: var(--bs-green) !important;
1050
+ opacity: 1 !important;
1051
+ display: flex; align-items: center; justify-content: center; gap: 6px;
1052
+ }
1053
+ .bs-submit-btn.bs-submit-err {
1054
+ background: var(--bs-red) !important;
1055
+ opacity: 1 !important;
1184
1056
  font-size: 13px;
1185
- font-weight: 600;
1186
- margin-top: 12px;
1187
- animation: bs-slideUp 0.3s ease;
1188
1057
  }
1189
- .bs-msg-ok { background: color-mix(in srgb, var(--bs-green) 10%, transparent); color: var(--bs-green); border: 1px solid color-mix(in srgb, var(--bs-green) 15%, transparent); }
1190
- .bs-msg-err { background: color-mix(in srgb, var(--bs-red) 10%, transparent); color: var(--bs-red); border: 1px solid color-mix(in srgb, var(--bs-red) 15%, transparent); }
1191
1058
 
1192
1059
  /* \u2500\u2500 Console \u2500\u2500 */
1193
1060
  .bs-log {
@@ -1594,7 +1461,7 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
1594
1461
  .bs-set-ly.bs-picked { border-color: var(--bs-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--bs-accent) 25%, transparent); }
1595
1462
  .bs-set-ly-name { font-size: 12px; font-weight: 600; color: var(--bs-text); margin-bottom: 2px; }
1596
1463
  .bs-set-ly-desc { font-size: 10px; color: var(--bs-muted); }
1597
- `;function An(){return`
1464
+ `;function Ds(){return`
1598
1465
  <div class="bs-login-form">
1599
1466
  <div class="bs-login-logo">BugStash</div>
1600
1467
  <div class="bs-login-subtitle">Sign in to report bugs & collaborate</div>
@@ -1604,59 +1471,55 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
1604
1471
  <button class="bs-login-btn" id="bs-login-submit">Sign In</button>
1605
1472
  <div style="font-size:11px;color:var(--bs-muted);margin-top:4px">Contact your admin for an account</div>
1606
1473
  </div>
1607
- `}function I(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function In(e){let t=Math.floor((Date.now()-e)/1e3);return t<5?"now":t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:new Date(e).toLocaleTimeString()}function _s(e){return new Date(e).toLocaleTimeString("en",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}var Fs="bugstash_history";function Le(){try{return JSON.parse(localStorage.getItem(Fs)||"[]")}catch{return[]}}function Ut(e){try{localStorage.setItem(Fs,JSON.stringify(e))}catch{}}function Hn(e){let t=Le(),s=Date.now();t.unshift({...e,id:s}),t.length>50&&(t.length=50),Ut(t)}function Rn(e){let t=Le().filter(s=>s.id!==e);Ut(t)}function Bn(e,t){let s=Le(),n=s.findIndex(r=>r.id===e);n>=0&&(s[n]={...s[n],...t},Ut(s))}function Ws(){return{url:window.location.href,userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,cookiesEnabled:navigator.cookieEnabled,online:navigator.onLine,screenWidth:screen.width,screenHeight:screen.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,devicePixelRatio:window.devicePixelRatio,timestamp:Date.now(),environment:W.environment??"development",commitHash:W.commitHash,user:W.user}}function Ys(){let e=ee(),t=G(),s=me(),n=ae(),r=ue(),i=he(),c=t.filter(x=>x.level==="error"),p="low";e.length>=3||n.length>=3?p="critical":e.length>=1||n.length>=2?p="high":(c.length>0||n.length>=1)&&(p="medium");let l=[];return e.length&&l.push("has-errors"),n.length&&l.push("network-failures"),c.length&&l.push("console-errors"),i?.pageLoadTime&&i.pageLoadTime>3e3&&l.push("slow-load"),i?.cumulativeLayoutShift&&i.cumulativeLayoutShift>.25&&l.push("layout-shift"),navigator.onLine||l.push("offline"),window.innerWidth<768&&l.push("mobile"),{severity:p,tags:l,counts:{logs:t.length,network:s.length,failedNet:n.length,errors:e.length,crumbs:r.length}}}function Xs(){let e=Ys(),t=[{id:"ui",label:"UI Bug"},{id:"functionality",label:"Broken Feature"},{id:"performance",label:"Slow / Laggy"},{id:"crash",label:"Crash"},{id:"security",label:"Security"},{id:"other",label:"Other"}];return`<div class="bs-view">
1474
+ `}function I(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function js(e){let t=Math.floor((Date.now()-e)/1e3);return t<5?"now":t<60?`${t}s ago`:t<3600?`${Math.floor(t/60)}m ago`:new Date(e).toLocaleTimeString()}function Jn(e){return new Date(e).toLocaleTimeString("en",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}var Kn="bugstash_history";function Te(){try{return JSON.parse(localStorage.getItem(Kn)||"[]")}catch{return[]}}function Yt(e){try{localStorage.setItem(Kn,JSON.stringify(e))}catch{}}function Os(e){let t=Te(),n=Date.now();t.unshift({...e,id:n}),t.length>50&&(t.length=50),Yt(t)}function qs(e){let t=Te().filter(n=>n.id!==e);Yt(t)}function Us(e,t){let n=Te(),s=n.findIndex(r=>r.id===e);s>=0&&(n[s]={...n[s],...t},Yt(n))}function Vn(){return{url:window.location.href,userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,cookiesEnabled:navigator.cookieEnabled,online:navigator.onLine,screenWidth:screen.width,screenHeight:screen.height,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,devicePixelRatio:window.devicePixelRatio,timestamp:Date.now(),environment:F.environment??"development",commitHash:F.commitHash,user:F.user}}function Qn(){let e=ne(),t=te(),n=ye(),s=ce(),r=he(),a=we(),l=t.filter(h=>h.level==="error"),d="low";e.length>=3||s.length>=3?d="critical":e.length>=1||s.length>=2?d="high":(l.length>0||s.length>=1)&&(d="medium");let c=[];return e.length&&c.push("has-errors"),s.length&&c.push("network-failures"),l.length&&c.push("console-errors"),a?.pageLoadTime&&a.pageLoadTime>3e3&&c.push("slow-load"),a?.cumulativeLayoutShift&&a.cumulativeLayoutShift>.25&&c.push("layout-shift"),navigator.onLine||c.push("offline"),window.innerWidth<768&&c.push("mobile"),{severity:d,tags:c,counts:{logs:t.length,network:n.length,failedNet:s.length,errors:e.length,crumbs:r.length}}}function Zn(){let e=Qn(),t=[{id:"ui",label:"UI"},{id:"functionality",label:"Feature"},{id:"performance",label:"Speed"},{id:"crash",label:"Crash"},{id:"security",label:"Security"},{id:"other",label:"Other"}],n=e.counts.errors>0||e.counts.failedNet>0;return`<div class="bs-view">
1608
1475
  <form data-bs-form>
1609
- <div class="bs-ctx-bar">
1610
- <div class="bs-ctx-chip${e.counts.logs?" bs-has":""}"><span class="bs-ctx-n">${e.counts.logs}</span><span class="bs-ctx-l">Logs</span></div>
1611
- <div class="bs-ctx-chip${e.counts.failedNet?" bs-alert":e.counts.network?" bs-has":""}"><span class="bs-ctx-n">${e.counts.network}</span><span class="bs-ctx-l">Network</span></div>
1612
- <div class="bs-ctx-chip${e.counts.errors?" bs-alert":""}"><span class="bs-ctx-n">${e.counts.errors}</span><span class="bs-ctx-l">Errors</span></div>
1613
- <div class="bs-ctx-chip${e.counts.crumbs?" bs-has":""}"><span class="bs-ctx-n">${e.counts.crumbs}</span><span class="bs-ctx-l">Actions</span></div>
1476
+ <div class="bs-report-summary${n?" bs-alert":e.counts.logs>0?" bs-has":""}">
1477
+ <div class="bs-report-summary-left">
1478
+ ${n?`<div class="bs-report-summary-icon bs-warn">!</div><span>${e.counts.errors} error${e.counts.errors!==1?"s":""}, ${e.counts.failedNet} failed request${e.counts.failedNet!==1?"s":""} detected</span>`:`<div class="bs-report-summary-icon">${N.check}</div><span>Auto-collecting ${e.counts.logs} logs, ${e.counts.network} requests, ${e.counts.crumbs} actions</span>`}
1479
+ </div>
1614
1480
  </div>
1615
1481
  <div class="bs-field">
1616
- <div class="bs-field-label">Bug title <span class="bs-field-hint">(required)</span></div>
1617
- <input class="bs-input" name="title" placeholder="Short summary \u2014 e.g. Checkout button unresponsive" required autocomplete="off" />
1482
+ <input class="bs-input bs-input-title" name="title" placeholder="What's the bug?" required autocomplete="off" />
1618
1483
  </div>
1619
1484
  <div class="bs-field">
1620
- <div class="bs-field-label">Description</div>
1621
- <textarea class="bs-textarea" name="description" placeholder="What were you doing? What went wrong?"></textarea>
1485
+ <textarea class="bs-textarea" name="description" placeholder="Steps to reproduce or extra details (optional)"></textarea>
1622
1486
  </div>
1623
1487
  <div class="bs-field">
1624
1488
  <div class="bs-field-label">Category</div>
1625
1489
  <input type="hidden" name="category" value="functionality" />
1626
1490
  <div class="bs-cat-row">
1627
- ${t.map(s=>`<button type="button" class="bs-cat-btn${s.id==="functionality"?" bs-picked":""}" data-cat="${s.id}">${s.label}</button>`).join("")}
1491
+ ${t.map(r=>`<button type="button" class="bs-cat-btn${r.id==="functionality"?" bs-picked":""}" data-cat="${r.id}">${r.label}</button>`).join("")}
1628
1492
  </div>
1629
1493
  </div>
1630
1494
  <div class="bs-field">
1631
- <div class="bs-field-label">Severity <span class="bs-field-hint">(suggested: ${e.severity})</span></div>
1495
+ <div class="bs-field-label">Severity</div>
1632
1496
  <input type="hidden" name="severity" value="${e.severity}" />
1633
1497
  <div class="bs-sev-row">
1634
1498
  <button type="button" class="bs-sev-btn bs-sev-low${e.severity==="low"?" bs-picked":""}" data-sev="low">Low</button>
1635
- <button type="button" class="bs-sev-btn bs-sev-medium${e.severity==="medium"?" bs-picked":""}" data-sev="medium">Medium</button>
1499
+ <button type="button" class="bs-sev-btn bs-sev-medium${e.severity==="medium"?" bs-picked":""}" data-sev="medium">Med</button>
1636
1500
  <button type="button" class="bs-sev-btn bs-sev-high${e.severity==="high"?" bs-picked":""}" data-sev="high">High</button>
1637
1501
  <button type="button" class="bs-sev-btn bs-sev-critical${e.severity==="critical"?" bs-picked":""}" data-sev="critical">Critical</button>
1638
1502
  </div>
1639
1503
  </div>
1640
1504
  <div class="bs-shot-area" data-bs-screenshot>
1641
- <div class="bs-shot-icon">${V.cam}</div>
1505
+ <div class="bs-shot-icon">${N.cam}</div>
1642
1506
  <div class="bs-shot-text">
1643
1507
  <div class="bs-shot-title" data-bs-shot-title>Attach screenshot</div>
1644
- <div class="bs-shot-sub" data-bs-shot-sub>Captures & lets you annotate the current view</div>
1508
+ <div class="bs-shot-sub" data-bs-shot-sub>Capture & annotate the current view</div>
1645
1509
  </div>
1646
1510
  </div>
1647
1511
  <div data-bs-annotate></div>
1648
1512
  <button type="submit" class="bs-submit-btn">Submit Report</button>
1649
- <div data-bs-msg></div>
1650
1513
  </form>
1651
- </div>`}function Nn(){let e=G(),t={error:"bs-le",warn:"bs-lw",log:"bs-ll",info:"bs-li",debug:"bs-ld"};return e.length?`<div class="bs-view">${e.slice().reverse().map(s=>`<div class="bs-log"><span class="bs-log-lv ${t[s.level]||"bs-ll"}">${s.level}</span><span class="bs-log-m">${I(s.args.join(" ")).slice(0,500)}</span><span class="bs-log-t">${_s(s.timestamp)}</span></div>`).join("")}</div>`:'<div class="bs-view"><div class="bs-empty"><p>No console logs captured yet.<br>Use the app \u2014 logs will appear here automatically.</p></div></div>'}function Dn(){let e=me();return e.length?`<div class="bs-view">${e.slice().reverse().map(t=>`<div class="bs-net"><span class="bs-net-m">${t.method}</span><span class="bs-net-s ${t.failed?"bs-fail":"bs-ok"}">${t.status||"ERR"}</span><span class="bs-net-u" title="${I(t.url)}">${I(t.url)}</span><span class="bs-net-d">${t.duration}ms</span></div>`).join("")}</div>`:'<div class="bs-view"><div class="bs-empty"><p>No network requests captured yet.<br>API calls will show up here automatically.</p></div></div>'}function jn(){let e='<div class="bs-view">',t=ee();t.length&&(e+=`<div class="bs-sec">Errors <span class="bs-sec-n">${t.length}</span></div>`,e+=t.slice().reverse().map(i=>`<div class="bs-err-card"><div class="bs-err-m">${I(i.message)}</div>${i.stack?`<div class="bs-err-stack">${I(i.stack)}</div>`:""}<div class="bs-err-meta">${i.type} &middot; ${_s(i.timestamp)}${i.source?` &middot; ${I(i.source)}:${i.lineno}`:""}</div></div>`).join(""));let s=he();if(s){e+='<div class="bs-sec">Performance</div>';let i=[["Page Load",s.pageLoadTime,5e3],["DOM Ready",s.domContentLoaded,3e3],["First Paint",s.firstPaint,2e3],["FCP",s.firstContentfulPaint,2500],["LCP",s.largestContentfulPaint,4e3],["FID",s.firstInputDelay,300]];for(let[c,p,l]of i){if(p===void 0)continue;let x=Math.min(100,p/l*100);e+=`<div class="bs-pf"><span class="bs-pf-l">${c}</span><div class="bs-pf-tr"><div class="bs-pf-fl${x>75?" bs-slow":""}" style="width:${x}%"></div></div><span class="bs-pf-v">${p}ms</span></div>`}if(s.cumulativeLayoutShift!==void 0){let c=Math.min(100,s.cumulativeLayoutShift*400);e+=`<div class="bs-pf"><span class="bs-pf-l">CLS</span><div class="bs-pf-tr"><div class="bs-pf-fl${c>40?" bs-slow":""}" style="width:${c}%"></div></div><span class="bs-pf-v">${s.cumulativeLayoutShift}</span></div>`}}let n=ue();n.length&&(e+=`<div class="bs-sec">Your activity trail <span class="bs-sec-n">${n.length}</span></div>`,e+=n.slice().reverse().map(i=>`<div class="bs-bc"><span class="bs-bc-t bs-t-${i.type}">${i.type}</span><span class="bs-bc-m">${I(i.message).slice(0,120)}</span><span class="bs-bc-time">${In(i.timestamp)}</span></div>`).join(""));let r=Ws();return e+='<div class="bs-sec">Environment</div>',e+=`<div class="bs-kv">
1514
+ </div>`}function _s(){let e=te(),t={error:"bs-le",warn:"bs-lw",log:"bs-ll",info:"bs-li",debug:"bs-ld"};return e.length?`<div class="bs-view">${e.slice().reverse().map(n=>`<div class="bs-log"><span class="bs-log-lv ${t[n.level]||"bs-ll"}">${n.level}</span><span class="bs-log-m">${I(n.args.join(" ")).slice(0,500)}</span><span class="bs-log-t">${Jn(n.timestamp)}</span></div>`).join("")}</div>`:'<div class="bs-view"><div class="bs-empty"><p>No console logs captured yet.<br>Use the app \u2014 logs will appear here automatically.</p></div></div>'}function Ws(){let e=ye();return e.length?`<div class="bs-view">${e.slice().reverse().map(t=>`<div class="bs-net"><span class="bs-net-m">${t.method}</span><span class="bs-net-s ${t.failed?"bs-fail":"bs-ok"}">${t.status||"ERR"}</span><span class="bs-net-u" title="${I(t.url)}">${I(t.url)}</span><span class="bs-net-d">${t.duration}ms</span></div>`).join("")}</div>`:'<div class="bs-view"><div class="bs-empty"><p>No network requests captured yet.<br>API calls will show up here automatically.</p></div></div>'}function Fs(){let e='<div class="bs-view">',t=ne();t.length&&(e+=`<div class="bs-sec">Errors <span class="bs-sec-n">${t.length}</span></div>`,e+=t.slice().reverse().map(a=>`<div class="bs-err-card"><div class="bs-err-m">${I(a.message)}</div>${a.stack?`<div class="bs-err-stack">${I(a.stack)}</div>`:""}<div class="bs-err-meta">${a.type} &middot; ${Jn(a.timestamp)}${a.source?` &middot; ${I(a.source)}:${a.lineno}`:""}</div></div>`).join(""));let n=we();if(n){e+='<div class="bs-sec">Performance</div>';let a=[["Page Load",n.pageLoadTime,5e3],["DOM Ready",n.domContentLoaded,3e3],["First Paint",n.firstPaint,2e3],["FCP",n.firstContentfulPaint,2500],["LCP",n.largestContentfulPaint,4e3],["FID",n.firstInputDelay,300]];for(let[l,d,c]of a){if(d===void 0)continue;let h=Math.min(100,d/c*100);e+=`<div class="bs-pf"><span class="bs-pf-l">${l}</span><div class="bs-pf-tr"><div class="bs-pf-fl${h>75?" bs-slow":""}" style="width:${h}%"></div></div><span class="bs-pf-v">${d}ms</span></div>`}if(n.cumulativeLayoutShift!==void 0){let l=Math.min(100,n.cumulativeLayoutShift*400);e+=`<div class="bs-pf"><span class="bs-pf-l">CLS</span><div class="bs-pf-tr"><div class="bs-pf-fl${l>40?" bs-slow":""}" style="width:${l}%"></div></div><span class="bs-pf-v">${n.cumulativeLayoutShift}</span></div>`}}let s=he();s.length&&(e+=`<div class="bs-sec">Your activity trail <span class="bs-sec-n">${s.length}</span></div>`,e+=s.slice().reverse().map(a=>`<div class="bs-bc"><span class="bs-bc-t bs-t-${a.type}">${a.type}</span><span class="bs-bc-m">${I(a.message).slice(0,120)}</span><span class="bs-bc-time">${js(a.timestamp)}</span></div>`).join(""));let r=Vn();return e+='<div class="bs-sec">Environment</div>',e+=`<div class="bs-kv">
1652
1515
  <span class="bs-kv-k">URL</span><span class="bs-kv-v">${I(r.url)}</span>
1653
1516
  <span class="bs-kv-k">Viewport</span><span class="bs-kv-v">${r.viewportWidth}&times;${r.viewportHeight} @${r.devicePixelRatio}x</span>
1654
1517
  <span class="bs-kv-k">Screen</span><span class="bs-kv-v">${r.screenWidth}&times;${r.screenHeight}</span>
1655
1518
  <span class="bs-kv-k">Platform</span><span class="bs-kv-v">${I(r.platform)}</span>
1656
1519
  <span class="bs-kv-k">Language</span><span class="bs-kv-v">${r.language}</span>
1657
- ${W.commitHash?`<span class="bs-kv-k">Commit</span><span class="bs-kv-v">${I(W.commitHash)}</span>`:""}
1658
- ${W.user?.email?`<span class="bs-kv-k">User</span><span class="bs-kv-v">${I(W.user.email)}</span>`:""}
1659
- </div>`,e+="</div>",e}function On(){let e=Le();if(!e.length)return'<div class="bs-view"><div class="bs-empty"><p>No reports yet.<br>Submitted bugs will appear here.</p></div></div>';let t={ui:"UI",functionality:"Feature",performance:"Perf",crash:"Crash",security:"Security",other:"Other"},s=r=>{let i=new Date(r),p=new Date().getTime()-i.getTime(),l=Math.floor(p/6e4);if(l<1)return"Just now";if(l<60)return`${l}m ago`;let x=Math.floor(l/60);if(x<24)return`${x}h ago`;let g=Math.floor(x/24);return g<7?`${g}d ago`:i.toLocaleDateString("en",{month:"short",day:"numeric"})},n='<div class="bs-view">';for(let r of e){let i=r.pins?.length?`<div class="bs-hist-pins">${r.pins.slice(0,5).map(c=>`<div class="bs-hist-pin-dot" style="background:${["#ef4444","#3b82f6","#f59e0b","#10b981","#8b5cf6"][c.number%5]}">${c.number}</div>`).join("")}${r.pins.length>5?`<span>+${r.pins.length-5}</span>`:""}</div>`:"";n+=`<div class="bs-hist-card" data-hist-id="${r.id}">
1520
+ ${F.commitHash?`<span class="bs-kv-k">Commit</span><span class="bs-kv-v">${I(F.commitHash)}</span>`:""}
1521
+ ${F.user?.email?`<span class="bs-kv-k">User</span><span class="bs-kv-v">${I(F.user.email)}</span>`:""}
1522
+ </div>`,e+="</div>",e}function Ys(){let e=Te();if(!e.length)return'<div class="bs-view"><div class="bs-empty"><p>No reports yet.<br>Submitted bugs will appear here.</p></div></div>';let t={ui:"UI",functionality:"Feature",performance:"Perf",crash:"Crash",security:"Security",other:"Other"},n=r=>{let a=new Date(r),d=new Date().getTime()-a.getTime(),c=Math.floor(d/6e4);if(c<1)return"Just now";if(c<60)return`${c}m ago`;let h=Math.floor(c/60);if(h<24)return`${h}h ago`;let p=Math.floor(h/24);return p<7?`${p}d ago`:a.toLocaleDateString("en",{month:"short",day:"numeric"})},s='<div class="bs-view">';for(let r of e){let a=r.pins?.length?`<div class="bs-hist-pins">${r.pins.slice(0,5).map(l=>`<div class="bs-hist-pin-dot" style="background:${["#ef4444","#3b82f6","#f59e0b","#10b981","#8b5cf6"][l.number%5]}">${l.number}</div>`).join("")}${r.pins.length>5?`<span>+${r.pins.length-5}</span>`:""}</div>`:"";s+=`<div class="bs-hist-card" data-hist-id="${r.id}">
1660
1523
  <div class="bs-hist-top">
1661
1524
  <div class="bs-hist-title">${I(r.title)}</div>
1662
1525
  ${r.screenshot?`<img class="bs-hist-thumb" src="${r.screenshot}" alt=""/>`:""}
@@ -1672,69 +1535,73 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
1672
1535
  </div>
1673
1536
  ${r.description?`<div class="bs-hist-desc">${I(r.description)}</div>`:""}
1674
1537
  <div class="bs-hist-foot">
1675
- <span>${s(r.createdAt)} &middot; ${I(r.url.replace(/^https?:\/\//,"").slice(0,40))}</span>
1676
- ${i}
1538
+ <span>${n(r.createdAt)} &middot; ${I(r.url.replace(/^https?:\/\//,"").slice(0,40))}</span>
1539
+ ${a}
1677
1540
  </div>
1678
- </div>`}return n+="</div>",n}function qn(){let e=ct(),t=bt(),s='<div class="bs-view">';s+='<div class="bs-set-sec">Layout</div>',s+='<div class="bs-set-ly-grid">';for(let n of t)s+=`<button class="bs-set-ly${n.id===de.id?" bs-picked":""}" data-set-layout="${n.id}"><div class="bs-set-ly-name">${I(n.name)}</div><div class="bs-set-ly-desc">${I(n.description)}</div></button>`;s+="</div>",s+='<div class="bs-set-sec">Theme</div>',s+='<div class="bs-set-grid">';for(let n of e)s+=`<button class="bs-set-card${n.id===wt.id?" bs-picked":""}" data-set-theme="${n.id}"><div class="bs-set-preview" style="background:${n.preview[0]}"><div class="bs-set-dot" style="background:${n.preview[1]}"></div><div class="bs-set-dot" style="background:${n.vars["--bs-accent2"]||n.preview[1]};opacity:0.6"></div></div><div class="bs-set-name">${I(n.name)}</div></button>`;return s+="</div>",s+="</div>",s}function Un(e,t){let s=["#f87171","#3b82f6","#fb923c","#4ade80","#a78bfa","#facc15"],n=s[0],r="draw",i=4,c=1,p=!1,l=[],x=[],g=-1,h=-1,y=!1,M=!1,re=0,Ce=0,R=0,P=0,k=[],Wt=["#ef4444","#3b82f6","#f59e0b","#10b981","#8b5cf6","#ec4899"],oe=new Image;oe.src=t;let Te=document.createElement("div");Te.className="bs-ann-wrap";let $e=document.createElement("div");$e.className="bs-ann-viewport";let w=document.createElement("canvas");w.className="bs-ann-canvas bs-draw";let Z=document.createElement("div");Z.className="bs-ann-toolbar";let Yt={select:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/></svg>',draw:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/></svg>',arrow:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>',rect:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>',circle:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/></svg>',text:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9.5" y1="20" x2="14.5" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/></svg>',highlight:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M9 11l-6 6v3h9l3-3"/><path d="M22 12l-4.6 4.6a2 2 0 01-2.8 0l-5.2-5.2a2 2 0 010-2.8L14 4"/></svg>',pin:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0118 0z"/><circle cx="12" cy="10" r="3"/></svg>'},rn={select:"Select & Move",draw:"Draw",arrow:"Arrow",rect:"Rectangle",circle:"Circle",text:"Text",highlight:"Highlight",pin:"Pin Issue"},Tt=[],on=o=>{r=o,g=-1,w.className=`bs-ann-canvas bs-${o}`,Tt.forEach(u=>u.classList.remove("bs-sel")),Tt.find(u=>u.dataset.tool===o)?.classList.add("bs-sel")};Object.keys(Yt).forEach(o=>{let u=document.createElement("button");u.type="button",u.dataset.tool=o,u.className=`bs-ann-btn${o===r?" bs-sel":""}`,u.title=rn[o],u.innerHTML=Yt[o],u.addEventListener("click",()=>on(o)),Tt.push(u),Z.appendChild(u)}),Z.appendChild(Object.assign(document.createElement("div"),{className:"bs-ann-sep"})),s.forEach((o,u)=>{let f=document.createElement("button");f.type="button",f.className=`bs-ann-dot${u===0?" bs-sel":""}`,f.style.background=o,f.addEventListener("click",()=>{n=o,Z.querySelectorAll(".bs-ann-dot").forEach(C=>C.classList.remove("bs-sel")),f.classList.add("bs-sel")}),Z.appendChild(f)}),Z.appendChild(Object.assign(document.createElement("div"),{className:"bs-ann-sep"}));let Q=document.createElement("input");Q.type="range",Q.min="1",Q.max="12",Q.value="4",Q.className="bs-ann-size",Q.title="Brush size",Q.addEventListener("input",()=>{i=parseInt(Q.value)}),Z.appendChild(Q);let Fe=document.createElement("div");Fe.className="bs-ann-right";let We=(o,u)=>{let f=document.createElement("button");return f.type="button",f.className="bs-ann-btn",f.title=o,f.innerHTML=u,f},Xt=We("Zoom out",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="8" y1="11" x2="14" y2="11"/></svg>'),Jt=Object.assign(document.createElement("span"),{className:"bs-ann-zoom-label",textContent:"100%"}),Vt=We("Zoom in",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></svg>'),Kt=We("Fit",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg>'),Zt=We("Undo",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 105.42-8.49L1 10"/></svg>'),Qt=Object.assign(document.createElement("button"),{type:"button",className:"bs-ann-clr-btn",textContent:"Clear"}),$t=()=>{w.style.transform=`scale(${c})`,Jt.textContent=`${Math.round(c*100)}%`};Vt.addEventListener("click",()=>{c<3&&(c=Math.min(3,c+.25),$t())}),Xt.addEventListener("click",()=>{c>.5&&(c=Math.max(.5,c-.25),$t())}),Kt.addEventListener("click",()=>{c=1,$t()}),Fe.appendChild(Object.assign(document.createElement("div"),{className:"bs-ann-sep"})),[Xt,Jt,Vt,Kt,Zt,Qt].forEach(o=>Fe.appendChild(o)),Z.appendChild(Fe);let Ye=document.createElement("div");Ye.className="bs-ann-pins";let pe=document.createElement("div");pe.className="bs-ann-pin-list",pe.style.display="none",$e.appendChild(w),$e.appendChild(Ye),Te.appendChild($e),Te.appendChild(Z),Te.appendChild(pe),e.innerHTML="",e.appendChild(Te);let Xe=()=>{Ye.innerHTML="",pe.innerHTML="",pe.style.display=x.length?"":"none",x.forEach((o,u)=>{let f=document.createElement("div");f.className="bs-ann-pin",f.style.background=o.color,f.style.color=o.color;let C=o.x/(w.width||1)*100,b=o.y/(w.height||1)*100;f.style.left=`${C}%`,f.style.top=`${b}%`,f.innerHTML=`<span class="bs-ann-pin-n">${u+1}</span><span class="bs-ann-pin-pulse"></span>`,f.title=`#${u+1}: ${o.note}`;let T=!1;f.addEventListener("mousedown",z=>{z.stopPropagation(),T=!0,f.classList.add("bs-dragging");let d=L=>{if(!T)return;let S=$e.getBoundingClientRect();o.x=(L.clientX-S.left)/S.width*w.width,o.y=(L.clientY-S.top)/S.height*w.height,f.style.left=`${(L.clientX-S.left)/S.width*100}%`,f.style.top=`${(L.clientY-S.top)/S.height*100}%`},v=()=>{T=!1,f.classList.remove("bs-dragging"),document.removeEventListener("mousemove",d),document.removeEventListener("mouseup",v),Xe()};document.addEventListener("mousemove",d),document.addEventListener("mouseup",v)}),Ye.appendChild(f);let B=document.createElement("div");B.className="bs-ann-pin-item",B.innerHTML=`
1679
- <div class="bs-ann-pin-num" style="background:${o.color}">${u+1}</div>
1541
+ </div>`}return s+="</div>",s}function Xs(){let e=gt(),t=ht(),n='<div class="bs-view">';n+='<div class="bs-set-sec">Layout</div>',n+='<div class="bs-set-ly-grid">';for(let s of t)n+=`<button class="bs-set-ly${s.id===me.id?" bs-picked":""}" data-set-layout="${s.id}"><div class="bs-set-ly-name">${I(s.name)}</div><div class="bs-set-ly-desc">${I(s.description)}</div></button>`;n+="</div>",n+='<div class="bs-set-sec">Theme</div>',n+='<div class="bs-set-grid">';for(let s of e)n+=`<button class="bs-set-card${s.id===pe.id?" bs-picked":""}" data-set-theme="${s.id}"><div class="bs-set-preview" style="background:${s.preview[0]}"><div class="bs-set-dot" style="background:${s.preview[1]}"></div><div class="bs-set-dot" style="background:${s.vars["--bs-accent2"]||s.preview[1]};opacity:0.6"></div></div><div class="bs-set-name">${I(s.name)}</div></button>`;return n+="</div>",n+="</div>",n}function Js(e,t){let n=["#f87171","#3b82f6","#fb923c","#4ade80","#a78bfa","#facc15"],s=n[0],r="draw",a=4,l=1,d=!1,c=[],h=[],p=-1,v=-1,w=!1,M=!1,ie=0,Me=0,R=0,P=0,k=[],Jt=["#ef4444","#3b82f6","#f59e0b","#10b981","#8b5cf6","#ec4899"],le=new Image;le.src=t;let Pe=document.createElement("div");Pe.className="bs-ann-wrap";let ze=document.createElement("div");ze.className="bs-ann-viewport";let y=document.createElement("canvas");y.className="bs-ann-canvas bs-draw";let G=document.createElement("div");G.className="bs-ann-toolbar";let Kt={select:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/></svg>',draw:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/></svg>',arrow:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>',rect:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>',circle:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/></svg>',text:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9.5" y1="20" x2="14.5" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/></svg>',highlight:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M9 11l-6 6v3h9l3-3"/><path d="M22 12l-4.6 4.6a2 2 0 01-2.8 0l-5.2-5.2a2 2 0 010-2.8L14 4"/></svg>',pin:'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0118 0z"/><circle cx="12" cy="10" r="3"/></svg>'},cs={select:"Select & Move",draw:"Draw",arrow:"Arrow",rect:"Rectangle",circle:"Circle",text:"Text",highlight:"Highlight",pin:"Pin Issue"},Pt=[],ds=o=>{r=o,p=-1,y.className=`bs-ann-canvas bs-${o}`,Pt.forEach(m=>m.classList.remove("bs-sel")),Pt.find(m=>m.dataset.tool===o)?.classList.add("bs-sel")};Object.keys(Kt).forEach(o=>{let m=document.createElement("button");m.type="button",m.dataset.tool=o,m.className=`bs-ann-btn${o===r?" bs-sel":""}`,m.title=cs[o],m.innerHTML=Kt[o],m.addEventListener("click",()=>ds(o)),Pt.push(m),G.appendChild(m)}),G.appendChild(Object.assign(document.createElement("div"),{className:"bs-ann-sep"})),n.forEach((o,m)=>{let g=document.createElement("button");g.type="button",g.className=`bs-ann-dot${m===0?" bs-sel":""}`,g.style.background=o,g.addEventListener("click",()=>{s=o,G.querySelectorAll(".bs-ann-dot").forEach(C=>C.classList.remove("bs-sel")),g.classList.add("bs-sel")}),G.appendChild(g)}),G.appendChild(Object.assign(document.createElement("div"),{className:"bs-ann-sep"}));let ee=document.createElement("input");ee.type="range",ee.min="1",ee.max="12",ee.value="4",ee.className="bs-ann-size",ee.title="Brush size",ee.addEventListener("input",()=>{a=parseInt(ee.value)}),G.appendChild(ee);let Qe=document.createElement("div");Qe.className="bs-ann-right";let Ze=(o,m)=>{let g=document.createElement("button");return g.type="button",g.className="bs-ann-btn",g.title=o,g.innerHTML=m,g},Vt=Ze("Zoom out",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="8" y1="11" x2="14" y2="11"/></svg>'),Qt=Object.assign(document.createElement("span"),{className:"bs-ann-zoom-label",textContent:"100%"}),Zt=Ze("Zoom in",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></svg>'),Gt=Ze("Fit",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg>'),en=Ze("Undo",'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 105.42-8.49L1 10"/></svg>'),tn=Object.assign(document.createElement("button"),{type:"button",className:"bs-ann-clr-btn",textContent:"Clear"}),zt=()=>{y.style.transform=`scale(${l})`,Qt.textContent=`${Math.round(l*100)}%`};Zt.addEventListener("click",()=>{l<3&&(l=Math.min(3,l+.25),zt())}),Vt.addEventListener("click",()=>{l>.5&&(l=Math.max(.5,l-.25),zt())}),Gt.addEventListener("click",()=>{l=1,zt()}),Qe.appendChild(Object.assign(document.createElement("div"),{className:"bs-ann-sep"})),[Vt,Qt,Zt,Gt,en,tn].forEach(o=>Qe.appendChild(o)),G.appendChild(Qe);let Ge=document.createElement("div");Ge.className="bs-ann-pins";let fe=document.createElement("div");fe.className="bs-ann-pin-list",fe.style.display="none",ze.appendChild(y),ze.appendChild(Ge),Pe.appendChild(ze),Pe.appendChild(G),Pe.appendChild(fe),e.innerHTML="",e.appendChild(Pe);let et=()=>{Ge.innerHTML="",fe.innerHTML="",fe.style.display=h.length?"":"none",h.forEach((o,m)=>{let g=document.createElement("div");g.className="bs-ann-pin",g.style.background=o.color,g.style.color=o.color;let C=o.x/(y.width||1)*100,u=o.y/(y.height||1)*100;g.style.left=`${C}%`,g.style.top=`${u}%`,g.innerHTML=`<span class="bs-ann-pin-n">${m+1}</span><span class="bs-ann-pin-pulse"></span>`,g.title=`#${m+1}: ${o.note}`;let T=!1;g.addEventListener("mousedown",z=>{z.stopPropagation(),T=!0,g.classList.add("bs-dragging");let b=L=>{if(!T)return;let S=ze.getBoundingClientRect();o.x=(L.clientX-S.left)/S.width*y.width,o.y=(L.clientY-S.top)/S.height*y.height,g.style.left=`${(L.clientX-S.left)/S.width*100}%`,g.style.top=`${(L.clientY-S.top)/S.height*100}%`},x=()=>{T=!1,g.classList.remove("bs-dragging"),document.removeEventListener("mousemove",b),document.removeEventListener("mouseup",x),et()};document.addEventListener("mousemove",b),document.addEventListener("mouseup",x)}),Ge.appendChild(g);let j=document.createElement("div");j.className="bs-ann-pin-item",j.innerHTML=`
1542
+ <div class="bs-ann-pin-num" style="background:${o.color}">${m+1}</div>
1680
1543
  <div class="bs-ann-pin-body">
1681
1544
  <div class="bs-ann-pin-note">${I(o.note)}</div>
1682
- <div class="bs-ann-pin-loc">${Math.round(C)}% \xD7 ${Math.round(b)}%</div>
1683
- </div>`;let D=document.createElement("button");D.type="button",D.className="bs-ann-pin-del",D.innerHTML="&times;",D.title="Remove pin",D.addEventListener("click",()=>{x.splice(u,1),Xe()}),B.appendChild(D),pe.appendChild(B)})},a,Mt=()=>p?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",le=(o,u)=>{a.save(),a.strokeStyle=Mt(),a.lineWidth=u+3,a.lineCap="round",a.lineJoin="round",a.globalAlpha=.5,o(),a.restore()},an=(o,u=!1)=>{if(o.type==="draw"||o.type==="highlight"){if(o.points.length<2)return;let b=o.type==="highlight"?.25:1,T=o.type==="highlight"?o.size*4+10:o.size,B=()=>{a.beginPath(),a.moveTo(o.points[0].x,o.points[0].y);for(let D=1;D<o.points.length;D++)a.lineTo(o.points[D].x,o.points[D].y);a.stroke()};o.type!=="highlight"&&le(B,T),a.strokeStyle=o.color,a.lineWidth=T,a.lineCap="round",a.lineJoin="round",a.globalAlpha=b,B(),a.globalAlpha=1}else if(o.type==="rect"){let b=()=>a.strokeRect(o.x,o.y,o.w,o.h);le(b,o.size),a.strokeStyle=o.color,a.lineWidth=o.size,a.lineCap="round",a.lineJoin="round",b()}else if(o.type==="circle"){let b=()=>{a.beginPath(),a.ellipse(o.cx,o.cy,Math.abs(o.rx),Math.abs(o.ry),0,0,Math.PI*2),a.stroke()};le(b,o.size),a.strokeStyle=o.color,a.lineWidth=o.size,b()}else if(o.type==="arrow"){let b=Math.atan2(o.y2-o.y1,o.x2-o.x1),T=12+o.size*2,B=()=>{a.beginPath(),a.moveTo(o.x1,o.y1),a.lineTo(o.x2,o.y2),a.stroke(),a.beginPath(),a.moveTo(o.x2,o.y2),a.lineTo(o.x2-T*Math.cos(b-.45),o.y2-T*Math.sin(b-.45)),a.moveTo(o.x2,o.y2),a.lineTo(o.x2-T*Math.cos(b+.45),o.y2-T*Math.sin(b+.45)),a.stroke()};le(B,o.size),a.strokeStyle=o.color,a.lineWidth=o.size,a.lineCap="round",a.lineJoin="round",B()}else if(o.type==="text"){let b=o.size*5+12;a.font=`bold ${b}px Inter, -apple-system, sans-serif`,a.fillStyle=Mt(),a.globalAlpha=.6,a.fillText(o.text,o.x+1,o.y+1),a.globalAlpha=1,a.fillStyle=o.color,a.fillText(o.text,o.x,o.y)}let f=!u&&g>=0&&l[g]===o,C=!u&&!f&&h>=0&&l[h]===o;if(f||C){let b=Me(o);if(a.save(),a.setLineDash([6,4]),a.strokeStyle=p?"#fff":"#000",a.lineWidth=f?1.5:1,a.globalAlpha=f?.7:.45,a.strokeRect(b.x-4,b.y-4,b.w+8,b.h+8),o.type==="rect"||o.type==="circle"){a.setLineDash([]),a.globalAlpha=f?.9:.6;let B=o.type==="rect"?[[b.x,b.y],[b.x+b.w,b.y],[b.x,b.y+b.h],[b.x+b.w,b.y+b.h]]:[[b.x+b.w/2,b.y],[b.x+b.w,b.y+b.h/2],[b.x+b.w/2,b.y+b.h],[b.x,b.y+b.h/2]];for(let[D,z]of B)a.fillStyle="#fff",a.fillRect(D-5,z-5,10,10),a.strokeStyle=p?"#aaa":"#333",a.lineWidth=1.2,a.strokeRect(D-5,z-5,10,10)}a.restore()}},N=()=>{a.clearRect(0,0,w.width,w.height),a.drawImage(oe,0,0);for(let o of l)an(o)},Me=o=>{if(o.type==="rect")return{x:Math.min(o.x,o.x+o.w),y:Math.min(o.y,o.y+o.h),w:Math.abs(o.w),h:Math.abs(o.h)};if(o.type==="circle")return{x:o.cx-Math.abs(o.rx),y:o.cy-Math.abs(o.ry),w:Math.abs(o.rx)*2,h:Math.abs(o.ry)*2};if(o.type==="arrow"){let T=Math.min(o.x1,o.x2),B=Math.min(o.y1,o.y2);return{x:T,y:B,w:Math.abs(o.x2-o.x1)||20,h:Math.abs(o.y2-o.y1)||20}}if(o.type==="text")return{x:o.x,y:o.y-(o.size*5+12),w:o.text.length*(o.size*3+8),h:o.size*5+16};if(o.points.length===0)return{x:0,y:0,w:0,h:0};let u=1/0,f=1/0,C=-1/0,b=-1/0;for(let T of o.points)u=Math.min(u,T.x),f=Math.min(f,T.y),C=Math.max(C,T.x),b=Math.max(b,T.y);return{x:u,y:f,w:C-u||10,h:b-f||10}},Je=(o,u)=>{for(let f=l.length-1;f>=0;f--){let C=Me(l[f]),b=8;if(o>=C.x-b&&o<=C.x+C.w+b&&u>=C.y-b&&u<=C.y+C.h+b)return f}return-1},ln=(o,u,f)=>{if(o.type==="draw"||o.type==="highlight")for(let C of o.points)C.x+=u,C.y+=f;else o.type==="rect"?(o.x+=u,o.y+=f):o.type==="circle"?(o.cx+=u,o.cy+=f):o.type==="arrow"?(o.x1+=u,o.y1+=f,o.x2+=u,o.y2+=f):o.type==="text"&&(o.x+=u,o.y+=f)};oe.onload=()=>{let u=(e.clientWidth||450)/oe.width;w.width=oe.width,w.height=oe.height,w.style.height=`${oe.height*u}px`,a=w.getContext("2d"),a.drawImage(oe,0,0);let f=[[10,10],[w.width-10,10],[10,w.height-10],[w.width-10,w.height-10],[w.width/2,w.height/2]],C=0;for(let[z,d]of f){let v=a.getImageData(z,d,1,1).data;C+=(v[0]*299+v[1]*587+v[2]*114)/1e3}p=C/f.length<128;let b=z=>{let d=w.getBoundingClientRect();return{x:(z.clientX-d.left)*(w.width/d.width),y:(z.clientY-d.top)*(w.height/d.height)}},T=!1;w.addEventListener("mousedown",z=>{let d=b(z);if(r==="select"){let v=Je(d.x,d.y);if(v>=0){g=v,y=!0;let L=Me(l[v]);re=d.x-L.x,Ce=d.y-L.y,w.classList.add("bs-grabbing"),w.classList.remove("bs-grab"),N()}else g=-1,N();return}if(r!=="pin"&&r!=="text"){let v=Je(d.x,d.y);if(v>=0){g=v,y=!0,T=!0;let L=Me(l[v]);re=d.x-L.x,Ce=d.y-L.y,w.classList.add("bs-grabbing"),N();return}}if(M=!0,R=d.x,P=d.y,r==="pin"){M=!1;let v=prompt("Describe the issue at this spot:");if(v){let L=Wt[x.length%Wt.length];x.push({x:d.x,y:d.y,note:v,color:L}),Xe()}return}if(r==="text"){M=!1;let v=prompt("Enter text:");v&&(l.push({type:"text",color:n,size:i,x:d.x,y:d.y,text:v}),N());return}(r==="draw"||r==="highlight")&&(k=[{x:d.x,y:d.y}])}),w.addEventListener("mousemove",z=>{let d=b(z);if(y&&g>=0){let v=Me(l[g]),L=d.x-re-v.x,S=d.y-Ce-v.y;ln(l[g],L,S),N();return}if(r==="select"){let v=Je(d.x,d.y);w.classList.toggle("bs-grab",v>=0),h!==v&&(h=v,N());return}if(r!=="pin"&&r!=="text"&&!M){let v=Je(d.x,d.y);w.classList.toggle("bs-grab",v>=0),h!==v&&(h=v,N())}if(M){if(r==="draw"||r==="highlight"){k.push({x:d.x,y:d.y}),N();let v=r==="highlight"?.25:1,L=r==="highlight"?i*4+10:i;if(r!=="highlight"){a.save(),a.strokeStyle=Mt(),a.lineWidth=L+3,a.lineCap="round",a.lineJoin="round",a.globalAlpha=.5,a.beginPath(),a.moveTo(k[0].x,k[0].y);for(let S=1;S<k.length;S++)a.lineTo(k[S].x,k[S].y);a.stroke(),a.restore()}a.strokeStyle=n,a.lineWidth=L,a.lineCap="round",a.lineJoin="round",a.globalAlpha=v,a.beginPath(),a.moveTo(k[0].x,k[0].y);for(let S=1;S<k.length;S++)a.lineTo(k[S].x,k[S].y);a.stroke(),a.globalAlpha=1}else if(N(),a.strokeStyle=n,a.lineWidth=i,a.lineCap="round",a.lineJoin="round",r==="rect")le(()=>a.strokeRect(R,P,d.x-R,d.y-P),i),a.strokeStyle=n,a.lineWidth=i,a.strokeRect(R,P,d.x-R,d.y-P);else if(r==="circle"){let v=Math.abs(d.x-R)/2,L=Math.abs(d.y-P)/2,S=R+(d.x-R)/2,Gt=P+(d.y-P)/2;le(()=>{a.beginPath(),a.ellipse(S,Gt,v,L,0,0,Math.PI*2),a.stroke()},i),a.strokeStyle=n,a.lineWidth=i,a.beginPath(),a.ellipse(S,Gt,v,L,0,0,Math.PI*2),a.stroke()}else if(r==="arrow"){let v=Math.atan2(d.y-P,d.x-R),L=12+i*2,S=()=>{a.beginPath(),a.moveTo(R,P),a.lineTo(d.x,d.y),a.stroke(),a.beginPath(),a.moveTo(d.x,d.y),a.lineTo(d.x-L*Math.cos(v-.45),d.y-L*Math.sin(v-.45)),a.moveTo(d.x,d.y),a.lineTo(d.x-L*Math.cos(v+.45),d.y-L*Math.sin(v+.45)),a.stroke()};le(S,i),a.strokeStyle=n,a.lineWidth=i,a.lineCap="round",a.lineJoin="round",S()}}});let B=z=>{if(y)return y=!1,T=!1,g=-1,w.classList.remove("bs-grabbing"),w.classList.remove("bs-grab"),N(),void 0;if(!M)return;M=!1;let d=b(z);if(r==="draw"||r==="highlight")k.length>1&&l.push({type:r,color:n,size:i,alpha:r==="highlight"?.25:1,points:[...k]}),k=[];else if(r==="rect")l.push({type:"rect",color:n,size:i,x:R,y:P,w:d.x-R,h:d.y-P});else if(r==="circle"){let v=Math.abs(d.x-R)/2,L=Math.abs(d.y-P)/2;l.push({type:"circle",color:n,size:i,cx:R+(d.x-R)/2,cy:P+(d.y-P)/2,rx:v,ry:L})}else r==="arrow"&&l.push({type:"arrow",color:n,size:i,x1:R,y1:P,x2:d.x,y2:d.y});N()};w.addEventListener("mouseup",B),w.addEventListener("mouseleave",z=>{y?(y=!1,T=!1,w.classList.remove("bs-grabbing"),w.classList.remove("bs-grab"),N()):M&&B(z)});let D=z=>{g>=0&&(z.key==="Delete"||z.key==="Backspace")&&(l.splice(g,1),g=-1,N())};document.addEventListener("keydown",D),Zt.addEventListener("click",()=>{l.length&&(l.pop(),g=-1,N())}),Qt.addEventListener("click",()=>{l.length=0,x.length=0,g=-1,N(),Xe()})};let cn=()=>{for(let o=0;o<x.length;o++){let u=x[o],f=16;a.beginPath(),a.arc(u.x,u.y-f,f,0,Math.PI*2),a.fillStyle=u.color,a.fill(),a.strokeStyle="#fff",a.lineWidth=2,a.stroke(),a.beginPath(),a.moveTo(u.x-8,u.y-6),a.lineTo(u.x,u.y+4),a.lineTo(u.x+8,u.y-6),a.fillStyle=u.color,a.fill(),a.fillStyle="#fff",a.font="bold 14px Inter, sans-serif",a.textAlign="center",a.textBaseline="middle",a.fillText(`${o+1}`,u.x,u.y-f),a.textAlign="start",a.textBaseline="alphabetic"}};return{getAnnotation:()=>{try{return g=-1,N(),cn(),w.toDataURL("image/jpeg",.7)}catch{return null}},getPins:()=>x.map((o,u)=>({number:u+1,x:Math.round(o.x),y:Math.round(o.y),note:o.note}))}}function vt(e){if(!m)return;ke=e,m.querySelectorAll(".bs-tab").forEach(n=>{n.classList.toggle("bs-active",n.dataset.tab===e)});let t=m.querySelector(".bs-scroll"),s={report:Xs,console:Nn,network:Dn,context:jn,history:On,settings:qn};t.innerHTML=s[e](),t.scrollTop=0,Js()}function Js(){if(!m)return;if(ke==="history"){m.querySelectorAll("[data-hist-del]").forEach(s=>{s.addEventListener("click",()=>{let n=parseInt(s.dataset.histDel),r=m.querySelector(`[data-hist-id="${n}"]`);if(!r)return;let i=r.querySelector(".bs-hist-confirm");if(i){i.remove();return}let c=document.createElement("div");c.className="bs-hist-confirm",c.innerHTML="<span>Delete this report?</span>";let p=document.createElement("button");p.type="button",p.className="bs-hist-confirm-yes",p.textContent="Delete";let l=document.createElement("button");l.type="button",l.className="bs-hist-confirm-no",l.textContent="Cancel",p.addEventListener("click",()=>{Rn(n),vt("history")}),l.addEventListener("click",()=>c.remove()),c.appendChild(p),c.appendChild(l),r.appendChild(c)})}),m.querySelectorAll("[data-hist-edit]").forEach(s=>{s.addEventListener("click",()=>{let n=parseInt(s.dataset.histEdit),r=m.querySelector(`[data-hist-id="${n}"]`);if(!r)return;let i=r.querySelector(".bs-hist-edit-wrap");if(i){i.remove();return}r.querySelector(".bs-hist-confirm")?.remove();let c=Le().find(y=>y.id===n);if(!c)return;let p=document.createElement("div");p.className="bs-hist-edit-wrap",p.innerHTML=`
1545
+ <div class="bs-ann-pin-loc">${Math.round(C)}% \xD7 ${Math.round(u)}%</div>
1546
+ </div>`;let q=document.createElement("button");q.type="button",q.className="bs-ann-pin-del",q.innerHTML="&times;",q.title="Remove pin",q.addEventListener("click",()=>{h.splice(m,1),et()}),j.appendChild(q),fe.appendChild(j)})},i,At=()=>d?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.35)",be=(o,m)=>{i.save(),i.strokeStyle=At(),i.lineWidth=m+3,i.lineCap="round",i.lineJoin="round",i.globalAlpha=.5,o(),i.restore()},ps=(o,m=!1)=>{if(o.type==="draw"||o.type==="highlight"){if(o.points.length<2)return;let u=o.type==="highlight"?.25:1,T=o.type==="highlight"?o.size*4+10:o.size,j=()=>{i.beginPath(),i.moveTo(o.points[0].x,o.points[0].y);for(let q=1;q<o.points.length;q++)i.lineTo(o.points[q].x,o.points[q].y);i.stroke()};o.type!=="highlight"&&be(j,T),i.strokeStyle=o.color,i.lineWidth=T,i.lineCap="round",i.lineJoin="round",i.globalAlpha=u,j(),i.globalAlpha=1}else if(o.type==="rect"){let u=()=>i.strokeRect(o.x,o.y,o.w,o.h);be(u,o.size),i.strokeStyle=o.color,i.lineWidth=o.size,i.lineCap="round",i.lineJoin="round",u()}else if(o.type==="circle"){let u=()=>{i.beginPath(),i.ellipse(o.cx,o.cy,Math.abs(o.rx),Math.abs(o.ry),0,0,Math.PI*2),i.stroke()};be(u,o.size),i.strokeStyle=o.color,i.lineWidth=o.size,u()}else if(o.type==="arrow"){let u=Math.atan2(o.y2-o.y1,o.x2-o.x1),T=12+o.size*2,j=()=>{i.beginPath(),i.moveTo(o.x1,o.y1),i.lineTo(o.x2,o.y2),i.stroke(),i.beginPath(),i.moveTo(o.x2,o.y2),i.lineTo(o.x2-T*Math.cos(u-.45),o.y2-T*Math.sin(u-.45)),i.moveTo(o.x2,o.y2),i.lineTo(o.x2-T*Math.cos(u+.45),o.y2-T*Math.sin(u+.45)),i.stroke()};be(j,o.size),i.strokeStyle=o.color,i.lineWidth=o.size,i.lineCap="round",i.lineJoin="round",j()}else if(o.type==="text"){let u=o.size*5+12;i.font=`bold ${u}px Inter, -apple-system, sans-serif`,i.fillStyle=At(),i.globalAlpha=.6,i.fillText(o.text,o.x+1,o.y+1),i.globalAlpha=1,i.fillStyle=o.color,i.fillText(o.text,o.x,o.y)}let g=!m&&p>=0&&c[p]===o,C=!m&&!g&&v>=0&&c[v]===o;if(g||C){let u=Ae(o);if(i.save(),i.setLineDash([6,4]),i.strokeStyle=d?"#fff":"#000",i.lineWidth=g?1.5:1,i.globalAlpha=g?.7:.45,i.strokeRect(u.x-4,u.y-4,u.w+8,u.h+8),o.type==="rect"||o.type==="circle"){i.setLineDash([]),i.globalAlpha=g?.9:.6;let j=o.type==="rect"?[[u.x,u.y],[u.x+u.w,u.y],[u.x,u.y+u.h],[u.x+u.w,u.y+u.h]]:[[u.x+u.w/2,u.y],[u.x+u.w,u.y+u.h/2],[u.x+u.w/2,u.y+u.h],[u.x,u.y+u.h/2]];for(let[q,z]of j)i.fillStyle="#fff",i.fillRect(q-5,z-5,10,10),i.strokeStyle=d?"#aaa":"#333",i.lineWidth=1.2,i.strokeRect(q-5,z-5,10,10)}i.restore()}},O=()=>{i.clearRect(0,0,y.width,y.height),i.drawImage(le,0,0);for(let o of c)ps(o)},Ae=o=>{if(o.type==="rect")return{x:Math.min(o.x,o.x+o.w),y:Math.min(o.y,o.y+o.h),w:Math.abs(o.w),h:Math.abs(o.h)};if(o.type==="circle")return{x:o.cx-Math.abs(o.rx),y:o.cy-Math.abs(o.ry),w:Math.abs(o.rx)*2,h:Math.abs(o.ry)*2};if(o.type==="arrow"){let T=Math.min(o.x1,o.x2),j=Math.min(o.y1,o.y2);return{x:T,y:j,w:Math.abs(o.x2-o.x1)||20,h:Math.abs(o.y2-o.y1)||20}}if(o.type==="text")return{x:o.x,y:o.y-(o.size*5+12),w:o.text.length*(o.size*3+8),h:o.size*5+16};if(o.points.length===0)return{x:0,y:0,w:0,h:0};let m=1/0,g=1/0,C=-1/0,u=-1/0;for(let T of o.points)m=Math.min(m,T.x),g=Math.min(g,T.y),C=Math.max(C,T.x),u=Math.max(u,T.y);return{x:m,y:g,w:C-m||10,h:u-g||10}},tt=(o,m)=>{for(let g=c.length-1;g>=0;g--){let C=Ae(c[g]),u=8;if(o>=C.x-u&&o<=C.x+C.w+u&&m>=C.y-u&&m<=C.y+C.h+u)return g}return-1},bs=(o,m,g)=>{if(o.type==="draw"||o.type==="highlight")for(let C of o.points)C.x+=m,C.y+=g;else o.type==="rect"?(o.x+=m,o.y+=g):o.type==="circle"?(o.cx+=m,o.cy+=g):o.type==="arrow"?(o.x1+=m,o.y1+=g,o.x2+=m,o.y2+=g):o.type==="text"&&(o.x+=m,o.y+=g)};le.onload=()=>{let m=(e.clientWidth||450)/le.width;y.width=le.width,y.height=le.height,y.style.height=`${le.height*m}px`,i=y.getContext("2d"),i.drawImage(le,0,0);let g=[[10,10],[y.width-10,10],[10,y.height-10],[y.width-10,y.height-10],[y.width/2,y.height/2]],C=0;for(let[z,b]of g){let x=i.getImageData(z,b,1,1).data;C+=(x[0]*299+x[1]*587+x[2]*114)/1e3}d=C/g.length<128;let u=z=>{let b=y.getBoundingClientRect();return{x:(z.clientX-b.left)*(y.width/b.width),y:(z.clientY-b.top)*(y.height/b.height)}},T=!1;y.addEventListener("mousedown",z=>{let b=u(z);if(r==="select"){let x=tt(b.x,b.y);if(x>=0){p=x,w=!0;let L=Ae(c[x]);ie=b.x-L.x,Me=b.y-L.y,y.classList.add("bs-grabbing"),y.classList.remove("bs-grab"),O()}else p=-1,O();return}if(r!=="pin"&&r!=="text"){let x=tt(b.x,b.y);if(x>=0){p=x,w=!0,T=!0;let L=Ae(c[x]);ie=b.x-L.x,Me=b.y-L.y,y.classList.add("bs-grabbing"),O();return}}if(M=!0,R=b.x,P=b.y,r==="pin"){M=!1;let x=prompt("Describe the issue at this spot:");if(x){let L=Jt[h.length%Jt.length];h.push({x:b.x,y:b.y,note:x,color:L}),et()}return}if(r==="text"){M=!1;let x=prompt("Enter text:");x&&(c.push({type:"text",color:s,size:a,x:b.x,y:b.y,text:x}),O());return}(r==="draw"||r==="highlight")&&(k=[{x:b.x,y:b.y}])}),y.addEventListener("mousemove",z=>{let b=u(z);if(w&&p>=0){let x=Ae(c[p]),L=b.x-ie-x.x,S=b.y-Me-x.y;bs(c[p],L,S),O();return}if(r==="select"){let x=tt(b.x,b.y);y.classList.toggle("bs-grab",x>=0),v!==x&&(v=x,O());return}if(r!=="pin"&&r!=="text"&&!M){let x=tt(b.x,b.y);y.classList.toggle("bs-grab",x>=0),v!==x&&(v=x,O())}if(M){if(r==="draw"||r==="highlight"){k.push({x:b.x,y:b.y}),O();let x=r==="highlight"?.25:1,L=r==="highlight"?a*4+10:a;if(r!=="highlight"){i.save(),i.strokeStyle=At(),i.lineWidth=L+3,i.lineCap="round",i.lineJoin="round",i.globalAlpha=.5,i.beginPath(),i.moveTo(k[0].x,k[0].y);for(let S=1;S<k.length;S++)i.lineTo(k[S].x,k[S].y);i.stroke(),i.restore()}i.strokeStyle=s,i.lineWidth=L,i.lineCap="round",i.lineJoin="round",i.globalAlpha=x,i.beginPath(),i.moveTo(k[0].x,k[0].y);for(let S=1;S<k.length;S++)i.lineTo(k[S].x,k[S].y);i.stroke(),i.globalAlpha=1}else if(O(),i.strokeStyle=s,i.lineWidth=a,i.lineCap="round",i.lineJoin="round",r==="rect")be(()=>i.strokeRect(R,P,b.x-R,b.y-P),a),i.strokeStyle=s,i.lineWidth=a,i.strokeRect(R,P,b.x-R,b.y-P);else if(r==="circle"){let x=Math.abs(b.x-R)/2,L=Math.abs(b.y-P)/2,S=R+(b.x-R)/2,nn=P+(b.y-P)/2;be(()=>{i.beginPath(),i.ellipse(S,nn,x,L,0,0,Math.PI*2),i.stroke()},a),i.strokeStyle=s,i.lineWidth=a,i.beginPath(),i.ellipse(S,nn,x,L,0,0,Math.PI*2),i.stroke()}else if(r==="arrow"){let x=Math.atan2(b.y-P,b.x-R),L=12+a*2,S=()=>{i.beginPath(),i.moveTo(R,P),i.lineTo(b.x,b.y),i.stroke(),i.beginPath(),i.moveTo(b.x,b.y),i.lineTo(b.x-L*Math.cos(x-.45),b.y-L*Math.sin(x-.45)),i.moveTo(b.x,b.y),i.lineTo(b.x-L*Math.cos(x+.45),b.y-L*Math.sin(x+.45)),i.stroke()};be(S,a),i.strokeStyle=s,i.lineWidth=a,i.lineCap="round",i.lineJoin="round",S()}}});let j=z=>{if(w)return w=!1,T=!1,p=-1,y.classList.remove("bs-grabbing"),y.classList.remove("bs-grab"),O(),void 0;if(!M)return;M=!1;let b=u(z);if(r==="draw"||r==="highlight")k.length>1&&c.push({type:r,color:s,size:a,alpha:r==="highlight"?.25:1,points:[...k]}),k=[];else if(r==="rect")c.push({type:"rect",color:s,size:a,x:R,y:P,w:b.x-R,h:b.y-P});else if(r==="circle"){let x=Math.abs(b.x-R)/2,L=Math.abs(b.y-P)/2;c.push({type:"circle",color:s,size:a,cx:R+(b.x-R)/2,cy:P+(b.y-P)/2,rx:x,ry:L})}else r==="arrow"&&c.push({type:"arrow",color:s,size:a,x1:R,y1:P,x2:b.x,y2:b.y});O()};y.addEventListener("mouseup",j),y.addEventListener("mouseleave",z=>{w?(w=!1,T=!1,y.classList.remove("bs-grabbing"),y.classList.remove("bs-grab"),O()):M&&j(z)});let q=z=>{p>=0&&(z.key==="Delete"||z.key==="Backspace")&&(c.splice(p,1),p=-1,O())};document.addEventListener("keydown",q),en.addEventListener("click",()=>{c.length&&(c.pop(),p=-1,O())}),tn.addEventListener("click",()=>{c.length=0,h.length=0,p=-1,O(),et()})};let us=()=>{for(let o=0;o<h.length;o++){let m=h[o],g=16;i.beginPath(),i.arc(m.x,m.y-g,g,0,Math.PI*2),i.fillStyle=m.color,i.fill(),i.strokeStyle="#fff",i.lineWidth=2,i.stroke(),i.beginPath(),i.moveTo(m.x-8,m.y-6),i.lineTo(m.x,m.y+4),i.lineTo(m.x+8,m.y-6),i.fillStyle=m.color,i.fill(),i.fillStyle="#fff",i.font="bold 14px Inter, sans-serif",i.textAlign="center",i.textBaseline="middle",i.fillText(`${o+1}`,m.x,m.y-g),i.textAlign="start",i.textBaseline="alphabetic"}};return{getAnnotation:()=>{try{return p=-1,O(),us(),y.toDataURL("image/jpeg",.7)}catch{return null}},getPins:()=>h.map((o,m)=>({number:m+1,x:Math.round(o.x),y:Math.round(o.y),note:o.note}))}}function kt(e){if(!f)return;Ce=e,f.querySelectorAll(".bs-tab").forEach(s=>{s.classList.toggle("bs-active",s.dataset.tab===e)});let t=f.querySelector(".bs-scroll"),n={report:Zn,console:_s,network:Ws,context:Fs,history:Ys,settings:Xs};t.innerHTML=n[e](),t.scrollTop=0,Gn()}function Gn(){if(!f)return;if(Ce==="history"){f.querySelectorAll("[data-hist-del]").forEach(n=>{n.addEventListener("click",()=>{let s=parseInt(n.dataset.histDel),r=f.querySelector(`[data-hist-id="${s}"]`);if(!r)return;let a=r.querySelector(".bs-hist-confirm");if(a){a.remove();return}let l=document.createElement("div");l.className="bs-hist-confirm",l.innerHTML="<span>Delete this report?</span>";let d=document.createElement("button");d.type="button",d.className="bs-hist-confirm-yes",d.textContent="Delete";let c=document.createElement("button");c.type="button",c.className="bs-hist-confirm-no",c.textContent="Cancel",d.addEventListener("click",()=>{qs(s),kt("history")}),c.addEventListener("click",()=>l.remove()),l.appendChild(d),l.appendChild(c),r.appendChild(l)})}),f.querySelectorAll("[data-hist-edit]").forEach(n=>{n.addEventListener("click",()=>{let s=parseInt(n.dataset.histEdit),r=f.querySelector(`[data-hist-id="${s}"]`);if(!r)return;let a=r.querySelector(".bs-hist-edit-wrap");if(a){a.remove();return}r.querySelector(".bs-hist-confirm")?.remove();let l=Te().find(w=>w.id===s);if(!l)return;let d=document.createElement("div");d.className="bs-hist-edit-wrap",d.innerHTML=`
1684
1547
  <div class="bs-field" style="margin-bottom:8px">
1685
- <input class="bs-input" data-edit-title value="${I(c.title)}" />
1548
+ <input class="bs-input" data-edit-title value="${I(l.title)}" />
1686
1549
  </div>
1687
1550
  <div class="bs-field" style="margin-bottom:8px">
1688
- <textarea class="bs-textarea" data-edit-desc style="min-height:56px">${I(c.description)}</textarea>
1551
+ <textarea class="bs-textarea" data-edit-desc style="min-height:56px">${I(l.description)}</textarea>
1689
1552
  </div>
1690
1553
  <div class="bs-field" style="margin-bottom:8px">
1691
1554
  <div class="bs-sev-row">
1692
- <button type="button" class="bs-sev-btn bs-sev-low${c.severity==="low"?" bs-picked":""}" data-edit-sev="low">Low</button>
1693
- <button type="button" class="bs-sev-btn bs-sev-medium${c.severity==="medium"?" bs-picked":""}" data-edit-sev="medium">Medium</button>
1694
- <button type="button" class="bs-sev-btn bs-sev-high${c.severity==="high"?" bs-picked":""}" data-edit-sev="high">High</button>
1695
- <button type="button" class="bs-sev-btn bs-sev-critical${c.severity==="critical"?" bs-picked":""}" data-edit-sev="critical">Critical</button>
1555
+ <button type="button" class="bs-sev-btn bs-sev-low${l.severity==="low"?" bs-picked":""}" data-edit-sev="low">Low</button>
1556
+ <button type="button" class="bs-sev-btn bs-sev-medium${l.severity==="medium"?" bs-picked":""}" data-edit-sev="medium">Medium</button>
1557
+ <button type="button" class="bs-sev-btn bs-sev-high${l.severity==="high"?" bs-picked":""}" data-edit-sev="high">High</button>
1558
+ <button type="button" class="bs-sev-btn bs-sev-critical${l.severity==="critical"?" bs-picked":""}" data-edit-sev="critical">Critical</button>
1696
1559
  </div>
1697
1560
  </div>
1698
- <div class="bs-hist-edit-row"></div>`;let l=c.severity;r.appendChild(p),p.querySelectorAll("[data-edit-sev]").forEach(y=>{y.addEventListener("click",()=>{l=y.dataset.editSev,p.querySelectorAll(".bs-sev-btn").forEach(M=>M.classList.remove("bs-picked")),y.classList.add("bs-picked")})});let x=p.querySelector(".bs-hist-edit-row"),g=document.createElement("button");g.type="button",g.className="bs-hist-save",g.textContent="Save";let h=document.createElement("button");h.type="button",h.className="bs-hist-cancel",h.textContent="Cancel",g.addEventListener("click",()=>{let y=p.querySelector("[data-edit-title]").value.trim(),M=p.querySelector("[data-edit-desc]").value.trim();y&&(Bn(n,{title:y,description:M,severity:l}),vt("history"))}),h.addEventListener("click",()=>p.remove()),x.appendChild(g),x.appendChild(h)})});return}if(ke==="settings"){m.querySelectorAll("[data-set-theme]").forEach(s=>{s.addEventListener("click",()=>{let n=s.dataset.setTheme;_t(n),m.querySelectorAll("[data-set-theme]").forEach(r=>r.classList.remove("bs-picked")),s.classList.add("bs-picked")})}),m.querySelectorAll("[data-set-layout]").forEach(s=>{s.addEventListener("click",()=>{let n=s.dataset.setLayout,r=De(n);r&&(de=r,Y(),setTimeout(()=>{ke="settings",Ee(),setTimeout(()=>vt("settings"),50)},400))})});return}if(ke!=="report")return;m.querySelectorAll(".bs-cat-btn").forEach(s=>{s.addEventListener("click",()=>{let n=s.dataset.cat;m.querySelector('input[name="category"]').value=n,m.querySelectorAll(".bs-cat-btn").forEach(r=>r.classList.remove("bs-picked")),s.classList.add("bs-picked")})}),m.querySelectorAll(".bs-sev-btn").forEach(s=>{s.addEventListener("click",()=>{let n=s.dataset.sev;m.querySelector('input[name="severity"]').value=n,m.querySelectorAll(".bs-sev-btn").forEach(r=>r.classList.remove("bs-picked")),s.classList.add("bs-picked")})});let e=null,t=null;m.querySelector("[data-bs-screenshot]")?.addEventListener("click",async()=>{let s=m?.querySelector("[data-bs-shot-title]"),n=m?.querySelector("[data-bs-shot-sub]"),r=m?.querySelector("[data-bs-screenshot]");if(s&&(s.textContent="Capturing..."),m&&(m.style.visibility="hidden"),F&&(F.style.visibility="hidden"),await new Promise(i=>setTimeout(i,200)),e=await ot(),m&&(m.style.visibility=""),F&&(F.style.visibility=""),e){s&&(s.textContent="Screenshot captured!"),n&&(n.textContent="Draw on the image below to highlight the issue"),r?.classList.add("bs-captured");let i=m?.querySelector("[data-bs-annotate]");i&&(t=Un(i,e))}else s&&(s.textContent="Screenshot unavailable"),n&&(n.textContent="Could not capture screenshot on this page")}),m.querySelector("[data-bs-form]")?.addEventListener("submit",async s=>{s.preventDefault();let n=s.target,r=n.querySelector(".bs-submit-btn"),i=n.querySelector("[data-bs-msg]"),c=n.elements.namedItem("title").value.trim(),p=n.elements.namedItem("description").value.trim(),l=n.elements.namedItem("severity").value,x=n.elements.namedItem("category").value;if(!c)return;r.disabled=!0,r.textContent="Sending...";let g=Ys(),h={projectId:W.projectId,title:c,description:p,category:x,severity:l,tags:g.tags.length?g.tags:void 0,context:Ws(),consoleLogs:G(),errors:ee(),networkCaptures:ae(),breadcrumbs:ue(),performance:he()??void 0,screenshot:e??void 0,annotation:t?.getAnnotation()??void 0,pins:t?.getPins().length?t.getPins():void 0,createdAt:Date.now()},y=await Rt(h);Hn({title:h.title,description:h.description,category:h.category,severity:h.severity,tags:h.tags,screenshot:h.screenshot,pins:h.pins,url:window.location.href,createdAt:h.createdAt,status:y.success?"sent":"draft"}),y.success?(i.className="bs-msg bs-msg-ok",i.innerHTML=`${V.check} Bug reported \u2014 thank you!`,setTimeout(Y,1200)):(i.className="bs-msg bs-msg-err",i.textContent=y.error??"Could not send. Saved as draft.",r.disabled=!1,r.textContent="Submit Report")})}function Ee(){if(be)return;be=!0,ke="report",F=document.createElement("div"),F.className="bs-backdrop",document.body.appendChild(F);let e=ae().length,t=ee().length;m=document.createElement("div"),m.className=`bs-modal bs-ly-${de.id}`,yt(m);let s=`
1561
+ <div class="bs-hist-edit-row"></div>`;let c=l.severity;r.appendChild(d),d.querySelectorAll("[data-edit-sev]").forEach(w=>{w.addEventListener("click",()=>{c=w.dataset.editSev,d.querySelectorAll(".bs-sev-btn").forEach(M=>M.classList.remove("bs-picked")),w.classList.add("bs-picked")})});let h=d.querySelector(".bs-hist-edit-row"),p=document.createElement("button");p.type="button",p.className="bs-hist-save",p.textContent="Save";let v=document.createElement("button");v.type="button",v.className="bs-hist-cancel",v.textContent="Cancel",p.addEventListener("click",()=>{let w=d.querySelector("[data-edit-title]").value.trim(),M=d.querySelector("[data-edit-desc]").value.trim();w&&(Us(s,{title:w,description:M,severity:c}),kt("history"))}),v.addEventListener("click",()=>d.remove()),h.appendChild(p),h.appendChild(v)})});return}if(Ce==="settings"){f.querySelectorAll("[data-set-theme]").forEach(n=>{n.addEventListener("click",()=>{let s=n.dataset.setTheme;Lt(s),f.querySelectorAll("[data-set-theme]").forEach(r=>r.classList.remove("bs-picked")),n.classList.add("bs-picked")})}),f.querySelectorAll("[data-set-layout]").forEach(n=>{n.addEventListener("click",()=>{let s=n.dataset.setLayout,r=Ue(s);r&&(me=r,K(),setTimeout(()=>{Ce="settings",oe(),setTimeout(()=>kt("settings"),50)},400))})});return}if(Ce!=="report")return;f.querySelectorAll(".bs-cat-btn").forEach(n=>{n.addEventListener("click",()=>{let s=n.dataset.cat;f.querySelector('input[name="category"]').value=s,f.querySelectorAll(".bs-cat-btn").forEach(r=>r.classList.remove("bs-picked")),n.classList.add("bs-picked")})}),f.querySelectorAll(".bs-sev-btn").forEach(n=>{n.addEventListener("click",()=>{let s=n.dataset.sev;f.querySelector('input[name="severity"]').value=s,f.querySelectorAll(".bs-sev-btn").forEach(r=>r.classList.remove("bs-picked")),n.classList.add("bs-picked")})});let e=null,t=null;f.querySelector("[data-bs-screenshot]")?.addEventListener("click",async()=>{let n=f?.querySelector("[data-bs-shot-title]"),s=f?.querySelector("[data-bs-shot-sub]"),r=f?.querySelector("[data-bs-screenshot]");if(n&&(n.textContent="Capturing..."),f&&(f.style.visibility="hidden"),X&&(X.style.visibility="hidden"),await new Promise(a=>setTimeout(a,200)),e=await qe(),f&&(f.style.visibility=""),X&&(X.style.visibility=""),e){n&&(n.textContent="Screenshot captured!"),s&&(s.textContent="Draw on the image below to highlight the issue"),r?.classList.add("bs-captured");let a=f?.querySelector("[data-bs-annotate]");a&&(t=Js(a,e))}else n&&(n.textContent="Screenshot unavailable"),s&&(s.textContent="Could not capture screenshot on this page")}),f.querySelector("[data-bs-form]")?.addEventListener("submit",async n=>{n.preventDefault();let s=n.target,r=s.querySelector(".bs-submit-btn"),a=s.elements.namedItem("title").value.trim(),l=s.elements.namedItem("description").value.trim(),d=s.elements.namedItem("severity").value,c=s.elements.namedItem("category").value;if(!a)return;r.disabled=!0,r.textContent="Sending...";let h=Qn(),p={projectId:F.projectId,title:a,description:l,category:c,severity:d,tags:h.tags.length?h.tags:void 0,context:Vn(),consoleLogs:te(),errors:ne(),networkCaptures:ce(),breadcrumbs:he(),performance:we()??void 0,screenshot:e??void 0,annotation:t?.getAnnotation()??void 0,pins:t?.getPins().length?t.getPins():void 0,createdAt:Date.now()},v=await Dt(p);Os({title:p.title,description:p.description,category:p.category,severity:p.severity,tags:p.tags,screenshot:p.screenshot,pins:p.pins,url:window.location.href,createdAt:p.createdAt,status:v.success?"sent":"draft"}),v.success?(r.innerHTML=`${N.check} Bug reported!`,r.classList.add("bs-submit-ok"),setTimeout(K,1200)):(r.textContent=v.error??"Failed \u2014 saved as draft",r.classList.add("bs-submit-err"),setTimeout(()=>{r.disabled=!1,r.textContent="Submit Report",r.classList.remove("bs-submit-err")},2500))})}function oe(){if(J)return;J=!0,Ce="report",Ft(),X=document.createElement("div"),X.className="bs-backdrop",document.body.appendChild(X);let e=ce().length,t=ne().length;f=document.createElement("div"),f.className=`bs-modal bs-ly-${me.id}`,ge(f);let n=`
1699
1562
  <div class="bs-tabs">
1700
- <button class="bs-tab bs-active" data-tab="report">${V.report} Report</button>
1701
- <button class="bs-tab" data-tab="console">${V.console} Console <span class="bs-tab-badge">${G().length}</span></button>
1702
- <button class="bs-tab" data-tab="network">${V.network} Network ${e?`<span class="bs-tab-badge bs-warn">${e}</span>`:`<span class="bs-tab-badge">${me().length}</span>`}</button>
1703
- <button class="bs-tab" data-tab="context">${V.ctx} Context ${t?`<span class="bs-tab-badge bs-warn">${t}</span>`:""}</button>
1704
- <button class="bs-tab" data-tab="history">${V.history} History <span class="bs-tab-badge">${Le().length}</span></button>
1705
- <button class="bs-tab" data-tab="settings" style="margin-left:auto">${V.settings}</button>
1706
- </div>`,n=J(),r=n?n.name.split(" ").map(h=>h[0]).join("").toUpperCase().slice(0,2):"",i=xt(),c=`
1563
+ <button class="bs-tab bs-active" data-tab="report">${N.report} Report</button>
1564
+ <button class="bs-tab" data-tab="console">${N.console} Console <span class="bs-tab-badge">${te().length}</span></button>
1565
+ <button class="bs-tab" data-tab="network">${N.network} Network ${e?`<span class="bs-tab-badge bs-warn">${e}</span>`:`<span class="bs-tab-badge">${ye().length}</span>`}</button>
1566
+ <button class="bs-tab" data-tab="context">${N.ctx} Context ${t?`<span class="bs-tab-badge bs-warn">${t}</span>`:""}</button>
1567
+ <button class="bs-tab" data-tab="history">${N.history} History <span class="bs-tab-badge">${Te().length}</span></button>
1568
+ <button class="bs-tab" data-tab="settings" style="margin-left:auto">${N.settings}</button>
1569
+ </div>`,s=V(),r=s?s.name.split(" ").map(v=>v[0]).join("").toUpperCase().slice(0,2):"",a=wt(),l=s?`
1707
1570
  <div class="bs-hdr">
1708
1571
  <div class="bs-logo">BugStash</div>
1709
1572
  <div class="bs-hdr-right">
1710
- ${n?`
1711
- <button class="bs-pin-toggle${i?" active":""}" data-bs-pin-toggle title="Toggle pin mode">
1712
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
1713
- Pins ${i?"ON":"OFF"}
1714
- </button>
1715
- <div class="bs-user-badge">
1716
- <div class="bs-user-avatar">${r}</div>
1717
- <span>${n.name.split(" ")[0]}</span>
1718
- </div>
1719
- <button class="bs-login-logout" data-bs-logout title="Sign out">Logout</button>
1720
- `:""}
1721
- <button class="bs-close-btn" data-bs-close title="Close">${V.x}</button>
1573
+ <button class="bs-pin-toggle${a?" active":""}" data-bs-pin-toggle title="Toggle pin mode">
1574
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
1575
+ Pins ${a?"ON":"OFF"}
1576
+ </button>
1577
+ <div class="bs-user-badge">
1578
+ <div class="bs-user-avatar">${r}</div>
1579
+ <span>${s.name.split(" ")[0]}</span>
1580
+ </div>
1581
+ <button class="bs-login-logout" data-bs-logout title="Sign out">Logout</button>
1582
+ <button class="bs-close-btn" data-bs-close title="Close">${N.x}</button>
1722
1583
  </div>
1723
- </div>`,p=de.tabPosition==="left",l=de.tabPosition==="bottom",x=n?Xs():An();p?m.innerHTML=`
1724
- ${c}
1584
+ </div>`:`
1585
+ <div class="bs-hdr" style="justify-content:flex-end">
1586
+ <button class="bs-close-btn" data-bs-close title="Close">${N.x}</button>
1587
+ </div>`,d=me.tabPosition==="left",c=me.tabPosition==="bottom",h=s?Zn():Ds();d?f.innerHTML=`
1588
+ ${l}
1725
1589
  <div class="bs-body-wrap">
1726
- ${n?s:""}
1727
- <div class="bs-scroll">${x}</div>
1728
- </div>`:l?m.innerHTML=`
1729
- ${c}
1730
- <div class="bs-scroll">${x}</div>
1731
- ${n?`<div class="bs-tab-divider"></div>${s}`:""}`:m.innerHTML=`
1732
- ${c}
1733
- ${n?`${s}<div class="bs-tab-divider"></div>`:""}
1734
- <div class="bs-scroll">${x}</div>`,document.body.appendChild(m),O&&O.classList.add("bs-open"),requestAnimationFrame(()=>{F?.classList.add("bs-in"),m?.classList.add("bs-in")}),m.querySelectorAll(".bs-tab").forEach(h=>{h.addEventListener("click",()=>vt(h.dataset.tab))}),m.querySelector("[data-bs-close]")?.addEventListener("click",Y),F.addEventListener("click",Y),m.querySelector("[data-bs-pin-toggle]")?.addEventListener("click",()=>{let h=ht(),y=m?.querySelector("[data-bs-pin-toggle]");y&&(y.classList.toggle("active",h),y.innerHTML=`
1590
+ ${s?n:""}
1591
+ <div class="bs-scroll">${h}</div>
1592
+ </div>`:c?f.innerHTML=`
1593
+ ${l}
1594
+ <div class="bs-scroll">${h}</div>
1595
+ ${s?`<div class="bs-tab-divider"></div>${n}`:""}`:f.innerHTML=`
1596
+ ${l}
1597
+ ${s?`${n}<div class="bs-tab-divider"></div>`:""}
1598
+ <div class="bs-scroll">${h}</div>`,document.body.appendChild(f),D&&D.classList.add("bs-open"),requestAnimationFrame(()=>{X?.classList.add("bs-in"),f?.classList.add("bs-in")}),f.querySelectorAll(".bs-tab").forEach(v=>{v.addEventListener("click",()=>kt(v.dataset.tab))}),f.querySelector("[data-bs-close]")?.addEventListener("click",K),X.addEventListener("click",K),f.querySelector("[data-bs-pin-toggle]")?.addEventListener("click",()=>{let v=Xe(),w=f?.querySelector("[data-bs-pin-toggle]");w&&(w.classList.toggle("active",v),w.innerHTML=`
1735
1599
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
1736
- Pins ${h?"ON":"OFF"}
1737
- `)}),m.querySelector("[data-bs-logout]")?.addEventListener("click",()=>{it(),Y(),setTimeout(()=>Ee(),300)}),n?Js():_n();let g=h=>{h.key==="Escape"&&(Y(),document.removeEventListener("keydown",g))};document.addEventListener("keydown",g)}function _n(){if(!m)return;let e=m.querySelector("#bs-login-submit"),t=m.querySelector("#bs-login-email"),s=m.querySelector("#bs-login-pass"),n=m.querySelector("#bs-login-error");if(!e||!t||!s)return;let r=async()=>{let i=t.value.trim(),c=s.value;if(!i||!c){n.textContent="Please enter email and password",n.style.display="block";return}e.setAttribute("disabled","true"),e.textContent="Signing in...",n.style.display="none";let p=await at(i,c,W.projectId);p.success?(mt(W.projectId),ft(W.projectId),Y(),setTimeout(()=>Ee(),300)):(n.textContent=p.error||"Invalid credentials",n.style.display="block",e.removeAttribute("disabled"),e.textContent="Sign In")};e.addEventListener("click",r),s.addEventListener("keydown",i=>{i.key==="Enter"&&r()}),t.addEventListener("keydown",i=>{i.key==="Enter"&&s.focus()}),setTimeout(()=>t.focus(),100)}function Y(){be&&(O&&O.classList.remove("bs-open"),m&&(m.classList.remove("bs-in"),m.classList.add("bs-out")),F&&F.classList.remove("bs-in"),setTimeout(()=>{m?.remove(),F?.remove(),m=null,F=null,be=!1},350))}function yt(e){for(let[t,s]of Object.entries(wt.vars))e.style.setProperty(t,s)}function _t(e){let t=dt(e);t&&(wt=t,m&&yt(m),O&&yt(O))}function Vs(){return wt.id}function Ks(e){let t=De(e);t&&(de=t,be&&(Y(),setTimeout(Ee,400)))}function Zs(){return de.id}function Qs(e){W=e,qe=document.createElement("style"),qe.textContent=zn+zs,document.head.appendChild(qe),O=document.createElement("button"),O.className="bs-fab",yt(O),O.innerHTML=`${V.bug}<span class="bs-fab-label">Report a bug</span>`,O.style[e.panelPosition==="bottom-left"?"left":"right"]="24px",O.addEventListener("click",()=>be?Y():Ee()),document.body.appendChild(O),Ue=t=>{(t.ctrlKey||t.metaKey)&&t.shiftKey&&t.key==="B"&&(t.preventDefault(),be?Y():Ee())},document.addEventListener("keydown",Ue)}function Gs(){Y(),O?.remove(),O=null,qe?.remove(),qe=null,Ue&&document.removeEventListener("keydown",Ue),Ue=null}var K=null,H=null,E=null,ne=null,kt="freehand",Et="#ef4444",Fn=3,Se=[],_=null,_e=!1,Lt=null,Wn=[{id:"freehand",label:"Draw",icon:"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25z"},{id:"rectangle",label:"Rect",icon:"M3 3h18v18H3V3zm2 2v14h14V5H5z"},{id:"circle",label:"Circle",icon:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"},{id:"arrow",label:"Arrow",icon:"M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"}],Yn=["#ef4444","#f97316","#eab308","#22c55e","#3b82f6","#8b5cf6","#ffffff","#000000"];function sn(e){return new Promise(t=>{Lt=t,Se=[],_=null,kt="freehand",Et="#ef4444",Xn(e)})}function Xn(e){K&&K.remove(),K=document.createElement("div"),K.id="bs-annotation-overlay";let t=document.createElement("style");t.textContent=`
1600
+ Pins ${v?"ON":"OFF"}
1601
+ `)}),f.querySelector("[data-bs-logout]")?.addEventListener("click",()=>{ut(),K(),setTimeout(()=>oe(),300)}),s?Gn():Ks();let p=v=>{v.key==="Escape"&&(K(),document.removeEventListener("keydown",p))};document.addEventListener("keydown",p)}function Ks(){if(!f)return;let e=f.querySelector("#bs-login-submit"),t=f.querySelector("#bs-login-email"),n=f.querySelector("#bs-login-pass"),s=f.querySelector("#bs-login-error");if(!e||!t||!n)return;let r=async()=>{let a=t.value.trim(),l=n.value;if(!a||!l){s.textContent="Please enter email and password",s.style.display="block";return}e.setAttribute("disabled","true"),e.textContent="Signing in...",s.style.display="none";let d=await bt(a,l,F.projectId);d.success?(Ye(F.projectId),_e(F.projectId),K(),setTimeout(()=>oe(),300)):(s.textContent=d.error||"Invalid credentials",s.style.display="block",e.removeAttribute("disabled"),e.textContent="Sign In")};e.addEventListener("click",r),n.addEventListener("keydown",a=>{a.key==="Enter"&&r()}),t.addEventListener("keydown",a=>{a.key==="Enter"&&n.focus()}),setTimeout(()=>t.focus(),100)}function K(){J&&(D&&D.classList.remove("bs-open"),f&&(f.classList.remove("bs-in"),f.classList.add("bs-out")),X&&X.classList.remove("bs-in"),setTimeout(()=>{f?.remove(),X?.remove(),f=null,X=null,J=!1},350))}function ge(e){for(let[t,n]of Object.entries(pe.vars))e.style.setProperty(t,n)}function Lt(e){let t=ft(e);t&&(pe=t,f&&ge(f),D&&ge(D),B&&ge(B))}function es(){return pe.id}function ts(e){let t=Ue(e);t&&(me=t,J&&(K(),setTimeout(oe,400)))}function ns(){return me.id}function ss(e){F=e,Je=document.createElement("style"),Je.textContent=Ns+Rn,document.head.appendChild(Je);let t=e.panelPosition==="bottom-left"?"left":"right";D=document.createElement("button"),D.className="bs-fab",ge(D),D.innerHTML=`${N.bug}<span class="bs-fab-label">Report a bug</span>`,D.style[t]="24px",D.addEventListener("click",()=>J?K():oe()),document.body.appendChild(D),B=document.createElement("div"),B.className="bs-toolbar",B.style[t]="32px",ge(B);let s=navigator.platform.toUpperCase().includes("MAC")?"\u2318":"Ctrl",r=[{icon:N.cam,tip:"Screenshot",kbd:`${s}+Shift+S`,action:async()=>{let a=await qe();a&&(J||oe(),setTimeout(()=>{let l=f?.querySelector("[data-bs-screenshot]");if(l){l.__screenshot=a,l.classList.add("bs-captured");let d=l.querySelector("[data-bs-shot-title]"),c=l.querySelector("[data-bs-shot-sub]");d&&(d.textContent="Screenshot captured!"),c&&(c.textContent="Click to retake or annotate"),l.click()}},400))}},{icon:N.pin,tip:"Toggle Pins",kbd:`${s}+Shift+P`,id:"bs-tb-pin",action:()=>{if(!V()){J||oe();return}document.getElementById("bugstash-live-pins")||(Ye(F.projectId),_e(F.projectId));let l=Xe(),d=B?.querySelector("#bs-tb-pin");d&&d.classList.toggle("bs-active",l);let c=f?.querySelector("[data-bs-pin-toggle]");c&&(c.classList.toggle("active",l),c.innerHTML=`
1602
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>
1603
+ Pins ${l?"ON":"OFF"}
1604
+ `)}},{icon:pe.id==="black"?N.sun:N.moon,tip:"Toggle Theme",kbd:`${s}+Shift+T`,id:"bs-tb-theme",action:()=>{let a=pe.id==="black"?"white":"black";Lt(a),B&&ge(B);let l=B?.querySelector("#bs-tb-theme");l&&(l.innerHTML=`${pe.id==="black"?N.sun:N.moon}<span class="bs-toolbar-tip">${pe.id==="black"?"Light":"Dark"} Mode<span class="bs-toolbar-kbd">${s}+Shift+T</span></span>`)}},{icon:N.report,tip:"Open Panel",kbd:`${s}+Shift+B`,action:()=>{J?K():oe()}}];for(let a of r){let l=document.createElement("button");l.className="bs-toolbar-btn",a.id&&(l.id=a.id),l.innerHTML=`${a.icon}<span class="bs-toolbar-tip">${a.tip}<span class="bs-toolbar-kbd">${a.kbd}</span></span>`,l.addEventListener("click",d=>{d.stopPropagation(),a.action()}),B.appendChild(l)}document.body.appendChild(B),D.addEventListener("mouseenter",()=>{J||Xn()}),D.addEventListener("mouseleave",a=>{let l=a.relatedTarget;B?.contains(l)||Ft()}),B.addEventListener("mouseenter",()=>Xn()),B.addEventListener("mouseleave",a=>{let l=a.relatedTarget;D?.contains(l)||Ft()}),Ke=a=>{(a.ctrlKey||a.metaKey)&&a.shiftKey&&(a.key==="B"||a.key==="b"?(a.preventDefault(),J?K():oe()):a.key==="S"||a.key==="s"?(a.preventDefault(),r[0].action()):a.key==="P"||a.key==="p"?(a.preventDefault(),r[1].action()):(a.key==="T"||a.key==="t")&&(a.preventDefault(),r[2].action()))},document.addEventListener("keydown",Ke)}function Xn(){Et||J||(Et=!0,B?.classList.add("bs-show"))}function Ft(){Et=!1,B?.classList.remove("bs-show")}function rs(){K(),D?.remove(),D=null,B?.remove(),B=null,Et=!1,Je?.remove(),Je=null,Ke&&document.removeEventListener("keydown",Ke),Ke=null}var Z=null,H=null,E=null,ae=null,St="freehand",Ct="#ef4444",Vs=3,$e=[],Y=null,Ve=!1,Tt=null,Qs=[{id:"freehand",label:"Draw",icon:"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25z"},{id:"rectangle",label:"Rect",icon:"M3 3h18v18H3V3zm2 2v14h14V5H5z"},{id:"circle",label:"Circle",icon:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"},{id:"arrow",label:"Arrow",icon:"M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"}],Zs=["#ef4444","#f97316","#eab308","#22c55e","#3b82f6","#8b5cf6","#ffffff","#000000"];function is(e){return new Promise(t=>{Tt=t,$e=[],Y=null,St="freehand",Ct="#ef4444",Gs(e)})}function Gs(e){Z&&Z.remove(),Z=document.createElement("div"),Z.id="bs-annotation-overlay";let t=document.createElement("style");t.textContent=`
1738
1605
  #bs-annotation-overlay {
1739
1606
  position: fixed; inset: 0; z-index: 2147483647;
1740
1607
  background: rgba(0,0,0,0.85);
@@ -1779,5 +1646,5 @@ ${t.stack??""}`;if(typeof t=="object")try{return JSON.stringify(t,null,2)}catch{
1779
1646
  overflow: hidden; padding: 16px;
1780
1647
  }
1781
1648
  .bs-ann-canvas-wrap canvas { cursor: crosshair; border-radius: 4px; }
1782
- `,K.appendChild(t);let s=document.createElement("div");s.className="bs-ann-toolbar";for(let p of Wn){let l=document.createElement("button");l.className=`bs-ann-tool${p.id===kt?" active":""}`,l.title=p.label,l.innerHTML=`<svg viewBox="0 0 24 24"><path d="${p.icon}"/></svg>`,l.addEventListener("click",()=>{kt=p.id,s.querySelectorAll(".bs-ann-tool").forEach(x=>x.classList.remove("active")),l.classList.add("active")}),s.appendChild(l)}s.appendChild(en());for(let p of Yn){let l=document.createElement("button");l.className=`bs-ann-color${p===Et?" active":""}`,l.style.background=p,l.addEventListener("click",()=>{Et=p,s.querySelectorAll(".bs-ann-color").forEach(x=>x.classList.remove("active")),l.classList.add("active")}),s.appendChild(l)}s.appendChild(en());let n=document.createElement("button");n.className="bs-ann-btn bs-ann-undo",n.textContent="Undo",n.addEventListener("click",()=>{Se.pop(),St()}),s.appendChild(n);let r=document.createElement("button");r.className="bs-ann-btn bs-ann-save",r.textContent="Save",r.addEventListener("click",Vn);let i=document.createElement("button");i.className="bs-ann-btn bs-ann-cancel",i.textContent="Cancel",i.addEventListener("click",()=>{Ft(),Lt?.(null)}),s.appendChild(r),s.appendChild(i),K.appendChild(s);let c=document.createElement("div");c.className="bs-ann-canvas-wrap",H=document.createElement("canvas"),E=H.getContext("2d"),c.appendChild(H),K.appendChild(c),document.body.appendChild(K),ne=new Image,ne.onload=()=>{if(!H||!E||!ne)return;let p=window.innerWidth-32,l=window.innerHeight-100,x=ne.width,g=ne.height,h=Math.min(1,p/x,l/g);x=Math.round(x*h),g=Math.round(g*h),H.width=x,H.height=g,St(),Jn()},ne.src=e}function en(){let e=document.createElement("div");return e.className="bs-ann-sep",e}function Jn(){if(!H)return;H.addEventListener("mousedown",t=>{_e=!0;let{x:s,y:n}=tn(t);_={type:kt,color:Et,lineWidth:Fn,points:[{x:s,y:n}],x:s,y:n,width:0,height:0}}),H.addEventListener("mousemove",t=>{if(!_e||!_)return;let{x:s,y:n}=tn(t);_.type==="freehand"?_.points.push({x:s,y:n}):(_.width=s-_.x,_.height=n-_.y),St(),nn(_)});let e=()=>{_e&&_&&(Se.push(_),_=null),_e=!1,St()};H.addEventListener("mouseup",e),H.addEventListener("mouseleave",e)}function tn(e){let t=H.getBoundingClientRect();return{x:e.clientX-t.left,y:e.clientY-t.top}}function St(){if(!(!E||!H||!ne)){E.clearRect(0,0,H.width,H.height),E.drawImage(ne,0,0,H.width,H.height);for(let e of Se)nn(e)}}function nn(e){if(E)switch(E.strokeStyle=e.color,E.fillStyle=e.color,E.lineWidth=e.lineWidth,E.lineCap="round",E.lineJoin="round",e.type){case"freehand":{if(!e.points||e.points.length<2)return;E.beginPath(),E.moveTo(e.points[0].x,e.points[0].y);for(let t=1;t<e.points.length;t++)E.lineTo(e.points[t].x,e.points[t].y);E.stroke();break}case"rectangle":{E.strokeRect(e.x,e.y,e.width,e.height);break}case"circle":{let t=e.x+e.width/2,s=e.y+e.height/2,n=Math.abs(e.width)/2,r=Math.abs(e.height)/2;E.beginPath(),E.ellipse(t,s,n,r,0,0,Math.PI*2),E.stroke();break}case"arrow":{let t=e.x,s=e.y,n=e.x+e.width,r=e.y+e.height,i=14,c=Math.atan2(r-s,n-t);E.beginPath(),E.moveTo(t,s),E.lineTo(n,r),E.stroke(),E.beginPath(),E.moveTo(n,r),E.lineTo(n-i*Math.cos(c-Math.PI/6),r-i*Math.sin(c-Math.PI/6)),E.lineTo(n-i*Math.cos(c+Math.PI/6),r-i*Math.sin(c+Math.PI/6)),E.closePath(),E.fill();break}}}function Vn(){if(!H){Ft(),Lt?.(null);return}let t={dataUrl:H.toDataURL("image/png"),annotations:Se};Ft(),Lt?.(t)}function Ft(){K?.remove(),K=null,H=null,E=null,ne=null,Se=[],_=null,_e=!1}var Ct=!1;function Kn(){if(typeof window>"u")return"production";let e=window.location.hostname;return e==="localhost"||e==="127.0.0.1"||e==="0.0.0.0"||e.endsWith(".local")||/^192\.168\./.test(e)||/^10\./.test(e)||/^172\.(1[6-9]|2\d|3[01])\./.test(e)?"development":e.includes("staging")||e.includes("stage")||e.includes("preview")||e.includes("preprod")||e.includes("pre-prod")||e.includes("qa.")||e.includes(".qa")||e.includes("test.")||e.includes(".dev.")||e.includes("vercel.app")||e.includes("netlify.app")||e.includes("pages.dev")||e.includes("ngrok.io")||e.includes("ngrok-free.app")||e.includes("localhost.run")||e.includes("loca.lt")?"staging":"production"}var Zn={init(e){Ct||typeof window>"u"||(e.environment??Kn())==="production"||(Ct=!0,e.endpoint&&ys(e.endpoint),ts(e.maxBreadcrumbs),as(e.maxLogs),bs(e.maxNetworkCaptures),fs(),e.enablePerformance!==!1&&hs(),Qs(e),e.enableLivePins!==!1&&J()&&(mt(e.projectId),ft(e.projectId)))},destroy(){Ct&&(Gs(),Os(),Is(),ls(),us(),ms(),ns(),xs(),Ct=!1)},getLogs:G,clearLogs:is,getNetworkCaptures:me,getFailedNetworkCaptures:ae,clearNetworkCaptures:ps,getErrors:ee,clearErrors:gs,getBreadcrumbs:ue,clearBreadcrumbs:ss,getPerformanceMetrics:he,addBreadcrumb:q,getThemes:ct,getThemeById:dt,setTheme:_t,getCurrentThemeId:Vs,getLayouts:bt,getLayoutById:De,setLayout:Ks,getCurrentLayoutId:Zs,getCurrentUser:J,login:at,logout:it,togglePinMode:ht,isPinModeActive:xt,isConnected:Rs,openAnnotationEditor:sn,redactString:fe,redactObject:Ke},Vr=Zn;export{Zn as BugStash,Vr as default};
1649
+ `,Z.appendChild(t);let n=document.createElement("div");n.className="bs-ann-toolbar";for(let d of Qs){let c=document.createElement("button");c.className=`bs-ann-tool${d.id===St?" active":""}`,c.title=d.label,c.innerHTML=`<svg viewBox="0 0 24 24"><path d="${d.icon}"/></svg>`,c.addEventListener("click",()=>{St=d.id,n.querySelectorAll(".bs-ann-tool").forEach(h=>h.classList.remove("active")),c.classList.add("active")}),n.appendChild(c)}n.appendChild(os());for(let d of Zs){let c=document.createElement("button");c.className=`bs-ann-color${d===Ct?" active":""}`,c.style.background=d,c.addEventListener("click",()=>{Ct=d,n.querySelectorAll(".bs-ann-color").forEach(h=>h.classList.remove("active")),c.classList.add("active")}),n.appendChild(c)}n.appendChild(os());let s=document.createElement("button");s.className="bs-ann-btn bs-ann-undo",s.textContent="Undo",s.addEventListener("click",()=>{$e.pop(),$t()}),n.appendChild(s);let r=document.createElement("button");r.className="bs-ann-btn bs-ann-save",r.textContent="Save",r.addEventListener("click",tr);let a=document.createElement("button");a.className="bs-ann-btn bs-ann-cancel",a.textContent="Cancel",a.addEventListener("click",()=>{Xt(),Tt?.(null)}),n.appendChild(r),n.appendChild(a),Z.appendChild(n);let l=document.createElement("div");l.className="bs-ann-canvas-wrap",H=document.createElement("canvas"),E=H.getContext("2d"),l.appendChild(H),Z.appendChild(l),document.body.appendChild(Z),ae=new Image,ae.onload=()=>{if(!H||!E||!ae)return;let d=window.innerWidth-32,c=window.innerHeight-100,h=ae.width,p=ae.height,v=Math.min(1,d/h,c/p);h=Math.round(h*v),p=Math.round(p*v),H.width=h,H.height=p,$t(),er()},ae.src=e}function os(){let e=document.createElement("div");return e.className="bs-ann-sep",e}function er(){if(!H)return;H.addEventListener("mousedown",t=>{Ve=!0;let{x:n,y:s}=as(t);Y={type:St,color:Ct,lineWidth:Vs,points:[{x:n,y:s}],x:n,y:s,width:0,height:0}}),H.addEventListener("mousemove",t=>{if(!Ve||!Y)return;let{x:n,y:s}=as(t);Y.type==="freehand"?Y.points.push({x:n,y:s}):(Y.width=n-Y.x,Y.height=s-Y.y),$t(),ls(Y)});let e=()=>{Ve&&Y&&($e.push(Y),Y=null),Ve=!1,$t()};H.addEventListener("mouseup",e),H.addEventListener("mouseleave",e)}function as(e){let t=H.getBoundingClientRect();return{x:e.clientX-t.left,y:e.clientY-t.top}}function $t(){if(!(!E||!H||!ae)){E.clearRect(0,0,H.width,H.height),E.drawImage(ae,0,0,H.width,H.height);for(let e of $e)ls(e)}}function ls(e){if(E)switch(E.strokeStyle=e.color,E.fillStyle=e.color,E.lineWidth=e.lineWidth,E.lineCap="round",E.lineJoin="round",e.type){case"freehand":{if(!e.points||e.points.length<2)return;E.beginPath(),E.moveTo(e.points[0].x,e.points[0].y);for(let t=1;t<e.points.length;t++)E.lineTo(e.points[t].x,e.points[t].y);E.stroke();break}case"rectangle":{E.strokeRect(e.x,e.y,e.width,e.height);break}case"circle":{let t=e.x+e.width/2,n=e.y+e.height/2,s=Math.abs(e.width)/2,r=Math.abs(e.height)/2;E.beginPath(),E.ellipse(t,n,s,r,0,0,Math.PI*2),E.stroke();break}case"arrow":{let t=e.x,n=e.y,s=e.x+e.width,r=e.y+e.height,a=14,l=Math.atan2(r-n,s-t);E.beginPath(),E.moveTo(t,n),E.lineTo(s,r),E.stroke(),E.beginPath(),E.moveTo(s,r),E.lineTo(s-a*Math.cos(l-Math.PI/6),r-a*Math.sin(l-Math.PI/6)),E.lineTo(s-a*Math.cos(l+Math.PI/6),r-a*Math.sin(l+Math.PI/6)),E.closePath(),E.fill();break}}}function tr(){if(!H){Xt(),Tt?.(null);return}let t={dataUrl:H.toDataURL("image/png"),annotations:$e};Xt(),Tt?.(t)}function Xt(){Z?.remove(),Z=null,H=null,E=null,ae=null,$e=[],Y=null,Ve=!1}var Mt=!1;function nr(){if(typeof window>"u")return"production";let e=window.location.hostname;return e==="localhost"||e==="127.0.0.1"||e==="0.0.0.0"||e.endsWith(".local")||/^192\.168\./.test(e)||/^10\./.test(e)||/^172\.(1[6-9]|2\d|3[01])\./.test(e)?"development":e.includes("staging")||e.includes("stage")||e.includes("preview")||e.includes("preprod")||e.includes("pre-prod")||e.includes("qa.")||e.includes(".qa")||e.includes("test.")||e.includes(".dev.")||e.includes("vercel.app")||e.includes("netlify.app")||e.includes("pages.dev")||e.includes("ngrok.io")||e.includes("ngrok-free.app")||e.includes("localhost.run")||e.includes("loca.lt")?"staging":"production"}var sr={init(e){Mt||typeof window>"u"||(e.environment??nr())==="production"||(Mt=!0,e.endpoint&&Ln(e.endpoint),rn(e.maxBreadcrumbs),dn(e.maxLogs),gn(e.maxNetworkCaptures),vn(),e.enablePerformance!==!1&&wn(),ss(e),e.enableLivePins!==!1&&V()&&(Ye(e.projectId),_e(e.projectId)))},destroy(){Mt&&(rs(),Wn(),Nn(),bn(),hn(),yn(),an(),kn(),Mt=!1)},getLogs:te,clearLogs:pn,getNetworkCaptures:ye,getFailedNetworkCaptures:ce,clearNetworkCaptures:fn,getErrors:ne,clearErrors:xn,getBreadcrumbs:he,clearBreadcrumbs:on,getPerformanceMetrics:we,addBreadcrumb:_,getThemes:gt,getThemeById:ft,setTheme:Lt,getCurrentThemeId:es,getLayouts:ht,getLayoutById:Ue,setLayout:ts,getCurrentLayoutId:ns,getCurrentUser:V,login:bt,logout:ut,togglePinMode:Xe,isPinModeActive:wt,isConnected:jn,openAnnotationEditor:is,redactString:ve,redactObject:st},to=sr;export{sr as BugStash,to as default};
1783
1650
  //# sourceMappingURL=index.js.map