brakit 0.8.7 → 0.9.1

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.
@@ -1,30 +1,30 @@
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`
1
+ (function(){'use strict';var Rs=Object.defineProperty;var ws=Object.getOwnPropertyDescriptor;var u=(i,e,t,s)=>{for(var r=s>1?void 0:s?ws(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&&Rs(e,t,r),r};var Lt=globalThis,Ot=Lt.ShadowRoot&&(Lt.ShadyCSS===void 0||Lt.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,xe=Symbol(),ye=new WeakMap,Mt=class{constructor(e,t,s){if(this._$cssResult$=true,s!==xe)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(Ot&&e===void 0){let s=t!==void 0&&t.length===1;s&&(e=ye.get(t)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),s&&ye.set(t,e));}return e}toString(){return this.cssText}},Re=i=>new Mt(typeof i=="string"?i:i+"",void 0,xe);var we=(i,e)=>{if(Ot)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);}},Qt=Ot?i=>i:i=>i instanceof CSSStyleSheet?(e=>{let t="";for(let s of e.cssRules)t+=s.cssText;return Re(t)})(i):i;var{is:As,defineProperty:Cs,getOwnPropertyDescriptor:Is,getOwnPropertyNames:Ls,getOwnPropertySymbols:Ms,getPrototypeOf:Os}=Object,k=globalThis,Ae=k.trustedTypes,Ns=Ae?Ae.emptyScript:"",ks=k.reactiveElementPolyfillSupport,ht=(i,e)=>i,mt={toAttribute(i,e){switch(e){case Boolean:i=i?Ns: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}},Nt=(i,e)=>!As(i,e),Ce={attribute:true,type:String,converter:mt,reflect:false,useDefault:false,hasChanged:Nt};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),k.litPropertyMetadata??(k.litPropertyMetadata=new WeakMap);var O=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=Ce){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&&Cs(this.prototype,e,r);}}static getPropertyDescriptor(e,t,s){let{get:r,set:o}=Is(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)??Ce}static _$Ei(){if(this.hasOwnProperty(ht("elementProperties")))return;let e=Os(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=[...Ls(t),...Ms(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(Qt(r));}else e!==void 0&&t.push(Qt(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 we(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??Nt)(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){}};O.elementStyles=[],O.shadowRootOptions={mode:"open"},O[ht("elementProperties")]=new Map,O[ht("finalized")]=new Map,ks?.({ReactiveElement:O}),(k.reactiveElementVersions??(k.reactiveElementVersions=[])).push("2.1.2");var ft=globalThis,Ie=i=>i,kt=ft.trustedTypes,Le=kt?kt.createPolicy("lit-html",{createHTML:i=>i}):void 0,He="$lit$",D=`lit$${Math.random().toFixed(9).slice(2)}$`,qe="?"+D,Ds=`<${qe}>`,W=document,gt=()=>W.createComment(""),Et=i=>i===null||typeof i!="object"&&typeof i!="function",Zt=Array.isArray,Hs=i=>Zt(i)||typeof i?.[Symbol.iterator]=="function",Vt=`[
2
+ \f\r]`,vt=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Me=/-->/g,Oe=/>/g,B=RegExp(`>|${Vt}(?:([^\\s"'>=/]+)(${Vt}*=${Vt}*(?:[^
3
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),Ne=/'/g,ke=/"/g,Pe=/^(?:script|style|textarea|title)$/i,te=i=>(e,...t)=>({_$litType$:i,strings:e,values:t}),a=te(1),j=Symbol.for("lit-noChange"),d=Symbol.for("lit-nothing"),De=new WeakMap,G=W.createTreeWalker(W,129);function Ue(i,e){if(!Zt(i)||!i.hasOwnProperty("raw"))throw Error("invalid template strings array");return Le!==void 0?Le.createHTML(e):e}var qs=(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,h,m=-1,E=0;for(;E<c.length&&(n.lastIndex=E,h=n.exec(c),h!==null);)E=n.lastIndex,n===vt?h[1]==="!--"?n=Me:h[1]!==void 0?n=Oe:h[2]!==void 0?(Pe.test(h[2])&&(r=RegExp("</"+h[2],"g")),n=B):h[3]!==void 0&&(n=B):n===B?h[0]===">"?(n=r??vt,m=-1):h[1]===void 0?m=-2:(m=n.lastIndex-h[2].length,p=h[1],n=h[3]===void 0?B:h[3]==='"'?ke:Ne):n===ke||n===Ne?n=B:n===Me||n===Oe?n=vt:(n=B,r=void 0);let T=n===B&&i[l+1].startsWith("/>")?" ":"";o+=n===vt?c+Ds:m>=0?(s.push(p),c.slice(0,m)+He+c.slice(m)+D+T):c+D+(m===-2?l:T);}return [Ue(i,o+(i[t]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),s]},bt=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,h]=qs(e,t);if(this.el=i.createElement(p,s),G.currentNode=this.el.content,t===2||t===3){let m=this.el.content.firstChild;m.replaceWith(...m.childNodes);}for(;(r=G.nextNode())!==null&&c.length<l;){if(r.nodeType===1){if(r.hasAttributes())for(let m of r.getAttributeNames())if(m.endsWith(He)){let E=h[n++],T=r.getAttribute(m).split(D),b=/([.?@])?(.*)/.exec(E);c.push({type:1,index:o,name:b[2],strings:T,ctor:b[1]==="."?Xt:b[1]==="?"?Kt:b[1]==="@"?zt:z}),r.removeAttribute(m);}else m.startsWith(D)&&(c.push({type:6,index:o}),r.removeAttribute(m));if(Pe.test(r.tagName)){let m=r.textContent.split(D),E=m.length-1;if(E>0){r.textContent=kt?kt.emptyScript:"";for(let T=0;T<E;T++)r.append(m[T],gt()),G.nextNode(),c.push({type:2,index:++o});r.append(m[E],gt());}}}else if(r.nodeType===8)if(r.data===qe)c.push({type:2,index:o});else {let m=-1;for(;(m=r.data.indexOf(D,m+1))!==-1;)c.push({type:7,index:o}),m+=D.length-1;}o++;}}static createElement(e,t){let s=W.createElement("template");return s.innerHTML=e,s}};function K(i,e,t=i,s){if(e===j)return e;let r=s!==void 0?t._$Co?.[s]:t._$Cl,o=Et(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=K(i,r._$AS(i,e.values),r,s)),e}var Yt=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??W).importNode(t,true);G.currentNode=r;let o=G.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 Jt(o,this,e)),this._$AV.push(p),c=s[++l];}n!==c?.index&&(o=G.nextNode(),n++);}return G.currentNode=W,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=K(this,e,t),Et(e)?e===d||e==null||e===""?(this._$AH!==d&&this._$AR(),this._$AH=d):e!==this._$AH&&e!==j&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):Hs(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&&Et(this._$AH)?this._$AA.nextSibling.data=e:this.T(W.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=bt.createElement(Ue(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===r)this._$AH.p(t);else {let o=new Yt(r,this),n=o.u(this.options);o.p(t),this.T(n),this._$AH=o;}}_$AC(e){let t=De.get(e.strings);return t===void 0&&De.set(e.strings,t=new bt(e)),t}k(e){Zt(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=Ie(e).nextSibling;Ie(e).remove(),e=s;}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e));}},z=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=K(this,e,t,0),n=!Et(e)||e!==this._$AH&&e!==j,n&&(this._$AH=e);else {let l=e,c,p;for(e=o[0],c=0;c<o.length-1;c++)p=K(this,l[s+c],t,c),p===j&&(p=this._$AH[c]),n||(n=!Et(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??"");}},Xt=class extends z{constructor(){super(...arguments),this.type=3;}j(e){this.element[this.name]=e===d?void 0:e;}},Kt=class extends z{constructor(){super(...arguments),this.type=4;}j(e){this.element.toggleAttribute(this.name,!!e&&e!==d);}},zt=class extends z{constructor(e,t,s,r,o){super(e,t,s,r,o),this.type=5;}_$AI(e,t=this){if((e=K(this,e,t,0)??d)===j)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);}},Jt=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){K(this,e);}};var Ps=ft.litHtmlPolyfillSupport;Ps?.(bt,_t),(ft.litHtmlVersions??(ft.litHtmlVersions=[])).push("3.3.2");var Fe=(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 O{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=Fe(t,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return j}};f._$litElement$=true,f.finalized=true,St.litElementHydrateSupport?.({LitElement:f});var Us=St.litElementPolyfillSupport;Us?.({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 Fs={attribute:true,type:String,converter:mt,reflect:false,hasChanged:Nt},Bs=(i=Fs,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 y(i){return (e,t)=>typeof t=="object"?Bs(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 _(i){return y({...i,state:true,attribute:false})}var Tt=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>`}};u([y()],Tt.prototype,"method",2),Tt=u([g("bk-method-badge")],Tt);var I="/__brakit/api",N="/__brakit",$={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 J="polling",Ht="static",Gs="auth-handshake",Ws="auth-check",js="middleware",$t={[Gs]:1,[Ws]:1,[js]:1};var ee="fetch";var se="error_event",re="query",oe="issues";var ie={overview:"Overview",actions:"Actions",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",performance:"Performance",security:"Security"},ne={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 le=100,Z=300,tt=800,ce=2e3,de=100,pe=50,ue=500;var H="__all__",Ft={SELECT:"var(--blue)",INSERT:"var(--green)",UPDATE:"var(--amber)",DELETE:"var(--red)",COUNT:"var(--text-muted)"},Ke={error:"var(--red)",warn:"var(--amber)",info:"var(--blue)",debug:"var(--text-muted)",log:"var(--text-dim)"},me=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],yt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},et=[{max:le,label:"Fast",color:"var(--green)",bg:"rgba(22,163,74,0.08)",border:"rgba(22,163,74,0.2)"},{max:Z,label:"Good",color:"var(--green)",bg:"rgba(22,163,74,0.06)",border:"rgba(22,163,74,0.15)"},{max:tt,label:"OK",color:"var(--amber)",bg:"rgba(217,119,6,0.06)",border:"rgba(217,119,6,0.15)"},{max:ce,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)"}],ze="rgba(228,228,231,0.8)",ve="rgba(113,113,122,0.7)",Je="10px monospace",fe="9px monospace";var Ze={top:16,right:16,bottom:28,left:52},ts={fetch:"var(--blue)",log:"var(--text-muted)",error:"var(--red)",query:"var(--accent)"},es={fetch:"FETCH",log:"LOG",error:"ERROR",query:"QUERY"},ss=new Set(["cookie","set-cookie","authorization","proxy-authorization","x-api-key","x-auth-token"]),rs={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"},os=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 v(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 is(i){return rs[i]||(i>=500?"Server Error":i>=400?"Client Error":"OK")}function Qs(i,e){if(ss.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(Qs(e,t))).join(`
4
+ `)}function Q(i){if(!i)return '<span style="color:var(--text-muted)">No body</span>';try{let e=JSON.parse(i);return Vs(JSON.stringify(e,null,2))}catch{return P(i)}}function Vs(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 xt=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>`}};u([y({type:Number})],xt.prototype,"code",2),xt=u([g("bk-status-pill")],xt);var Rt=class extends f{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return a`<span class="req-duration">${v(this.ms)}</span>`}};u([y({type:Number})],Rt.prototype,"ms",2),Rt=u([g("bk-duration-label")],Rt);var ot=class extends f{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return a`
5
5
  <div class="empty">
6
6
  <span class="empty-title">${this.title}</span>
7
7
  <span class="empty-sub">${this.subtitle}</span>
8
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`
9
+ `}};u([y()],ot.prototype,"title",2),u([y()],ot.prototype,"subtitle",2),ot=u([g("bk-empty-state")],ot);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>`}};u([_()],C.prototype,"message",2),u([_()],C.prototype,"visible",2),C=u([g("bk-toast")],C);var V=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>`}};u([y()],V.prototype,"text",2),u([y()],V.prototype,"label",2),u([y({attribute:"toast-message"})],V.prototype,"toastMessage",2),V=u([g("bk-copy-button")],V);var Y=class extends f{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return a`
10
10
  <div class="fetch-stat">
11
11
  <span class="fetch-stat-value" style="color:${this.color}">${this.value}</span>
12
12
  <span class="fetch-stat-label">${this.label}</span>
13
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`
14
+ `}};u([y()],Y.prototype,"value",2),u([y()],Y.prototype,"label",2),u([y()],Y.prototype,"color",2),Y=u([g("bk-stat-card")],Y);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 it=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 Bt=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 ge=class extends Event{constructor(e,t){super("context-provider",{bubbles:true,composed:true}),this.context=e,this.contextTarget=t;}},nt=class extends Bt{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 ge(this.context,this.host));}};function Ee({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 it(this,{context:i,callback:r=>{t.set.call(this,r);},subscribe:e});})):t.constructor.addInitializer((r=>{new it(r,{context:i,callback:o=>{r[s]=o;},subscribe:e});}));}}var x="dashboard-store",Gt=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
15
  <div
16
- class="req-row tel-clickable ${i?"expanded":""}"
16
+ class="req-row tel-clickable ${o?"expanded":""}"
17
17
  @click=${()=>this.toggleError(s)}
18
18
  >
19
19
  <span class="tel-error-name" title=${t.name}>${t.name}</span>
20
20
  <span class="tel-message" title=${t.message}>${t.message}</span>
21
21
  <span class="tel-timestamp">${r}</span>
22
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
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
25
  title="No errors"
26
26
  subtitle="No errors have been captured yet"
27
- ></bk-empty-state>`:n`
27
+ ></bk-empty-state>`:a`
28
28
  <div class="col-header">
29
29
  <span style="width:180px">Type</span>
30
30
  <span style="flex:1">Message</span>
@@ -33,27 +33,27 @@
33
33
  <div id="error-list">
34
34
  ${t.map((s,r)=>this.renderErrorRow(s,r))}
35
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`
36
+ `}};u([R({context:x})],at.prototype,"store",2),u([_()],at.prototype,"expandedIdx",2),at=u([g("bk-errors-view")],at);var wt=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
37
  <div id="log-analysis">
38
38
  <div class="fetch-summary">
39
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}
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
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}
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
45
  </div>
46
46
  </div>
47
- `}renderLogRow(e){let t=new Date(e.timestamp).toLocaleTimeString();return n`
47
+ `}renderLogRow(e){let t=new Date(e.timestamp).toLocaleTimeString();return a`
48
48
  <div class="req-row">
49
49
  <span class="tel-level tel-level-${e.level}">${e.level.toUpperCase()}</span>
50
50
  <span class="tel-message tel-mono" title=${e.message}>${e.message}</span>
51
51
  <span class="tel-timestamp">${t}</span>
52
52
  </div>
53
- `}render(){let e=this.store.state.logs;return e.length===0?n`<bk-empty-state
53
+ `}render(){let e=this.store.state.logs;return e.length===0?a`<bk-empty-state
54
54
  title="No logs"
55
55
  subtitle="No console output has been captured yet"
56
- ></bk-empty-state>`:n`
56
+ ></bk-empty-state>`:a`
57
57
  ${this.renderAnalysis(e)}
58
58
  <div class="col-header">
59
59
  <span style="width:52px">Level</span>
@@ -63,28 +63,28 @@
63
63
  <div id="log-list">
64
64
  ${e.map(t=>this.renderLogRow(t))}
65
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`
66
+ `}};u([R({context:x})],wt.prototype,"store",2),wt=u([g("bk-logs-view")],wt);var Xs=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 ns(i){let e=i.trim().match(/^(\w+)/);return e?e[1].toUpperCase():"?"}function as(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 ls(i){return P(i).replace(/\b\w+\b/g,e=>Xs.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":v(t)}getQueryInfo(t){let s=(t.normalizedOp||t.operation||(t.sql?ns(t.sql):"?")).toUpperCase(),r=t.table||t.model||(t.sql?as(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>de,p=t.sql||r+" "+o,h=this.expandedIdx===s;return a`
67
67
  <div>
68
68
  <div
69
- class="req-row query-row tel-clickable ${m?"expanded":""}"
69
+ class="req-row query-row tel-clickable ${h?"expanded":""}"
70
70
  @click=${()=>this.toggleQuery(s)}
71
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>
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 ${h?"open":""}">
78
+ ${h?a`
79
+ <pre class="query-detail-sql" .innerHTML=${ls(n)}></pre>
80
+ <bk-copy-button .text=${n} label="Copy"></bk-copy-button>
81
81
  `:d}
82
82
  </div>
83
83
  </div>
84
- `}render(){let t=this.store.state.queries;return t.length===0?n`<bk-empty-state
84
+ `}render(){let t=this.store.state.queries;return t.length===0?a`<bk-empty-state
85
85
  title="No queries"
86
86
  subtitle="No database queries have been captured yet"
87
- ></bk-empty-state>`:n`
87
+ ></bk-empty-state>`:a`
88
88
  <div class="col-header">
89
89
  <span style="width:70px;border-right:1px solid var(--border);padding-right:16px">Operation</span>
90
90
  <span style="width:170px;border-right:1px solid var(--border);padding-right:16px">Table</span>
@@ -94,35 +94,35 @@
94
94
  <div id="query-list">
95
95
  ${t.map((s,r)=>this.renderQueryRow(s,r))}
96
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`
97
+ `}};u([R({context:x})],lt.prototype,"store",2),u([_()],lt.prototype,"expandedIdx",2),lt=u([g("bk-queries-view")],lt);function be(i){return i.replace(/'/g,"'\\''")}function Ks(i,e){let t=Object.entries(i.headers||{}).filter(([o])=>!os.has(o)).map(([o,n])=>`-H '${be(o)}: ${be(n)}'`).join(" "),s=i.requestBody?` -d '${be(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=Ks(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
98
  <div class="detail-meta">
99
99
  <span><bk-method-badge .method=${t.method}></bk-method-badge> ${t.url}</span>
100
100
  <span><bk-status-pill .code=${t.statusCode}></bk-status-pill></span>
101
101
  <span>${t.durationMs}ms</span>
102
- ${t.responseSize?n`<span>${Y(t.responseSize)}</span>`:d}
102
+ ${t.responseSize?a`<span>${U(t.responseSize)}</span>`:d}
103
103
  </div>
104
104
  <div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>
105
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>
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=${Q(t.requestBody)}></pre></div>
109
+ <div class="detail-section"><h4>Response Body</h4><pre .innerHTML=${Q(t.responseBody)}></pre></div>
110
110
  </div>
111
111
  <div class="detail-actions">
112
112
  <button class="btn btn-curl" @click=${s=>this.handleCopyAsCurl(t,s)}>Copy cURL</button>
113
113
  </div>
114
- `}renderRequestRow(t){let s=this.expandedId===t.id;return n`
114
+ `}renderRequestRow(t){let s=this.expandedId===t.id;return a`
115
115
  <div class="req-row ${s?"expanded":""}" @click=${()=>this.toggleRequest(t.id)}>
116
116
  <div class="req-summary">
117
117
  <bk-method-badge .method=${t.method}></bk-method-badge>
118
118
  <span class="req-url">${t.url}</span>
119
119
  <bk-status-pill .code=${t.statusCode}></bk-status-pill>
120
120
  <bk-duration-label .ms=${t.durationMs}></bk-duration-label>
121
- <span class="req-size">${Y(t.responseSize)}</span>
121
+ <span class="req-size">${U(t.responseSize)}</span>
122
122
  </div>
123
123
  </div>
124
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`
125
+ `}render(){let t=this.store.state.requests.filter(s=>!s.path?.startsWith(N));return t.length===0?a`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:a`
126
126
  <div class="col-header">
127
127
  <span style="width:60px">Method</span>
128
128
  <span style="flex:1">URL</span>
@@ -131,50 +131,53 @@
131
131
  <span style="width:60px;text-align:right">Size</span>
132
132
  </div>
133
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`
134
+ `}};u([R({context:x})],dt.prototype,"store",2),u([_()],dt.prototype,"expandedId",2),dt=u([g("bk-requests-view")],dt);var At=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
135
  <div class="fetch-summary">
