brakit 0.8.6 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,826 @@
1
+ (function(){'use strict';var Ls=Object.defineProperty;var Ms=Object.getOwnPropertyDescriptor;var h=(i,e,t,s)=>{for(var r=s>1?void 0:s?Ms(e,t):e,o=i.length-1,n;o>=0;o--)(n=i[o])&&(r=(s?n(e,t,r):n(r))||r);return s&&r&&Ls(e,t,r),r};var Lt=globalThis,kt=Lt.ShadowRoot&&(Lt.ShadyCSS===void 0||Lt.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Re=Symbol(),xe=new WeakMap,Mt=class{constructor(e,t,s){if(this._$cssResult$=true,s!==Re)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t;}get styleSheet(){let e=this.o,t=this.t;if(kt&&e===void 0){let s=t!==void 0&&t.length===1;s&&(e=xe.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),s&&xe.set(t,e));}return e}toString(){return this.cssText}},we=i=>new Mt(typeof i=="string"?i:i+"",void 0,Re);var Ae=(i,e)=>{if(kt)i.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let s=document.createElement("style"),r=Lt.litNonce;r!==void 0&&s.setAttribute("nonce",r),s.textContent=t.cssText,i.appendChild(s);}},Yt=kt?i=>i:i=>i instanceof CSSStyleSheet?(e=>{let t="";for(let s of e.cssRules)t+=s.cssText;return we(t)})(i):i;var{is:ks,defineProperty:Os,getOwnPropertyDescriptor:Ds,getOwnPropertyNames:Ns,getOwnPropertySymbols:Hs,getPrototypeOf:qs}=Object,D=globalThis,Ce=D.trustedTypes,Ps=Ce?Ce.emptyScript:"",Us=D.reactiveElementPolyfillSupport,ht=(i,e)=>i,mt={toAttribute(i,e){switch(e){case Boolean:i=i?Ps:null;break;case Object:case Array:i=i==null?i:JSON.stringify(i);}return i},fromAttribute(i,e){let t=i;switch(e){case Boolean:t=i!==null;break;case Number:t=i===null?null:Number(i);break;case Object:case Array:try{t=JSON.parse(i);}catch{t=null;}}return t}},Ot=(i,e)=>!ks(i,e),Ie={attribute:true,type:String,converter:mt,reflect:false,useDefault:false,hasChanged:Ot};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),D.litPropertyMetadata??(D.litPropertyMetadata=new WeakMap);var k=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??(this.l=[])).push(e);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=Ie){if(t.state&&(t.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=true),this.elementProperties.set(e,t),!t.noAccessor){let s=Symbol(),r=this.getPropertyDescriptor(e,s,t);r!==void 0&&Os(this.prototype,e,r);}}static getPropertyDescriptor(e,t,s){let{get:r,set:o}=Ds(this.prototype,e)??{get(){return this[t]},set(n){this[t]=n;}};return {get:r,set(n){let l=r?.call(this);o?.call(this,n),this.requestUpdate(e,l,s);},configurable:true,enumerable:true}}static getPropertyOptions(e){return this.elementProperties.get(e)??Ie}static _$Ei(){if(this.hasOwnProperty(ht("elementProperties")))return;let e=qs(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties);}static finalize(){if(this.hasOwnProperty(ht("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(ht("properties"))){let t=this.properties,s=[...Ns(t),...Hs(t)];for(let r of s)this.createProperty(r,t[r]);}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[s,r]of t)this.elementProperties.set(s,r);}this._$Eh=new Map;for(let[t,s]of this.elementProperties){let r=this._$Eu(t,s);r!==void 0&&this._$Eh.set(r,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let s=new Set(e.flat(1/0).reverse());for(let r of s)t.unshift(Yt(r));}else e!==void 0&&t.push(Yt(e));return t}static _$Eu(e,t){let s=t.attribute;return s===false?void 0:typeof s=="string"?s:typeof e=="string"?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=false,this.hasUpdated=false,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this));}addController(e){(this._$EO??(this._$EO=new Set)).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.();}removeController(e){this._$EO?.delete(e);}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let s of t.keys())this.hasOwnProperty(s)&&(e.set(s,this[s]),delete this[s]);e.size>0&&(this._$Ep=e);}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return Ae(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??(this.renderRoot=this.createRenderRoot()),this.enableUpdating(true),this._$EO?.forEach(e=>e.hostConnected?.());}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.());}attributeChangedCallback(e,t,s){this._$AK(e,s);}_$ET(e,t){let s=this.constructor.elementProperties.get(e),r=this.constructor._$Eu(e,s);if(r!==void 0&&s.reflect===true){let o=(s.converter?.toAttribute!==void 0?s.converter:mt).toAttribute(t,s.type);this._$Em=e,o==null?this.removeAttribute(r):this.setAttribute(r,o),this._$Em=null;}}_$AK(e,t){let s=this.constructor,r=s._$Eh.get(e);if(r!==void 0&&this._$Em!==r){let o=s.getPropertyOptions(r),n=typeof o.converter=="function"?{fromAttribute:o.converter}:o.converter?.fromAttribute!==void 0?o.converter:mt;this._$Em=r;let l=n.fromAttribute(t,o.type);this[r]=l??this._$Ej?.get(r)??l,this._$Em=null;}}requestUpdate(e,t,s,r=false,o){if(e!==void 0){let n=this.constructor;if(r===false&&(o=this[e]),s??(s=n.getPropertyOptions(e)),!((s.hasChanged??Ot)(o,t)||s.useDefault&&s.reflect&&o===this._$Ej?.get(e)&&!this.hasAttribute(n._$Eu(e,s))))return;this.C(e,t,s);}this.isUpdatePending===false&&(this._$ES=this._$EP());}C(e,t,{useDefault:s,reflect:r,wrapped:o},n){s&&!(this._$Ej??(this._$Ej=new Map)).has(e)&&(this._$Ej.set(e,n??t??this[e]),o!==true||n!==void 0)||(this._$AL.has(e)||(this.hasUpdated||s||(t=void 0),this._$AL.set(e,t)),r===true&&this._$Em!==e&&(this._$Eq??(this._$Eq=new Set)).add(e));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}let e=this.scheduleUpdate();return e!=null&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??(this.renderRoot=this.createRenderRoot()),this._$Ep){for(let[r,o]of this._$Ep)this[r]=o;this._$Ep=void 0;}let s=this.constructor.elementProperties;if(s.size>0)for(let[r,o]of s){let{wrapped:n}=o,l=this[r];n!==true||this._$AL.has(r)||l===void 0||this.C(r,void 0,o,l);}}let e=false,t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(s=>s.hostUpdate?.()),this.update(t)):this._$EM();}catch(s){throw e=false,this._$EM(),s}e&&this._$AE(t);}willUpdate(e){}_$AE(e){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(e)),this.updated(e);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return true}update(e){this._$Eq&&(this._$Eq=this._$Eq.forEach(t=>this._$ET(t,this[t]))),this._$EM();}updated(e){}firstUpdated(e){}};k.elementStyles=[],k.shadowRootOptions={mode:"open"},k[ht("elementProperties")]=new Map,k[ht("finalized")]=new Map,Us?.({ReactiveElement:k}),(D.reactiveElementVersions??(D.reactiveElementVersions=[])).push("2.1.2");var ft=globalThis,Le=i=>i,Dt=ft.trustedTypes,Me=Dt?Dt.createPolicy("lit-html",{createHTML:i=>i}):void 0,qe="$lit$",N=`lit$${Math.random().toFixed(9).slice(2)}$`,Pe="?"+N,Fs=`<${Pe}>`,j=document,gt=()=>j.createComment(""),bt=i=>i===null||typeof i!="object"&&typeof i!="function",ee=Array.isArray,Bs=i=>ee(i)||typeof i?.[Symbol.iterator]=="function",Xt=`[
2
+ \f\r]`,vt=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,ke=/-->/g,Oe=/>/g,G=RegExp(`>|${Xt}(?:([^\\s"'>=/]+)(${Xt}*=${Xt}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),De=/'/g,Ne=/"/g,Ue=/^(?:script|style|textarea|title)$/i,se=i=>(e,...t)=>({_$litType$:i,strings:e,values:t}),a=se(1),Q=Symbol.for("lit-noChange"),d=Symbol.for("lit-nothing"),He=new WeakMap,W=j.createTreeWalker(j,129);function Fe(i,e){if(!ee(i)||!i.hasOwnProperty("raw"))throw Error("invalid template strings array");return Me!==void 0?Me.createHTML(e):e}var Gs=(i,e)=>{let t=i.length-1,s=[],r,o=e===2?"<svg>":e===3?"<math>":"",n=vt;for(let l=0;l<t;l++){let c=i[l],p,u,m=-1,b=0;for(;b<c.length&&(n.lastIndex=b,u=n.exec(c),u!==null);)b=n.lastIndex,n===vt?u[1]==="!--"?n=ke:u[1]!==void 0?n=Oe:u[2]!==void 0?(Ue.test(u[2])&&(r=RegExp("</"+u[2],"g")),n=G):u[3]!==void 0&&(n=G):n===G?u[0]===">"?(n=r??vt,m=-1):u[1]===void 0?m=-2:(m=n.lastIndex-u[2].length,p=u[1],n=u[3]===void 0?G:u[3]==='"'?Ne:De):n===Ne||n===De?n=G:n===ke||n===Oe?n=vt:(n=G,r=void 0);let $=n===G&&i[l+1].startsWith("/>")?" ":"";o+=n===vt?c+Fs:m>=0?(s.push(p),c.slice(0,m)+qe+c.slice(m)+N+$):c+N+(m===-2?l:$);}return [Fe(i,o+(i[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),s]},Et=class i{constructor({strings:e,_$litType$:t},s){let r;this.parts=[];let o=0,n=0,l=e.length-1,c=this.parts,[p,u]=Gs(e,t);if(this.el=i.createElement(p,s),W.currentNode=this.el.content,t===2||t===3){let m=this.el.content.firstChild;m.replaceWith(...m.childNodes);}for(;(r=W.nextNode())!==null&&c.length<l;){if(r.nodeType===1){if(r.hasAttributes())for(let m of r.getAttributeNames())if(m.endsWith(qe)){let b=u[n++],$=r.getAttribute(m).split(N),v=/([.?@])?(.*)/.exec(b);c.push({type:1,index:o,name:v[2],strings:$,ctor:v[1]==="."?zt:v[1]==="?"?Jt:v[1]==="@"?Zt:tt}),r.removeAttribute(m);}else m.startsWith(N)&&(c.push({type:6,index:o}),r.removeAttribute(m));if(Ue.test(r.tagName)){let m=r.textContent.split(N),b=m.length-1;if(b>0){r.textContent=Dt?Dt.emptyScript:"";for(let $=0;$<b;$++)r.append(m[$],gt()),W.nextNode(),c.push({type:2,index:++o});r.append(m[b],gt());}}}else if(r.nodeType===8)if(r.data===Pe)c.push({type:2,index:o});else {let m=-1;for(;(m=r.data.indexOf(N,m+1))!==-1;)c.push({type:7,index:o}),m+=N.length-1;}o++;}}static createElement(e,t){let s=j.createElement("template");return s.innerHTML=e,s}};function Z(i,e,t=i,s){if(e===Q)return e;let r=s!==void 0?t._$Co?.[s]:t._$Cl,o=bt(e)?void 0:e._$litDirective$;return r?.constructor!==o&&(r?._$AO?.(false),o===void 0?r=void 0:(r=new o(i),r._$AT(i,t,s)),s!==void 0?(t._$Co??(t._$Co=[]))[s]=r:t._$Cl=r),r!==void 0&&(e=Z(i,r._$AS(i,e.values),r,s)),e}var Kt=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:s}=this._$AD,r=(e?.creationScope??j).importNode(t,true);W.currentNode=r;let o=W.nextNode(),n=0,l=0,c=s[0];for(;c!==void 0;){if(n===c.index){let p;c.type===2?p=new _t(o,o.nextSibling,this,e):c.type===1?p=new c.ctor(o,c.name,c.strings,this,e):c.type===6&&(p=new te(o,this,e)),this._$AV.push(p),c=s[++l];}n!==c?.index&&(o=W.nextNode(),n++);}return W.currentNode=j,r}p(e){let t=0;for(let s of this._$AV)s!==void 0&&(s.strings!==void 0?(s._$AI(e,s,t),t+=s.strings.length-2):s._$AI(e[t])),t++;}},_t=class i{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,s,r){this.type=2,this._$AH=d,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=s,this.options=r,this._$Cv=r?.isConnected??true;}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=Z(this,e,t),bt(e)?e===d||e==null||e===""?(this._$AH!==d&&this._$AR(),this._$AH=d):e!==this._$AH&&e!==Q&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):Bs(e)?this.k(e):this._(e);}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e));}_(e){this._$AH!==d&&bt(this._$AH)?this._$AA.nextSibling.data=e:this.T(j.createTextNode(e)),this._$AH=e;}$(e){let{values:t,_$litType$:s}=e,r=typeof s=="number"?this._$AC(e):(s.el===void 0&&(s.el=Et.createElement(Fe(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(t);else {let o=new Kt(r,this),n=o.u(this.options);o.p(t),this.T(n),this._$AH=o;}}_$AC(e){let t=He.get(e.strings);return t===void 0&&He.set(e.strings,t=new Et(e)),t}k(e){ee(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,s,r=0;for(let o of e)r===t.length?t.push(s=new i(this.O(gt()),this.O(gt()),this,this.options)):s=t[r],s._$AI(o),r++;r<t.length&&(this._$AR(s&&s._$AB.nextSibling,r),t.length=r);}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(false,true,t);e!==this._$AB;){let s=Le(e).nextSibling;Le(e).remove(),e=s;}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e));}},tt=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,s,r,o){this.type=1,this._$AH=d,this._$AN=void 0,this.element=e,this.name=t,this._$AM=r,this.options=o,s.length>2||s[0]!==""||s[1]!==""?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=d;}_$AI(e,t=this,s,r){let o=this.strings,n=false;if(o===void 0)e=Z(this,e,t,0),n=!bt(e)||e!==this._$AH&&e!==Q,n&&(this._$AH=e);else {let l=e,c,p;for(e=o[0],c=0;c<o.length-1;c++)p=Z(this,l[s+c],t,c),p===Q&&(p=this._$AH[c]),n||(n=!bt(p)||p!==this._$AH[c]),p===d?e=d:e!==d&&(e+=(p??"")+o[c+1]),this._$AH[c]=p;}n&&!r&&this.j(e);}j(e){e===d?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??"");}},zt=class extends tt{constructor(){super(...arguments),this.type=3;}j(e){this.element[this.name]=e===d?void 0:e;}},Jt=class extends tt{constructor(){super(...arguments),this.type=4;}j(e){this.element.toggleAttribute(this.name,!!e&&e!==d);}},Zt=class extends tt{constructor(e,t,s,r,o){super(e,t,s,r,o),this.type=5;}_$AI(e,t=this){if((e=Z(this,e,t,0)??d)===Q)return;let s=this._$AH,r=e===d&&s!==d||e.capture!==s.capture||e.once!==s.once||e.passive!==s.passive,o=e!==d&&(s===d||r);r&&this.element.removeEventListener(this.name,this,s),o&&this.element.addEventListener(this.name,this,e),this._$AH=e;}handleEvent(e){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e);}},te=class{constructor(e,t,s){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=s;}get _$AU(){return this._$AM._$AU}_$AI(e){Z(this,e);}};var Ws=ft.litHtmlPolyfillSupport;Ws?.(Et,_t),(ft.litHtmlVersions??(ft.litHtmlVersions=[])).push("3.3.2");var Be=(i,e,t)=>{let s=t?.renderBefore??e,r=s._$litPart$;if(r===void 0){let o=t?.renderBefore??null;s._$litPart$=r=new _t(e.insertBefore(gt(),o),o,void 0,t??{});}return r._$AI(i),r};var St=globalThis,f=class extends k{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t;let e=super.createRenderRoot();return (t=this.renderOptions).renderBefore??(t.renderBefore=e.firstChild),e}update(e){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=Be(t,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return Q}};f._$litElement$=true,f.finalized=true,St.litElementHydrateSupport?.({LitElement:f});var js=St.litElementPolyfillSupport;js?.({LitElement:f});(St.litElementVersions??(St.litElementVersions=[])).push("4.2.2");var g=i=>(e,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(i,e);}):customElements.define(i,e);};var Qs={attribute:true,type:String,converter:mt,reflect:false,hasChanged:Ot},Vs=(i=Qs,e,t)=>{let{kind:s,metadata:r}=t,o=globalThis.litPropertyMetadata.get(r);if(o===void 0&&globalThis.litPropertyMetadata.set(r,o=new Map),s==="setter"&&((i=Object.create(i)).wrapped=true),o.set(t.name,i),s==="accessor"){let{name:n}=t;return {set(l){let c=e.get.call(this);e.set.call(this,l),this.requestUpdate(n,c,i,true,l);},init(l){return l!==void 0&&this.C(n,void 0,i,l),l}}}if(s==="setter"){let{name:n}=t;return function(l){let c=this[n];e.call(this,l),this.requestUpdate(n,c,i,true,l);}}throw Error("Unsupported decorator location: "+s)};function T(i){return (e,t)=>typeof t=="object"?Vs(i,e,t):((s,r,o)=>{let n=r.hasOwnProperty(o);return r.constructor.createProperty(o,s),n?Object.getOwnPropertyDescriptor(r,o):void 0})(i,e,t)}function E(i){return T({...i,state:true,attribute:false})}var $t=class extends f{constructor(){super(...arguments);this.method="";}createRenderRoot(){return this}render(){let t=this.method.toUpperCase();return a`<span class="method-badge method-badge-${t}">${t}</span>`}};h([T()],$t.prototype,"method",2),$t=h([g("bk-method-badge")],$t);var I="/__brakit/api",O="/__brakit",y={flows:`${I}/flows`,requests:`${I}/requests`,events:`${I}/events`,clear:`${I}/clear`,fetches:`${I}/fetches`,errors:`${I}/errors`,logs:`${I}/logs`,queries:`${I}/queries`,metricsLive:`${I}/metrics/live`,insights:`${I}/insights`,tab:`${I}/tab`,activity:`${I}/activity`};var et="polling",Ht="static",Ys="auth-handshake",Xs="auth-check",Ks="middleware",Tt={[Ys]:1,[Xs]:1,[Ks]:1};var re="fetch";var ie="error_event",oe="query",ne="issues";var ae={overview:"Overview",queries:"Queries",requests:"Requests",actions:"Actions",errors:"Errors",security:"Security",fetches:"Fetches",logs:"Logs",performance:"Performance"};var yt={overview:"Overview",actions:"Actions",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",performance:"Performance",security:"Security"},le={overview:"Live summary of your application",actions:"User actions captured as sequences of HTTP requests",requests:"All HTTP requests proxied through brakit",fetches:"Outbound HTTP calls made by your server to external services",queries:"Database queries executed during request handling",errors:"Unhandled exceptions and errors thrown by your application",logs:"Console output from your application",performance:"Endpoint health and response time trends",security:"Security findings and recommendations"};var de=100,V=300,Y=800,pe=2e3,ue=100,he=50,me=500;var H="__all__",Ft={SELECT:"var(--blue)",INSERT:"var(--green)",UPDATE:"var(--amber)",DELETE:"var(--red)",COUNT:"var(--text-muted)"},ze={error:"var(--red)",warn:"var(--amber)",info:"var(--blue)",debug:"var(--text-muted)",log:"var(--text-dim)"},fe=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],xt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},Bt=[{max:de,label:"Fast",color:"var(--green)",bg:"rgba(22,163,74,0.08)",border:"rgba(22,163,74,0.2)"},{max:V,label:"Good",color:"var(--green)",bg:"rgba(22,163,74,0.06)",border:"rgba(22,163,74,0.15)"},{max:Y,label:"OK",color:"var(--amber)",bg:"rgba(217,119,6,0.06)",border:"rgba(217,119,6,0.15)"},{max:pe,label:"Slow",color:"var(--red)",bg:"rgba(220,38,38,0.06)",border:"rgba(220,38,38,0.15)"},{max:1/0,label:"Critical",color:"var(--red)",bg:"rgba(220,38,38,0.08)",border:"rgba(220,38,38,0.2)"}],Je="rgba(228,228,231,0.8)",ge="rgba(113,113,122,0.7)",Ze="10px monospace",be="9px monospace",ts="8px monospace",es={top:16,right:16,bottom:28,left:52},ss={fetch:"var(--blue)",log:"var(--text-muted)",error:"var(--red)",query:"var(--accent)"},rs={fetch:"FETCH",log:"LOG",error:"ERROR",query:"QUERY"},is=new Set(["cookie","set-cookie","authorization","proxy-authorization","x-api-key","x-auth-token"]),os={400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",408:"Timeout",409:"Conflict",422:"Unprocessable",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout"},ns=new Set(["host","connection","accept-encoding"]),q={critical:{icon:"\u2717",cls:"critical",sort:0},warning:{icon:"\u26A0",cls:"warning",sort:1},info:{icon:"\u2139",cls:"info",sort:2}};function S(i){return i<1e3?i+"ms":(i/1e3).toFixed(1)+"s"}function U(i){return !i||i===0?"":i<1024?i+"b":(i/1024).toFixed(1)+"kb"}function P(i){return i?i.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}function st(i){return i>=500?"status-pill-5xx":i>=400?"status-pill-4xx":i>=300?"status-pill-3xx":"status-pill-2xx"}function as(i){return os[i]||(i>=500?"Server Error":i>=400?"Client Error":"OK")}function zs(i,e){if(is.has(i.toLowerCase())){let t=String(e);return t.length<=8?"****":t.slice(0,4)+"..."+t.slice(-4)+" ("+t.length+" chars)"}return String(e)}function rt(i){return !i||Object.keys(i).length===0?'<span style="color:var(--text-muted)">No headers</span>':Object.entries(i).map(([e,t])=>'<span class="json-key">'+P(e)+"</span>: "+P(zs(e,t))).join(`
4
+ `)}function X(i){if(!i)return '<span style="color:var(--text-muted)">No body</span>';try{let e=JSON.parse(i);return Js(JSON.stringify(e,null,2))}catch{return P(i)}}function Js(i){return P(i).replace(/("(?:[^"\\]|\\.)*")(\s*:)?|\b(true|false)\b|\bnull\b|(-?\d+\.?\d*(?:[eE][+-]?\d+)?)/g,(e,t,s,r,o)=>t?s?'<span class="json-key">'+t+"</span>"+s:'<span class="json-str">'+t+"</span>":r?'<span class="json-bool">'+e+"</span>":o?'<span class="json-num">'+e+"</span>":e==="null"?'<span class="json-null">null</span>':e)}var Rt=class extends f{constructor(){super(...arguments);this.code=0;}createRenderRoot(){return this}render(){let t=st(this.code);return a`<span class="status-pill ${t}">${this.code}</span>`}};h([T({type:Number})],Rt.prototype,"code",2),Rt=h([g("bk-status-pill")],Rt);var wt=class extends f{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return a`<span class="req-duration">${S(this.ms)}</span>`}};h([T({type:Number})],wt.prototype,"ms",2),wt=h([g("bk-duration-label")],wt);var it=class extends f{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return a`
5
+ <div class="empty">
6
+ <span class="empty-title">${this.title}</span>
7
+ <span class="empty-sub">${this.subtitle}</span>
8
+ </div>
9
+ `}};h([T()],it.prototype,"title",2),h([T()],it.prototype,"subtitle",2),it=h([g("bk-empty-state")],it);var C=class extends f{constructor(){super(...arguments);this.message="";this.visible=false;}createRenderRoot(){return this}static show(t){let s=document.querySelector("bk-toast");s&&s.showMessage(t);}showMessage(t){this.hideTimer&&clearTimeout(this.hideTimer),this.message=t,this.visible=true,this.hideTimer=setTimeout(()=>{this.visible=false;},2e3);}render(){return a`<div class="toast ${this.visible?"show":""}">${this.message}</div>`}};h([E()],C.prototype,"message",2),h([E()],C.prototype,"visible",2),C=h([g("bk-toast")],C);var K=class extends f{constructor(){super(...arguments);this.text="";this.label="Copy";this.toastMessage="Copied";}createRenderRoot(){return this}async copy(t){t.stopPropagation();try{await navigator.clipboard.writeText(this.text),C.show(this.toastMessage);}catch{}}render(){return a`<button class="query-detail-copy" @click=${this.copy}>${this.label}</button>`}};h([T()],K.prototype,"text",2),h([T()],K.prototype,"label",2),h([T({attribute:"toast-message"})],K.prototype,"toastMessage",2),K=h([g("bk-copy-button")],K);var z=class extends f{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return a`
10
+ <div class="fetch-stat">
11
+ <span class="fetch-stat-value" style="color:${this.color}">${this.value}</span>
12
+ <span class="fetch-stat-label">${this.label}</span>
13
+ </div>
14
+ `}};h([T()],z.prototype,"value",2),h([T()],z.prototype,"label",2),h([T()],z.prototype,"color",2),z=h([g("bk-stat-card")],z);var F=class extends Event{constructor(e,t,s,r){super("context-request",{bubbles:true,composed:true}),this.context=e,this.contextTarget=t,this.callback=s,this.subscribe=r??false;}};var ot=class{constructor(e,t,s,r){if(this.subscribe=false,this.provided=false,this.value=void 0,this.t=(o,n)=>{this.unsubscribe&&(this.unsubscribe!==n&&(this.provided=false,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=o,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=true,this.callback&&this.callback(o,n)),this.unsubscribe=n;},this.host=e,t.context!==void 0){let o=t;this.context=o.context,this.callback=o.callback,this.subscribe=o.subscribe??false;}else this.context=t,this.callback=s,this.subscribe=r??false;this.host.addController(this);}hostConnected(){this.dispatchRequest();}hostDisconnected(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=void 0);}dispatchRequest(){this.host.dispatchEvent(new F(this.context,this.host,this.t,this.subscribe));}};var Gt=class{get value(){return this.o}set value(e){this.setValue(e);}setValue(e,t=false){let s=t||!Object.is(e,this.o);this.o=e,s&&this.updateObservers();}constructor(e){this.subscriptions=new Map,this.updateObservers=()=>{for(let[t,{disposer:s}]of this.subscriptions)t(this.o,s);},e!==void 0&&(this.value=e);}addCallback(e,t,s){if(!s)return void e(this.value);this.subscriptions.has(e)||this.subscriptions.set(e,{disposer:()=>{this.subscriptions.delete(e);},consumerHost:t});let{disposer:r}=this.subscriptions.get(e);e(this.value,r);}clearCallbacks(){this.subscriptions.clear();}};var Ee=class extends Event{constructor(e,t){super("context-provider",{bubbles:true,composed:true}),this.context=e,this.contextTarget=t;}},nt=class extends Gt{constructor(e,t,s){super(t.context!==void 0?t.initialValue:s),this.onContextRequest=r=>{if(r.context!==this.context)return;let o=r.contextTarget??r.composedPath()[0];o!==this.host&&(r.stopPropagation(),this.addCallback(r.callback,o,r.subscribe));},this.onProviderRequest=r=>{if(r.context!==this.context||(r.contextTarget??r.composedPath()[0])===this.host)return;let o=new Set;for(let[n,{consumerHost:l}]of this.subscriptions)o.has(n)||(o.add(n),l.dispatchEvent(new F(this.context,l,n,true)));r.stopPropagation();},this.host=e,t.context!==void 0?this.context=t.context:this.context=t,this.attachListeners(),this.host.addController?.(this);}attachListeners(){this.host.addEventListener("context-request",this.onContextRequest),this.host.addEventListener("context-provider",this.onProviderRequest);}hostConnected(){this.host.dispatchEvent(new Ee(this.context,this.host));}};function _e({context:i}){return (e,t)=>{let s=new WeakMap;if(typeof t=="object")return {get(){return e.get.call(this)},set(r){return s.get(this).setValue(r),e.set.call(this,r)},init(r){return s.set(this,new nt(this,{context:i,initialValue:r})),r}};{e.constructor.addInitializer((n=>{s.set(n,new nt(n,{context:i}));}));let r=Object.getOwnPropertyDescriptor(e,t),o;if(r===void 0){let n=new WeakMap;o={get(){return n.get(this)},set(l){s.get(this).setValue(l),n.set(this,l);},configurable:true,enumerable:true};}else {let n=r.set;o={...r,set(l){s.get(this).setValue(l),n?.call(this,l);}};}return void Object.defineProperty(e,t,o)}}}function R({context:i,subscribe:e}){return (t,s)=>{typeof s=="object"?s.addInitializer((function(){new ot(this,{context:i,callback:r=>{t.set.call(this,r);},subscribe:e});})):t.constructor.addInitializer((r=>{new ot(r,{context:i,callback:o=>{r[s]=o;},subscribe:e});}));}}var x="dashboard-store",Wt=class extends EventTarget{constructor(){super(...arguments);this._state={flows:[],requests:[],fetches:[],errors:[],logs:[],queries:[],issues:[],metrics:[],viewMode:"simple",activeView:"overview"};}get state(){return this._state}setFlows(t){this._state={...this._state,flows:t},this.notify("flows");}setRequests(t){this._state={...this._state,requests:t},this.notify("requests");}setFetches(t){this._state={...this._state,fetches:t},this.notify("fetches");}setErrors(t){this._state={...this._state,errors:t},this.notify("errors");}setLogs(t){this._state={...this._state,logs:t},this.notify("logs");}setQueries(t){this._state={...this._state,queries:t},this.notify("queries");}setIssues(t){this._state={...this._state,issues:t},this.notify("issues");}setMetrics(t){this._state={...this._state,metrics:t},this.notify("metrics");}prependRequest(t){let s=[t,...this._state.requests.slice(0,999)];this._state={...this._state,requests:s},this.notify("requests");}prependFetch(t){this._state={...this._state,fetches:[t,...this._state.fetches]},this.notify("fetches");}prependError(t){this._state={...this._state,errors:[t,...this._state.errors]},this.notify("errors");}prependLog(t){this._state={...this._state,logs:[t,...this._state.logs]},this.notify("logs");}prependQuery(t){this._state={...this._state,queries:[t,...this._state.queries]},this.notify("queries");}setActiveView(t){this._state={...this._state,activeView:t},this.notify("activeView");}setViewMode(t){this._state={...this._state,viewMode:t},this.notify("viewMode");}clearAll(){this._state={...this._state,flows:[],requests:[],fetches:[],errors:[],logs:[],queries:[],issues:[],metrics:[]},this.notify("all");}notify(t){this.dispatchEvent(new CustomEvent("state-changed",{detail:t}));}};var at=class extends f{constructor(){super(...arguments);this.expandedIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleError(t){this.expandedIdx=this.expandedIdx===t?-1:t;}renderErrorRow(t,s){let r=new Date(t.timestamp).toLocaleTimeString(),o=this.expandedIdx===s;return a`
15
+ <div
16
+ class="req-row tel-clickable ${o?"expanded":""}"
17
+ @click=${()=>this.toggleError(s)}
18
+ >
19
+ <span class="tel-error-name" title=${t.name}>${t.name}</span>
20
+ <span class="tel-message" title=${t.message}>${t.message}</span>
21
+ <span class="tel-timestamp">${r}</span>
22
+ </div>
23
+ ${o&&t.stack?a`<div class="error-stack">${t.stack}</div>`:d}
24
+ `}render(){let t=this.store.state.errors;return t.length===0?a`<bk-empty-state
25
+ title="No errors"
26
+ subtitle="No errors have been captured yet"
27
+ ></bk-empty-state>`:a`
28
+ <div class="col-header">
29
+ <span style="width:180px">Type</span>
30
+ <span style="flex:1">Message</span>
31
+ <span style="width:130px;text-align:right">Time</span>
32
+ </div>
33
+ <div id="error-list">
34
+ ${t.map((s,r)=>this.renderErrorRow(s,r))}
35
+ </div>
36
+ `}};h([R({context:x})],at.prototype,"store",2),h([E()],at.prototype,"expandedIdx",2),at=h([g("bk-errors-view")],at);var At=class extends f{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}renderAnalysis(e){if(e.length===0)return d;let t={error:0,warn:0,info:0,debug:0,log:0};for(let s of e)t[s.level]!==void 0&&t[s.level]++;return a`
37
+ <div id="log-analysis">
38
+ <div class="fetch-summary">
39
+ <bk-stat-card value=${String(e.length)} label="Total Logs"></bk-stat-card>
40
+ ${t.error>0?a`<bk-stat-card value=${String(t.error)} label="Errors" color="var(--red)"></bk-stat-card>`:d}
41
+ ${t.warn>0?a`<bk-stat-card value=${String(t.warn)} label="Warnings" color="var(--amber)"></bk-stat-card>`:d}
42
+ <bk-stat-card value=${String(t.info)} label="Info"></bk-stat-card>
43
+ ${t.debug>0?a`<bk-stat-card value=${String(t.debug)} label="Debug"></bk-stat-card>`:d}
44
+ ${t.log>0?a`<bk-stat-card value=${String(t.log)} label="Log"></bk-stat-card>`:d}
45
+ </div>
46
+ </div>
47
+ `}renderLogRow(e){let t=new Date(e.timestamp).toLocaleTimeString();return a`
48
+ <div class="req-row">
49
+ <span class="tel-level tel-level-${e.level}">${e.level.toUpperCase()}</span>
50
+ <span class="tel-message tel-mono" title=${e.message}>${e.message}</span>
51
+ <span class="tel-timestamp">${t}</span>
52
+ </div>
53
+ `}render(){let e=this.store.state.logs;return e.length===0?a`<bk-empty-state
54
+ title="No logs"
55
+ subtitle="No console output has been captured yet"
56
+ ></bk-empty-state>`:a`
57
+ ${this.renderAnalysis(e)}
58
+ <div class="col-header">
59
+ <span style="width:52px">Level</span>
60
+ <span style="flex:1">Message</span>
61
+ <span style="width:130px;text-align:right">Time</span>
62
+ </div>
63
+ <div id="log-list">
64
+ ${e.map(t=>this.renderLogRow(t))}
65
+ </div>
66
+ `}};h([R({context:x})],At.prototype,"store",2),At=h([g("bk-logs-view")],At);var tr=new Set(["SELECT","FROM","WHERE","AND","OR","INSERT","INTO","VALUES","UPDATE","SET","DELETE","JOIN","LEFT","RIGHT","INNER","OUTER","ON","GROUP","BY","ORDER","HAVING","LIMIT","OFFSET","AS","IN","NOT","NULL","IS","LIKE","BETWEEN","EXISTS","CASE","WHEN","THEN","ELSE","END","COUNT","SUM","AVG","MIN","MAX","DISTINCT","UNION","ALL","CREATE","TABLE","ALTER","DROP","INDEX","RETURNING","WITH","RECURSIVE","OVER","PARTITION","WINDOW","FETCH","NEXT","ROWS","ONLY","CAST","COALESCE","NULLIF","EXTRACT","INTERVAL","TRUE","FALSE","ASC","DESC","USING","NATURAL","CROSS","FULL","ROLLBACK","COMMIT","BEGIN","TRANSACTION","SAVEPOINT","RELEASE"]);function ls(i){let e=i.trim().match(/^(\w+)/);return e?e[1].toUpperCase():"?"}function cs(i){let e=i.replace(/\s+/g," ").trim(),t=e.match(/\bFROM\s+["'`]?(\w+)["'`]?/i);if(t)return t[1];let s=e.match(/\bINTO\s+["'`]?(\w+)["'`]?/i);if(s)return s[1];let r=e.match(/\bUPDATE\s+["'`]?(\w+)["'`]?/i);return r?r[1]:""}function ds(i){return P(i).replace(/\b\w+\b/g,e=>tr.has(e.toUpperCase())?'<span class="sql-kw">'+e+"</span>":e)}var lt=class extends f{constructor(){super(...arguments);this.expandedIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleQuery(t){this.expandedIdx=this.expandedIdx===t?-1:t;}queryDuration(t){return t===0?"<1ms":S(t)}getQueryInfo(t){let s=(t.normalizedOp||t.operation||(t.sql?ls(t.sql):"?")).toUpperCase(),r=t.table||t.model||(t.sql?cs(t.sql):""),o=t.sql||s+" "+r;return {op:s,table:r,sqlText:o}}renderQueryRow(t,s){let{op:r,table:o,sqlText:n}=this.getQueryInfo(t),l=Ft[r]||"var(--text-dim)",c=t.durationMs>ue,p=t.sql||r+" "+o,u=this.expandedIdx===s;return a`
67
+ <div>
68
+ <div
69
+ class="req-row query-row tel-clickable ${u?"expanded":""}"
70
+ @click=${()=>this.toggleQuery(s)}
71
+ >
72
+ <span class="query-op" title=${r} style="color:${l}">${r}</span>
73
+ <span class="query-table" title=${o}>${o}</span>
74
+ <span class="query-preview" title=${p}>${p}</span>
75
+ <span class="query-dur${c?" query-slow":""}">${this.queryDuration(t.durationMs)}</span>
76
+ </div>
77
+ <div class="query-detail ${u?"open":""}">
78
+ ${u?a`
79
+ <pre class="query-detail-sql" .innerHTML=${ds(n)}></pre>
80
+ <bk-copy-button .text=${n} label="Copy"></bk-copy-button>
81
+ `:d}
82
+ </div>
83
+ </div>
84
+ `}render(){let t=this.store.state.queries;return t.length===0?a`<bk-empty-state
85
+ title="No queries"
86
+ subtitle="No database queries have been captured yet"
87
+ ></bk-empty-state>`:a`
88
+ <div class="col-header">
89
+ <span style="width:70px;border-right:1px solid var(--border);padding-right:16px">Operation</span>
90
+ <span style="width:170px;border-right:1px solid var(--border);padding-right:16px">Table</span>
91
+ <span style="flex:1;border-right:1px solid var(--border);padding-right:16px">Query</span>
92
+ <span style="width:60px;text-align:right">Time</span>
93
+ </div>
94
+ <div id="query-list">
95
+ ${t.map((s,r)=>this.renderQueryRow(s,r))}
96
+ </div>
97
+ `}};h([R({context:x})],lt.prototype,"store",2),h([E()],lt.prototype,"expandedIdx",2),lt=h([g("bk-queries-view")],lt);function Se(i){return i.replace(/'/g,"'\\''")}function er(i,e){let t=Object.entries(i.headers||{}).filter(([o])=>!ns.has(o)).map(([o,n])=>`-H '${Se(o)}: ${Se(n)}'`).join(" "),s=i.requestBody?` -d '${Se(i.requestBody)}'`:"",r=e?`http://localhost:${e}`:"";return `curl -X ${i.method} ${t}${s} '${r}${i.url}'`}function ct(i){let e=window.__BRAKIT_CONFIG__?.port??"",t=er(i,e);navigator.clipboard.writeText(t).then(()=>C.show("Copied cURL command"));}var dt=class extends f{constructor(){super(...arguments);this.expandedId=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleRequest(t){this.expandedId=this.expandedId===t?null:t;}handleCopyAsCurl(t,s){s.stopPropagation(),ct(t);}renderDetail(t){return a`
98
+ <div class="detail-meta">
99
+ <span><bk-method-badge .method=${t.method}></bk-method-badge> ${t.url}</span>
100
+ <span><bk-status-pill .code=${t.statusCode}></bk-status-pill></span>
101
+ <span>${t.durationMs}ms</span>
102
+ ${t.responseSize?a`<span>${U(t.responseSize)}</span>`:d}
103
+ </div>
104
+ <div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>
105
+ <div class="detail-grid">
106
+ <div class="detail-section"><h4>Request Headers</h4><pre .innerHTML=${rt(t.headers)}></pre></div>
107
+ <div class="detail-section"><h4>Response Headers</h4><pre .innerHTML=${rt(t.responseHeaders)}></pre></div>
108
+ <div class="detail-section"><h4>Request Body</h4><pre .innerHTML=${X(t.requestBody)}></pre></div>
109
+ <div class="detail-section"><h4>Response Body</h4><pre .innerHTML=${X(t.responseBody)}></pre></div>
110
+ </div>
111
+ <div class="detail-actions">
112
+ <button class="btn btn-curl" @click=${s=>this.handleCopyAsCurl(t,s)}>Copy cURL</button>
113
+ </div>
114
+ `}renderRequestRow(t){let s=this.expandedId===t.id;return a`
115
+ <div class="req-row ${s?"expanded":""}" @click=${()=>this.toggleRequest(t.id)}>
116
+ <div class="req-summary">
117
+ <bk-method-badge .method=${t.method}></bk-method-badge>
118
+ <span class="req-url">${t.url}</span>
119
+ <bk-status-pill .code=${t.statusCode}></bk-status-pill>
120
+ <bk-duration-label .ms=${t.durationMs}></bk-duration-label>
121
+ <span class="req-size">${U(t.responseSize)}</span>
122
+ </div>
123
+ </div>
124
+ <div class="req-detail ${s?"open":""}">${s?this.renderDetail(t):d}</div>
125
+ `}render(){let t=this.store.state.requests.filter(s=>!s.path?.startsWith(O));return t.length===0?a`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:a`
126
+ <div class="col-header">
127
+ <span style="width:60px">Method</span>
128
+ <span style="flex:1">URL</span>
129
+ <span style="width:36px;text-align:right">Status</span>
130
+ <span style="width:70px;text-align:right">Time</span>
131
+ <span style="width:60px;text-align:right">Size</span>
132
+ </div>
133
+ <div id="request-list">${t.map(s=>this.renderRequestRow(s))}</div>
134
+ `}};h([R({context:x})],dt.prototype,"store",2),h([E()],dt.prototype,"expandedId",2),dt=h([g("bk-requests-view")],dt);var Ct=class extends f{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}buildGroups(e,t){let s=new Map;for(let o of t)s.set(o.id,o);let r={};for(let o of e){let n=o.method+" "+o.url;r[n]||(r[n]={method:o.method,url:o.url,count:0,totalDur:0,maxDur:0,errors:0,callers:{},statusCodes:{},firstTs:o.timestamp,lastTs:o.timestamp});let l=r[n];if(l.count++,l.totalDur+=o.durationMs,o.durationMs>l.maxDur&&(l.maxDur=o.durationMs),o.statusCode>=400&&l.errors++,l.statusCodes[o.statusCode]=(l.statusCodes[o.statusCode]||0)+1,o.timestamp<l.firstTs&&(l.firstTs=o.timestamp),o.timestamp>l.lastTs&&(l.lastTs=o.timestamp),o.parentRequestId){let c=s.get(o.parentRequestId);c&&(l.callers[c.method+" "+(c.path||c.url)]=1);}}return Object.values(r).sort((o,n)=>n.count-o.count)}renderSummary(e){let t=new Set,s=0,r=0;for(let n of e)t.add(n.url),n.statusCode>=400&&s++,r+=n.durationMs;let o=Math.round(r/e.length);return a`
135
+ <div class="fetch-summary">
136
+ <bk-stat-card value=${String(e.length)} label="Total Fetches"></bk-stat-card>
137
+ <bk-stat-card value=${String(t.size)} label="Unique URLs"></bk-stat-card>
138
+ <bk-stat-card value=${String(s)} label="Errors" color=${s>0?"var(--red)":""}></bk-stat-card>
139
+ <bk-stat-card value=${S(o)} label="Avg Duration"></bk-stat-card>
140
+ </div>
141
+ `}formatTime(e){return new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}renderGroup(e){let t=Math.round(e.totalDur/e.count),s=e.count>0?Math.round(e.errors/e.count*100):0,r=Object.keys(e.callers),o=Object.entries(e.statusCodes),n=o.length>0?Number(o.sort((l,c)=>c[1]-l[1])[0][0]):0;return a`
142
+ <div class="fetch-group">
143
+ <div class="fetch-group-header">
144
+ <bk-method-badge .method=${e.method}></bk-method-badge>
145
+ <span class="fetch-group-url" title=${e.url}>${e.url}</span>
146
+ ${n>0?a`<bk-status-pill .code=${n}></bk-status-pill>`:d}
147
+ <span class="fetch-group-count">${e.count}x</span>
148
+ </div>
149
+ <div class="fetch-group-meta">
150
+ <span>avg ${S(t)}</span>
151
+ <span class="fetch-group-sep">\u00b7</span>
152
+ <span>max ${S(e.maxDur)}</span>
153
+ <span class="fetch-group-sep">\u00b7</span>
154
+ ${s>0?a`<span class="fetch-group-err">${s}% errors</span>`:a`<span class="fetch-group-ok">0% errors</span>`}
155
+ </div>
156
+ ${e.firstTs>0?a`
157
+ <div class="fetch-group-timeline">
158
+ <span class="fetch-group-timeline-dot"></span>
159
+ <span class="fetch-group-timeline-range">
160
+ ${this.formatTime(e.firstTs)}${e.firstTs!==e.lastTs?a` \u2192 ${this.formatTime(e.lastTs)}`:d}
161
+ </span>
162
+ </div>`:d}
163
+ ${r.length>0?a`
164
+ <div class="fetch-group-callers">
165
+ <span class="fetch-group-callers-label">Called by</span>
166
+ ${r.map(l=>a`<span class="fetch-group-caller-pill">${l}</span>`)}
167
+ </div>`:d}
168
+ </div>
169
+ `}render(){let e=this.store.state.fetches,t=this.store.state.requests;if(e.length===0)return a`<bk-empty-state title="No fetches" subtitle="No outbound HTTP calls have been captured yet"></bk-empty-state>`;let s=this.buildGroups(e,t);return a`
170
+ <div class="fetch-analysis" id="fetch-analysis">
171
+ ${this.renderSummary(e)}
172
+ ${s.length>0?a`
173
+ <div class="fetch-groups-title">Grouped by URL (${s.length})</div>
174
+ <div class="fetch-groups">${s.map(r=>this.renderGroup(r))}</div>
175
+ `:d}
176
+ </div>
177
+ `}};h([R({context:x})],Ct.prototype,"store",2),Ct=h([g("bk-fetches-view")],Ct);function ps(i,e){if(e>=400)return "var(--red)";switch(i){case "GET":return "var(--green)";case "POST":return "var(--blue)";case "PUT":case "PATCH":return "var(--amber)";case "DELETE":return "var(--red)";default:return "var(--text-muted)"}}function $e(i){return i==="query"?"var(--accent)":"var(--cyan)"}function or(i){return i.type==="query"||i.type==="fetch"}function nr(i){let e=(i.normalizedOp||i.operation||"QUERY").toUpperCase(),t=i.table||i.model||"";return {label:`${e} ${t}`,tooltip:i.sql||`${e} ${t}`}}function ar(i){return {label:`${i.method} ${i.url}`,tooltip:`${i.method} ${i.url}`}}function lr(i,e,t,s,r,o){let n=i.data.durationMs||0,l,c;if(o){let p=Math.max(i.timestamp-s,0);l=Math.min(p/r*100,95),c=Math.max(n/r*100,1.5);}else {let p=t[0].timestamp,m=t[t.length-1].timestamp-p;l=m>0?(i.timestamp-p)/m*85:e/Math.max(t.length-1,1)*85,c=Math.max(n/r*100,1.5);}return l+c>100&&(c=Math.max(100-l,1.5)),{leftPct:l,widthPct:c}}function cr(i,e){let t=i.timeline.filter(or);if(t.length===0)return [];let s=e.startedAt,r=e.durationMs||1,o=Math.abs(t[0].timestamp-s)<r*10;return t.map((n,l)=>{let c=n.data.durationMs||0,{leftPct:p,widthPct:u}=lr(n,l,t,s,r,o),m=n.type==="query"?nr(n.data):ar(n.data);return {type:n.type,label:m.label,durMs:c,durLabel:S(c),tooltip:m.tooltip,leftPct:p,widthPct:u}})}function hs(i,e){let t=i.requests.filter(l=>!l.isStrictModeDupe);if(t.length===0)return {rows:[],totalMs:0};let s=Math.min(...t.map(l=>l.startedAt)),o=Math.max(...t.map(l=>l.startedAt+l.durationMs))-s;return o===0?{rows:[],totalMs:0}:{rows:t.map(l=>{let c=(l.startedAt-s)/o*100,p=Math.max(l.durationMs/o*100,.5),u=e?.activities?.[l.id],m=u?cr(u,l):[];return {label:`${l.method} ${l.label}`,leftPct:c,widthPct:p,color:ps(l.method,l.statusCode),durMs:l.durationMs,durLabel:S(l.durationMs),tooltip:`${l.method} ${l.label} (${S(l.durationMs)})`,subEvents:m}}),totalMs:o}}function ms(i){let e=i.requests,t=[],s=[],r=[],o=[],n=new Map;for(let p of e){let u=p.label,m=p.pollingDurationMs||p.durationMs;if(!Tt[p.category||""]){if(p.isDuplicate){let b=n.get(u);b?(b.count++,b.wastedMs+=m):n.set(u,{name:u,count:2,wastedMs:m});continue}if(p.statusCode>=400){s.push(u+" ("+as(p.statusCode)+")");continue}p.responseSize>51200&&r.push("Large response: "+u+" returned "+U(p.responseSize)),t.push(u);}}for(let p of n.values())o.push(p);let l="";if(o.length>0){let p=o.map(m=>m.name).join(", "),u=o.reduce((m,b)=>m+b.wastedMs,0);l="Your app fetches "+p+" multiple times on this page. This wastes ~"+S(u)+". Try caching these calls, deduplicating with React Query/SWR, or moving them to a shared layout.";}else s.length>0&&(l="Some requests are failing. Check your API routes and make sure the endpoints exist.");let c=e.filter(p=>p.durationMs>2e3&&p.category!==et);return c.length>0&&!l&&(l=c.map(p=>p.label).join(", ")+` is taking over ${S(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:t,errors:s,warnings:r,duplicates:o,tip:l}}var M=class extends f{constructor(){super(...arguments);this.expandedFlowIdx=-1;this.expandedSubReqIdx=-1;this.flowDetailTab="insights";this.flowTimeline=null;this.flowTimelineLoading=false;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}get flows(){return this.store.state.flows}get viewMode(){return this.store.state.viewMode}flowDotClass(t){return t.hasErrors?"dot-error":t.redundancyPct>0?"dot-warn":"dot-clean"}flowBadgeInfo(t){if(t.hasErrors){let s=t.requests.filter(r=>r.statusCode>=400).length;return {text:s+" error"+(s!==1?"s":""),cls:"badge-error"}}return t.redundancyPct>0?{text:t.redundancyPct+"% redundant",cls:"badge-warn"}:{text:"clean",cls:"badge-clean"}}toggleFlow(t){this.expandedFlowIdx===t?this.expandedFlowIdx=-1:(this.expandedFlowIdx=t,this.expandedSubReqIdx=-1,this.flowDetailTab="insights",this.flowTimeline=null);}toggleSubReq(t,s){s.stopPropagation(),this.expandedSubReqIdx=this.expandedSubReqIdx===t?-1:t;}toggleBodyBlock(t){t.stopPropagation();let s=t.currentTarget,r=s.parentElement;if(!r)return;s.classList.toggle("open");let o=r.querySelector("pre");o&&o.classList.toggle("open");}switchTab(t,s,r){r.stopPropagation(),this.flowDetailTab=t,t==="timeline"&&!this.flowTimeline&&this.loadFlowTimeline(s);}async loadFlowTimeline(t){if(this.flowTimelineLoading)return;let s=t.requests.map(r=>r.id).filter(Boolean);if(s.length!==0){this.flowTimelineLoading=true;try{let r=await fetch(`${y.activity}?requestIds=${s.join(",")}`);if(!r.ok){this.flowTimelineLoading=!1;return}this.flowTimeline=await r.json();}catch{}this.flowTimelineLoading=false;}}loadTimelineForContainer(t){let s=t.querySelectorAll(".request-timeline");for(let r of s){let o=r.getAttribute("data-request-id");if(o&&!r.hasAttribute("data-loaded")){r.setAttribute("data-loaded","1");let n=document.createElement("bk-timeline-panel");n.setAttribute("request-id",o),n.setAttribute("request-started",r.getAttribute("data-request-started")||"0"),r.appendChild(n),r.classList.remove("tl-hidden");}}}updated(){if(this.expandedFlowIdx>=0&&this.flowDetailTab==="insights"){let t=this.querySelector(".flow-expand.open");t&&this.loadTimelineForContainer(t);}}render(){let t=this.flows;return t.length===0?a`<bk-empty-state
178
+ title="No actions yet"
179
+ subtitle="Start using your app to see user action flows here"
180
+ ></bk-empty-state>`:a`
181
+ <div id="flow-col-header" class="col-header">
182
+ <span style="width:8px"></span>
183
+ <span style="flex:1">Action</span>
184
+ <span style="width:60px;text-align:right">Reqs</span>
185
+ <span style="width:120px;text-align:right">Status</span>
186
+ <span style="width:70px;text-align:right">Time</span>
187
+ </div>
188
+ <div id="flow-list">
189
+ ${t.map((s,r)=>this.renderFlowRow(s,r))}
190
+ </div>
191
+ `}renderFlowRow(t,s){let r=this.expandedFlowIdx===s,o=this.flowDotClass(t),n=this.flowBadgeInfo(t);return a`
192
+ <div
193
+ class="flow-row ${r?"expanded":""}"
194
+ @click=${()=>this.toggleFlow(s)}
195
+ >
196
+ <div class="flow-summary-row">
197
+ <span class="flow-status-dot ${o}"></span>
198
+ <span class="flow-label">${t.label}</span>
199
+ <span class="flow-req-count"
200
+ >${t.requests.length}
201
+ req${t.requests.length!==1?"s":""}</span
202
+ >
203
+ <span class="flow-badge-pill ${n.cls}">${n.text}</span>
204
+ <span class="flow-duration"
205
+ >${S(t.totalDurationMs)}</span
206
+ >
207
+ </div>
208
+ </div>
209
+ <div class="flow-expand ${r?"open":""}">
210
+ ${r?this.renderFlowDetail(t):d}
211
+ </div>
212
+ `}renderFlowDetail(t){let s=this.viewMode==="simple"?"Insights":"Details";return a`
213
+ <div class="flow-detail-tabs">
214
+ <button
215
+ class="flow-tab ${this.flowDetailTab==="insights"?"active":""}"
216
+ @click=${r=>this.switchTab("insights",t,r)}
217
+ >
218
+ ${s}
219
+ </button>
220
+ <button
221
+ class="flow-tab ${this.flowDetailTab==="timeline"?"active":""}"
222
+ @click=${r=>this.switchTab("timeline",t,r)}
223
+ >
224
+ Timeline
225
+ </button>
226
+ </div>
227
+ ${this.flowDetailTab==="insights"?this.viewMode==="simple"?this.renderFlowInsights(t):this.renderFlowSubReqs(t):this.renderFlowWaterfall(t)}
228
+ `}renderFlowWaterfall(t){if(this.flowTimelineLoading)return a`<div class="wf-loading">Loading timeline...</div>`;let{rows:s,totalMs:r}=hs(t,this.flowTimeline);if(s.length===0)return d;let o=[];for(let n=0;n<=5;n++)o.push(S(r/5*n));return a`
229
+ <div class="flow-waterfall">
230
+ <div class="wf-time-axis">
231
+ ${o.map(n=>a`<span>${n}</span>`)}
232
+ </div>
233
+ <div class="wf-rows">
234
+ ${s.map(n=>this.renderWaterfallGroup(n))}
235
+ </div>
236
+ </div>
237
+ `}renderWaterfallGroup(t){return a`
238
+ <div class="wf-request-group">
239
+ <div class="wf-req-row" title="${t.tooltip}">
240
+ <div class="wf-req-label">${t.label}</div>
241
+ <div class="wf-bar-track">
242
+ <div
243
+ class="wf-bar"
244
+ style="left:${t.leftPct}%;width:${t.widthPct}%;background:${t.color}"
245
+ ></div>
246
+ </div>
247
+ <div class="wf-req-dur">${t.durLabel}</div>
248
+ </div>
249
+ ${t.subEvents.length>0?t.subEvents.map(s=>a`
250
+ <div class="wf-sub-row" title="${s.tooltip}">
251
+ <div class="wf-sub-label">
252
+ <span
253
+ class="wf-sub-dot"
254
+ style="background:${$e(s.type)}"
255
+ ></span>
256
+ ${s.label}
257
+ </div>
258
+ <div class="wf-bar-track">
259
+ <div
260
+ class="wf-bar wf-sub-bar-sized"
261
+ style="left:${t.leftPct+s.leftPct/100*t.widthPct}%;width:${s.widthPct/100*t.widthPct}%;background:${$e(s.type)}"
262
+ ></div>
263
+ </div>
264
+ <div class="wf-sub-dur">${s.durLabel}</div>
265
+ </div>
266
+ `):d}
267
+ </div>
268
+ `}renderFlowInsights(t){let s=ms(t),r=s.errors.length>0||s.duplicates.length>0||s.warnings.length>0||!!s.tip;return a`
269
+ <div>
270
+ <div class="flow-traffic">
271
+ ${t.requests.map(o=>this.renderTrafficCard(o))}
272
+ </div>
273
+ ${r?a`
274
+ <div class="flow-divider"></div>
275
+ <div class="flow-insights">
276
+ ${s.errors.map(o=>a`<div class="insight-line insight-error">
277
+ ✗ ${o}
278
+ </div>`)}
279
+ ${s.duplicates.map(o=>a`<div class="insight-line insight-warn">
280
+ ⚠ ${o.name} — loaded ${o.count}x (wasting
281
+ ~${S(o.wastedMs)})
282
+ </div>`)}
283
+ ${s.warnings.map(o=>a`<div class="insight-line insight-warn">⚠ ${o}</div>`)}
284
+ ${s.tip?a`<div class="insight-line insight-tip">
285
+ Tip: ${s.tip}
286
+ </div>`:d}
287
+ </div>
288
+ `:d}
289
+ </div>
290
+ `}renderTrafficCard(t){if(Tt[t.category||""])return d;let s=st(t.statusCode),r=S(t.pollingDurationMs||t.durationMs),o=!t.isDuplicate&&t.category!==Ht&&t.category!==et||t.requestBody&&t.method!=="GET"||!!t.responseBody;return a`
291
+ <div
292
+ class="traffic-card ${t.isStrictModeDupe?"strict-mode-dupe":""}"
293
+ >
294
+ <div class="traffic-card-header ${o?"has-details":""}">
295
+ <bk-method-badge .method=${t.method}></bk-method-badge>
296
+ <span class="traffic-card-path ${t.isDuplicate?"is-dup":""}"
297
+ >${t.label}</span
298
+ >
299
+ <span class="status-pill ${s}">${t.statusCode}</span>
300
+ <span class="traffic-card-dur">${r}</span>
301
+ ${t.isDuplicate?a`<span class="traffic-card-dup">duplicate</span>`:a`<span class="traffic-card-size"
302
+ >${U(t.responseSize)}</span
303
+ >`}
304
+ </div>
305
+ ${t.isStrictModeDupe?a`<div class="strict-mode-banner">
306
+ React Strict Mode duplicate — does not happen in production
307
+ </div>`:d}
308
+ ${!t.isDuplicate&&t.category!==Ht&&t.category!==et?a`<div
309
+ class="request-timeline tl-hidden"
310
+ data-request-id=${t.id}
311
+ data-request-started=${String(t.startedAt)}
312
+ ></div>`:d}
313
+ ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):d}
314
+ ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):d}
315
+ </div>
316
+ `}renderBodyToggle(t,s,r){let o=t==="out"?"\u2192":"\u2190";return a`
317
+ <div class="traffic-body">
318
+ <button class="traffic-body-toggle" @click=${this.toggleBodyBlock}>
319
+ <span class="chevron">▸</span
320
+ ><span class="arrow-${t}">${o}</span> ${s}
321
+ </button>
322
+ <pre .innerHTML=${X(r)}></pre>
323
+ </div>
324
+ `}renderFlowSubReqs(t){return a`<div class="flow-subreqs">
325
+ ${t.requests.map((s,r)=>this.renderSubReqRow(s,r))}
326
+ </div>`}renderSubReqRow(t,s){let r=this.expandedSubReqIdx===s,o=st(t.statusCode),n=t.pollingDurationMs?S(t.pollingDurationMs):S(t.durationMs);return a`
327
+ <div
328
+ class="flow-subreq ${r?"expanded":""}"
329
+ @click=${l=>this.toggleSubReq(s,l)}
330
+ >
331
+ <bk-method-badge .method=${t.method}></bk-method-badge>
332
+ <span class="subreq-label ${t.isDuplicate?"is-dup":""}"
333
+ >${t.path||t.url}</span
334
+ >
335
+ ${t.isDuplicate?a`<span class="subreq-dup-tag">duplicate</span>`:d}
336
+ <span class="status-pill ${o}">${t.statusCode}</span>
337
+ <span class="subreq-dur">${n}</span>
338
+ </div>
339
+ <div class="flow-subreq-detail ${r?"open":""}">
340
+ ${r?this.renderSubReqDetail(t):d}
341
+ </div>
342
+ `}renderSubReqDetail(t){let s=st(t.statusCode);return a`
343
+ <div class="detail-meta">
344
+ <span
345
+ ><bk-method-badge .method=${t.method}></bk-method-badge> ${P(t.url)}</span
346
+ >
347
+ <span
348
+ ><span class="status-pill ${s}">${t.statusCode}</span></span
349
+ >
350
+ <span>${t.durationMs}ms</span>
351
+ ${t.responseSize?a`<span>${U(t.responseSize)}</span>`:d}
352
+ </div>
353
+ <div
354
+ class="request-timeline tl-hidden"
355
+ data-request-id=${t.id}
356
+ data-request-started=${String(t.startedAt)}
357
+ ></div>
358
+ <div class="detail-grid">
359
+ <div class="detail-section">
360
+ <h4>Request Headers</h4>
361
+ <pre .innerHTML=${rt(t.headers)}></pre>
362
+ </div>
363
+ <div class="detail-section">
364
+ <h4>Response Headers</h4>
365
+ <pre .innerHTML=${rt(t.responseHeaders)}></pre>
366
+ </div>
367
+ <div class="detail-section">
368
+ <h4>Request Body</h4>
369
+ <pre .innerHTML=${X(t.requestBody)}></pre>
370
+ </div>
371
+ <div class="detail-section">
372
+ <h4>Response Body</h4>
373
+ <pre .innerHTML=${X(t.responseBody)}></pre>
374
+ </div>
375
+ </div>
376
+ <div class="detail-actions">
377
+ <button
378
+ class="btn btn-curl"
379
+ @click=${r=>{r.stopPropagation(),ct(t);}}
380
+ >
381
+ Copy cURL
382
+ </button>
383
+ </div>
384
+ `}};h([R({context:x})],M.prototype,"store",2),h([E()],M.prototype,"expandedFlowIdx",2),h([E()],M.prototype,"expandedSubReqIdx",2),h([E()],M.prototype,"flowDetailTab",2),h([E()],M.prototype,"flowTimeline",2),h([E()],M.prototype,"flowTimelineLoading",2),M=h([g("bk-flows-view")],M);var It=class extends f{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}render(){let e=(this.store.state.issues||[]).slice(),t=e.filter(l=>l.state==="open"||l.state==="fixing"||l.state==="regressed"),s=e.filter(l=>l.state==="resolved");if(t.length===0&&s.length===0)return this.store.state.requests.length>0||this.store.state.logs.length>0||this.store.state.queries.length>0?a`
385
+ <div class="sec-clear">
386
+ <span class="sec-clear-icon">\u2713</span>
387
+ <div class="sec-clear-text">
388
+ <div class="sec-clear-title">All clear</div>
389
+ <div class="sec-clear-sub">No security or quality issues detected this session</div>
390
+ </div>
391
+ </div>
392
+ `:a`<bk-empty-state title="Waiting for requests..." subtitle="Start using your app to see security findings here"></bk-empty-state>`;let r=0,o=0,n=0;for(let l of t){let c=l.issue.severity;c==="critical"?r++:c==="info"?n++:o++;}return a`
393
+ <div id="security-content">
394
+ ${this.renderSummary(t.length,s.length,r,o,n)}
395
+ ${t.length===0&&s.length>0?a`
396
+ <div class="sec-clear">
397
+ <span class="sec-clear-icon">\u2713</span>
398
+ <div class="sec-clear-text">
399
+ <div class="sec-clear-title">All issues resolved</div>
400
+ <div class="sec-clear-sub">${s.length} finding${s.length!==1?"s were":" was"} detected and fixed</div>
401
+ </div>
402
+ </div>
403
+ `:d}
404
+ ${t.length>0?this.renderOpenGroups(t):d}
405
+ ${s.length>0?this.renderResolved(s):d}
406
+ </div>
407
+ `}renderSummary(e,t,s,r,o){return a`
408
+ <div class="sec-summary">
409
+ <div class="sec-summary-left">
410
+ <span class="sec-summary-count">${e}</span>
411
+ <span class="sec-summary-label">open issue${e!==1?"s":""}</span>
412
+ ${t>0?a`<span class="sec-resolved-badge">${t} resolved</span>`:d}
413
+ </div>
414
+ <div class="sec-summary-right">
415
+ ${s>0?a`<span class="sec-badge critical">${s} critical</span>`:d}
416
+ ${r>0?a`<span class="sec-badge warning">${r} warning</span>`:d}
417
+ ${o>0?a`<span class="sec-badge info">${o} info</span>`:d}
418
+ </div>
419
+ </div>
420
+ `}renderOpenGroups(e){let t={},s=[];for(let r of e){let o=r.issue,n=o.rule||o.type;t[n]||(t[n]={rule:n,title:o.title,severity:o.severity,hint:o.hint,items:[]},s.push(n)),t[n].items.push(r);}return s.sort((r,o)=>{let n=q[t[r].severity]?.sort??2,l=q[t[o].severity]?.sort??2;return n!==l?n-l:t[o].items.length-t[r].items.length}),a`${s.map(r=>this.renderGroup(t[r]))}`}renderGroup(e){let t=q[e.severity]||q.info;return a`
421
+ <div class="sec-group">
422
+ <div class="sec-group-header">
423
+ <span class="sec-group-icon ${t.cls}">${t.icon}</span>
424
+ <span class="sec-group-title">${e.title}</span>
425
+ <span class="sec-group-count">${e.items.length}</span>
426
+ </div>
427
+ ${e.hint?a`<div class="sec-hint">${e.hint}</div>`:d}
428
+ <div class="sec-items">${e.items.map(s=>this.renderIssueItem(s))}</div>
429
+ </div>
430
+ `}renderIssueItem(e){let t=e.issue;return a`
431
+ <div class="sec-item">
432
+ <div class="sec-item-desc">${t.desc}</div>
433
+ ${e.occurrences>1?a`<span class="sec-item-count">${e.occurrences}x</span>`:d}
434
+ ${e.state==="fixing"&&e.aiStatus==="fixed"?a`<span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>`:e.aiStatus==="wont_fix"?a`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:e.state==="regressed"?a`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:d}
435
+ ${e.aiNotes?a`<div class="sec-ai-notes">${e.aiNotes}</div>`:d}
436
+ </div>
437
+ `}renderResolved(e){return a`
438
+ <div class="sec-resolved-title">
439
+ <span class="sec-resolved-check">\u2713</span> Resolved
440
+ <span class="sec-resolved-count">${e.length}</span>
441
+ </div>
442
+ <div class="sec-group sec-group-resolved">
443
+ <div class="sec-items">
444
+ ${e.map(t=>a`
445
+ <div class="sec-item sec-item-resolved">
446
+ <span class="sec-resolved-item-icon">\u2713</span>
447
+ <div class="sec-item-desc">${t.issue.title} \u2014 ${t.issue.endpoint||"global"}</div>
448
+ ${t.aiStatus==="fixed"?a`<span class="sec-ai-badge sec-ai-verified">Verified fix</span>`:d}
449
+ ${t.aiNotes?a`<div class="sec-ai-notes">${t.aiNotes}</div>`:d}
450
+ </div>
451
+ `)}
452
+ </div>
453
+ </div>
454
+ `}};h([R({context:x})],It.prototype,"store",2),It=h([g("bk-security-view")],It);var pt=class extends f{constructor(){super(...arguments);this.expandedCardIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}navigateToView(t){let s=document.querySelectorAll(".sidebar-item");for(let r of s){let o=r.querySelector(".item-label");if(o&&o.textContent?.trim()===(yt[t]||t)){r.click();return}}}toggleCard(t,s){let r=s.target;for(;r&&r!==s.currentTarget;){if(r.classList?.contains("ov-card-link")){let o=r.getAttribute("data-nav");o&&this.navigateToView(o);return}r=r.parentElement;}this.expandedCardIdx=this.expandedCardIdx===t?-1:t;}render(){let t=this.store.state,s=t.requests.filter(v=>!v.isStatic&&!v.isHealthCheck&&(!v.path||v.path.indexOf(O)!==0));if(!(s.length>0||t.queries.length>0||t.errors.length>0))return a`<bk-empty-state
455
+ title="Waiting for requests..."
456
+ subtitle="Start using your app to see insights here"
457
+ ></bk-empty-state>`;let o=s.filter(v=>v.statusCode>=400).length,n=new Set(["data-fetch","api-call","server-action","page-load"]),l=s.filter(v=>v.category&&n.has(v.category)),c=l.length>0?l:s,p=c.length>0?Math.round(c.reduce((v,L)=>v+L.durationMs,0)/c.length):0,u=t.issues||[],m=u.filter(v=>v.state==="open"||v.state==="regressed"),b=u.filter(v=>v.state==="fixing"),$=u.filter(v=>v.state==="resolved");return a`
458
+ <div class="ov-container" id="overview-content">
459
+ ${this.renderSummary(s.length,t.flows.length,p,t.queries.length,o,t.fetches.length)}
460
+ ${m.length===0&&b.length===0&&$.length===0?a`<div class="ov-clear">
461
+ <span class="ov-clear-icon">\u2713</span>All clear \u2014 no issues detected
462
+ </div>`:d}
463
+ ${m.length===0&&$.length>0?a`<div class="ov-clear">
464
+ <span class="ov-clear-icon">\u2713</span>All issues resolved \u2014
465
+ ${$.length} finding${$.length!==1?"s were":" was"} detected and
466
+ fixed
467
+ </div>`:d}
468
+ ${m.length>0?this.renderOpenIssues(m):d}
469
+ ${b.length>0?this.renderVerifying(b):d}
470
+ ${$.length>0?this.renderResolvedIssues($):d}
471
+ </div>
472
+ `}renderSummary(t,s,r,o,n,l){return a`
473
+ <div class="ov-summary">
474
+ <div class="ov-stat"><span class="ov-stat-value">${t}</span><span class="ov-stat-label">Requests</span></div>
475
+ <div class="ov-stat"><span class="ov-stat-value">${s}</span><span class="ov-stat-label">Actions</span></div>
476
+ <div class="ov-stat"><span class="ov-stat-value">${S(r)}</span><span class="ov-stat-label">Avg Response</span></div>
477
+ <div class="ov-stat"><span class="ov-stat-value">${o}</span><span class="ov-stat-label">Queries</span></div>
478
+ <div class="ov-stat"><span class="ov-stat-value" style="color:${n>0?"var(--red)":"var(--green)"}">${n}</span><span class="ov-stat-label">Errors</span></div>
479
+ <div class="ov-stat"><span class="ov-stat-value">${l}</span><span class="ov-stat-label">Fetches</span></div>
480
+ </div>
481
+ `}renderOpenIssues(t){return a`
482
+ <div class="ov-section-title">Issues Found <span class="ov-issue-count">${t.length}</span></div>
483
+ <div class="ov-cards">${t.map((s,r)=>this.renderIssueCard(s,r))}</div>
484
+ `}renderIssueCard(t,s){let r=t.issue,o=q[r.severity]||q.info,n=this.expandedCardIdx===s,l=t.aiStatus==="wont_fix"?a`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:t.state==="regressed"?a`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:d,c=t.cleanHitsSinceLastSeen>0?a`<div class="ov-card-resolving">Resolving\u2026 ${t.cleanHitsSinceLastSeen}/${5} clean requests</div>`:d;return a`
485
+ <div class="ov-card ${n?"expanded":""}" @click=${p=>this.toggleCard(s,p)}>
486
+ <span class="ov-card-icon ${o.cls}">${o.icon}</span>
487
+ <div class="ov-card-body">
488
+ <div class="ov-card-title">${r.title}${l}</div>
489
+ <div class="ov-card-desc">${r.desc}</div>
490
+ ${c}
491
+ <div class="ov-card-expand" style="display:${n?"block":"none"}">
492
+ ${r.detail?a`<div .innerHTML=${r.detail}></div>`:d}
493
+ ${r.hint?a`<div class="ov-card-hint">${r.hint}</div>`:d}
494
+ ${r.nav?a`<span class="ov-card-link" data-nav=${r.nav}>View in ${ae[r.nav]||r.nav} \u2192</span>`:d}
495
+ </div>
496
+ </div>
497
+ <span class="ov-card-arrow">${n?"\u2193":"\u2192"}</span>
498
+ </div>
499
+ `}renderVerifying(t){return a`
500
+ <div class="ov-section-title ov-resolved-title">
501
+ <span style="color:var(--yellow,#f5a623)">\u29d7</span> Awaiting Verification
502
+ <span class="ov-issue-count">${t.length}</span>
503
+ </div>
504
+ <div class="ov-cards">
505
+ ${t.map(s=>{let r=s.issue,o=s.cleanHitsSinceLastSeen>0?a`<div class="ov-card-resolving">Verifying\u2026 ${s.cleanHitsSinceLastSeen}/${5} clean requests</div>`:d;return a`
506
+ <div class="ov-card ov-card-resolved">
507
+ <span class="ov-card-icon resolved">\u29d7</span>
508
+ <div class="ov-card-body">
509
+ <div class="ov-card-title" style="color:var(--text-muted)">
510
+ ${r.title}
511
+ <span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>
512
+ </div>
513
+ <div class="ov-card-desc">${r.desc}</div>
514
+ ${o}
515
+ </div>
516
+ </div>
517
+ `})}
518
+ </div>
519
+ `}renderResolvedIssues(t){return a`
520
+ <div class="ov-section-title ov-resolved-title">
521
+ <span style="color:var(--green)">\u2713</span> Resolved
522
+ <span class="ov-issue-count">${t.length}</span>
523
+ </div>
524
+ <div class="ov-cards">
525
+ ${t.map(s=>a`
526
+ <div class="ov-card ov-card-resolved">
527
+ <span class="ov-card-icon resolved">\u2713</span>
528
+ <div class="ov-card-body">
529
+ <div class="ov-card-title" style="text-decoration:line-through;color:var(--text-muted)">${s.issue.title}</div>
530
+ <div class="ov-card-desc">${s.issue.desc}</div>
531
+ </div>
532
+ </div>
533
+ `)}
534
+ </div>
535
+ `}};h([R({context:x})],pt.prototype,"store",2),h([E()],pt.prototype,"expandedCardIdx",2),pt=h([g("bk-overview-view")],pt);function jt(i){return i<1?"<1ms":i<1e3?Math.round(i)+"ms":(i/1e3).toFixed(1)+"s"}function dr(i){return i<V?xt.green:i<Y?xt.amber:xt.red}function vs(i){return i.statusCode>=400?xt.red:dr(i.durationMs)}function fs(i){return [parseInt(i.slice(1,3),16),parseInt(i.slice(3,5),16),parseInt(i.slice(5,7),16)]}function gs(i){let e=i.getContext("2d");if(!e)return null;let t=window.devicePixelRatio||1,s=i.clientWidth,r=i.clientHeight;return i.width=s*t,i.height=r*t,e.scale(t,t),{ctx:e,w:s,h:r}}function bs(i,e,t,s,r){let[o,n,l]=fs(r);i.beginPath(),i.arc(e,t,s+2,0,Math.PI*2),i.fillStyle=`rgba(${o},${n},${l},0.25)`,i.fill(),i.beginPath(),i.arc(e,t,s,0,Math.PI*2),i.fillStyle=r,i.fill();}function Es(i,e,t,s,r,o){let[n,l,c]=fs(r);i.strokeStyle=`rgba(${n},${l},${c},0.3)`,i.lineWidth=o+2,i.beginPath(),i.moveTo(e-s,t-s),i.lineTo(e+s,t+s),i.moveTo(e+s,t-s),i.lineTo(e-s,t+s),i.stroke(),i.strokeStyle=r,i.lineWidth=o,i.beginPath(),i.moveTo(e-s,t-s),i.lineTo(e+s,t+s),i.moveTo(e+s,t-s),i.lineTo(e-s,t+s),i.stroke();}function _s(i,e){let t=[],s=gs(i);if(!s||e.length===0)return t;let{ctx:r,w:o,h:n}=s,l=es,c=o-l.left-l.right,p=n-l.top-l.bottom,u=0,m=e[0].timestamp,b=e[0].timestamp;for(let _ of e)_.durationMs>u&&(u=_.durationMs),_.timestamp<m&&(m=_.timestamp),_.timestamp>b&&(b=_.timestamp);u=Math.max(u,10),u=Math.ceil(u*1.15/10)*10;let $=b-m||1;r.strokeStyle=Je,r.lineWidth=1;let v=4;for(let _=0;_<=v;_++){let w=l.top+p-_/v*p;r.beginPath(),r.moveTo(l.left,w),r.lineTo(l.left+c,w),r.stroke(),r.fillStyle=ge,r.font=Ze,r.textAlign="right",r.fillText(jt(Math.round(_/v*u)),l.left-8,w+3);}for(let _ of [{ms:V},{ms:Y}]){if(_.ms>=u)continue;let w=l.top+p-_.ms/u*p;r.beginPath(),r.setLineDash([4,4]),r.strokeStyle="rgba(113,113,122,0.3)",r.lineWidth=1,r.moveTo(l.left,w),r.lineTo(l.left+c,w),r.stroke(),r.setLineDash([]),r.fillStyle="rgba(113,113,122,0.5)",r.font=be,r.textAlign="left",r.fillText(jt(_.ms),l.left+c+2,w+3);}for(let _=0;_<e.length;_++){let w=e[_],ut=e.length===1?l.left+c/2:l.left+(w.timestamp-m)/$*c,Vt=l.top+p-w.durationMs/u*p,ye=vs(w);t.push({x:ut,y:Vt,idx:_,r:w}),w.statusCode>=400?Es(r,ut,Vt,4,ye,2):bs(r,ut,Vt,4,ye);}r.fillStyle=ge,r.font=be,r.textAlign="center";let L=[m,m+$/2,b];for(let _=0;_<L.length;_++){let w=l.left+_/2*c,ut=new Date(L[_]);r.fillText(ut.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),w,l.top+p+14);}return t}function Ss(i,e){let t=gs(i);if(!t||e.length===0)return;let{ctx:s,w:r,h:o}=t,n=4,l=4,c=r-n*2,p=o-l*2,u=0,m=e[0].timestamp,b=e[0].timestamp;for(let v of e)v.durationMs>u&&(u=v.durationMs),v.timestamp<m&&(m=v.timestamp),v.timestamp>b&&(b=v.timestamp);u=Math.max(u,10),u=Math.ceil(u*1.15/10)*10;let $=b-m||1;for(let v of [V,Y]){if(v>=u)continue;let L=l+p-v/u*p;s.beginPath(),s.setLineDash([2,3]),s.strokeStyle="rgba(113,113,122,0.15)",s.lineWidth=1,s.moveTo(n,L),s.lineTo(n+c,L),s.stroke(),s.setLineDash([]);}for(let v of e){let L=e.length===1?n+c/2:n+(v.timestamp-m)/$*c,_=l+p-v.durationMs/u*p,w=vs(v);v.statusCode>=400?Es(s,L,_,2.5,w,1.5):bs(s,L,_,2.5,w);}s.fillStyle="rgba(113,113,122,0.5)",s.font=ts,s.textAlign="right",s.fillText(jt(u),r-2,l+8),s.fillText(jt(0),r-2,o-2);}var B=class extends f{constructor(){super(...arguments);this.selectedEndpoint=H;this.graphData=[];this.loadError=false;this.scatterDots=[];}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate()),this.loadMetrics();}async loadMetrics(){try{let s=await(await fetch(y.metricsLive)).json();this.graphData=s.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===H)&&(this.selectedEndpoint=H);}catch{this.loadError=true;}}healthGrade(t){for(let s of Bt)if(t<s.max)return s;return Bt[Bt.length-1]}fmtMs(t){return t<1?"<1ms":t<1e3?Math.round(t)+"ms":(t/1e3).toFixed(1)+"s"}renderScatterChart(t,s){this.scatterDots=_s(t,s),t.style.cursor="pointer",t.onclick=r=>{let o=t.getBoundingClientRect(),n=r.clientX-o.left,l=r.clientY-o.top,c=null,p=1/0;for(let u of this.scatterDots){let m=Math.sqrt((u.x-n)**2+(u.y-l)**2);m<p&&(p=m,c=u);}c&&p<16&&this.highlightRow(c.idx);};}highlightRow(t){let s=this.querySelector(".perf-hist-row-hl");s&&s.classList.remove("perf-hist-row-hl");let r=this.querySelector(`[data-req-idx="${t}"]`);r&&(r.classList.add("perf-hist-row-hl"),r.scrollIntoView({behavior:"smooth",block:"center"}));}updated(){if(this.selectedEndpoint===H)this.graphData.forEach((t,s)=>{if(t.requests.length===0)return;let r=this.querySelector(`#inline-scatter-${s}`);r&&Ss(r,t.requests);});else {let t=this.querySelector("#perf-detail-canvas");if(t){let s=this.graphData.find(r=>r.endpoint===this.selectedEndpoint);s&&this.renderScatterChart(t,s.requests);}}}render(){return !this.graphData||this.graphData.length===0?a`<bk-empty-state title="No performance data yet" subtitle="Hit some endpoints and data will appear here"></bk-empty-state>`:a`
536
+ <div id="graph-content">
537
+ ${this.renderSelector()}
538
+ ${this.selectedEndpoint===H?this.renderOverview():this.renderDetail()}
539
+ </div>
540
+ `}renderSelector(){return a`
541
+ <div class="perf-selector">
542
+ <button class="perf-selector-btn ${this.selectedEndpoint===H?"active":""}"
543
+ @click=${()=>{this.selectedEndpoint=H;}}>Overview</button>
544
+ ${this.graphData.map((t,s)=>a`
545
+ <button class="perf-selector-btn ${t.endpoint===this.selectedEndpoint?"active":""}"
546
+ @click=${()=>{this.selectedEndpoint=t.endpoint;}}>
547
+ <span class="perf-dot" style="background:${fe[s%fe.length]}"></span>${t.endpoint}
548
+ </button>
549
+ `)}
550
+ </div>
551
+ `}renderOverview(){return a`
552
+ <div class="perf-endpoint-list">
553
+ ${this.graphData.map((t,s)=>t.requests.length===0?d:this.renderEndpointCard(t,s))}
554
+ </div>
555
+ `}renderEndpointCard(t,s){let r=t.summary,o=this.healthGrade(r.p95Ms),n=Math.round(r.errorRate*r.totalRequests),l=(r.avgQueryTimeMs||0)+(r.avgFetchTimeMs||0)+(r.avgAppTimeMs||0),c=d;if(l>0){let p=Math.round((r.avgQueryTimeMs||0)/l*100),u=Math.round((r.avgFetchTimeMs||0)/l*100),m=Math.max(0,100-p-u);c=a`
556
+ <div class="perf-breakdown-inline">
557
+ <div class="perf-breakdown-bar perf-breakdown-bar-sm">
558
+ ${p>0?a`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${p}%"></div>`:d}
559
+ ${u>0?a`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${u}%"></div>`:d}
560
+ ${m>0?a`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${m}%"></div>`:d}
561
+ </div>
562
+ <span class="perf-breakdown-labels">
563
+ ${p>0?a`<span class="perf-breakdown-lbl"><span class="perf-breakdown-dot perf-breakdown-db"></span>${this.fmtMs(r.avgQueryTimeMs||0)}</span>`:d}
564
+ ${u>0?a`<span class="perf-breakdown-lbl"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>${this.fmtMs(r.avgFetchTimeMs||0)}</span>`:d}
565
+ <span class="perf-breakdown-lbl"><span class="perf-breakdown-dot perf-breakdown-app"></span>${this.fmtMs(r.avgAppTimeMs||0)}</span>
566
+ </span>
567
+ </div>
568
+ `;}return a`
569
+ <div class="perf-endpoint-card" @click=${()=>{this.selectedEndpoint=t.endpoint;}}>
570
+ <div class="perf-ep-header">
571
+ <span class="perf-ep-name">${t.endpoint}</span>
572
+ <span class="perf-ep-stats">
573
+ <span class="perf-ep-stat" style="color:${o.color}">p95: ${this.fmtMs(r.p95Ms)}</span>
574
+ <span class="perf-ep-stat ${n>0?"perf-ep-stat-err":""}">${n} err</span>
575
+ ${r.avgQueryCount>0?a`<span class="perf-ep-stat ${r.avgQueryCount>5?"perf-ep-stat-warn":""}">${r.avgQueryCount} q/req</span>`:d}
576
+ <span class="perf-ep-stat perf-ep-stat-muted">${r.totalRequests} req${r.totalRequests!==1?"s":""}</span>
577
+ </span>
578
+ </div>
579
+ ${c}
580
+ <canvas id="inline-scatter-${s}" class="perf-inline-canvas"></canvas>
581
+ </div>
582
+ `}renderDetail(){let t=this.graphData.find(n=>n.endpoint===this.selectedEndpoint);if(!t?.requests?.length)return a`<bk-empty-state subtitle="No data for this endpoint"></bk-empty-state>`;let s=t.summary,r=this.healthGrade(s.p95Ms),o=Math.round(s.errorRate*s.totalRequests);return a`
583
+ ${this.renderDetailHeader(t,r)}
584
+ ${this.renderDetailMetrics(s,r,o)}
585
+ ${this.renderDetailBreakdown(s)}
586
+ ${this.renderDetailChart()}
587
+ ${this.renderDetailHistory(t)}
588
+ `}renderDetailHeader(t,s){return a`
589
+ <div class="perf-detail-header">
590
+ <div class="perf-detail-title">
591
+ <span class="perf-badge perf-badge-lg" style="color:${s.color};background:${s.bg};border-color:${s.border}">${s.label}</span>
592
+ <span>${t.endpoint}</span>
593
+ </div>
594
+ </div>
595
+ `}renderDetailMetrics(t,s,r){return a`
596
+ <div class="perf-metric-row">
597
+ <div class="perf-metric-card">
598
+ <span class="perf-metric-label">P95</span>
599
+ <span class="perf-metric-value" style="color:${s.color}">${this.fmtMs(t.p95Ms)}</span>
600
+ </div>
601
+ <div class="perf-metric-card">
602
+ <span class="perf-metric-label">Errors</span>
603
+ <span class="perf-metric-value" style="color:${r>0?"var(--red)":"var(--green)"}">
604
+ ${r>0?r+" ("+Math.round(t.errorRate*100)+"%)":"0"}
605
+ </span>
606
+ </div>
607
+ <div class="perf-metric-card">
608
+ <span class="perf-metric-label">Queries/req</span>
609
+ <span class="perf-metric-value" style="color:${t.avgQueryCount>5?"var(--amber)":"var(--text)"}">${t.avgQueryCount}</span>
610
+ </div>
611
+ </div>
612
+ `}renderDetailBreakdown(t){let s=(t.avgQueryTimeMs||0)+(t.avgFetchTimeMs||0)+(t.avgAppTimeMs||0);if(s<=0)return d;let r=Math.round((t.avgQueryTimeMs||0)/s*100),o=Math.round((t.avgFetchTimeMs||0)/s*100),n=Math.max(0,100-r-o);return a`
613
+ <div class="perf-breakdown">
614
+ <div class="perf-section-title">Time Breakdown</div>
615
+ <div class="perf-breakdown-bar">
616
+ ${r>0?a`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${r}%"></div>`:d}
617
+ ${o>0?a`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${o}%"></div>`:d}
618
+ ${n>0?a`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${n}%"></div>`:d}
619
+ </div>
620
+ <div class="perf-breakdown-legend">
621
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${this.fmtMs(t.avgQueryTimeMs||0)} (${r}%)</span>
622
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${this.fmtMs(t.avgFetchTimeMs||0)} (${o}%)</span>
623
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${this.fmtMs(t.avgAppTimeMs||0)} (${n}%)</span>
624
+ </div>
625
+ </div>
626
+ `}renderDetailChart(){return a`
627
+ <div class="perf-chart-wrap">
628
+ <div class="perf-section-title">Response Time</div>
629
+ <canvas id="perf-detail-canvas" class="perf-canvas" style="width:100%;height:240px"></canvas>
630
+ </div>
631
+ `}renderDetailHistory(t){if(t.requests.length===0)return d;let s=[];for(let r=t.requests.length-1;r>=0&&s.length<50;r--)s.push({r:t.requests[r],origIdx:r});return a`
632
+ <div class="perf-history-wrap">
633
+ <div class="col-header">
634
+ <span class="perf-col perf-col-date">Time</span>
635
+ <span class="perf-col perf-col-health">Health</span>
636
+ <span class="perf-col perf-col-avg">Duration</span>
637
+ <span class="perf-col perf-col-breakdown">Breakdown</span>
638
+ <span class="perf-col perf-col-status">Status</span>
639
+ <span class="perf-col perf-col-qpr">Queries</span>
640
+ </div>
641
+ ${s.map(r=>this.renderHistoryRow(r.r,r.origIdx))}
642
+ </div>
643
+ `}renderHistoryRow(t,s){let r=this.healthGrade(t.durationMs),o=new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),n=t.statusCode>=400,l=t.queryTimeMs||0,c=t.fetchTimeMs||0,p=Math.max(0,t.durationMs-l-c);return a`
644
+ <div class="perf-hist-row ${n?"perf-hist-row-err":""}" data-req-idx=${s}>
645
+ <span class="perf-col perf-col-date">${o}</span>
646
+ <span class="perf-col perf-col-health">
647
+ <span class="perf-badge perf-badge-sm" style="color:${r.color};background:${r.bg};border-color:${r.border}">${r.label}</span>
648
+ </span>
649
+ <span class="perf-col perf-col-avg">${this.fmtMs(t.durationMs)}</span>
650
+ <span class="perf-col perf-col-breakdown">
651
+ ${l>0?a`<span class="perf-bd-tag perf-bd-tag-db">DB ${this.fmtMs(l)}</span>`:d}
652
+ ${c>0?a`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${this.fmtMs(c)}</span>`:d}
653
+ <span class="perf-bd-tag perf-bd-tag-app">App ${this.fmtMs(p)}</span>
654
+ </span>
655
+ <span class="perf-col perf-col-status" style="color:${n?"var(--red)":"var(--text-muted)"}">${t.statusCode}</span>
656
+ <span class="perf-col perf-col-qpr">${t.queryCount}</span>
657
+ </div>
658
+ `}};h([R({context:x})],B.prototype,"store",2),h([E()],B.prototype,"selectedEndpoint",2),h([E()],B.prototype,"graphData",2),h([E()],B.prototype,"loadError",2),B=h([g("bk-performance-view")],B);function pr(i){return i===0?"<1ms":S(i)}var A=class extends f{constructor(){super(...arguments);this.requestId="";this.requestStarted=0;this.data=null;this.loading=false;this.failed=false;this.expandedSqlIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate()),this.requestId&&this.loadTimeline();}async loadTimeline(){if(!this.requestId)return;let t=A.cache.get(this.requestId);if(t){this.data=t;return}this.loading=true;try{let s=await fetch(`${y.activity}?requestId=${this.requestId}`);if(!s.ok){this.failed=!0,this.loading=!1;return}let r=await s.json();if(A.cache.size>=he){let o=A.cache.keys().next().value;o!==void 0&&A.cache.delete(o);}A.cache.set(this.requestId,r),this.data=r,this.loading=!1;}catch(s){console.debug("[brakit] timeline load failed:",s),this.failed=true,this.loading=false;}}toggleSql(t,s){s.stopPropagation(),this.expandedSqlIdx=this.expandedSqlIdx===t?-1:t;}copySql(t,s){s.stopPropagation(),navigator.clipboard.writeText(t).then(()=>C.show("SQL copied")).catch(()=>C.show("Copy failed"));}render(){if(this.loading)return a`<div class="tl-loading">Loading activity...</div>`;if(this.failed||!this.data||this.data.total===0)return d;let t=this.data,s=t.timeline[0]?.timestamp??0;return a`
659
+ <div class="tl-header">
660
+ <span class="tl-title">Activity Timeline</span>
661
+ <span class="tl-counts">
662
+ ${t.counts.queries>0?a`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:d}
663
+ ${t.counts.fetches>0?a`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:d}
664
+ ${t.counts.logs>0?a`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:d}
665
+ ${t.counts.errors>0?a`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:d}
666
+ </span>
667
+ </div>
668
+ <div class="tl-events">${this.renderTimeline(t.timeline,s)}</div>
669
+ `}renderTimeline(t,s){let r=new Map,o=[];for(let l of t){let c=l.type==="query"?l.data.parentFetchId:void 0;if(l.type==="query"&&c){let p=r.get(c);p||(p=[],r.set(c,p)),p.push(l);}else o.push(l);}let n=0;return o.map(l=>{let c=n++,p=l.type==="fetch"?l.data.fetchId:void 0,u=p?r.get(p):void 0;if(u&&u.length>0){let m=u.length;return a`
670
+ ${this.renderEvent(l,c,s)}
671
+ <div class="tl-nested">
672
+ <span class="tl-nested-label">${m} nested quer${m===1?"y":"ies"}</span>
673
+ ${u.map(b=>{let $=n++;return this.renderEvent(b,$,s,true)})}
674
+ </div>
675
+ `}return this.renderEvent(l,c,s)})}renderEvent(t,s,r,o=false){let n=ss[t.type]||"var(--text-dim)",l=rs[t.type]||t.type,c="+"+S(Math.round(t.timestamp-r)),p=t.type==="query"?t.data.sql:void 0,u=!!p,m=this.expandedSqlIdx===s;return a`
676
+ <div class="tl-event ${u?"tl-clickable":""} ${o?"tl-nested-event":""}"
677
+ style="${u?"":`border-left-color:${n}`}"
678
+ @click=${u?b=>this.toggleSql(s,b):d}>
679
+ <span class="tl-event-time">${c}</span>
680
+ <span class="tl-event-type" style="color:${n}">${l}</span>
681
+ ${this.renderEventContent(t)}
682
+ ${p?a`
683
+ <div class="tl-event-sql ${m?"open":""}">
684
+ <button class="tl-sql-copy" @click=${b=>this.copySql(p,b)}>Copy</button>
685
+ ${p}
686
+ </div>`:d}
687
+ </div>
688
+ `}renderEventContent(t){switch(t.type){case "fetch":{let s=t.data,r=s.statusCode>=400;return a`
689
+ <span class="tl-event-summary">${s.method} ${s.url}</span>
690
+ <span class="tl-event-status" style="${r?"color:var(--red)":""}">${s.statusCode}</span>
691
+ <span class="tl-event-dur">${S(s.durationMs)}</span>
692
+ `}case "query":{let s=t.data,r=(s.normalizedOp||s.operation||"?").toUpperCase(),o=s.table||s.model||"",n=Ft[r]||"var(--text-dim)";return a`
693
+ <span class="tl-event-summary"><span style="color:${n};font-weight:600">${r}</span> ${o}</span>
694
+ <span class="tl-event-dur">${pr(s.durationMs)}</span>
695
+ `}case "log":{let s=t.data,r=ze[s.level]||"var(--text-dim)";return a`<span class="tl-event-summary"><span style="color:${r}">${s.level.toUpperCase()}</span> ${s.message}</span>`}case "error":{let s=t.data;return a`<span class="tl-event-summary" style="color:var(--red)">${s.name}: ${s.message}</span>`}default:return d}}};A.cache=new Map,h([R({context:x})],A.prototype,"store",2),h([T({attribute:"request-id"})],A.prototype,"requestId",2),h([T({attribute:"request-started",type:Number})],A.prototype,"requestStarted",2),h([E()],A.prototype,"data",2),h([E()],A.prototype,"loading",2),h([E()],A.prototype,"failed",2),h([E()],A.prototype,"expandedSqlIdx",2),A=h([g("bk-timeline-panel")],A);var Qt=class{constructor(e,t){this.host=e;this.store=t;this.retryCount=0;e.addController(this);}hostConnected(){this.connect();}hostDisconnected(){this.eventSource?.close(),clearTimeout(this.reloadTimer),clearTimeout(this.perfReloadTimer),clearTimeout(this.reconnectTimer);}connect(){this.eventSource?.close(),this.eventSource=new EventSource(y.events),this.eventSource.onopen=()=>{this.retryCount=0;},this.eventSource.onerror=()=>{this.eventSource?.close(),this.scheduleReconnect();},this.eventSource.onmessage=e=>{let t=JSON.parse(e.data);t.path?.startsWith(O)||(this.store.prependRequest(t),clearTimeout(this.reloadTimer),this.reloadTimer=setTimeout(()=>this.reloadFlows(),300),this.store.state.activeView==="performance"&&(clearTimeout(this.perfReloadTimer),this.perfReloadTimer=setTimeout(()=>this.reloadMetrics(),me)));},this.eventSource.addEventListener(re,e=>{this.store.prependFetch(JSON.parse(e.data));}),this.eventSource.addEventListener("log",e=>{this.store.prependLog(JSON.parse(e.data));}),this.eventSource.addEventListener(ie,e=>{this.store.prependError(JSON.parse(e.data));}),this.eventSource.addEventListener(oe,e=>{this.store.prependQuery(JSON.parse(e.data));}),this.eventSource.addEventListener(ne,e=>{this.store.setIssues(JSON.parse(e.data));});}scheduleReconnect(){if(this.retryCount>=10)return;let e=Math.min(1e3*2**this.retryCount,3e4);this.retryCount++,this.reconnectTimer=setTimeout(()=>this.connect(),e);}async reloadFlows(){try{let t=await(await fetch(y.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch(y.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function $s(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>`}function Ts(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>`}function ys(){return a`<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>`}function xs(){return a`<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="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>`}function Rs(){return a`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>`}function ws(){return a`<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="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>`}function As(){return a`<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>`}function Cs(){return a`<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="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`}function Is(){return a`<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="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>`}var J=class extends f{constructor(){super(...arguments);this.store=new Wt;this.activeView="overview";this.viewMode="simple";this.sse=new Qt(this,this.store);}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadInitialData(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}async loadInitialData(){try{let[t,s]=await Promise.all([fetch(y.flows),fetch(y.requests)]),[r,o]=await Promise.all([t.json(),s.json()]);this.store.setFlows(r.flows),this.store.setRequests(o.requests);}catch(t){console.warn("[brakit]",t);}try{let[t,s,r,o,n]=await Promise.all([fetch(y.fetches),fetch(y.errors),fetch(y.logs),fetch(y.queries),fetch(y.metricsLive)]),[l,c,p,u,m]=await Promise.all([t.json(),s.json(),r.json(),o.json(),n.json()]);this.store.setFetches(l.entries),this.store.setErrors(c.entries),this.store.setLogs(p.entries),this.store.setQueries(u.entries),this.store.setMetrics(m.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let s=await(await fetch(y.insights)).json();this.store.setIssues(s.issues||[]);}catch(t){console.warn("[brakit]",t);}}switchView(t){t!==this.activeView&&(this.activeView=t,this.store.setActiveView(t),fetch(`${y.tab}?tab=${encodeURIComponent(t)}`).catch(()=>{}),t==="performance"&&this.sse.reloadMetrics());}async handleClear(){confirm("This will clear all data including performance metrics history. Continue?")&&(await fetch(y.clear,{method:"POST"}),this.store.clearAll(),C.show("Cleared"));}handleCopyAsCurl(t){ct(t);}render(){let t=this.store.state,s=t.requests.filter(c=>!c.path?.startsWith(O)),r=s.filter(c=>c.statusCode>=400).length,o=s.length>0?Math.round(s.reduce((c,p)=>c+p.durationMs,0)/s.length):0,n=(t.issues||[]).filter(c=>c.state!=="resolved"&&c.state!=="stale").length,l=window.__BRAKIT_CONFIG__;return a`
696
+ <div class="app" id="app">
697
+ <aside class="sidebar">
698
+ <div class="sidebar-logo">
699
+ <span class="logo-text">brakit</span>
700
+ <span class="logo-version">v${l?.version??""}</span>
701
+ </div>
702
+ <nav class="sidebar-nav">
703
+ ${this.renderSidebarItem("overview","Overview",$s(),void 0)}
704
+ <div class="sidebar-section">Monitor</div>
705
+ ${this.renderSidebarItem("actions","Actions",Ts(),t.flows.length)}
706
+ ${this.renderSidebarItem("requests","Requests",ys(),s.length)}
707
+ ${this.renderSidebarItem("fetches","Fetches",xs(),t.fetches.length)}
708
+ <div class="sidebar-section">Insights</div>
709
+ ${this.renderSidebarItem("queries","Queries",Rs(),t.queries.length)}
710
+ ${this.renderSidebarItem("errors","Errors",ws(),t.errors.length)}
711
+ ${this.renderSidebarItem("logs","Logs",As(),t.logs.length)}
712
+ ${this.renderSidebarItem("security","Security",Cs(),n,n===0)}
713
+ ${this.renderSidebarItem("performance","Performance",Is(),void 0)}
714
+ </nav>
715
+ <div class="sidebar-footer">:${l?.port??""}</div>
716
+ </aside>
717
+ <div class="main-panel">
718
+ <div class="header">
719
+ <div class="header-left">
720
+ <span class="header-title" id="header-title">${yt[this.activeView]||this.activeView}</span>
721
+ <span class="header-sub" id="header-sub">${le[this.activeView]||""}</span>
722
+ </div>
723
+ <div class="header-right">
724
+ ${this.activeView==="actions"?a`
725
+ <div class="segmented-control" id="mode-toggle">
726
+ <button class="segmented-btn ${this.viewMode==="simple"?"active":""}" @click=${()=>{this.viewMode="simple",this.store.setViewMode("simple");}}>Quick</button>
727
+ <button class="segmented-btn ${this.viewMode==="detailed"?"active":""}" @click=${()=>{this.viewMode="detailed",this.store.setViewMode("detailed");}}>Detailed</button>
728
+ </div>
729
+ `:d}
730
+ <button class="btn btn-danger" @click=${this.handleClear}>Clear</button>
731
+ </div>
732
+ </div>
733
+ <div class="main-content">
734
+ <div id="overview-container" style="display:${this.activeView==="overview"?"block":"none"}">
735
+ <bk-overview-view></bk-overview-view>
736
+ </div>
737
+ <div class="view-flows" id="flow-container" style="display:${this.activeView==="actions"?"block":"none"}">
738
+ <bk-flows-view></bk-flows-view>
739
+ </div>
740
+ <div class="view-requests" id="request-container" style="display:${this.activeView==="requests"?"block":"none"}">
741
+ <bk-requests-view></bk-requests-view>
742
+ </div>
743
+ <div class="view-telemetry" id="fetch-container" style="display:${this.activeView==="fetches"?"block":"none"}">
744
+ <bk-fetches-view></bk-fetches-view>
745
+ </div>
746
+ <div class="view-telemetry" id="query-container" style="display:${this.activeView==="queries"?"block":"none"}">
747
+ <bk-queries-view></bk-queries-view>
748
+ </div>
749
+ <div class="view-telemetry" id="error-container" style="display:${this.activeView==="errors"?"block":"none"}">
750
+ <bk-errors-view></bk-errors-view>
751
+ </div>
752
+ <div class="view-telemetry" id="log-container" style="display:${this.activeView==="logs"?"block":"none"}">
753
+ <bk-logs-view></bk-logs-view>
754
+ </div>
755
+ <div class="view-telemetry" id="security-container" style="display:${this.activeView==="security"?"block":"none"}">
756
+ <bk-security-view></bk-security-view>
757
+ </div>
758
+ <div class="view-telemetry" id="performance-container" style="display:${this.activeView==="performance"?"block":"none"}">
759
+ <bk-performance-view></bk-performance-view>
760
+ </div>
761
+ </div>
762
+ <div class="footer">
763
+ <span id="stat-total">${s.length} request${s.length!==1?"s":""}</span>
764
+ <span id="stat-flows">${t.flows.length} action${t.flows.length!==1?"s":""}</span>
765
+ <span id="stat-errors" class="error-count">${r} error${r!==1?"s":""}</span>
766
+ <span id="stat-avg">Avg: ${o}ms</span>
767
+ </div>
768
+ </div>
769
+ </div>
770
+ <bk-toast></bk-toast>
771
+ `}renderSidebarItem(t,s,r,o,n=false){return a`
772
+ <button class="sidebar-item ${this.activeView===t?"active":""}" @click=${()=>this.switchView(t)}>
773
+ <span class="item-icon">${r}</span>
774
+ <span class="item-label">${s}</span>
775
+ ${o!==void 0?a`<span class="item-count" style="display:${n?"none":""}">${o}</span>`:d}
776
+ </button>
777
+ `}};h([_e({context:x})],J.prototype,"store",2),h([E()],J.prototype,"activeView",2),h([E()],J.prototype,"viewMode",2),J=h([g("bk-dashboard")],J);
778
+ /*! Bundled license information:
779
+
780
+ @lit/reactive-element/css-tag.js:
781
+ (**
782
+ * @license
783
+ * Copyright 2019 Google LLC
784
+ * SPDX-License-Identifier: BSD-3-Clause
785
+ *)
786
+
787
+ @lit/reactive-element/reactive-element.js:
788
+ lit-html/lit-html.js:
789
+ lit-element/lit-element.js:
790
+ @lit/reactive-element/decorators/custom-element.js:
791
+ @lit/reactive-element/decorators/property.js:
792
+ @lit/reactive-element/decorators/state.js:
793
+ @lit/reactive-element/decorators/event-options.js:
794
+ @lit/reactive-element/decorators/base.js:
795
+ @lit/reactive-element/decorators/query.js:
796
+ @lit/reactive-element/decorators/query-all.js:
797
+ @lit/reactive-element/decorators/query-async.js:
798
+ @lit/reactive-element/decorators/query-assigned-nodes.js:
799
+ @lit/context/lib/decorators/provide.js:
800
+ (**
801
+ * @license
802
+ * Copyright 2017 Google LLC
803
+ * SPDX-License-Identifier: BSD-3-Clause
804
+ *)
805
+
806
+ lit-html/is-server.js:
807
+ @lit/context/lib/decorators/consume.js:
808
+ (**
809
+ * @license
810
+ * Copyright 2022 Google LLC
811
+ * SPDX-License-Identifier: BSD-3-Clause
812
+ *)
813
+
814
+ @lit/reactive-element/decorators/query-assigned-elements.js:
815
+ @lit/context/lib/context-request-event.js:
816
+ @lit/context/lib/create-context.js:
817
+ @lit/context/lib/controllers/context-consumer.js:
818
+ @lit/context/lib/value-notifier.js:
819
+ @lit/context/lib/controllers/context-provider.js:
820
+ @lit/context/lib/context-root.js:
821
+ (**
822
+ * @license
823
+ * Copyright 2021 Google LLC
824
+ * SPDX-License-Identifier: BSD-3-Clause
825
+ *)
826
+ */})();