brakit 0.8.5 → 0.8.7

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,703 @@
1
+ (function(){'use strict';var $s=Object.defineProperty;var ys=Object.getOwnPropertyDescriptor;var u=(o,e,t,s)=>{for(var r=s>1?void 0:s?ys(e,t):e,i=o.length-1,a;i>=0;i--)(a=o[i])&&(r=(s?a(e,t,r):a(r))||r);return s&&r&&$s(e,t,r),r};var Mt=globalThis,Dt=Mt.ShadowRoot&&(Mt.ShadyCSS===void 0||Mt.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,Re=Symbol(),Te=new WeakMap,Ot=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(Dt&&e===void 0){let s=t!==void 0&&t.length===1;s&&(e=Te.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),s&&Te.set(t,e));}return e}toString(){return this.cssText}},we=o=>new Ot(typeof o=="string"?o:o+"",void 0,Re);var Ce=(o,e)=>{if(Dt)o.adoptedStyleSheets=e.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of e){let s=document.createElement("style"),r=Mt.litNonce;r!==void 0&&s.setAttribute("nonce",r),s.textContent=t.cssText,o.appendChild(s);}},zt=Dt?o=>o:o=>o instanceof CSSStyleSheet?(e=>{let t="";for(let s of e.cssRules)t+=s.cssText;return we(t)})(o):o;var{is:Ss,defineProperty:_s,getOwnPropertyDescriptor:xs,getOwnPropertyNames:Ts,getOwnPropertySymbols:Rs,getPrototypeOf:ws}=Object,D=globalThis,Ae=D.trustedTypes,Cs=Ae?Ae.emptyScript:"",As=D.reactiveElementPolyfillSupport,vt=(o,e)=>o,ft={toAttribute(o,e){switch(e){case Boolean:o=o?Cs:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o);}return o},fromAttribute(o,e){let t=o;switch(e){case Boolean:t=o!==null;break;case Number:t=o===null?null:Number(o);break;case Object:case Array:try{t=JSON.parse(o);}catch{t=null;}}return t}},Nt=(o,e)=>!Ss(o,e),ke={attribute:true,type:String,converter:ft,reflect:false,useDefault:false,hasChanged:Nt};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),D.litPropertyMetadata??(D.litPropertyMetadata=new WeakMap);var M=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=ke){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&&_s(this.prototype,e,r);}}static getPropertyDescriptor(e,t,s){let{get:r,set:i}=xs(this.prototype,e)??{get(){return this[t]},set(a){this[t]=a;}};return {get:r,set(a){let c=r?.call(this);i?.call(this,a),this.requestUpdate(e,c,s);},configurable:true,enumerable:true}}static getPropertyOptions(e){return this.elementProperties.get(e)??ke}static _$Ei(){if(this.hasOwnProperty(vt("elementProperties")))return;let e=ws(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties);}static finalize(){if(this.hasOwnProperty(vt("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(vt("properties"))){let t=this.properties,s=[...Ts(t),...Rs(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(zt(r));}else e!==void 0&&t.push(zt(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 Ce(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 i=(s.converter?.toAttribute!==void 0?s.converter:ft).toAttribute(t,s.type);this._$Em=e,i==null?this.removeAttribute(r):this.setAttribute(r,i),this._$Em=null;}}_$AK(e,t){let s=this.constructor,r=s._$Eh.get(e);if(r!==void 0&&this._$Em!==r){let i=s.getPropertyOptions(r),a=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:ft;this._$Em=r;let c=a.fromAttribute(t,i.type);this[r]=c??this._$Ej?.get(r)??c,this._$Em=null;}}requestUpdate(e,t,s,r=false,i){if(e!==void 0){let a=this.constructor;if(r===false&&(i=this[e]),s??(s=a.getPropertyOptions(e)),!((s.hasChanged??Nt)(i,t)||s.useDefault&&s.reflect&&i===this._$Ej?.get(e)&&!this.hasAttribute(a._$Eu(e,s))))return;this.C(e,t,s);}this.isUpdatePending===false&&(this._$ES=this._$EP());}C(e,t,{useDefault:s,reflect:r,wrapped:i},a){s&&!(this._$Ej??(this._$Ej=new Map)).has(e)&&(this._$Ej.set(e,a??t??this[e]),i!==true||a!==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,i]of this._$Ep)this[r]=i;this._$Ep=void 0;}let s=this.constructor.elementProperties;if(s.size>0)for(let[r,i]of s){let{wrapped:a}=i,c=this[r];a!==true||this._$AL.has(r)||c===void 0||this.C(r,void 0,i,c);}}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){}};M.elementStyles=[],M.shadowRootOptions={mode:"open"},M[vt("elementProperties")]=new Map,M[vt("finalized")]=new Map,As?.({ReactiveElement:M}),(D.reactiveElementVersions??(D.reactiveElementVersions=[])).push("2.1.2");var bt=globalThis,Le=o=>o,qt=bt.trustedTypes,Ie=qt?qt.createPolicy("lit-html",{createHTML:o=>o}):void 0,He="$lit$",N=`lit$${Math.random().toFixed(9).slice(2)}$`,Pe="?"+N,ks=`<${Pe}>`,j=document,Et=()=>j.createComment(""),$t=o=>o===null||typeof o!="object"&&typeof o!="function",ie=Array.isArray,Ls=o=>ie(o)||typeof o?.[Symbol.iterator]=="function",Jt=`[
2
+ \f\r]`,gt=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Me=/-->/g,Oe=/>/g,B=RegExp(`>|${Jt}(?:([^\\s"'>=/]+)(${Jt}*=${Jt}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),De=/'/g,Ne=/"/g,Ue=/^(?:script|style|textarea|title)$/i,oe=o=>(e,...t)=>({_$litType$:o,strings:e,values:t}),n=oe(1),Q=Symbol.for("lit-noChange"),d=Symbol.for("lit-nothing"),qe=new WeakMap,G=j.createTreeWalker(j,129);function Fe(o,e){if(!ie(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return Ie!==void 0?Ie.createHTML(e):e}var Is=(o,e)=>{let t=o.length-1,s=[],r,i=e===2?"<svg>":e===3?"<math>":"",a=gt;for(let c=0;c<t;c++){let l=o[c],h,m,p=-1,v=0;for(;v<l.length&&(a.lastIndex=v,m=a.exec(l),m!==null);)v=a.lastIndex,a===gt?m[1]==="!--"?a=Me:m[1]!==void 0?a=Oe:m[2]!==void 0?(Ue.test(m[2])&&(r=RegExp("</"+m[2],"g")),a=B):m[3]!==void 0&&(a=B):a===B?m[0]===">"?(a=r??gt,p=-1):m[1]===void 0?p=-2:(p=a.lastIndex-m[2].length,h=m[1],a=m[3]===void 0?B:m[3]==='"'?Ne:De):a===Ne||a===De?a=B:a===Me||a===Oe?a=gt:(a=B,r=void 0);let E=a===B&&o[c+1].startsWith("/>")?" ":"";i+=a===gt?l+ks:p>=0?(s.push(h),l.slice(0,p)+He+l.slice(p)+N+E):l+N+(p===-2?c:E);}return [Fe(o,i+(o[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),s]},yt=class o{constructor({strings:e,_$litType$:t},s){let r;this.parts=[];let i=0,a=0,c=e.length-1,l=this.parts,[h,m]=Is(e,t);if(this.el=o.createElement(h,s),G.currentNode=this.el.content,t===2||t===3){let p=this.el.content.firstChild;p.replaceWith(...p.childNodes);}for(;(r=G.nextNode())!==null&&l.length<c;){if(r.nodeType===1){if(r.hasAttributes())for(let p of r.getAttributeNames())if(p.endsWith(He)){let v=m[a++],E=r.getAttribute(p).split(N),C=/([.?@])?(.*)/.exec(v);l.push({type:1,index:i,name:C[2],strings:E,ctor:C[1]==="."?te:C[1]==="?"?ee:C[1]==="@"?se:st}),r.removeAttribute(p);}else p.startsWith(N)&&(l.push({type:6,index:i}),r.removeAttribute(p));if(Ue.test(r.tagName)){let p=r.textContent.split(N),v=p.length-1;if(v>0){r.textContent=qt?qt.emptyScript:"";for(let E=0;E<v;E++)r.append(p[E],Et()),G.nextNode(),l.push({type:2,index:++i});r.append(p[v],Et());}}}else if(r.nodeType===8)if(r.data===Pe)l.push({type:2,index:i});else {let p=-1;for(;(p=r.data.indexOf(N,p+1))!==-1;)l.push({type:7,index:i}),p+=N.length-1;}i++;}}static createElement(e,t){let s=j.createElement("template");return s.innerHTML=e,s}};function et(o,e,t=o,s){if(e===Q)return e;let r=s!==void 0?t._$Co?.[s]:t._$Cl,i=$t(e)?void 0:e._$litDirective$;return r?.constructor!==i&&(r?._$AO?.(false),i===void 0?r=void 0:(r=new i(o),r._$AT(o,t,s)),s!==void 0?(t._$Co??(t._$Co=[]))[s]=r:t._$Cl=r),r!==void 0&&(e=et(o,r._$AS(o,e.values),r,s)),e}var Zt=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);G.currentNode=r;let i=G.nextNode(),a=0,c=0,l=s[0];for(;l!==void 0;){if(a===l.index){let h;l.type===2?h=new St(i,i.nextSibling,this,e):l.type===1?h=new l.ctor(i,l.name,l.strings,this,e):l.type===6&&(h=new re(i,this,e)),this._$AV.push(h),l=s[++c];}a!==l?.index&&(i=G.nextNode(),a++);}return G.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++;}},St=class o{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=et(this,e,t),$t(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):Ls(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&&$t(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=yt.createElement(Fe(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(t);else {let i=new Zt(r,this),a=i.u(this.options);i.p(t),this.T(a),this._$AH=i;}}_$AC(e){let t=qe.get(e.strings);return t===void 0&&qe.set(e.strings,t=new yt(e)),t}k(e){ie(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,s,r=0;for(let i of e)r===t.length?t.push(s=new o(this.O(Et()),this.O(Et()),this,this.options)):s=t[r],s._$AI(i),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));}},st=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,s,r,i){this.type=1,this._$AH=d,this._$AN=void 0,this.element=e,this.name=t,this._$AM=r,this.options=i,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 i=this.strings,a=false;if(i===void 0)e=et(this,e,t,0),a=!$t(e)||e!==this._$AH&&e!==Q,a&&(this._$AH=e);else {let c=e,l,h;for(e=i[0],l=0;l<i.length-1;l++)h=et(this,c[s+l],t,l),h===Q&&(h=this._$AH[l]),a||(a=!$t(h)||h!==this._$AH[l]),h===d?e=d:e!==d&&(e+=(h??"")+i[l+1]),this._$AH[l]=h;}a&&!r&&this.j(e);}j(e){e===d?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??"");}},te=class extends st{constructor(){super(...arguments),this.type=3;}j(e){this.element[this.name]=e===d?void 0:e;}},ee=class extends st{constructor(){super(...arguments),this.type=4;}j(e){this.element.toggleAttribute(this.name,!!e&&e!==d);}},se=class extends st{constructor(e,t,s,r,i){super(e,t,s,r,i),this.type=5;}_$AI(e,t=this){if((e=et(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,i=e!==d&&(s===d||r);r&&this.element.removeEventListener(this.name,this,s),i&&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);}},re=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){et(this,e);}};var Ms=bt.litHtmlPolyfillSupport;Ms?.(yt,St),(bt.litHtmlVersions??(bt.litHtmlVersions=[])).push("3.3.2");var Be=(o,e,t)=>{let s=t?.renderBefore??e,r=s._$litPart$;if(r===void 0){let i=t?.renderBefore??null;s._$litPart$=r=new St(e.insertBefore(Et(),i),i,void 0,t??{});}return r._$AI(o),r};var _t=globalThis,f=class extends M{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,_t.litElementHydrateSupport?.({LitElement:f});var Os=_t.litElementPolyfillSupport;Os?.({LitElement:f});(_t.litElementVersions??(_t.litElementVersions=[])).push("4.2.2");var g=o=>(e,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(o,e);}):customElements.define(o,e);};var Ds={attribute:true,type:String,converter:ft,reflect:false,hasChanged:Nt},Ns=(o=Ds,e,t)=>{let{kind:s,metadata:r}=t,i=globalThis.litPropertyMetadata.get(r);if(i===void 0&&globalThis.litPropertyMetadata.set(r,i=new Map),s==="setter"&&((o=Object.create(o)).wrapped=true),i.set(t.name,o),s==="accessor"){let{name:a}=t;return {set(c){let l=e.get.call(this);e.set.call(this,c),this.requestUpdate(a,l,o,true,c);},init(c){return c!==void 0&&this.C(a,void 0,o,c),c}}}if(s==="setter"){let{name:a}=t;return function(c){let l=this[a];e.call(this,c),this.requestUpdate(a,l,o,true,c);}}throw Error("Unsupported decorator location: "+s)};function y(o){return (e,t)=>typeof t=="object"?Ns(o,e,t):((s,r,i)=>{let a=r.hasOwnProperty(i);return r.constructor.createProperty(i,s),a?Object.getOwnPropertyDescriptor(r,i):void 0})(o,e,t)}function $(o){return y({...o,state:true,attribute:false})}var xt=class extends f{constructor(){super(...arguments);this.method="";}createRenderRoot(){return this}render(){let t=this.method.toUpperCase();return n`<span class="method-badge method-badge-${t}">${t}</span>`}};u([y()],xt.prototype,"method",2),xt=u([g("bk-method-badge")],xt);var L="/__brakit/api",O="/__brakit",R={flows:`${L}/flows`,requests:`${L}/requests`,events:`${L}/events`,clear:`${L}/clear`,fetches:`${L}/fetches`,errors:`${L}/errors`,logs:`${L}/logs`,queries:`${L}/queries`,metricsLive:`${L}/metrics/live`,insights:`${L}/insights`,tab:`${L}/tab`,activity:`${L}/activity`};var Tt="polling",Pt="static",qs="auth-handshake",Hs="auth-check",Ps="middleware",Ut={[qs]:1,[Hs]:1,[Ps]:1};var ne="fetch";var ae="error_event",ce="query",le="issues";var de={overview:"Overview",queries:"Queries",requests:"Requests",actions:"Actions",errors:"Errors",security:"Security",fetches:"Fetches",logs:"Logs",performance:"Performance"};var Rt={overview:"Overview",actions:"Actions",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",performance:"Performance",security:"Security"},pe={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 he=100,V=300,W=800,me=2e3,ve=100,fe=50,ge=500;var q="__all__",jt={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)"},be=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],wt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},Qt=[{max:he,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:W,label:"OK",color:"var(--amber)",bg:"rgba(217,119,6,0.06)",border:"rgba(217,119,6,0.15)"},{max:me,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)",Ee="rgba(113,113,122,0.7)",Ze="10px monospace",$e="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"]),H={critical:{icon:"\u2717",cls:"critical",sort:0},warning:{icon:"\u26A0",cls:"warning",sort:1},info:{icon:"\u2139",cls:"info",sort:2}};function S(o){return o<1e3?o+"ms":(o/1e3).toFixed(1)+"s"}function Y(o){return !o||o===0?"":o<1024?o+"b":(o/1024).toFixed(1)+"kb"}function P(o){return o?o.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;"):""}function rt(o){return o>=500?"status-pill-5xx":o>=400?"status-pill-4xx":o>=300?"status-pill-3xx":"status-pill-2xx"}function as(o){return os[o]||(o>=500?"Server Error":o>=400?"Client Error":"OK")}function Us(o,e){if(is.has(o.toLowerCase())){let t=String(e);return t.length<=8?"****":t.slice(0,4)+"..."+t.slice(-4)+" ("+t.length+" chars)"}return String(e)}function it(o){return !o||Object.keys(o).length===0?'<span style="color:var(--text-muted)">No headers</span>':Object.entries(o).map(([e,t])=>'<span class="json-key">'+P(e)+"</span>: "+P(Us(e,t))).join(`
4
+ `)}function X(o){if(!o)return '<span style="color:var(--text-muted)">No body</span>';try{let e=JSON.parse(o);return Fs(JSON.stringify(e,null,2))}catch{return P(o)}}function Fs(o){return P(o).replace(/("(?:[^"\\]|\\.)*")(\s*:)?|\b(true|false)\b|\bnull\b|(-?\d+\.?\d*(?:[eE][+-]?\d+)?)/g,(e,t,s,r,i)=>t?s?'<span class="json-key">'+t+"</span>"+s:'<span class="json-str">'+t+"</span>":r?'<span class="json-bool">'+e+"</span>":i?'<span class="json-num">'+e+"</span>":e==="null"?'<span class="json-null">null</span>':e)}var Ct=class extends f{constructor(){super(...arguments);this.code=0;}createRenderRoot(){return this}render(){let t=rt(this.code);return n`<span class="status-pill ${t}">${this.code}</span>`}};u([y({type:Number})],Ct.prototype,"code",2),Ct=u([g("bk-status-pill")],Ct);var At=class extends f{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return n`<span class="req-duration">${S(this.ms)}</span>`}};u([y({type:Number})],At.prototype,"ms",2),At=u([g("bk-duration-label")],At);var ot=class extends f{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return n`
5
+ <div class="empty">
6
+ <span class="empty-title">${this.title}</span>
7
+ <span class="empty-sub">${this.subtitle}</span>
8
+ </div>
9
+ `}};u([y()],ot.prototype,"title",2),u([y()],ot.prototype,"subtitle",2),ot=u([g("bk-empty-state")],ot);var k=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 n`<div class="toast ${this.visible?"show":""}">${this.message}</div>`}};u([$()],k.prototype,"message",2),u([$()],k.prototype,"visible",2),k=u([g("bk-toast")],k);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),k.show(this.toastMessage);}catch{}}render(){return n`<button class="query-detail-copy" @click=${this.copy}>${this.label}</button>`}};u([y()],K.prototype,"text",2),u([y()],K.prototype,"label",2),u([y({attribute:"toast-message"})],K.prototype,"toastMessage",2),K=u([g("bk-copy-button")],K);var z=class extends f{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return n`
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
+ `}};u([y()],z.prototype,"value",2),u([y()],z.prototype,"label",2),u([y()],z.prototype,"color",2),z=u([g("bk-stat-card")],z);var U=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 nt=class{constructor(e,t,s,r){if(this.subscribe=false,this.provided=false,this.value=void 0,this.t=(i,a)=>{this.unsubscribe&&(this.unsubscribe!==a&&(this.provided=false,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=i,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=true,this.callback&&this.callback(i,a)),this.unsubscribe=a;},this.host=e,t.context!==void 0){let i=t;this.context=i.context,this.callback=i.callback,this.subscribe=i.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 U(this.context,this.host,this.t,this.subscribe));}};var Vt=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 ye=class extends Event{constructor(e,t){super("context-provider",{bubbles:true,composed:true}),this.context=e,this.contextTarget=t;}},at=class extends Vt{constructor(e,t,s){super(t.context!==void 0?t.initialValue:s),this.onContextRequest=r=>{if(r.context!==this.context)return;let i=r.contextTarget??r.composedPath()[0];i!==this.host&&(r.stopPropagation(),this.addCallback(r.callback,i,r.subscribe));},this.onProviderRequest=r=>{if(r.context!==this.context||(r.contextTarget??r.composedPath()[0])===this.host)return;let i=new Set;for(let[a,{consumerHost:c}]of this.subscriptions)i.has(a)||(i.add(a),c.dispatchEvent(new U(this.context,c,a,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 ye(this.context,this.host));}};function Se({context:o}){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 at(this,{context:o,initialValue:r})),r}};{e.constructor.addInitializer((a=>{s.set(a,new at(a,{context:o}));}));let r=Object.getOwnPropertyDescriptor(e,t),i;if(r===void 0){let a=new WeakMap;i={get(){return a.get(this)},set(c){s.get(this).setValue(c),a.set(this,c);},configurable:true,enumerable:true};}else {let a=r.set;i={...r,set(c){s.get(this).setValue(c),a?.call(this,c);}};}return void Object.defineProperty(e,t,i)}}}function T({context:o,subscribe:e}){return (t,s)=>{typeof s=="object"?s.addInitializer((function(){new nt(this,{context:o,callback:r=>{t.set.call(this,r);},subscribe:e});})):t.constructor.addInitializer((r=>{new nt(r,{context:o,callback:i=>{r[s]=i;},subscribe:e});}));}}var _="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 ct=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(),i=this.expandedIdx===s;return n`
15
+ <div
16
+ class="req-row tel-clickable ${i?"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
+ ${i&&t.stack?n`<div class="error-stack">${t.stack}</div>`:d}
24
+ `}render(){let t=this.store.state.errors;return t.length===0?n`<bk-empty-state
25
+ title="No errors"
26
+ subtitle="No errors have been captured yet"
27
+ ></bk-empty-state>`:n`
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
+ `}};u([T({context:_})],ct.prototype,"store",2),u([$()],ct.prototype,"expandedIdx",2),ct=u([g("bk-errors-view")],ct);var kt=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 n`
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?n`<bk-stat-card value=${String(t.error)} label="Errors" color="var(--red)"></bk-stat-card>`:d}
41
+ ${t.warn>0?n`<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?n`<bk-stat-card value=${String(t.debug)} label="Debug"></bk-stat-card>`:d}
44
+ ${t.log>0?n`<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 n`
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?n`<bk-empty-state
54
+ title="No logs"
55
+ subtitle="No console output has been captured yet"
56
+ ></bk-empty-state>`:n`
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
+ `}};u([T({context:_})],kt.prototype,"store",2),kt=u([g("bk-logs-view")],kt);var Gs=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 cs(o){let e=o.trim().match(/^(\w+)/);return e?e[1].toUpperCase():"?"}function ls(o){let e=o.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(o){return P(o).replace(/\b\w+\b/g,e=>Gs.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?cs(t.sql):"?")).toUpperCase(),r=t.table||t.model||(t.sql?ls(t.sql):""),i=t.sql||s+" "+r;return {op:s,table:r,sqlText:i}}renderQueryRow(t,s){let{op:r,table:i,sqlText:a}=this.getQueryInfo(t),c=jt[r]||"var(--text-dim)",l=t.durationMs>ve,h=t.sql||r+" "+i,m=this.expandedIdx===s;return n`
67
+ <div>
68
+ <div
69
+ class="req-row query-row tel-clickable ${m?"expanded":""}"
70
+ @click=${()=>this.toggleQuery(s)}
71
+ >
72
+ <span class="query-op" title=${r} style="color:${c}">${r}</span>
73
+ <span class="query-table" title=${i}>${i}</span>
74
+ <span class="query-preview" title=${h}>${h}</span>
75
+ <span class="query-dur${l?" query-slow":""}">${this.queryDuration(t.durationMs)}</span>
76
+ </div>
77
+ <div class="query-detail ${m?"open":""}">
78
+ ${m?n`
79
+ <pre class="query-detail-sql" .innerHTML=${ds(a)}></pre>
80
+ <bk-copy-button .text=${a} label="Copy"></bk-copy-button>
81
+ `:d}
82
+ </div>
83
+ </div>
84
+ `}render(){let t=this.store.state.queries;return t.length===0?n`<bk-empty-state
85
+ title="No queries"
86
+ subtitle="No database queries have been captured yet"
87
+ ></bk-empty-state>`:n`
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
+ `}};u([T({context:_})],lt.prototype,"store",2),u([$()],lt.prototype,"expandedIdx",2),lt=u([g("bk-queries-view")],lt);function _e(o){return o.replace(/'/g,"'\\''")}function js(o,e){let t=Object.entries(o.headers||{}).filter(([i])=>!ns.has(i)).map(([i,a])=>`-H '${_e(i)}: ${_e(a)}'`).join(" "),s=o.requestBody?` -d '${_e(o.requestBody)}'`:"",r=e?`http://localhost:${e}`:"";return `curl -X ${o.method} ${t}${s} '${r}${o.url}'`}function dt(o){let e=window.__BRAKIT_CONFIG__?.port??"",t=js(o,e);navigator.clipboard.writeText(t).then(()=>k.show("Copied cURL command"));}var pt=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(),dt(t);}renderDetail(t){return n`
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?n`<span>${Y(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=${it(t.headers)}></pre></div>
107
+ <div class="detail-section"><h4>Response Headers</h4><pre .innerHTML=${it(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 n`
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">${Y(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?n`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:n`
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
+ `}};u([T({context:_})],pt.prototype,"store",2),u([$()],pt.prototype,"expandedId",2),pt=u([g("bk-requests-view")],pt);var Lt=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 i of t)s.set(i.id,i);let r={};for(let i of e){let a=i.method+" "+i.url;r[a]||(r[a]={method:i.method,url:i.url,count:0,totalDur:0,maxDur:0,errors:0,callers:{},statusCodes:{},firstTs:i.timestamp,lastTs:i.timestamp});let c=r[a];if(c.count++,c.totalDur+=i.durationMs,i.durationMs>c.maxDur&&(c.maxDur=i.durationMs),i.statusCode>=400&&c.errors++,c.statusCodes[i.statusCode]=(c.statusCodes[i.statusCode]||0)+1,i.timestamp<c.firstTs&&(c.firstTs=i.timestamp),i.timestamp>c.lastTs&&(c.lastTs=i.timestamp),i.parentRequestId){let l=s.get(i.parentRequestId);l&&(c.callers[l.method+" "+(l.path||l.url)]=1);}}return Object.values(r).sort((i,a)=>a.count-i.count)}renderSummary(e){let t=new Set,s=0,r=0;for(let a of e)t.add(a.url),a.statusCode>=400&&s++,r+=a.durationMs;let i=Math.round(r/e.length);return n`
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(i)} 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),i=Object.entries(e.statusCodes),a=i.length>0?Number(i.sort((c,l)=>l[1]-c[1])[0][0]):0;return n`
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
+ ${a>0?n`<bk-status-pill .code=${a}></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?n`<span class="fetch-group-err">${s}% errors</span>`:n`<span class="fetch-group-ok">0% errors</span>`}
155
+ </div>
156
+ ${e.firstTs>0?n`
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?n` \u2192 ${this.formatTime(e.lastTs)}`:d}
161
+ </span>
162
+ </div>`:d}
163
+ ${r.length>0?n`
164
+ <div class="fetch-group-callers">
165
+ <span class="fetch-group-callers-label">Called by</span>
166
+ ${r.map(c=>n`<span class="fetch-group-caller-pill">${c}</span>`)}
167
+ </div>`:d}
168
+ </div>
169
+ `}render(){let e=this.store.state.fetches,t=this.store.state.requests;if(e.length===0)return n`<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 n`
170
+ <div class="fetch-analysis" id="fetch-analysis">
171
+ ${this.renderSummary(e)}
172
+ ${s.length>0?n`
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
+ `}};u([T({context:_})],Lt.prototype,"store",2),Lt=u([g("bk-fetches-view")],Lt);var J=class extends f{constructor(){super(...arguments);this.expandedFlowIdx=-1;this.expandedSubReqIdx=-1;}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"}}analyzeFlow(t){let s=t.requests,r=[],i=[],a=[],c=[],l=new Map;for(let p of s){let v=p.label,E=p.pollingDurationMs||p.durationMs;if(!Ut[p.category||""]){if(p.isDuplicate){let C=l.get(v);C?(C.count++,C.wastedMs+=E):l.set(v,{name:v,count:2,wastedMs:E});continue}if(p.statusCode>=400){i.push(v+" ("+as(p.statusCode)+")");continue}p.responseSize>51200&&a.push("Large response: "+v+" returned "+Y(p.responseSize)),r.push(v);}}for(let p of l.values())c.push(p);let h="";if(c.length>0){let p=c.map(E=>E.name).join(", "),v=c.reduce((E,C)=>E+C.wastedMs,0);h="Your app fetches "+p+" multiple times on this page. This wastes ~"+S(v)+". Try caching these calls, deduplicating with React Query/SWR, or moving them to a shared layout.";}else i.length>0&&(h="Some requests are failing. Check your API routes and make sure the endpoints exist.");let m=s.filter(p=>p.durationMs>2e3&&p.category!==Tt);return m.length>0&&!h&&(h=m.map(p=>p.label).join(", ")+` is taking over ${S(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:r,errors:i,warnings:a,duplicates:c,tip:h}}toggleFlow(t){this.expandedFlowIdx===t?this.expandedFlowIdx=-1:(this.expandedFlowIdx=t,this.expandedSubReqIdx=-1);}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 i=r.querySelector("pre");i&&i.classList.toggle("open");}loadTimelineForContainer(t){let s=t.querySelectorAll(".request-timeline");for(let r of s){let i=r.getAttribute("data-request-id");if(i&&!r.hasAttribute("data-loaded")){r.setAttribute("data-loaded","1");let a=document.createElement("bk-timeline-panel");a.setAttribute("request-id",i),a.setAttribute("request-started",r.getAttribute("data-request-started")||"0"),r.appendChild(a),r.classList.remove("tl-hidden");}}}updated(){if(this.expandedFlowIdx>=0){let t=this.querySelector(".flow-expand.open");t&&this.loadTimelineForContainer(t);}}render(){let t=this.flows;return t.length===0?n`<bk-empty-state title="No actions yet" subtitle="Start using your app to see user action flows here"></bk-empty-state>`:n`
178
+ <div id="flow-col-header" class="col-header">
179
+ <span style="width:8px"></span>
180
+ <span style="flex:1">Action</span>
181
+ <span style="width:60px;text-align:right">Reqs</span>
182
+ <span style="width:120px;text-align:right">Status</span>
183
+ <span style="width:70px;text-align:right">Time</span>
184
+ </div>
185
+ <div id="flow-list">${t.map((s,r)=>this.renderFlowRow(s,r))}</div>
186
+ `}renderFlowRow(t,s){let r=this.expandedFlowIdx===s,i=this.flowDotClass(t),a=this.flowBadgeInfo(t);return n`
187
+ <div class="flow-row ${r?"expanded":""}" @click=${()=>this.toggleFlow(s)}>
188
+ <div class="flow-summary-row">
189
+ <span class="flow-status-dot ${i}"></span>
190
+ <span class="flow-label">${t.label}</span>
191
+ <span class="flow-req-count">${t.requests.length} req${t.requests.length!==1?"s":""}</span>
192
+ <span class="flow-badge-pill ${a.cls}">${a.text}</span>
193
+ <span class="flow-duration">${S(t.totalDurationMs)}</span>
194
+ </div>
195
+ </div>
196
+ <div class="flow-expand ${r?"open":""}">
197
+ ${r?this.viewMode==="simple"?this.renderFlowInsights(t):this.renderFlowSubReqs(t):d}
198
+ </div>
199
+ `}renderFlowInsights(t){let s=this.analyzeFlow(t),r=s.errors.length>0||s.duplicates.length>0||s.warnings.length>0||!!s.tip;return n`
200
+ <div>
201
+ <div class="flow-traffic">${t.requests.map(i=>this.renderTrafficCard(i))}</div>
202
+ ${r?n`
203
+ <div class="flow-divider"></div>
204
+ <div class="flow-insights">
205
+ ${s.errors.map(i=>n`<div class="insight-line insight-error">\u2717 ${i}</div>`)}
206
+ ${s.duplicates.map(i=>n`<div class="insight-line insight-warn">\u26A0 ${i.name} \u2014 loaded ${i.count}x (wasting ~${S(i.wastedMs)})</div>`)}
207
+ ${s.warnings.map(i=>n`<div class="insight-line insight-warn">\u26A0 ${i}</div>`)}
208
+ ${s.tip?n`<div class="insight-line insight-tip">Tip: ${s.tip}</div>`:d}
209
+ </div>
210
+ `:d}
211
+ </div>
212
+ `}renderTrafficCard(t){if(Ut[t.category||""])return d;let s=rt(t.statusCode),r=S(t.pollingDurationMs||t.durationMs),i=!t.isDuplicate&&t.category!==Pt&&t.category!==Tt||t.requestBody&&t.method!=="GET"||!!t.responseBody;return n`
213
+ <div class="traffic-card ${t.isStrictModeDupe?"strict-mode-dupe":""}">
214
+ <div class="traffic-card-header ${i?"has-details":""}">
215
+ <bk-method-badge .method=${t.method}></bk-method-badge>
216
+ <span class="traffic-card-path ${t.isDuplicate?"is-dup":""}">${t.label}</span>
217
+ <span class="status-pill ${s}">${t.statusCode}</span>
218
+ <span class="traffic-card-dur">${r}</span>
219
+ ${t.isDuplicate?n`<span class="traffic-card-dup">duplicate</span>`:n`<span class="traffic-card-size">${Y(t.responseSize)}</span>`}
220
+ </div>
221
+ ${t.isStrictModeDupe?n`<div class="strict-mode-banner">React Strict Mode duplicate \u2014 does not happen in production</div>`:d}
222
+ ${!t.isDuplicate&&t.category!==Pt&&t.category!==Tt?n`<div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>`:d}
223
+ ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):d}
224
+ ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):d}
225
+ </div>
226
+ `}renderBodyToggle(t,s,r){let i=t==="out"?"\u2192":"\u2190";return n`
227
+ <div class="traffic-body">
228
+ <button class="traffic-body-toggle" @click=${this.toggleBodyBlock}>
229
+ <span class="chevron">\u25B8</span><span class="arrow-${t}">${i}</span> ${s}
230
+ </button>
231
+ <pre .innerHTML=${X(r)}></pre>
232
+ </div>
233
+ `}renderFlowSubReqs(t){return n`<div class="flow-subreqs">${t.requests.map((s,r)=>this.renderSubReqRow(s,r))}</div>`}renderSubReqRow(t,s){let r=this.expandedSubReqIdx===s,i=rt(t.statusCode),a=t.pollingDurationMs?S(t.pollingDurationMs):S(t.durationMs);return n`
234
+ <div class="flow-subreq ${r?"expanded":""}" @click=${c=>this.toggleSubReq(s,c)}>
235
+ <bk-method-badge .method=${t.method}></bk-method-badge>
236
+ <span class="subreq-label ${t.isDuplicate?"is-dup":""}">${t.path||t.url}</span>
237
+ ${t.isDuplicate?n`<span class="subreq-dup-tag">duplicate</span>`:d}
238
+ <span class="status-pill ${i}">${t.statusCode}</span>
239
+ <span class="subreq-dur">${a}</span>
240
+ </div>
241
+ <div class="flow-subreq-detail ${r?"open":""}">
242
+ ${r?this.renderSubReqDetail(t):d}
243
+ </div>
244
+ `}renderSubReqDetail(t){let s=rt(t.statusCode);return n`
245
+ <div class="detail-meta">
246
+ <span><bk-method-badge .method=${t.method}></bk-method-badge> ${P(t.url)}</span>
247
+ <span><span class="status-pill ${s}">${t.statusCode}</span></span>
248
+ <span>${t.durationMs}ms</span>
249
+ ${t.responseSize?n`<span>${Y(t.responseSize)}</span>`:d}
250
+ </div>
251
+ <div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>
252
+ <div class="detail-grid">
253
+ <div class="detail-section"><h4>Request Headers</h4><pre .innerHTML=${it(t.headers)}></pre></div>
254
+ <div class="detail-section"><h4>Response Headers</h4><pre .innerHTML=${it(t.responseHeaders)}></pre></div>
255
+ <div class="detail-section"><h4>Request Body</h4><pre .innerHTML=${X(t.requestBody)}></pre></div>
256
+ <div class="detail-section"><h4>Response Body</h4><pre .innerHTML=${X(t.responseBody)}></pre></div>
257
+ </div>
258
+ <div class="detail-actions">
259
+ <button class="btn btn-curl" @click=${r=>{r.stopPropagation(),dt(t);}}>Copy cURL</button>
260
+ </div>
261
+ `}};u([T({context:_})],J.prototype,"store",2),u([$()],J.prototype,"expandedFlowIdx",2),u([$()],J.prototype,"expandedSubReqIdx",2),J=u([g("bk-flows-view")],J);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(c=>c.state==="open"||c.state==="fixing"||c.state==="regressed"),s=e.filter(c=>c.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?n`
262
+ <div class="sec-clear">
263
+ <span class="sec-clear-icon">\u2713</span>
264
+ <div class="sec-clear-text">
265
+ <div class="sec-clear-title">All clear</div>
266
+ <div class="sec-clear-sub">No security or quality issues detected this session</div>
267
+ </div>
268
+ </div>
269
+ `:n`<bk-empty-state title="Waiting for requests..." subtitle="Start using your app to see security findings here"></bk-empty-state>`;let r=0,i=0,a=0;for(let c of t){let l=c.issue.severity;l==="critical"?r++:l==="info"?a++:i++;}return n`
270
+ <div id="security-content">
271
+ ${this.renderSummary(t.length,s.length,r,i,a)}
272
+ ${t.length===0&&s.length>0?n`
273
+ <div class="sec-clear">
274
+ <span class="sec-clear-icon">\u2713</span>
275
+ <div class="sec-clear-text">
276
+ <div class="sec-clear-title">All issues resolved</div>
277
+ <div class="sec-clear-sub">${s.length} finding${s.length!==1?"s were":" was"} detected and fixed</div>
278
+ </div>
279
+ </div>
280
+ `:d}
281
+ ${t.length>0?this.renderOpenGroups(t):d}
282
+ ${s.length>0?this.renderResolved(s):d}
283
+ </div>
284
+ `}renderSummary(e,t,s,r,i){return n`
285
+ <div class="sec-summary">
286
+ <div class="sec-summary-left">
287
+ <span class="sec-summary-count">${e}</span>
288
+ <span class="sec-summary-label">open issue${e!==1?"s":""}</span>
289
+ ${t>0?n`<span class="sec-resolved-badge">${t} resolved</span>`:d}
290
+ </div>
291
+ <div class="sec-summary-right">
292
+ ${s>0?n`<span class="sec-badge critical">${s} critical</span>`:d}
293
+ ${r>0?n`<span class="sec-badge warning">${r} warning</span>`:d}
294
+ ${i>0?n`<span class="sec-badge info">${i} info</span>`:d}
295
+ </div>
296
+ </div>
297
+ `}renderOpenGroups(e){let t={},s=[];for(let r of e){let i=r.issue,a=i.rule||i.type;t[a]||(t[a]={rule:a,title:i.title,severity:i.severity,hint:i.hint,items:[]},s.push(a)),t[a].items.push(r);}return s.sort((r,i)=>{let a=H[t[r].severity]?.sort??2,c=H[t[i].severity]?.sort??2;return a!==c?a-c:t[i].items.length-t[r].items.length}),n`${s.map(r=>this.renderGroup(t[r]))}`}renderGroup(e){let t=H[e.severity]||H.info;return n`
298
+ <div class="sec-group">
299
+ <div class="sec-group-header">
300
+ <span class="sec-group-icon ${t.cls}">${t.icon}</span>
301
+ <span class="sec-group-title">${e.title}</span>
302
+ <span class="sec-group-count">${e.items.length}</span>
303
+ </div>
304
+ ${e.hint?n`<div class="sec-hint">${e.hint}</div>`:d}
305
+ <div class="sec-items">${e.items.map(s=>this.renderIssueItem(s))}</div>
306
+ </div>
307
+ `}renderIssueItem(e){let t=e.issue;return n`
308
+ <div class="sec-item">
309
+ <div class="sec-item-desc">${t.desc}</div>
310
+ ${e.occurrences>1?n`<span class="sec-item-count">${e.occurrences}x</span>`:d}
311
+ ${e.state==="fixing"&&e.aiStatus==="fixed"?n`<span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>`:e.aiStatus==="wont_fix"?n`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:e.state==="regressed"?n`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:d}
312
+ ${e.aiNotes?n`<div class="sec-ai-notes">${e.aiNotes}</div>`:d}
313
+ </div>
314
+ `}renderResolved(e){return n`
315
+ <div class="sec-resolved-title">
316
+ <span class="sec-resolved-check">\u2713</span> Resolved
317
+ <span class="sec-resolved-count">${e.length}</span>
318
+ </div>
319
+ <div class="sec-group sec-group-resolved">
320
+ <div class="sec-items">
321
+ ${e.map(t=>n`
322
+ <div class="sec-item sec-item-resolved">
323
+ <span class="sec-resolved-item-icon">\u2713</span>
324
+ <div class="sec-item-desc">${t.issue.title} \u2014 ${t.issue.endpoint||"global"}</div>
325
+ ${t.aiStatus==="fixed"?n`<span class="sec-ai-badge sec-ai-verified">Verified fix</span>`:d}
326
+ ${t.aiNotes?n`<div class="sec-ai-notes">${t.aiNotes}</div>`:d}
327
+ </div>
328
+ `)}
329
+ </div>
330
+ </div>
331
+ `}};u([T({context:_})],It.prototype,"store",2),It=u([g("bk-security-view")],It);var ut=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 i=r.querySelector(".item-label");if(i&&i.textContent?.trim()===(Rt[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 i=r.getAttribute("data-nav");i&&this.navigateToView(i);return}r=r.parentElement;}this.expandedCardIdx=this.expandedCardIdx===t?-1:t;}render(){let t=this.store.state,s=t.requests.filter(p=>!p.isStatic&&(!p.path||p.path.indexOf(O)!==0));if(!(s.length>0||t.queries.length>0||t.errors.length>0))return n`<bk-empty-state
332
+ title="Waiting for requests..."
333
+ subtitle="Start using your app to see insights here"
334
+ ></bk-empty-state>`;let i=s.filter(p=>p.statusCode>=400).length,a=s.length>0?Math.round(s.reduce((p,v)=>p+v.durationMs,0)/s.length):0,c=t.issues||[],l=c.filter(p=>p.state==="open"||p.state==="regressed"),h=c.filter(p=>p.state==="fixing"),m=c.filter(p=>p.state==="resolved");return n`
335
+ <div class="ov-container" id="overview-content">
336
+ ${this.renderSummary(s.length,t.flows.length,a,t.queries.length,i,t.fetches.length)}
337
+ ${l.length===0&&h.length===0&&m.length===0?n`<div class="ov-clear">
338
+ <span class="ov-clear-icon">\u2713</span>All clear \u2014 no issues detected
339
+ </div>`:d}
340
+ ${l.length===0&&m.length>0?n`<div class="ov-clear">
341
+ <span class="ov-clear-icon">\u2713</span>All issues resolved \u2014
342
+ ${m.length} finding${m.length!==1?"s were":" was"} detected and
343
+ fixed
344
+ </div>`:d}
345
+ ${l.length>0?this.renderOpenIssues(l):d}
346
+ ${h.length>0?this.renderVerifying(h):d}
347
+ ${m.length>0?this.renderResolvedIssues(m):d}
348
+ </div>
349
+ `}renderSummary(t,s,r,i,a,c){return n`
350
+ <div class="ov-summary">
351
+ <div class="ov-stat"><span class="ov-stat-value">${t}</span><span class="ov-stat-label">Requests</span></div>
352
+ <div class="ov-stat"><span class="ov-stat-value">${s}</span><span class="ov-stat-label">Actions</span></div>
353
+ <div class="ov-stat"><span class="ov-stat-value">${S(r)}</span><span class="ov-stat-label">Avg Response</span></div>
354
+ <div class="ov-stat"><span class="ov-stat-value">${i}</span><span class="ov-stat-label">Queries</span></div>
355
+ <div class="ov-stat"><span class="ov-stat-value" style="color:${a>0?"var(--red)":"var(--green)"}">${a}</span><span class="ov-stat-label">Errors</span></div>
356
+ <div class="ov-stat"><span class="ov-stat-value">${c}</span><span class="ov-stat-label">Fetches</span></div>
357
+ </div>
358
+ `}renderOpenIssues(t){return n`
359
+ <div class="ov-section-title">Issues Found <span class="ov-issue-count">${t.length}</span></div>
360
+ <div class="ov-cards">${t.map((s,r)=>this.renderIssueCard(s,r))}</div>
361
+ `}renderIssueCard(t,s){let r=t.issue,i=H[r.severity]||H.info,a=this.expandedCardIdx===s,c=t.aiStatus==="wont_fix"?n`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:t.state==="regressed"?n`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:d,l=t.cleanHitsSinceLastSeen>0?n`<div class="ov-card-resolving">Resolving\u2026 ${t.cleanHitsSinceLastSeen}/${5} clean requests</div>`:d;return n`
362
+ <div class="ov-card ${a?"expanded":""}" @click=${h=>this.toggleCard(s,h)}>
363
+ <span class="ov-card-icon ${i.cls}">${i.icon}</span>
364
+ <div class="ov-card-body">
365
+ <div class="ov-card-title">${r.title}${c}</div>
366
+ <div class="ov-card-desc">${r.desc}</div>
367
+ ${l}
368
+ <div class="ov-card-expand" style="display:${a?"block":"none"}">
369
+ ${r.detail?n`<div .innerHTML=${r.detail}></div>`:d}
370
+ ${r.hint?n`<div class="ov-card-hint">${r.hint}</div>`:d}
371
+ ${r.nav?n`<span class="ov-card-link" data-nav=${r.nav}>View in ${de[r.nav]||r.nav} \u2192</span>`:d}
372
+ </div>
373
+ </div>
374
+ <span class="ov-card-arrow">${a?"\u2193":"\u2192"}</span>
375
+ </div>
376
+ `}renderVerifying(t){return n`
377
+ <div class="ov-section-title ov-resolved-title">
378
+ <span style="color:var(--yellow,#f5a623)">\u29d7</span> Awaiting Verification
379
+ <span class="ov-issue-count">${t.length}</span>
380
+ </div>
381
+ <div class="ov-cards">
382
+ ${t.map(s=>{let r=s.issue,i=s.cleanHitsSinceLastSeen>0?n`<div class="ov-card-resolving">Verifying\u2026 ${s.cleanHitsSinceLastSeen}/${5} clean requests</div>`:d;return n`
383
+ <div class="ov-card ov-card-resolved">
384
+ <span class="ov-card-icon resolved">\u29d7</span>
385
+ <div class="ov-card-body">
386
+ <div class="ov-card-title" style="color:var(--text-muted)">
387
+ ${r.title}
388
+ <span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>
389
+ </div>
390
+ <div class="ov-card-desc">${r.desc}</div>
391
+ ${i}
392
+ </div>
393
+ </div>
394
+ `})}
395
+ </div>
396
+ `}renderResolvedIssues(t){return n`
397
+ <div class="ov-section-title ov-resolved-title">
398
+ <span style="color:var(--green)">\u2713</span> Resolved
399
+ <span class="ov-issue-count">${t.length}</span>
400
+ </div>
401
+ <div class="ov-cards">
402
+ ${t.map(s=>n`
403
+ <div class="ov-card ov-card-resolved">
404
+ <span class="ov-card-icon resolved">\u2713</span>
405
+ <div class="ov-card-body">
406
+ <div class="ov-card-title" style="text-decoration:line-through;color:var(--text-muted)">${s.issue.title}</div>
407
+ <div class="ov-card-desc">${s.issue.desc}</div>
408
+ </div>
409
+ </div>
410
+ `)}
411
+ </div>
412
+ `}};u([T({context:_})],ut.prototype,"store",2),u([$()],ut.prototype,"expandedCardIdx",2),ut=u([g("bk-overview-view")],ut);var F=class extends f{constructor(){super(...arguments);this.selectedEndpoint=q;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(R.metricsLive)).json();this.graphData=s.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===q)&&(this.selectedEndpoint=q);}catch{this.loadError=true;}}healthGrade(t){for(let s of Qt)if(t<s.max)return s;return Qt[Qt.length-1]}fmtMs(t){return t<1?"<1ms":t<1e3?Math.round(t)+"ms":(t/1e3).toFixed(1)+"s"}dotColor(t){return t<V?wt.green:t<W?wt.amber:wt.red}reqDotColor(t){return t.statusCode>=400?wt.red:this.dotColor(t.durationMs)}parseHex(t){return [parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)]}setupCanvas(t){let s=t.getContext("2d");if(!s)return null;let r=window.devicePixelRatio||1,i=t.clientWidth,a=t.clientHeight;return t.width=i*r,t.height=a*r,s.scale(r,r),{ctx:s,w:i,h:a}}drawDot(t,s,r,i,a){let[c,l,h]=this.parseHex(a);t.beginPath(),t.arc(s,r,i+2,0,Math.PI*2),t.fillStyle=`rgba(${c},${l},${h},0.25)`,t.fill(),t.beginPath(),t.arc(s,r,i,0,Math.PI*2),t.fillStyle=a,t.fill();}drawErrorX(t,s,r,i,a,c){let[l,h,m]=this.parseHex(a);t.strokeStyle=`rgba(${l},${h},${m},0.3)`,t.lineWidth=c+2,t.beginPath(),t.moveTo(s-i,r-i),t.lineTo(s+i,r+i),t.moveTo(s+i,r-i),t.lineTo(s-i,r+i),t.stroke(),t.strokeStyle=a,t.lineWidth=c,t.beginPath(),t.moveTo(s-i,r-i),t.lineTo(s+i,r+i),t.moveTo(s+i,r-i),t.lineTo(s-i,r+i),t.stroke();}drawScatterChart(t,s){this.scatterDots=[];let r=this.setupCanvas(t);if(!r||s.length===0)return;let{ctx:i,w:a,h:c}=r,l=es,h=a-l.left-l.right,m=c-l.top-l.bottom,p=0,v=s[0].timestamp,E=s[0].timestamp;for(let b of s)b.durationMs>p&&(p=b.durationMs),b.timestamp<v&&(v=b.timestamp),b.timestamp>E&&(E=b.timestamp);p=Math.max(p,10),p=Math.ceil(p*1.15/10)*10;let C=E-v||1;i.strokeStyle=Je,i.lineWidth=1;let ht=4;for(let b=0;b<=ht;b++){let x=l.top+m-b/ht*m;i.beginPath(),i.moveTo(l.left,x),i.lineTo(l.left+h,x),i.stroke(),i.fillStyle=Ee,i.font=Ze,i.textAlign="right",i.fillText(this.fmtMs(Math.round(b/ht*p)),l.left-8,x+3);}for(let b of [{ms:V},{ms:W}]){if(b.ms>=p)continue;let x=l.top+m-b.ms/p*m;i.beginPath(),i.setLineDash([4,4]),i.strokeStyle="rgba(113,113,122,0.3)",i.lineWidth=1,i.moveTo(l.left,x),i.lineTo(l.left+h,x),i.stroke(),i.setLineDash([]),i.fillStyle="rgba(113,113,122,0.5)",i.font=$e,i.textAlign="left",i.fillText(this.fmtMs(b.ms),l.left+h+2,x+3);}for(let b=0;b<s.length;b++){let x=s[b],I=s.length===1?l.left+h/2:l.left+(x.timestamp-v)/C*h,mt=l.top+m-x.durationMs/p*m,tt=this.reqDotColor(x);this.scatterDots.push({x:I,y:mt,idx:b,r:x}),x.statusCode>=400?this.drawErrorX(i,I,mt,4,tt,2):this.drawDot(i,I,mt,4,tt);}i.fillStyle=Ee,i.font=$e,i.textAlign="center";let A=[v,v+C/2,E];for(let b=0;b<A.length;b++){let x=l.left+b/2*h,I=new Date(A[b]);i.fillText(I.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),x,l.top+m+14);}t.style.cursor="pointer",t.onclick=b=>{let x=t.getBoundingClientRect(),I=b.clientX-x.left,mt=b.clientY-x.top,tt=null,Xt=1/0;for(let Kt of this.scatterDots){let xe=Math.sqrt((Kt.x-I)**2+(Kt.y-mt)**2);xe<Xt&&(Xt=xe,tt=Kt);}tt&&Xt<16&&this.highlightRow(tt.idx);};}drawInlineScatter(t,s){let r=this.setupCanvas(t);if(!r||s.length===0)return;let{ctx:i,w:a,h:c}=r,l=4,h=4,m=a-l*2,p=c-h*2,v=0,E=s[0].timestamp,C=s[0].timestamp;for(let A of s)A.durationMs>v&&(v=A.durationMs),A.timestamp<E&&(E=A.timestamp),A.timestamp>C&&(C=A.timestamp);v=Math.max(v,10),v=Math.ceil(v*1.15/10)*10;let ht=C-E||1;for(let A of [V,W]){if(A>=v)continue;let b=h+p-A/v*p;i.beginPath(),i.setLineDash([2,3]),i.strokeStyle="rgba(113,113,122,0.15)",i.lineWidth=1,i.moveTo(l,b),i.lineTo(l+m,b),i.stroke(),i.setLineDash([]);}for(let A of s){let b=s.length===1?l+m/2:l+(A.timestamp-E)/ht*m,x=h+p-A.durationMs/v*p,I=this.reqDotColor(A);A.statusCode>=400?this.drawErrorX(i,b,x,2.5,I,1.5):this.drawDot(i,b,x,2.5,I);}i.fillStyle="rgba(113,113,122,0.5)",i.font=ts,i.textAlign="right",i.fillText(this.fmtMs(v),a-2,h+8),i.fillText(this.fmtMs(0),a-2,c-2);}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===q)this.graphData.forEach((t,s)=>{if(t.requests.length===0)return;let r=this.querySelector(`#inline-scatter-${s}`);r&&this.drawInlineScatter(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.drawScatterChart(t,s.requests);}}}render(){return !this.graphData||this.graphData.length===0?n`<bk-empty-state title="No performance data yet" subtitle="Hit some endpoints and data will appear here"></bk-empty-state>`:n`
413
+ <div id="graph-content">
414
+ ${this.renderSelector()}
415
+ ${this.selectedEndpoint===q?this.renderOverview():this.renderDetail()}
416
+ </div>
417
+ `}renderSelector(){return n`
418
+ <div class="perf-selector">
419
+ <button class="perf-selector-btn ${this.selectedEndpoint===q?"active":""}"
420
+ @click=${()=>{this.selectedEndpoint=q;}}>Overview</button>
421
+ ${this.graphData.map((t,s)=>n`
422
+ <button class="perf-selector-btn ${t.endpoint===this.selectedEndpoint?"active":""}"
423
+ @click=${()=>{this.selectedEndpoint=t.endpoint;}}>
424
+ <span class="perf-dot" style="background:${be[s%be.length]}"></span>${t.endpoint}
425
+ </button>
426
+ `)}
427
+ </div>
428
+ `}renderOverview(){return n`
429
+ <div class="perf-endpoint-list">
430
+ ${this.graphData.map((t,s)=>t.requests.length===0?d:this.renderEndpointCard(t,s))}
431
+ </div>
432
+ `}renderEndpointCard(t,s){let r=t.summary,i=this.healthGrade(r.p95Ms),a=Math.round(r.errorRate*r.totalRequests),c=(r.avgQueryTimeMs||0)+(r.avgFetchTimeMs||0)+(r.avgAppTimeMs||0),l=d;if(c>0){let h=Math.round((r.avgQueryTimeMs||0)/c*100),m=Math.round((r.avgFetchTimeMs||0)/c*100),p=Math.max(0,100-h-m);l=n`
433
+ <div class="perf-breakdown-inline">
434
+ <div class="perf-breakdown-bar perf-breakdown-bar-sm">
435
+ ${h>0?n`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${h}%"></div>`:d}
436
+ ${m>0?n`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${m}%"></div>`:d}
437
+ ${p>0?n`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${p}%"></div>`:d}
438
+ </div>
439
+ <span class="perf-breakdown-labels">
440
+ ${h>0?n`<span class="perf-breakdown-lbl"><span class="perf-breakdown-dot perf-breakdown-db"></span>${this.fmtMs(r.avgQueryTimeMs||0)}</span>`:d}
441
+ ${m>0?n`<span class="perf-breakdown-lbl"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>${this.fmtMs(r.avgFetchTimeMs||0)}</span>`:d}
442
+ <span class="perf-breakdown-lbl"><span class="perf-breakdown-dot perf-breakdown-app"></span>${this.fmtMs(r.avgAppTimeMs||0)}</span>
443
+ </span>
444
+ </div>
445
+ `;}return n`
446
+ <div class="perf-endpoint-card" @click=${()=>{this.selectedEndpoint=t.endpoint;}}>
447
+ <div class="perf-ep-header">
448
+ <span class="perf-ep-name">${t.endpoint}</span>
449
+ <span class="perf-ep-stats">
450
+ <span class="perf-ep-stat" style="color:${i.color}">p95: ${this.fmtMs(r.p95Ms)}</span>
451
+ <span class="perf-ep-stat ${a>0?"perf-ep-stat-err":""}">${a} err</span>
452
+ ${r.avgQueryCount>0?n`<span class="perf-ep-stat ${r.avgQueryCount>5?"perf-ep-stat-warn":""}">${r.avgQueryCount} q/req</span>`:d}
453
+ <span class="perf-ep-stat perf-ep-stat-muted">${r.totalRequests} req${r.totalRequests!==1?"s":""}</span>
454
+ </span>
455
+ </div>
456
+ ${l}
457
+ <canvas id="inline-scatter-${s}" class="perf-inline-canvas"></canvas>
458
+ </div>
459
+ `}renderDetail(){let t=this.graphData.find(a=>a.endpoint===this.selectedEndpoint);if(!t?.requests?.length)return n`<bk-empty-state subtitle="No data for this endpoint"></bk-empty-state>`;let s=t.summary,r=this.healthGrade(s.p95Ms),i=Math.round(s.errorRate*s.totalRequests);return n`
460
+ ${this.renderDetailHeader(t,r)}
461
+ ${this.renderDetailMetrics(s,r,i)}
462
+ ${this.renderDetailBreakdown(s)}
463
+ ${this.renderDetailChart()}
464
+ ${this.renderDetailHistory(t)}
465
+ `}renderDetailHeader(t,s){return n`
466
+ <div class="perf-detail-header">
467
+ <div class="perf-detail-title">
468
+ <span class="perf-badge perf-badge-lg" style="color:${s.color};background:${s.bg};border-color:${s.border}">${s.label}</span>
469
+ <span>${t.endpoint}</span>
470
+ </div>
471
+ </div>
472
+ `}renderDetailMetrics(t,s,r){return n`
473
+ <div class="perf-metric-row">
474
+ <div class="perf-metric-card">
475
+ <span class="perf-metric-label">P95</span>
476
+ <span class="perf-metric-value" style="color:${s.color}">${this.fmtMs(t.p95Ms)}</span>
477
+ </div>
478
+ <div class="perf-metric-card">
479
+ <span class="perf-metric-label">Errors</span>
480
+ <span class="perf-metric-value" style="color:${r>0?"var(--red)":"var(--green)"}">
481
+ ${r>0?r+" ("+Math.round(t.errorRate*100)+"%)":"0"}
482
+ </span>
483
+ </div>
484
+ <div class="perf-metric-card">
485
+ <span class="perf-metric-label">Queries/req</span>
486
+ <span class="perf-metric-value" style="color:${t.avgQueryCount>5?"var(--amber)":"var(--text)"}">${t.avgQueryCount}</span>
487
+ </div>
488
+ </div>
489
+ `}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),i=Math.round((t.avgFetchTimeMs||0)/s*100),a=Math.max(0,100-r-i);return n`
490
+ <div class="perf-breakdown">
491
+ <div class="perf-section-title">Time Breakdown</div>
492
+ <div class="perf-breakdown-bar">
493
+ ${r>0?n`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${r}%"></div>`:d}
494
+ ${i>0?n`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${i}%"></div>`:d}
495
+ ${a>0?n`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${a}%"></div>`:d}
496
+ </div>
497
+ <div class="perf-breakdown-legend">
498
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${this.fmtMs(t.avgQueryTimeMs||0)} (${r}%)</span>
499
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${this.fmtMs(t.avgFetchTimeMs||0)} (${i}%)</span>
500
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${this.fmtMs(t.avgAppTimeMs||0)} (${a}%)</span>
501
+ </div>
502
+ </div>
503
+ `}renderDetailChart(){return n`
504
+ <div class="perf-chart-wrap">
505
+ <div class="perf-section-title">Response Time</div>
506
+ <canvas id="perf-detail-canvas" class="perf-canvas" style="width:100%;height:240px"></canvas>
507
+ </div>
508
+ `}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 n`
509
+ <div class="perf-history-wrap">
510
+ <div class="col-header">
511
+ <span class="perf-col perf-col-date">Time</span>
512
+ <span class="perf-col perf-col-health">Health</span>
513
+ <span class="perf-col perf-col-avg">Duration</span>
514
+ <span class="perf-col perf-col-breakdown">Breakdown</span>
515
+ <span class="perf-col perf-col-status">Status</span>
516
+ <span class="perf-col perf-col-qpr">Queries</span>
517
+ </div>
518
+ ${s.map(r=>this.renderHistoryRow(r.r,r.origIdx))}
519
+ </div>
520
+ `}renderHistoryRow(t,s){let r=this.healthGrade(t.durationMs),i=new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),a=t.statusCode>=400,c=t.queryTimeMs||0,l=t.fetchTimeMs||0,h=Math.max(0,t.durationMs-c-l);return n`
521
+ <div class="perf-hist-row ${a?"perf-hist-row-err":""}" data-req-idx=${s}>
522
+ <span class="perf-col perf-col-date">${i}</span>
523
+ <span class="perf-col perf-col-health">
524
+ <span class="perf-badge perf-badge-sm" style="color:${r.color};background:${r.bg};border-color:${r.border}">${r.label}</span>
525
+ </span>
526
+ <span class="perf-col perf-col-avg">${this.fmtMs(t.durationMs)}</span>
527
+ <span class="perf-col perf-col-breakdown">
528
+ ${c>0?n`<span class="perf-bd-tag perf-bd-tag-db">DB ${this.fmtMs(c)}</span>`:d}
529
+ ${l>0?n`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${this.fmtMs(l)}</span>`:d}
530
+ <span class="perf-bd-tag perf-bd-tag-app">App ${this.fmtMs(h)}</span>
531
+ </span>
532
+ <span class="perf-col perf-col-status" style="color:${a?"var(--red)":"var(--text-muted)"}">${t.statusCode}</span>
533
+ <span class="perf-col perf-col-qpr">${t.queryCount}</span>
534
+ </div>
535
+ `}};u([T({context:_})],F.prototype,"store",2),u([$()],F.prototype,"selectedEndpoint",2),u([$()],F.prototype,"graphData",2),u([$()],F.prototype,"loadError",2),F=u([g("bk-performance-view")],F);function Qs(o){return o===0?"<1ms":S(o)}var w=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=w.cache.get(this.requestId);if(t){this.data=t;return}this.loading=true;try{let s=await fetch(`${R.activity}?requestId=${this.requestId}`);if(!s.ok){this.failed=!0,this.loading=!1;return}let r=await s.json();if(w.cache.size>=fe){let i=w.cache.keys().next().value;i!==void 0&&w.cache.delete(i);}w.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(()=>k.show("SQL copied")).catch(()=>k.show("Copy failed"));}render(){if(this.loading)return n`<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 n`
536
+ <div class="tl-header">
537
+ <span class="tl-title">Activity Timeline</span>
538
+ <span class="tl-counts">
539
+ ${t.counts.queries>0?n`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:d}
540
+ ${t.counts.fetches>0?n`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:d}
541
+ ${t.counts.logs>0?n`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:d}
542
+ ${t.counts.errors>0?n`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:d}
543
+ </span>
544
+ </div>
545
+ <div class="tl-events">${this.renderTimeline(t.timeline,s)}</div>
546
+ `}renderTimeline(t,s){let r=new Map,i=[];for(let c of t){let l=c.type==="query"?c.data.parentFetchId:void 0;if(c.type==="query"&&l){let h=r.get(l);h||(h=[],r.set(l,h)),h.push(c);}else i.push(c);}let a=0;return i.map(c=>{let l=a++,h=c.type==="fetch"?c.data.fetchId:void 0,m=h?r.get(h):void 0;if(m&&m.length>0){let p=m.length;return n`
547
+ ${this.renderEvent(c,l,s)}
548
+ <div class="tl-nested">
549
+ <span class="tl-nested-label">${p} nested quer${p===1?"y":"ies"}</span>
550
+ ${m.map(v=>{let E=a++;return this.renderEvent(v,E,s,true)})}
551
+ </div>
552
+ `}return this.renderEvent(c,l,s)})}renderEvent(t,s,r,i=false){let a=ss[t.type]||"var(--text-dim)",c=rs[t.type]||t.type,l="+"+S(Math.round(t.timestamp-r)),h=t.type==="query"?t.data.sql:void 0,m=!!h,p=this.expandedSqlIdx===s;return n`
553
+ <div class="tl-event ${m?"tl-clickable":""} ${i?"tl-nested-event":""}"
554
+ style="${m?"":`border-left-color:${a}`}"
555
+ @click=${m?v=>this.toggleSql(s,v):d}>
556
+ <span class="tl-event-time">${l}</span>
557
+ <span class="tl-event-type" style="color:${a}">${c}</span>
558
+ ${this.renderEventContent(t)}
559
+ ${h?n`
560
+ <div class="tl-event-sql ${p?"open":""}">
561
+ <button class="tl-sql-copy" @click=${v=>this.copySql(h,v)}>Copy</button>
562
+ ${h}
563
+ </div>`:d}
564
+ </div>
565
+ `}renderEventContent(t){switch(t.type){case "fetch":{let s=t.data,r=s.statusCode>=400;return n`
566
+ <span class="tl-event-summary">${s.method} ${s.url}</span>
567
+ <span class="tl-event-status" style="${r?"color:var(--red)":""}">${s.statusCode}</span>
568
+ <span class="tl-event-dur">${S(s.durationMs)}</span>
569
+ `}case "query":{let s=t.data,r=(s.normalizedOp||s.operation||"?").toUpperCase(),i=s.table||s.model||"",a=jt[r]||"var(--text-dim)";return n`
570
+ <span class="tl-event-summary"><span style="color:${a};font-weight:600">${r}</span> ${i}</span>
571
+ <span class="tl-event-dur">${Qs(s.durationMs)}</span>
572
+ `}case "log":{let s=t.data,r=ze[s.level]||"var(--text-dim)";return n`<span class="tl-event-summary"><span style="color:${r}">${s.level.toUpperCase()}</span> ${s.message}</span>`}case "error":{let s=t.data;return n`<span class="tl-event-summary" style="color:var(--red)">${s.name}: ${s.message}</span>`}default:return d}}};w.cache=new Map,u([T({context:_})],w.prototype,"store",2),u([y({attribute:"request-id"})],w.prototype,"requestId",2),u([y({attribute:"request-started",type:Number})],w.prototype,"requestStarted",2),u([$()],w.prototype,"data",2),u([$()],w.prototype,"loading",2),u([$()],w.prototype,"failed",2),u([$()],w.prototype,"expandedSqlIdx",2),w=u([g("bk-timeline-panel")],w);var Yt=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(R.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(),ge)));},this.eventSource.addEventListener(ne,e=>{this.store.prependFetch(JSON.parse(e.data));}),this.eventSource.addEventListener("log",e=>{this.store.prependLog(JSON.parse(e.data));}),this.eventSource.addEventListener(ae,e=>{this.store.prependError(JSON.parse(e.data));}),this.eventSource.addEventListener(ce,e=>{this.store.prependQuery(JSON.parse(e.data));}),this.eventSource.addEventListener(le,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(R.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch(R.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function ps(){return n`<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 us(){return n`<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 hs(){return n`<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 ms(){return n`<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 vs(){return n`<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 fs(){return n`<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 gs(){return n`<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 bs(){return n`<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 Es(){return n`<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 Z=class extends f{constructor(){super(...arguments);this.store=new Wt;this.activeView="overview";this.viewMode="simple";this.sse=new Yt(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(R.flows),fetch(R.requests)]),[r,i]=await Promise.all([t.json(),s.json()]);this.store.setFlows(r.flows),this.store.setRequests(i.requests);}catch(t){console.warn("[brakit]",t);}try{let[t,s,r,i,a]=await Promise.all([fetch(R.fetches),fetch(R.errors),fetch(R.logs),fetch(R.queries),fetch(R.metricsLive)]),[c,l,h,m,p]=await Promise.all([t.json(),s.json(),r.json(),i.json(),a.json()]);this.store.setFetches(c.entries),this.store.setErrors(l.entries),this.store.setLogs(h.entries),this.store.setQueries(m.entries),this.store.setMetrics(p.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let s=await(await fetch(R.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(`${R.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(R.clear,{method:"POST"}),this.store.clearAll(),k.show("Cleared"));}handleCopyAsCurl(t){dt(t);}render(){let t=this.store.state,s=t.requests.filter(l=>!l.path?.startsWith(O)),r=s.filter(l=>l.statusCode>=400).length,i=s.length>0?Math.round(s.reduce((l,h)=>l+h.durationMs,0)/s.length):0,a=(t.issues||[]).filter(l=>l.state!=="resolved"&&l.state!=="stale").length,c=window.__BRAKIT_CONFIG__;return n`
573
+ <div class="app" id="app">
574
+ <aside class="sidebar">
575
+ <div class="sidebar-logo">
576
+ <span class="logo-text">brakit</span>
577
+ <span class="logo-version">v${c?.version??""}</span>
578
+ </div>
579
+ <nav class="sidebar-nav">
580
+ ${this.renderSidebarItem("overview","Overview",ps(),void 0)}
581
+ <div class="sidebar-section">Monitor</div>
582
+ ${this.renderSidebarItem("actions","Actions",us(),t.flows.length)}
583
+ ${this.renderSidebarItem("requests","Requests",hs(),s.length)}
584
+ ${this.renderSidebarItem("fetches","Fetches",ms(),t.fetches.length)}
585
+ <div class="sidebar-section">Insights</div>
586
+ ${this.renderSidebarItem("queries","Queries",vs(),t.queries.length)}
587
+ ${this.renderSidebarItem("errors","Errors",fs(),t.errors.length)}
588
+ ${this.renderSidebarItem("logs","Logs",gs(),t.logs.length)}
589
+ ${this.renderSidebarItem("security","Security",bs(),a,a===0)}
590
+ ${this.renderSidebarItem("performance","Performance",Es(),void 0)}
591
+ </nav>
592
+ <div class="sidebar-footer">:${c?.port??""}</div>
593
+ </aside>
594
+ <div class="main-panel">
595
+ <div class="header">
596
+ <div class="header-left">
597
+ <span class="header-title" id="header-title">${Rt[this.activeView]||this.activeView}</span>
598
+ <span class="header-sub" id="header-sub">${pe[this.activeView]||""}</span>
599
+ </div>
600
+ <div class="header-right">
601
+ ${this.activeView==="actions"?n`
602
+ <div class="segmented-control" id="mode-toggle">
603
+ <button class="segmented-btn ${this.viewMode==="simple"?"active":""}" @click=${()=>{this.viewMode="simple",this.store.setViewMode("simple");}}>Quick</button>
604
+ <button class="segmented-btn ${this.viewMode==="detailed"?"active":""}" @click=${()=>{this.viewMode="detailed",this.store.setViewMode("detailed");}}>Detailed</button>
605
+ </div>
606
+ `:d}
607
+ <button class="btn btn-danger" @click=${this.handleClear}>Clear</button>
608
+ </div>
609
+ </div>
610
+ <div class="main-content">
611
+ <div id="overview-container" style="display:${this.activeView==="overview"?"block":"none"}">
612
+ <bk-overview-view></bk-overview-view>
613
+ </div>
614
+ <div class="view-flows" id="flow-container" style="display:${this.activeView==="actions"?"block":"none"}">
615
+ <bk-flows-view></bk-flows-view>
616
+ </div>
617
+ <div class="view-requests" id="request-container" style="display:${this.activeView==="requests"?"block":"none"}">
618
+ <bk-requests-view></bk-requests-view>
619
+ </div>
620
+ <div class="view-telemetry" id="fetch-container" style="display:${this.activeView==="fetches"?"block":"none"}">
621
+ <bk-fetches-view></bk-fetches-view>
622
+ </div>
623
+ <div class="view-telemetry" id="query-container" style="display:${this.activeView==="queries"?"block":"none"}">
624
+ <bk-queries-view></bk-queries-view>
625
+ </div>
626
+ <div class="view-telemetry" id="error-container" style="display:${this.activeView==="errors"?"block":"none"}">
627
+ <bk-errors-view></bk-errors-view>
628
+ </div>
629
+ <div class="view-telemetry" id="log-container" style="display:${this.activeView==="logs"?"block":"none"}">
630
+ <bk-logs-view></bk-logs-view>
631
+ </div>
632
+ <div class="view-telemetry" id="security-container" style="display:${this.activeView==="security"?"block":"none"}">
633
+ <bk-security-view></bk-security-view>
634
+ </div>
635
+ <div class="view-telemetry" id="performance-container" style="display:${this.activeView==="performance"?"block":"none"}">
636
+ <bk-performance-view></bk-performance-view>
637
+ </div>
638
+ </div>
639
+ <div class="footer">
640
+ <span id="stat-total">${s.length} request${s.length!==1?"s":""}</span>
641
+ <span id="stat-flows">${t.flows.length} action${t.flows.length!==1?"s":""}</span>
642
+ <span id="stat-errors" class="error-count">${r} error${r!==1?"s":""}</span>
643
+ <span id="stat-avg">Avg: ${i}ms</span>
644
+ </div>
645
+ </div>
646
+ </div>
647
+ <bk-toast></bk-toast>
648
+ `}renderSidebarItem(t,s,r,i,a=false){return n`
649
+ <button class="sidebar-item ${this.activeView===t?"active":""}" @click=${()=>this.switchView(t)}>
650
+ <span class="item-icon">${r}</span>
651
+ <span class="item-label">${s}</span>
652
+ ${i!==void 0?n`<span class="item-count" style="display:${a?"none":""}">${i}</span>`:d}
653
+ </button>
654
+ `}};u([Se({context:_})],Z.prototype,"store",2),u([$()],Z.prototype,"activeView",2),u([$()],Z.prototype,"viewMode",2),Z=u([g("bk-dashboard")],Z);
655
+ /*! Bundled license information:
656
+
657
+ @lit/reactive-element/css-tag.js:
658
+ (**
659
+ * @license
660
+ * Copyright 2019 Google LLC
661
+ * SPDX-License-Identifier: BSD-3-Clause
662
+ *)
663
+
664
+ @lit/reactive-element/reactive-element.js:
665
+ lit-html/lit-html.js:
666
+ lit-element/lit-element.js:
667
+ @lit/reactive-element/decorators/custom-element.js:
668
+ @lit/reactive-element/decorators/property.js:
669
+ @lit/reactive-element/decorators/state.js:
670
+ @lit/reactive-element/decorators/event-options.js:
671
+ @lit/reactive-element/decorators/base.js:
672
+ @lit/reactive-element/decorators/query.js:
673
+ @lit/reactive-element/decorators/query-all.js:
674
+ @lit/reactive-element/decorators/query-async.js:
675
+ @lit/reactive-element/decorators/query-assigned-nodes.js:
676
+ @lit/context/lib/decorators/provide.js:
677
+ (**
678
+ * @license
679
+ * Copyright 2017 Google LLC
680
+ * SPDX-License-Identifier: BSD-3-Clause
681
+ *)
682
+
683
+ lit-html/is-server.js:
684
+ @lit/context/lib/decorators/consume.js:
685
+ (**
686
+ * @license
687
+ * Copyright 2022 Google LLC
688
+ * SPDX-License-Identifier: BSD-3-Clause
689
+ *)
690
+
691
+ @lit/reactive-element/decorators/query-assigned-elements.js:
692
+ @lit/context/lib/context-request-event.js:
693
+ @lit/context/lib/create-context.js:
694
+ @lit/context/lib/controllers/context-consumer.js:
695
+ @lit/context/lib/value-notifier.js:
696
+ @lit/context/lib/controllers/context-provider.js:
697
+ @lit/context/lib/context-root.js:
698
+ (**
699
+ * @license
700
+ * Copyright 2021 Google LLC
701
+ * SPDX-License-Identifier: BSD-3-Clause
702
+ *)
703
+ */})();