136
136
  <bk-stat-card value=${String(e.length)} label="Total Fetches"></bk-stat-card>
137
137
  <bk-stat-card value=${String(t.size)} label="Unique URLs"></bk-stat-card>
138
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>
139
+ <bk-stat-card value=${v(o)} label="Avg Duration"></bk-stat-card>
140
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`
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
142
  <div class="fetch-group">
143
143
  <div class="fetch-group-header">
144
144
  <bk-method-badge .method=${e.method}></bk-method-badge>
145
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}
146
+ ${n>0?a`<bk-status-pill .code=${n}></bk-status-pill>`:d}
147
147
  <span class="fetch-group-count">${e.count}x</span>
148
148
  </div>
149
149
  <div class="fetch-group-meta">
150
- <span>avg ${S(t)}</span>
150
+ <span>avg ${v(t)}</span>
151
151
  <span class="fetch-group-sep">\u00b7</span>
152
- <span>max ${S(e.maxDur)}</span>
152
+ <span>max ${v(e.maxDur)}</span>
153
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>`}
154
+ ${s>0?a`<span class="fetch-group-err">${s}% errors</span>`:a`<span class="fetch-group-ok">0% errors</span>`}
155
155
  </div>
156
- ${e.firstTs>0?n`
156
+ ${e.firstTs>0?a`
157
157
  <div class="fetch-group-timeline">
158
158
  <span class="fetch-group-timeline-dot"></span>
159
159
  <span class="fetch-group-timeline-range">
160
- ${this.formatTime(e.firstTs)}${e.firstTs!==e.lastTs?n` \u2192 ${this.formatTime(e.lastTs)}`:d}
160
+ ${this.formatTime(e.firstTs)}${e.firstTs!==e.lastTs?a` \u2192 ${this.formatTime(e.lastTs)}`:d}
161
161
  </span>
162
162
  </div>`:d}
163
- ${r.length>0?n`
163
+ ${r.length>0?a`
164
164
  <div class="fetch-group-callers">
165
165
  <span class="fetch-group-callers-label">Called by</span>
166
- ${r.map(c=>n`<span class="fetch-group-caller-pill">${c}</span>`)}
166
+ ${r.map(l=>a`<span class="fetch-group-caller-pill">${l}</span>`)}
167
167
  </div>`:d}
168
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`
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
170
  <div class="fetch-analysis" id="fetch-analysis">
171
171
  ${this.renderSummary(e)}
172
- ${s.length>0?n`
172
+ ${s.length>0?a`
173
173
  <div class="fetch-groups-title">Grouped by URL (${s.length})</div>
174
174
  <div class="fetch-groups">${s.map(r=>this.renderGroup(r))}</div>
175
175
  `:d}
176
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`
177
+ `}};u([R({context:x})],At.prototype,"store",2),At=u([g("bk-fetches-view")],At);function cs(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 tr(i){return i.type==="query"||i.type==="fetch"}function er(i){let e=(i.normalizedOp||i.operation||"QUERY").toUpperCase(),t=i.table||i.model||"";return {label:`${e} ${t}`,tooltip:i.sql||`${e} ${t}`}}function sr(i){return {label:`${i.method} ${i.url}`,tooltip:`${i.method} ${i.url}`}}function rr(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 or(i,e){let t=i.timeline.filter(tr);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:h}=rr(n,l,t,s,r,o),m=n.type==="query"?er(n.data):sr(n.data);return {type:n.type,label:m.label,durMs:c,durLabel:v(c),tooltip:m.tooltip,leftPct:p,widthPct:h}})}function ps(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),h=e?.activities?.[l.id],m=h?or(h,l):[];return {label:`${l.method} ${l.label}`,leftPct:c,widthPct:p,color:cs(l.method,l.statusCode),durMs:l.durationMs,durLabel:v(l.durationMs),tooltip:`${l.method} ${l.label} (${v(l.durationMs)})`,subEvents:m}}),totalMs:o}}function us(i){let e=i.requests,t=[],s=[],r=[],o=[],n=new Map;for(let p of e){let h=p.label,m=p.pollingDurationMs||p.durationMs;if(!$t[p.category||""]){if(p.isDuplicate){let E=n.get(h);E?(E.count++,E.wastedMs+=m):n.set(h,{name:h,count:2,wastedMs:m});continue}if(p.statusCode>=400){s.push(h+" ("+is(p.statusCode)+")");continue}p.responseSize>51200&&r.push("Large response: "+h+" returned "+U(p.responseSize)),t.push(h);}}for(let p of n.values())o.push(p);let l="";if(o.length>0){let p=o.map(m=>m.name).join(", "),h=o.reduce((m,E)=>m+E.wastedMs,0);l="Your app fetches "+p+" multiple times on this page. This wastes ~"+v(h)+". 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!==J);return c.length>0&&!l&&(l=c.map(p=>p.label).join(", ")+` is taking over ${v(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:t,errors:s,warnings:r,duplicates:o,tip:l}}var L=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(`${$.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`
178
181
  <div id="flow-col-header" class="col-header">
179
182
  <span style="width:8px"></span>
180
183
  <span style="flex:1">Action</span>
@@ -182,83 +185,203 @@
182
185
  <span style="width:120px;text-align:right">Status</span>
183
186
  <span style="width:70px;text-align:right">Time</span>
184
187
  </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 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
+ >
188
196
  <div class="flow-summary-row">
189
- <span class="flow-status-dot ${i}"></span>
197
+ <span class="flow-status-dot ${o}"></span>
190
198
  <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>
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
+ >${v(t.totalDurationMs)}</span
206
+ >
194
207
  </div>
195
208
  </div>
196
209
  <div class="flow-expand ${r?"open":""}">
197
- ${r?this.viewMode==="simple"?this.renderFlowInsights(t):this.renderFlowSubReqs(t):d}
210
+ ${r?this.renderFlowDetail(t):d}
198
211
  </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}
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}=ps(t,this.flowTimeline);if(s.length===0)return d;let o=[];for(let n=0;n<=5;n++)o.push(v(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>
209
246
  </div>
210
- `:d}
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=us(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
+ ~${v(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}
211
289
  </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":""}">
290
+ `}renderTrafficCard(t){if($t[t.category||""])return d;let s=st(t.statusCode),r=v(t.pollingDurationMs||t.durationMs),o=!t.isDuplicate&&t.category!==Ht&&t.category!==J||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":""}">
215
295
  <bk-method-badge .method=${t.method}></bk-method-badge>
216
- <span class="traffic-card-path ${t.isDuplicate?"is-dup":""}">${t.label}</span>
296
+ <span class="traffic-card-path ${t.isDuplicate?"is-dup":""}"
297
+ >${t.label}</span
298
+ >
217
299
  <span class="status-pill ${s}">${t.statusCode}</span>
218
300
  <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>`}
301
+ ${t.isDuplicate?a`<span class="traffic-card-dup">duplicate</span>`:a`<span class="traffic-card-size"
302
+ >${U(t.responseSize)}</span
303
+ >`}
220
304
  </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}
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!==J?a`<div
309
+ class="request-timeline tl-hidden"
310
+ data-request-id=${t.id}
311
+ data-request-started=${String(t.startedAt)}
312
+ ></div>`:d}
223
313
  ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):d}
224
314
  ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):d}
225
315
  </div>
226
- `}renderBodyToggle(t,s,r){let i=t==="out"?"\u2192":"\u2190";return n`
316
+ `}renderBodyToggle(t,s,r){let o=t==="out"?"\u2192":"\u2190";return a`
227
317
  <div class="traffic-body">
228
318
  <button class="traffic-body-toggle" @click=${this.toggleBodyBlock}>
229
- <span class="chevron">\u25B8</span><span class="arrow-${t}">${i}</span> ${s}
319
+ <span class="chevron">▸</span
320
+ ><span class="arrow-${t}">${o}</span> ${s}
230
321
  </button>
231
- <pre .innerHTML=${X(r)}></pre>
322
+ <pre .innerHTML=${Q(r)}></pre>
232
323
  </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)}>
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?v(t.pollingDurationMs):v(t.durationMs);return a`
327
+ <div
328
+ class="flow-subreq ${r?"expanded":""}"
329
+ @click=${l=>this.toggleSubReq(s,l)}
330
+ >
235
331
  <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>
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>
240
338
  </div>
241
339
  <div class="flow-subreq-detail ${r?"open":""}">
242
340
  ${r?this.renderSubReqDetail(t):d}
243
341
  </div>
244
- `}renderSubReqDetail(t){let s=rt(t.statusCode);return n`
342
+ `}renderSubReqDetail(t){let s=st(t.statusCode);return a`
245
343
  <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>
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
+ >
248
350
  <span>${t.durationMs}ms</span>
249
- ${t.responseSize?n`<span>${Y(t.responseSize)}</span>`:d}
351
+ ${t.responseSize?a`<span>${U(t.responseSize)}</span>`:d}
250
352
  </div>
251
- <div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>
353
+ <div
354
+ class="request-timeline tl-hidden"
355
+ data-request-id=${t.id}
356
+ data-request-started=${String(t.startedAt)}
357
+ ></div>
252
358
  <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>
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=${Q(t.requestBody)}></pre>
370
+ </div>
371
+ <div class="detail-section">
372
+ <h4>Response Body</h4>
373
+ <pre .innerHTML=${Q(t.responseBody)}></pre>
374
+ </div>
257
375
  </div>
258
376
  <div class="detail-actions">
259
- <button class="btn btn-curl" @click=${r=>{r.stopPropagation(),dt(t);}}>Copy cURL</button>
377
+ <button
378
+ class="btn btn-curl"
379
+ @click=${r=>{r.stopPropagation(),ct(t);}}
380
+ >
381
+ Copy cURL
382
+ </button>
260
383
  </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`
384
+ `}};u([R({context:x})],L.prototype,"store",2),u([_()],L.prototype,"expandedFlowIdx",2),u([_()],L.prototype,"expandedSubReqIdx",2),u([_()],L.prototype,"flowDetailTab",2),u([_()],L.prototype,"flowTimeline",2),u([_()],L.prototype,"flowTimelineLoading",2),L=u([g("bk-flows-view")],L);var Ct=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`
262
385
  <div class="sec-clear">
263
386
  <span class="sec-clear-icon">\u2713</span>
264
387
  <div class="sec-clear-text">
@@ -266,10 +389,10 @@
266
389
  <div class="sec-clear-sub">No security or quality issues detected this session</div>
267
390
  </div>
268
391
  </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`
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`
270
393
  <div id="security-content">
271
- ${this.renderSummary(t.length,s.length,r,i,a)}
272
- ${t.length===0&&s.length>0?n`
394
+ ${this.renderSummary(t.length,s.length,r,o,n)}
395
+ ${t.length===0&&s.length>0?a`
273
396
  <div class="sec-clear">
274
397
  <span class="sec-clear-icon">\u2713</span>
275
398
  <div class="sec-clear-text">
@@ -281,105 +404,102 @@
281
404
  ${t.length>0?this.renderOpenGroups(t):d}
282
405
  ${s.length>0?this.renderResolved(s):d}
283
406
  </div>
284
- `}renderSummary(e,t,s,r,i){return n`
407
+ `}renderSummary(e,t,s,r,o){return a`
285
408
  <div class="sec-summary">
286
409
  <div class="sec-summary-left">
287
410
  <span class="sec-summary-count">${e}</span>
288
411
  <span class="sec-summary-label">open issue${e!==1?"s":""}</span>
289
- ${t>0?n`<span class="sec-resolved-badge">${t} resolved</span>`:d}
412
+ ${t>0?a`<span class="sec-resolved-badge">${t} resolved</span>`:d}
290
413
  </div>
291
414
  <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}
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}
295
418
  </div>
296
419
  </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`
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`
298
421
  <div class="sec-group">
299
422
  <div class="sec-group-header">
300
423
  <span class="sec-group-icon ${t.cls}">${t.icon}</span>
301
424
  <span class="sec-group-title">${e.title}</span>
302
425
  <span class="sec-group-count">${e.items.length}</span>
303
426
  </div>
304
- ${e.hint?n`<div class="sec-hint">${e.hint}</div>`:d}
427
+ ${e.hint?a`<div class="sec-hint">${e.hint}</div>`:d}
305
428
  <div class="sec-items">${e.items.map(s=>this.renderIssueItem(s))}</div>
306
429
  </div>
307
- `}renderIssueItem(e){let t=e.issue;return n`
430
+ `}renderIssueItem(e){let t=e.issue;return a`
308
431
  <div class="sec-item">
309
432
  <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}
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}
313
436
  </div>
314
- `}renderResolved(e){return n`
437
+ `}renderResolved(e){return a`
315
438
  <div class="sec-resolved-title">
316
439
  <span class="sec-resolved-check">\u2713</span> Resolved
317
440
  <span class="sec-resolved-count">${e.length}</span>
318
441
  </div>
319
442
  <div class="sec-group sec-group-resolved">
320
443
  <div class="sec-items">
321
- ${e.map(t=>n`
444
+ ${e.map(t=>a`
322
445
  <div class="sec-item sec-item-resolved">
323
446
  <span class="sec-resolved-item-icon">\u2713</span>
324
447
  <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}
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}
327
450
  </div>
328
451
  `)}
329
452
  </div>
330
453
  </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
454
+ `}};u([R({context:x})],Ct.prototype,"store",2),Ct=u([g("bk-security-view")],Ct);var pt=class extends f{constructor(){super(...arguments);this.expandedCardIdx=-1;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}toggleCard(t){this.expandedCardIdx=this.expandedCardIdx===t?-1:t;}render(){let t=this.store.state,s=t.requests.filter(b=>!b.isStatic&&!b.isHealthCheck&&(!b.path||b.path.indexOf(N)!==0));if(!(s.length>0||t.queries.length>0||t.errors.length>0))return a`<bk-empty-state
332
455
  title="Waiting for requests..."
333
456
  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`
457
+ ></bk-empty-state>`;let o=s.filter(b=>b.statusCode>=400).length,n=new Set(["data-fetch","api-call","server-action","page-load"]),l=s.filter(b=>b.category&&n.has(b.category)),c=l.length>0?l:s,p=c.length>0?Math.round(c.reduce((b,It)=>b+It.durationMs,0)/c.length):0,h=t.issues||[],m=h.filter(b=>b.state==="open"||b.state==="regressed"),E=h.filter(b=>b.state==="fixing"),T=h.filter(b=>b.state==="resolved");return a`
335
458
  <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">
459
+ ${this.renderSummary(s.length,t.flows.length,p,t.queries.length,o,t.fetches.length)}
460
+ ${m.length===0&&E.length===0&&T.length===0?a`<div class="ov-clear">
338
461
  <span class="ov-clear-icon">\u2713</span>All clear \u2014 no issues detected
339
462
  </div>`:d}
340
- ${l.length===0&&m.length>0?n`<div class="ov-clear">
463
+ ${m.length===0&&T.length>0?a`<div class="ov-clear">
341
464
  <span class="ov-clear-icon">\u2713</span>All issues resolved \u2014
342
- ${m.length} finding${m.length!==1?"s were":" was"} detected and
465
+ ${T.length} finding${T.length!==1?"s were":" was"} detected and
343
466
  fixed
344
467
  </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}
468
+ ${m.length>0?this.renderOpenIssues(m):d}
469
+ ${E.length>0?this.renderVerifying(E):d}
470
+ ${T.length>0?this.renderResolvedIssues(T):d}
348
471
  </div>
349
- `}renderSummary(t,s,r,i,a,c){return n`
472
+ `}renderSummary(t,s,r,o,n,l){return a`
350
473
  <div class="ov-summary">
351
474
  <div class="ov-stat"><span class="ov-stat-value">${t}</span><span class="ov-stat-label">Requests</span></div>
352
475
  <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>
476
+ <div class="ov-stat"><span class="ov-stat-value">${v(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>
357
480
  </div>
358
- `}renderOpenIssues(t){return n`
481
+ `}renderOpenIssues(t){return a`
359
482
  <div class="ov-section-title">Issues Found <span class="ov-issue-count">${t.length}</span></div>
360
483
  <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>
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=${()=>this.toggleCard(s)}>
486
+ <span class="ov-card-icon ${o.cls}">${o.icon}</span>
364
487
  <div class="ov-card-body">
365
- <div class="ov-card-title">${r.title}${c}</div>
488
+ <div class="ov-card-title">${r.title}${l}</div>
366
489
  <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>
490
+ ${r.detail?a`<div class="ov-card-detail">${r.detail}</div>`:d}
491
+ ${c}
492
+ ${n&&r.hint?a`<div class="ov-card-hint">${r.hint}</div>`:d}
373
493
  </div>
374
- <span class="ov-card-arrow">${a?"\u2193":"\u2192"}</span>
494
+ ${r.hint?a`<span class="ov-card-arrow">${n?"\u2193":"\u2192"}</span>`:d}
375
495
  </div>
376
- `}renderVerifying(t){return n`
496
+ `}renderVerifying(t){return a`
377
497
  <div class="ov-section-title ov-resolved-title">
378
498
  <span style="color:var(--yellow,#f5a623)">\u29d7</span> Awaiting Verification
379
499
  <span class="ov-issue-count">${t.length}</span>
380
500
  </div>
381
501
  <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`
502
+ ${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`
383
503
  <div class="ov-card ov-card-resolved">
384
504
  <span class="ov-card-icon resolved">\u29d7</span>
385
505
  <div class="ov-card-body">
@@ -388,18 +508,18 @@
388
508
  <span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>
389
509
  </div>
390
510
  <div class="ov-card-desc">${r.desc}</div>
391
- ${i}
511
+ ${o}
392
512
  </div>
393
513
  </div>
394
514
  `})}
395
515
  </div>
396
- `}renderResolvedIssues(t){return n`
516
+ `}renderResolvedIssues(t){return a`
397
517
  <div class="ov-section-title ov-resolved-title">
398
518
  <span style="color:var(--green)">\u2713</span> Resolved
399
519
  <span class="ov-issue-count">${t.length}</span>
400
520
  </div>
401
521
  <div class="ov-cards">
402
- ${t.map(s=>n`
522
+ ${t.map(s=>a`
403
523
  <div class="ov-card ov-card-resolved">
404
524
  <span class="ov-card-icon resolved">\u2713</span>
405
525
  <div class="ov-card-body">
@@ -409,71 +529,98 @@
409
529
  </div>
410
530
  `)}
411
531
  </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`
532
+ `}};u([R({context:x})],pt.prototype,"store",2),u([_()],pt.prototype,"expandedCardIdx",2),pt=u([g("bk-overview-view")],pt);function hs(i){return i<1?"<1ms":i<1e3?Math.round(i)+"ms":(i/1e3).toFixed(1)+"s"}function ir(i){return i<Z?yt.green:i<tt?yt.amber:yt.red}function nr(i){return i.statusCode>=400?yt.red:ir(i.durationMs)}function ms(i){return [parseInt(i.slice(1,3),16),parseInt(i.slice(3,5),16),parseInt(i.slice(5,7),16)]}function ar(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 lr(i,e,t,s,r){let[o,n,l]=ms(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 cr(i,e,t,s,r,o){let[n,l,c]=ms(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 vs(i,e){let t=[],s=ar(i);if(!s||e.length===0)return t;let{ctx:r,w:o,h:n}=s,l=Ze,c=o-l.left-l.right,p=n-l.top-l.bottom,h=0,m=e[0].timestamp,E=e[0].timestamp;for(let S of e)S.durationMs>h&&(h=S.durationMs),S.timestamp<m&&(m=S.timestamp),S.timestamp>E&&(E=S.timestamp);h=Math.max(h,10),h=Math.ceil(h*1.15/10)*10;let T=E-m||1;r.strokeStyle=ze,r.lineWidth=1;let b=4;for(let S=0;S<=b;S++){let A=l.top+p-S/b*p;r.beginPath(),r.moveTo(l.left,A),r.lineTo(l.left+c,A),r.stroke(),r.fillStyle=ve,r.font=Je,r.textAlign="right",r.fillText(hs(Math.round(S/b*h)),l.left-8,A+3);}for(let S of [{ms:Z},{ms:tt}]){if(S.ms>=h)continue;let A=l.top+p-S.ms/h*p;r.beginPath(),r.setLineDash([4,4]),r.strokeStyle="rgba(113,113,122,0.3)",r.lineWidth=1,r.moveTo(l.left,A),r.lineTo(l.left+c,A),r.stroke(),r.setLineDash([]),r.fillStyle="rgba(113,113,122,0.5)",r.font=fe,r.textAlign="left",r.fillText(hs(S.ms),l.left+c+2,A+3);}for(let S=0;S<e.length;S++){let A=e[S],ut=e.length===1?l.left+c/2:l.left+(A.timestamp-m)/T*c,jt=l.top+p-A.durationMs/h*p,$e=nr(A);t.push({x:ut,y:jt,idx:S,r:A}),A.statusCode>=400?cr(r,ut,jt,4,$e,2):lr(r,ut,jt,4,$e);}r.fillStyle=ve,r.font=fe,r.textAlign="center";let It=[m,m+T/2,E];for(let S=0;S<It.length;S++){let A=l.left+S/2*c,ut=new Date(It[S]);r.fillText(ut.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),A,l.top+p+14);}return t}var vr={max:1/0,label:"Pending",color:"var(--text-muted)",bg:"var(--bg-muted)",border:"var(--border)"};function fs(i,e,t){return t>=20?i:e}function Te(i,e){if(!e||e<=0)return vr;let t=i/e;return t<.7?et[0]:t<1.2?et[1]:t<2?et[2]:t<3?et[3]:et[4]}var M=class extends f{constructor(){super(...arguments);this.selectedEndpoint=H;this.graphData=[];this.loadError=false;this.queryBreakdown=[];this.queryBreakdownLoading=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($.metricsLive)).json();this.graphData=s.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===H)&&(this.selectedEndpoint=H);}catch{this.loadError=true;}}healthGradeForEndpoint(t){let s=fs(t.summary.p95Ms,t.summary.medianMs,t.summary.totalRequests);return Te(s,t.baselineP95Ms)}healthGradeForDuration(t,s){return Te(t,s)}getCallers(t){let s=this.store.state.flows,r=new Map;for(let o of s)for(let n of o.requests)if(`${n.method} ${n.path}`===t||this.normalizeEndpoint(n)===t){let c=r.get(o.label);c?(c.count++,c.totalMs+=n.durationMs):r.set(o.label,{count:1,totalMs:n.durationMs});}return [...r.entries()].map(([o,n])=>({label:o,count:n.count,avgMs:Math.round(n.totalMs/n.count)})).sort((o,n)=>n.count-o.count)}normalizeEndpoint(t){let s=t.path.replace(/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,"/:id").replace(/\/\d+/g,"/:id");return `${t.method} ${s}`}async loadQueryBreakdown(t){if(this.queryBreakdownLoading)return;let r=this.store.state.requests.filter(o=>`${o.method} ${o.path}`===t||this.normalizeEndpoint(o)===t).slice(-20).map(o=>o.id).filter(Boolean);if(r.length===0){this.queryBreakdown=[];return}this.queryBreakdownLoading=true;try{let o=await fetch(`${$.activity}?requestIds=${r.join(",")}`);if(!o.ok){this.queryBreakdownLoading=!1;return}let n=await o.json(),l=new Map;for(let c of Object.values(n.activities))for(let p of c.timeline){if(p.type!=="query")continue;let h=p.data,m=(h.normalizedOp||h.operation||"QUERY").toUpperCase(),E=h.table||h.model||"",T=`${m} ${E}`.trim(),b=l.get(T);b?(b.totalMs+=h.durationMs,b.count++):l.set(T,{label:T,totalMs:h.durationMs,count:1});}this.queryBreakdown=[...l.values()].map(c=>({...c,avgMs:Math.round(c.totalMs/c.count)})).sort((c,p)=>p.totalMs-c.totalMs);}catch{}this.queryBreakdownLoading=false;}renderScatterChart(t,s){this.scatterDots=vs(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 h of this.scatterDots){let m=Math.sqrt((h.x-n)**2+(h.y-l)**2);m<p&&(p=m,c=h);}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)return;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`
413
533
  <div id="graph-content">
414
534
  ${this.renderSelector()}
415
- ${this.selectedEndpoint===q?this.renderOverview():this.renderDetail()}
535
+ ${this.selectedEndpoint===H?this.renderOverview():this.renderDetail()}
416
536
  </div>
417
- `}renderSelector(){return n`
537
+ `}renderSelector(){return a`
418
538
  <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`
539
+ <button class="perf-selector-btn ${this.selectedEndpoint===H?"active":""}"
540
+ @click=${()=>{this.selectedEndpoint=H;}}>Overview</button>
541
+ ${this.graphData.map((t,s)=>a`
422
542
  <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}
543
+ @click=${()=>{this.selectedEndpoint=t.endpoint,this.queryBreakdown=[],this.loadQueryBreakdown(t.endpoint);}}>
544
+ <span class="perf-dot" style="background:${me[s%me.length]}"></span>${t.endpoint}
425
545
  </button>
426
546
  `)}
427
547
  </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}
548
+ `}renderOverview(){let t=this.graphData.filter(c=>c.requests.length>0);if(t.length===0)return d;let s=t.reduce((c,p)=>c+p.summary.totalRequests,0),r=s>0?Math.round(t.reduce((c,p)=>c+p.summary.p95Ms*p.summary.totalRequests,0)/s):0,o=t.reduce((c,p)=>c+Math.round(p.summary.errorRate*p.summary.totalRequests),0),n=s>0?o/s:0,l=t[0];return a`
549
+ <div class="perf-overview">
550
+ <div class="perf-summary-row">
551
+ <div class="perf-summary-card">
552
+ <span class="perf-summary-label">Total Requests</span>
553
+ <span class="perf-summary-value">${s}</span>
554
+ </div>
555
+ <div class="perf-summary-card">
556
+ <span class="perf-summary-label">Avg P95</span>
557
+ <span class="perf-summary-value" style="color:${this.healthGradeForDuration(r).color}">${v(r)}</span>
558
+ </div>
559
+ <div class="perf-summary-card">
560
+ <span class="perf-summary-label">Error Rate</span>
561
+ <span class="perf-summary-value" style="color:${o>0?"var(--red)":"var(--green)"}">${Math.round(n*100)}%</span>
562
+ </div>
563
+ <div class="perf-summary-card">
564
+ <span class="perf-summary-label">Slowest</span>
565
+ <span class="perf-summary-value perf-summary-value-sm">${l?.endpoint??"-"}</span>
438
566
  </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
567
  </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>
568
+
569
+ <table class="perf-table perf-heatmap">
570
+ <thead>
571
+ <tr>
572
+ <th>Endpoint</th>
573
+ <th class="perf-th-right">Calls</th>
574
+ <th class="perf-th-center">P95</th>
575
+ <th class="perf-th-center">Errors</th>
576
+ <th class="perf-th-center">Q/Req</th>
577
+ <th>Time Split</th>
578
+ </tr>
579
+ </thead>
580
+ <tbody>
581
+ ${t.map(c=>this.renderHeatmapRow(c))}
582
+ </tbody>
583
+ </table>
584
+ </div>
585
+ `}renderHeatmapRow(t){let s=t.summary,r=this.healthGradeForEndpoint(t),o=Math.round(s.errorRate*s.totalRequests),n=(s.avgQueryTimeMs||0)+(s.avgFetchTimeMs||0)+(s.avgAppTimeMs||0),l=0,c=0,p=100;return n>0&&(l=Math.round((s.avgQueryTimeMs||0)/n*100),c=Math.round((s.avgFetchTimeMs||0)/n*100),p=Math.max(0,100-l-c)),a`
586
+ <tr class="perf-table-row" @click=${()=>{this.selectedEndpoint=t.endpoint,this.queryBreakdown=[],this.loadQueryBreakdown(t.endpoint);}}>
587
+ <td class="perf-td-name">${t.endpoint}</td>
588
+ <td class="perf-td-right">${s.totalRequests}</td>
589
+ <td class="perf-td-center">
590
+ <span class="perf-hm-p95" style="color:${r.color};background:${r.bg};border-color:${r.border}">${v(s.p95Ms)}</span>
591
+ </td>
592
+ <td class="perf-td-center" style="color:${o>0?"var(--red)":"var(--text-muted)"}">${o>0?o:"-"}</td>
593
+ <td class="perf-td-center" style="color:${s.avgQueryCount>5?"var(--amber)":"var(--text-muted)"}">${s.avgQueryCount}</td>
594
+ <td>
595
+ <span class="perf-hm-split-bar">
596
+ ${l>0?a`<span class="perf-breakdown-seg perf-breakdown-db" style="width:${l}%"></span>`:d}
597
+ ${c>0?a`<span class="perf-breakdown-seg perf-breakdown-fetch" style="width:${c}%"></span>`:d}
598
+ ${p>0?a`<span class="perf-breakdown-seg perf-breakdown-app" style="width:${p}%"></span>`:d}
454
599
  </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`
600
+ </td>
601
+ </tr>
602
+ `}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.healthGradeForEndpoint(t),o=Math.round(s.errorRate*s.totalRequests);return a`
460
603
  ${this.renderDetailHeader(t,r)}
461
- ${this.renderDetailMetrics(s,r,i)}
604
+ ${this.renderDetailMetrics(s,r,o)}
462
605
  ${this.renderDetailBreakdown(s)}
606
+ ${this.renderCallers(t.endpoint)}
607
+ ${this.renderQueryBreakdown()}
608
+ ${this.renderTrends(t)}
463
609
  ${this.renderDetailChart()}
464
610
  ${this.renderDetailHistory(t)}
465
- `}renderDetailHeader(t,s){return n`
611
+ `}renderDetailHeader(t,s){return a`
466
612
  <div class="perf-detail-header">
467
613
  <div class="perf-detail-title">
468
614
  <span class="perf-badge perf-badge-lg" style="color:${s.color};background:${s.bg};border-color:${s.border}">${s.label}</span>
469
615
  <span>${t.endpoint}</span>
616
+ ${t.baselineP95Ms?a`<span class="perf-baseline-hint">Baseline: ${v(t.baselineP95Ms)}</span>`:d}
470
617
  </div>
471
618
  </div>
472
- `}renderDetailMetrics(t,s,r){return n`
619
+ `}renderDetailMetrics(t,s,r){return a`
473
620
  <div class="perf-metric-row">
474
621
  <div class="perf-metric-card">
475
622
  <span class="perf-metric-label">P95</span>
476
- <span class="perf-metric-value" style="color:${s.color}">${this.fmtMs(t.p95Ms)}</span>
623
+ <span class="perf-metric-value" style="color:${s.color}">${v(t.p95Ms)}</span>
477
624
  </div>
478
625
  <div class="perf-metric-card">
479
626
  <span class="perf-metric-label">Errors</span>
@@ -486,119 +633,170 @@
486
633
  <span class="perf-metric-value" style="color:${t.avgQueryCount>5?"var(--amber)":"var(--text)"}">${t.avgQueryCount}</span>
487
634
  </div>
488
635
  </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`
636
+ `}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`
490
637
  <div class="perf-breakdown">
491
638
  <div class="perf-section-title">Time Breakdown</div>
492
639
  <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}
640
+ ${r>0?a`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${r}%"></div>`:d}
641
+ ${o>0?a`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${o}%"></div>`:d}
642
+ ${n>0?a`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${n}%"></div>`:d}
496
643
  </div>
497
644
  <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>
645
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${v(t.avgQueryTimeMs||0)} (${r}%)</span>
646
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${v(t.avgFetchTimeMs||0)} (${o}%)</span>
647
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${v(t.avgAppTimeMs||0)} (${n}%)</span>
501
648
  </div>
502
649
  </div>
503
- `}renderDetailChart(){return n`
650
+ `}renderCallers(t){let s=this.getCallers(t);return s.length===0?d:a`
651
+ <div class="perf-callers">
652
+ <div class="perf-section-title">Called By</div>
653
+ <div class="perf-callers-list">
654
+ ${s.map(r=>a`
655
+ <div class="perf-caller-row">
656
+ <span class="perf-caller-name">${r.label}</span>
657
+ <span class="perf-caller-count">${r.count} call${r.count!==1?"s":""}</span>
658
+ <span class="perf-caller-avg">avg ${v(r.avgMs)}</span>
659
+ </div>
660
+ `)}
661
+ </div>
662
+ </div>
663
+ `}renderQueryBreakdown(){return this.queryBreakdownLoading?a`<div class="perf-queries"><div class="perf-section-title">DB Queries</div><div class="perf-queries-loading">Loading...</div></div>`:this.queryBreakdown.length===0?d:a`
664
+ <div class="perf-queries">
665
+ <div class="perf-section-title">DB Queries</div>
666
+ <div class="perf-queries-list">
667
+ ${this.queryBreakdown.map(t=>a`
668
+ <div class="perf-query-row">
669
+ <span class="perf-query-label">${t.label}</span>
670
+ <span class="perf-query-avg">avg ${v(t.avgMs)}</span>
671
+ <span class="perf-query-count">${t.count} call${t.count!==1?"s":""}</span>
672
+ </div>
673
+ `)}
674
+ </div>
675
+ </div>
676
+ `}renderTrends(t){let s=t.sessions;if(!s||s.length===0)return d;let r=s.slice(-10);return a`
677
+ <div class="perf-trends">
678
+ <div class="perf-section-title">Session Trend</div>
679
+ <div class="perf-trends-list">
680
+ ${r.map((o,n)=>{let l=n>0?r[n-1].p95DurationMs:null,c=l!==null?o.p95DurationMs>l*1.2?"slower":o.p95DurationMs<l*.8?"faster":"":"",p=this.formatTimeAgo(o.startedAt),h=n===r.length-1,m=this.healthGradeForDuration(o.p95DurationMs,t.baselineP95Ms);return a`
681
+ <div class="perf-trend-row ${h?"perf-trend-current":""}">
682
+ <span class="perf-trend-time">${h?"Current":p}</span>
683
+ <span class="perf-trend-p95">
684
+ <span class="perf-hm-p95" style="color:${m.color};background:${m.bg};border-color:${m.border}">
685
+ p95: ${v(o.p95DurationMs)}
686
+ </span>
687
+ </span>
688
+ <span class="perf-trend-reqs">${o.requestCount} req${o.requestCount!==1?"s":""}</span>
689
+ <span class="perf-trend-errs" style="color:${o.errorCount>0?"var(--red)":"var(--text-dim)"}">${o.errorCount} err${o.errorCount!==1?"s":""}</span>
690
+ ${c?a`<span class="perf-trend-arrow ${c==="slower"?"perf-trend-slower":"perf-trend-faster"}">${c==="slower"?"\u2191 slower":"\u2193 faster"}</span>`:d}
691
+ </div>
692
+ `})}
693
+ </div>
694
+ </div>
695
+ `}formatTimeAgo(t){let s=Date.now()-t,r=Math.round(s/6e4);if(r<1)return "just now";if(r<60)return `${r}m ago`;let o=Math.round(r/60);return o<24?`${o}h ago`:`${Math.round(o/24)}d ago`}renderDetailChart(){return a`
504
696
  <div class="perf-chart-wrap">
505
697
  <div class="perf-section-title">Response Time</div>
506
698
  <canvas id="perf-detail-canvas" class="perf-canvas" style="width:100%;height:240px"></canvas>
507
699
  </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`
700
+ `}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({point:t.requests[r],originalIndex:r});return a`
509
701
  <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`
702
+ <table class="perf-table">
703
+ <thead>
704
+ <tr>
705
+ <th>Time</th>
706
+ <th>Health</th>
707
+ <th>Duration</th>
708
+ <th>Breakdown</th>
709
+ <th class="perf-th-center">Status</th>
710
+ <th class="perf-th-right">Queries</th>
711
+ </tr>
712
+ </thead>
713
+ <tbody>
714
+ ${s.map(r=>this.renderHistoryRow(r.point,r.originalIndex,t.baselineP95Ms))}
715
+ </tbody>
716
+ </table>
717
+ </div>
718
+ `}renderHistoryRow(t,s,r){let o=this.healthGradeForDuration(t.durationMs,r),n=new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),l=t.statusCode>=400,c=t.queryTimeMs||0,p=t.fetchTimeMs||0,h=Math.max(0,t.durationMs-c-p);return a`
719
+ <tr class="perf-table-row ${l?"perf-row-err":""}" data-req-idx=${s}>
720
+ <td class="perf-td-muted">${n}</td>
721
+ <td>
722
+ <span class="perf-badge perf-badge-sm" style="color:${o.color};background:${o.bg};border-color:${o.border}">${o.label}</span>
723
+ </td>
724
+ <td>${v(t.durationMs)}</td>
725
+ <td>
726
+ ${c>0?a`<span class="perf-bd-tag perf-bd-tag-db">DB ${v(c)}</span>`:d}
727
+ ${p>0?a`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${v(p)}</span>`:d}
728
+ <span class="perf-bd-tag perf-bd-tag-app">App ${v(h)}</span>
729
+ </td>
730
+ <td class="perf-td-center" style="color:${l?"var(--red)":"var(--text-muted)"}">${t.statusCode}</td>
731
+ <td class="perf-td-right perf-td-muted">${t.queryCount}</td>
732
+ </tr>
733
+ `}};u([R({context:x})],M.prototype,"store",2),u([_()],M.prototype,"selectedEndpoint",2),u([_()],M.prototype,"graphData",2),u([_()],M.prototype,"loadError",2),u([_()],M.prototype,"queryBreakdown",2),u([_()],M.prototype,"queryBreakdownLoading",2),M=u([g("bk-performance-view")],M);function _r(i){return i===0?"<1ms":v(i)}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(`${$.activity}?requestId=${this.requestId}`);if(!s.ok){this.failed=!0,this.loading=!1;return}let r=await s.json();if(w.cache.size>=pe){let o=w.cache.keys().next().value;o!==void 0&&w.cache.delete(o);}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(()=>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`
536
734
  <div class="tl-header">
537
735
  <span class="tl-title">Activity Timeline</span>
538
736
  <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}
737
+ ${t.counts.queries>0?a`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:d}
738
+ ${t.counts.fetches>0?a`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:d}
739
+ ${t.counts.logs>0?a`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:d}
740
+ ${t.counts.errors>0?a`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:d}
543
741
  </span>
544
742
  </div>
545
743
  <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)}
744
+ `}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,h=p?r.get(p):void 0;if(h&&h.length>0){let m=h.length;return a`
745
+ ${this.renderEvent(l,c,s)}
548
746
  <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)})}
747
+ <span class="tl-nested-label">${m} nested quer${m===1?"y":"ies"}</span>
748
+ ${h.map(E=>{let T=n++;return this.renderEvent(E,T,s,true)})}
551
749
  </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>
750
+ `}return this.renderEvent(l,c,s)})}renderEvent(t,s,r,o=false){let n=ts[t.type]||"var(--text-dim)",l=es[t.type]||t.type,c="+"+v(Math.round(t.timestamp-r)),p=t.type==="query"?t.data.sql:void 0,h=!!p,m=this.expandedSqlIdx===s;return a`
751
+ <div class="tl-event ${h?"tl-clickable":""} ${o?"tl-nested-event":""}"
752
+ style="${h?"":`border-left-color:${n}`}"
753
+ @click=${h?E=>this.toggleSql(s,E):d}>
754
+ <span class="tl-event-time">${c}</span>
755
+ <span class="tl-event-type" style="color:${n}">${l}</span>
558
756
  ${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}
757
+ ${p?a`
758
+ <div class="tl-event-sql ${m?"open":""}">
759
+ <button class="tl-sql-copy" @click=${E=>this.copySql(p,E)}>Copy</button>
760
+ ${p}
563
761
  </div>`:d}
564
762
  </div>
565
- `}renderEventContent(t){switch(t.type){case "fetch":{let s=t.data,r=s.statusCode>=400;return n`
763
+ `}renderEventContent(t){switch(t.type){case "fetch":{let s=t.data,r=s.statusCode>=400;return a`
566
764
  <span class="tl-event-summary">${s.method} ${s.url}</span>
567
765
  <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`
766
+ <span class="tl-event-dur">${v(s.durationMs)}</span>
767
+ `}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`
768
+ <span class="tl-event-summary"><span style="color:${n};font-weight:600">${r}</span> ${o}</span>
769
+ <span class="tl-event-dur">${_r(s.durationMs)}</span>
770
+ `}case "log":{let s=t.data,r=Ke[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}}};w.cache=new Map,u([R({context:x})],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 Wt=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($.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(N)||(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(),ue)));},this.eventSource.addEventListener(ee,e=>{this.store.prependFetch(JSON.parse(e.data));}),this.eventSource.addEventListener("log",e=>{this.store.prependLog(JSON.parse(e.data));}),this.eventSource.addEventListener(se,e=>{this.store.prependError(JSON.parse(e.data));}),this.eventSource.addEventListener(re,e=>{this.store.prependQuery(JSON.parse(e.data));}),this.eventSource.addEventListener(oe,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($.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch($.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function gs(){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 Es(){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 bs(){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 _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"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>`}function Ss(){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 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"><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 $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"><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 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"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 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"><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 X=class extends f{constructor(){super(...arguments);this.store=new Gt;this.activeView="overview";this.viewMode="simple";this.sse=new Wt(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($.flows),fetch($.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($.fetches),fetch($.errors),fetch($.logs),fetch($.queries),fetch($.metricsLive)]),[l,c,p,h,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(h.entries),this.store.setMetrics(m.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let s=await(await fetch($.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(`${$.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($.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(N)),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`
573
771
  <div class="app" id="app">
574
772
  <aside class="sidebar">
575
773
  <div class="sidebar-logo">
576
774
  <span class="logo-text">brakit</span>
577
- <span class="logo-version">v${c?.version??""}</span>
775
+ <span class="logo-version">v${l?.version??""}</span>
578
776
  </div>
579
777
  <nav class="sidebar-nav">
580
- ${this.renderSidebarItem("overview","Overview",ps(),void 0)}
778
+ ${this.renderSidebarItem("overview","Overview",gs(),void 0)}
581
779
  <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)}
780
+ ${this.renderSidebarItem("actions","Actions",Es(),t.flows.length)}
781
+ ${this.renderSidebarItem("requests","Requests",bs(),s.length)}
782
+ ${this.renderSidebarItem("fetches","Fetches",_s(),t.fetches.length)}
585
783
  <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)}
784
+ ${this.renderSidebarItem("queries","Queries",Ss(),t.queries.length)}
785
+ ${this.renderSidebarItem("errors","Errors",Ts(),t.errors.length)}
786
+ ${this.renderSidebarItem("logs","Logs",$s(),t.logs.length)}
787
+ ${this.renderSidebarItem("security","Security",ys(),n,n===0)}
788
+ ${this.renderSidebarItem("performance","Performance",xs(),void 0)}
591
789
  </nav>
592
- <div class="sidebar-footer">:${c?.port??""}</div>
790
+ <div class="sidebar-footer">:${l?.port??""}</div>
593
791
  </aside>
594
792
  <div class="main-panel">
595
793
  <div class="header">
596
794
  <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>
795
+ <span class="header-title" id="header-title">${ie[this.activeView]||this.activeView}</span>
796
+ <span class="header-sub" id="header-sub">${ne[this.activeView]||""}</span>
599
797
  </div>
600
798
  <div class="header-right">
601
- ${this.activeView==="actions"?n`
799
+ ${this.activeView==="actions"?a`
602
800
  <div class="segmented-control" id="mode-toggle">
603
801
  <button class="segmented-btn ${this.viewMode==="simple"?"active":""}" @click=${()=>{this.viewMode="simple",this.store.setViewMode("simple");}}>Quick</button>
604
802
  <button class="segmented-btn ${this.viewMode==="detailed"?"active":""}" @click=${()=>{this.viewMode="detailed",this.store.setViewMode("detailed");}}>Detailed</button>
@@ -640,18 +838,18 @@
640
838
  <span id="stat-total">${s.length} request${s.length!==1?"s":""}</span>
641
839
  <span id="stat-flows">${t.flows.length} action${t.flows.length!==1?"s":""}</span>
642
840
  <span id="stat-errors" class="error-count">${r} error${r!==1?"s":""}</span>
643
- <span id="stat-avg">Avg: ${i}ms</span>
841
+ <span id="stat-avg">Avg: ${o}ms</span>
644
842
  </div>
645
843
  </div>
646
844
  </div>
647
845
  <bk-toast></bk-toast>
648
- `}renderSidebarItem(t,s,r,i,a=false){return n`
846
+ `}renderSidebarItem(t,s,r,o,n=false){return a`
649
847
  <button class="sidebar-item ${this.activeView===t?"active":""}" @click=${()=>this.switchView(t)}>
650
848
  <span class="item-icon">${r}</span>
651
849
  <span class="item-label">${s}</span>
652
- ${i!==void 0?n`<span class="item-count" style="display:${a?"none":""}">${i}</span>`:d}
850
+ ${o!==void 0?a`<span class="item-count" style="display:${n?"none":""}">${o}</span>`:d}
653
851
  </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);
852
+ `}};u([Ee({context:x})],X.prototype,"store",2),u([_()],X.prototype,"activeView",2),u([_()],X.prototype,"viewMode",2),X=u([g("bk-dashboard")],X);
655
853
  /*! Bundled license information:
656
854
 
657
855
  @lit/reactive-element/css-tag.js: