brakit 0.10.0 → 0.10.2

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.
@@ -18,7 +18,10 @@
18
18
  --red:#dc2626;
19
19
  --cyan:#0891b2;
20
20
  --green-bg:rgba(22,163,74,0.08);--green-bg-subtle:rgba(22,163,74,0.05);--green-border:rgba(22,163,74,0.2);--green-border-subtle:rgba(22,163,74,0.15);
21
- --amber-bg:rgba(217,119,6,0.07);--red-bg:rgba(220,38,38,0.07);--blue-bg:rgba(37,99,235,0.08);--cyan-bg:rgba(8,145,178,0.07);
21
+ --amber-bg:rgba(217,119,6,0.08);--amber-border:rgba(217,119,6,0.15);
22
+ --red-bg:rgba(220,38,38,0.08);--red-border:rgba(220,38,38,0.2);
23
+ --blue-bg:rgba(37,99,235,0.08);--cyan-bg:rgba(8,145,178,0.07);
24
+ --accent-bg:rgba(99,102,241,0.08);
22
25
  --sidebar-width:232px;--header-height:52px;
23
26
  --radius:8px;--radius-sm:6px;
24
27
  --shadow-sm:0 1px 3px rgba(0,0,0,0.06),0 1px 2px rgba(0,0,0,0.03);
@@ -65,6 +68,7 @@ html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--s
65
68
  .sidebar-logo .logo-version{font-weight:400;font-size:11px;color:var(--text-muted);margin-left:8px;letter-spacing:0}
66
69
  .sidebar-nav{padding:12px;flex:1}
67
70
  .sidebar-section{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.8px;color:var(--text-muted);padding:16px 12px 8px}
71
+ .sidebar-divider{height:1px;background:var(--border-subtle);margin:8px 12px}
68
72
  .sidebar-item{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:var(--radius);color:var(--text-dim);font-size:14px;font-weight:500;cursor:pointer;transition:all .15s;border:none;background:transparent;width:100%;text-align:left;font-family:var(--sans)}
69
73
  .sidebar-item:hover{background:var(--bg-hover);color:var(--text)}
70
74
  .sidebar-item.active{background:var(--bg-active);color:var(--accent)}
@@ -98,7 +102,7 @@ html,body{height:100%;background:var(--bg);color:var(--text);font-family:var(--s
98
102
  /* Content */
99
103
  .main-content{flex:1;overflow-y:auto}
100
104
  bk-dashboard{display:contents}
101
- bk-overview-view,bk-flows-view,bk-requests-view,bk-fetches-view,bk-queries-view,bk-errors-view,bk-logs-view,bk-security-view,bk-performance-view,bk-timeline-panel,bk-empty-state{display:block}
105
+ bk-overview-view,bk-flows-view,bk-requests-view,bk-fetches-view,bk-queries-view,bk-errors-view,bk-logs-view,bk-security-view,bk-performance-view,bk-explorer-view,bk-insights-view,bk-timeline-panel,bk-empty-state{display:block}
102
106
  bk-graph-view{display:block}
103
107
  bk-method-badge,bk-status-pill,bk-duration-label,bk-copy-button{display:inline-flex;flex-shrink:0}
104
108
  bk-stat-card{display:inline-flex}
@@ -445,53 +449,25 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
445
449
  .perf-trend-slower{color:var(--red)}
446
450
  .perf-trend-faster{color:var(--green)}
447
451
 
448
- /* Overview */
449
- .ov-container{padding:24px 28px}
450
-
451
- /* Summary banner */
452
- .ov-summary{display:flex;gap:10px;margin-bottom:24px;flex-wrap:wrap}
453
- .ov-stat{display:flex;flex-direction:column;gap:4px;flex:1;min-width:100px;padding:16px 18px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-sm);transition:box-shadow var(--transition, .15s ease)}
454
- .ov-stat:hover{box-shadow:var(--shadow-md)}
455
- .ov-stat-value{font-size:22px;font-weight:700;font-family:var(--mono);color:var(--text);line-height:1.2}
456
- .ov-stat-label{font-size:10px;text-transform:uppercase;letter-spacing:.8px;color:var(--text-muted);font-weight:600}
457
-
458
- /* Section header */
459
- .ov-section-title{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.8px;color:var(--text-muted);margin-bottom:12px;display:flex;align-items:center;gap:8px}
460
- .ov-issue-count{font-size:11px;font-family:var(--mono);color:var(--text-dim);background:var(--bg-muted);border:1px solid var(--border);padding:1px 8px;border-radius:10px}
461
-
462
- /* Insight cards */
463
- .ov-cards{display:flex;flex-direction:column;gap:8px}
464
- .ov-card{display:flex;align-items:flex-start;gap:14px;padding:16px 20px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all var(--transition, .15s ease);box-shadow:var(--shadow-sm)}
465
- .ov-card:hover{background:var(--bg-hover);border-color:var(--border-light);box-shadow:var(--shadow-md);transform:translateY(-1px)}
466
- .ov-card-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:10px;border-radius:50%;margin-top:2px}
467
- .ov-card-icon.critical{background:rgba(220,38,38,.08);color:var(--red)}
468
- .ov-card-icon.warning{background:rgba(217,119,6,.08);color:var(--amber)}
469
- .ov-card-icon.info{background:rgba(37,99,235,.08);color:var(--blue)}
470
- .ov-card-icon.resolved{background:var(--green-bg);color:var(--green)}
471
- .ov-card-body{flex:1;min-width:0}
472
- .ov-card-title{font-size:13px;font-weight:600;color:var(--text);margin-bottom:2px}
473
- .ov-card-desc{font-size:12px;color:var(--text-dim);line-height:1.5}
474
- .ov-card-detail{font-size:11px;font-family:var(--mono);color:var(--text-muted);margin-top:6px;padding:8px 10px;background:var(--bg-muted);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);line-height:1.5}
475
- .ov-card-desc strong{color:var(--text);font-family:var(--mono);font-weight:600}
476
- .ov-card-arrow{color:var(--text-muted);font-size:12px;flex-shrink:0;margin-top:2px;font-family:var(--mono);transition:transform .15s}
477
-
478
- /* Expanded card */
479
- .ov-card.expanded{border-color:var(--border-light);box-shadow:var(--shadow-md)}
480
- .ov-card-expand{display:none;margin-top:10px;padding-top:10px;border-top:1px solid var(--border)}
481
- .ov-card-hint{font-size:12px;color:var(--text-dim);line-height:1.5;margin-bottom:10px}
482
- .ov-card-link{font-size:12px;font-weight:600;color:var(--blue);cursor:pointer;display:inline-block;padding:4px 0}
483
- .ov-card-link:hover{text-decoration:underline}
484
- .ov-detail-label{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}
485
- .ov-detail-item{font-size:12px;color:var(--text);font-family:var(--mono);padding:2px 0}
486
-
487
- /* All-clear banner */
488
- .ov-clear{display:flex;align-items:center;gap:12px;padding:16px 20px;background:var(--green-bg-subtle);border:1px solid var(--green-border);border-radius:var(--radius);color:var(--green);font-size:13px;font-weight:500}
489
- .ov-clear-icon{font-size:16px}
452
+ .ov-container{padding:28px}
490
453
 
491
- /* Resolved section */
492
- .ov-resolved-title{margin-top:24px}
493
- .ov-card-resolved{opacity:.7;border-color:var(--green-border);cursor:default}
494
- .ov-card-resolved:hover{opacity:1;box-shadow:var(--shadow-sm)}
454
+ .ov-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
455
+
456
+ .ov-card-nav{display:flex;align-items:center;gap:16px;padding:20px 24px;background:var(--bg-card);border:1px solid var(--border);border-radius:12px;cursor:pointer;transition:all .18s ease;box-shadow:0 1px 3px rgba(0,0,0,.04)}
457
+ .ov-card-nav:hover{border-color:var(--border-light);box-shadow:0 4px 16px rgba(0,0,0,.06);transform:translateY(-2px)}
458
+ .ov-card-nav:active{transform:translateY(0)}
459
+
460
+ .ov-card-empty{opacity:.55}
461
+ .ov-card-empty:hover{opacity:.8}
462
+
463
+ .ov-card-icon-lg{font-size:22px;width:40px;height:40px;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--bg-muted);border-radius:10px;color:var(--text-muted)}
464
+
465
+ .ov-card-content{flex:1;min-width:0}
466
+ .ov-card-headline{font-size:16px;font-weight:700;color:var(--text);font-family:var(--mono);line-height:1.3}
467
+ .ov-card-context{font-size:12px;color:var(--text-muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
468
+
469
+ .ov-card-arrow{font-size:16px;color:var(--text-muted);opacity:0;transition:opacity .15s,transform .15s;flex-shrink:0}
470
+ .ov-card-nav:hover .ov-card-arrow{opacity:1;transform:translateX(2px)}
495
471
 
496
472
  /* Security tab */
497
473
  .sec-container{padding:24px 28px}
@@ -847,98 +823,173 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
847
823
  /* Flow edge animation */
848
824
  @keyframes graph-flow-dash{to{stroke-dashoffset:-24}}
849
825
  .graph-flow-edge{animation:graph-flow-dash 1s linear infinite}
826
+
827
+ /* Explorer sub-tabs */
828
+ .explorer-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);padding:0 28px;background:var(--bg);position:sticky;top:0;z-index:2}
829
+ .explorer-tab{padding:10px 16px;font-size:13px;font-weight:500;color:var(--text-muted);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:6px;font-family:var(--sans);white-space:nowrap}
830
+ .explorer-tab:hover{color:var(--text)}
831
+ .explorer-tab.active{color:var(--accent);border-bottom-color:var(--accent)}
832
+ .explorer-tab-count{font-size:11px;font-family:var(--mono);color:var(--text-muted);background:var(--bg-muted);padding:1px 6px;border-radius:8px}
833
+ .explorer-tab.active .explorer-tab-count{color:var(--accent);background:var(--accent-bg)}
834
+
835
+ /* Insights filter chips */
836
+ .insights-filters{display:flex;gap:6px;padding:16px 28px;border-bottom:1px solid var(--border);background:var(--bg);position:sticky;top:0;z-index:2}
837
+ .insights-chip{font-size:12px;font-weight:500;padding:5px 14px;border:1px solid var(--border);border-radius:20px;background:var(--bg);color:var(--text-muted);cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:5px;font-family:var(--sans)}
838
+ .insights-chip:hover{border-color:var(--text-muted);color:var(--text)}
839
+ .insights-chip.active{background:var(--accent);color:white;border-color:var(--accent)}
840
+ .insights-chip-count{font-size:10px;font-family:var(--mono);background:rgba(0,0,0,.08);padding:1px 5px;border-radius:8px}
841
+ .insights-chip.active .insights-chip-count{background:rgba(255,255,255,.25)}
842
+
843
+ /* Summary bar */
844
+ .insights-summary{display:flex;gap:14px;padding:10px 28px;font-size:12px;font-weight:500;border-bottom:1px solid var(--border)}
845
+ .insights-summary-stat{display:flex;align-items:center;gap:4px}
846
+ .insights-summary-stat.critical{color:var(--red)}
847
+ .insights-summary-stat.warning{color:var(--amber)}
848
+ .insights-summary-stat.resolved{color:var(--green)}
849
+
850
+ /* AI hint */
851
+ .insights-ai-hint{font-size:11px;color:var(--text-muted);padding:0 0 12px}
852
+ .insights-ai-hint code{background:var(--bg-muted);padding:2px 6px;border-radius:4px;font-family:var(--mono);font-size:11px}
853
+
854
+ /* Insights card list */
855
+ .insights-list{padding:16px 28px}
856
+
857
+ .insights-empty{display:flex;align-items:center;gap:10px;padding:24px;color:var(--green);font-size:14px;font-weight:500}
858
+ .insights-empty-icon{font-size:18px}
859
+
860
+ .insights-card{display:flex;align-items:flex-start;gap:12px;padding:12px 16px;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;cursor:pointer;transition:all .15s;margin-bottom:6px}
861
+ .insights-card:hover{border-color:var(--border-light);box-shadow:0 2px 8px rgba(0,0,0,.04)}
862
+ .insights-card.expanded{border-color:var(--border-light);box-shadow:0 2px 8px rgba(0,0,0,.04)}
863
+ .insights-card.resolved{opacity:.55}
864
+ .insights-card.resolved:hover{opacity:.8}
865
+
866
+ .insights-card-left{flex-shrink:0;padding-top:2px}
867
+ .insights-sev{width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:10px;border-radius:50%}
868
+ .insights-sev.critical{background:var(--red-bg);color:var(--red)}
869
+ .insights-sev.warning{background:var(--amber-bg);color:var(--amber)}
870
+ .insights-sev.info{background:var(--blue-bg);color:var(--blue)}
871
+
872
+ .insights-card-body{flex:1;min-width:0}
873
+ .insights-card-header{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:3px}
874
+ .insights-card-title{font-size:13px;font-weight:600;color:var(--text)}
875
+ .insights-card-title.resolved{text-decoration:line-through;color:var(--text-muted)}
876
+ .insights-card-cat{font-size:9px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);background:var(--bg-muted);padding:1px 6px;border-radius:4px}
877
+ .insights-card-count{font-size:11px;font-family:var(--mono);color:var(--text-muted)}
878
+ .insights-card-desc{font-size:12px;color:var(--text-dim);line-height:1.5}
879
+ .insights-card-detail{font-size:11px;font-family:var(--mono);color:var(--text-muted);margin-top:6px;padding:6px 10px;background:var(--bg-muted);border:1px solid var(--border-subtle);border-radius:6px;line-height:1.5}
880
+ .insights-card-progress{font-size:11px;color:var(--text-muted);margin-top:4px;font-family:var(--mono)}
881
+ .insights-card-hint{font-size:12px;color:var(--text-dim);line-height:1.6;margin-top:8px;padding-top:8px;border-top:1px solid var(--border)}
882
+
883
+ .insights-badge-regressed{font-size:9px;font-weight:700;color:var(--red);background:var(--red-bg);padding:1px 6px;border-radius:4px}
884
+ .insights-badge-verifying{font-size:9px;font-weight:700;color:var(--amber);background:var(--amber-bg);padding:1px 6px;border-radius:4px}
885
+ .insights-badge-resolved{font-size:9px;font-weight:700;color:var(--green);background:var(--green-bg);padding:1px 6px;border-radius:4px}
886
+
887
+ .insights-card-arrow{color:var(--text-muted);font-size:12px;flex-shrink:0;padding-top:2px;font-family:var(--mono);transition:transform .15s}
888
+
889
+ .insights-section{display:flex;align-items:center;gap:8px;padding:14px 0 8px;margin-top:4px;font-size:12px;font-weight:700;color:var(--text);text-transform:uppercase;letter-spacing:.5px;border-top:1px solid var(--border);user-select:none}
890
+ .insights-section:first-child{border-top:none;margin-top:0}
891
+ .insights-section-icon{font-size:11px;width:16px;text-align:center}
892
+ .insights-section-count{font-size:11px;font-family:var(--mono);color:var(--text-muted);background:var(--bg-muted);padding:1px 7px;border-radius:8px;font-weight:500}
893
+ .insights-section-regressed{color:var(--red)}
894
+ .insights-section-regressed .insights-section-count{color:var(--red);background:var(--red-bg)}
895
+ .insights-section-verifying{color:var(--amber)}
896
+ .insights-section-verifying .insights-section-count{color:var(--amber);background:var(--amber-bg)}
897
+ .insights-section-resolved{color:var(--green)}
898
+ .insights-section-resolved .insights-section-count{color:var(--green);background:var(--green-bg)}
899
+ .insights-section-dismissed{color:var(--text-muted);cursor:pointer}
900
+ .insights-section-dismissed:hover{color:var(--text)}
850
901
  </style>
851
902
  </head>
852
903
  <body>
853
904
  <bk-dashboard></bk-dashboard>
854
905
  <script>window.__BRAKIT_CONFIG__={port:{{PORT}},version:"{{VERSION}}"};</script>
855
- <script>(function(){'use strict';var wr=Object.defineProperty;var Rr=Object.getOwnPropertyDescriptor;var u=(o,s,t,e)=>{for(var r=e>1?void 0:e?Rr(s,t):s,i=o.length-1,n;i>=0;i--)(n=o[i])&&(r=(e?n(s,t,r):n(r))||r);return e&&r&&wr(s,t,r),r};var zt=globalThis,Zt=zt.ShadowRoot&&(zt.ShadyCSS===void 0||zt.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,os=Symbol(),is=new WeakMap,Jt=class{constructor(s,t,e){if(this._$cssResult$=true,e!==os)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=s,this.t=t;}get styleSheet(){let s=this.o,t=this.t;if(Zt&&s===void 0){let e=t!==void 0&&t.length===1;e&&(s=is.get(t)),s===void 0&&((this.o=s=new CSSStyleSheet).replaceSync(this.cssText),e&&is.set(t,s));}return s}toString(){return this.cssText}},ns=o=>new Jt(typeof o=="string"?o:o+"",void 0,os);var as=(o,s)=>{if(Zt)o.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of s){let e=document.createElement("style"),r=zt.litNonce;r!==void 0&&e.setAttribute("nonce",r),e.textContent=t.cssText,o.appendChild(e);}},ye=Zt?o=>o:o=>o instanceof CSSStyleSheet?(s=>{let t="";for(let e of s.cssRules)t+=e.cssText;return ns(t)})(o):o;var{is:Ar,defineProperty:Ir,getOwnPropertyDescriptor:Cr,getOwnPropertyNames:Lr,getOwnPropertySymbols:Mr,getPrototypeOf:Nr}=Object,K=globalThis,ls=K.trustedTypes,Or=ls?ls.emptyScript:"",kr=K.reactiveElementPolyfillSupport,Mt=(o,s)=>o,Nt={toAttribute(o,s){switch(s){case Boolean:o=o?Or:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o);}return o},fromAttribute(o,s){let t=o;switch(s){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}},te=(o,s)=>!Ar(o,s),cs={attribute:true,type:String,converter:Nt,reflect:false,useDefault:false,hasChanged:te};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),K.litPropertyMetadata??(K.litPropertyMetadata=new WeakMap);var j=class extends HTMLElement{static addInitializer(s){this._$Ei(),(this.l??(this.l=[])).push(s);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(s,t=cs){if(t.state&&(t.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(s)&&((t=Object.create(t)).wrapped=true),this.elementProperties.set(s,t),!t.noAccessor){let e=Symbol(),r=this.getPropertyDescriptor(s,e,t);r!==void 0&&Ir(this.prototype,s,r);}}static getPropertyDescriptor(s,t,e){let{get:r,set:i}=Cr(this.prototype,s)??{get(){return this[t]},set(n){this[t]=n;}};return {get:r,set(n){let l=r?.call(this);i?.call(this,n),this.requestUpdate(s,l,e);},configurable:true,enumerable:true}}static getPropertyOptions(s){return this.elementProperties.get(s)??cs}static _$Ei(){if(this.hasOwnProperty(Mt("elementProperties")))return;let s=Nr(this);s.finalize(),s.l!==void 0&&(this.l=[...s.l]),this.elementProperties=new Map(s.elementProperties);}static finalize(){if(this.hasOwnProperty(Mt("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(Mt("properties"))){let t=this.properties,e=[...Lr(t),...Mr(t)];for(let r of e)this.createProperty(r,t[r]);}let s=this[Symbol.metadata];if(s!==null){let t=litPropertyMetadata.get(s);if(t!==void 0)for(let[e,r]of t)this.elementProperties.set(e,r);}this._$Eh=new Map;for(let[t,e]of this.elementProperties){let r=this._$Eu(t,e);r!==void 0&&this._$Eh.set(r,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){let t=[];if(Array.isArray(s)){let e=new Set(s.flat(1/0).reverse());for(let r of e)t.unshift(ye(r));}else s!==void 0&&t.push(ye(s));return t}static _$Eu(s,t){let e=t.attribute;return e===false?void 0:typeof e=="string"?e:typeof s=="string"?s.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(s=>this.enableUpdating=s),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(s=>s(this));}addController(s){(this._$EO??(this._$EO=new Set)).add(s),this.renderRoot!==void 0&&this.isConnected&&s.hostConnected?.();}removeController(s){this._$EO?.delete(s);}_$E_(){let s=new Map,t=this.constructor.elementProperties;for(let e of t.keys())this.hasOwnProperty(e)&&(s.set(e,this[e]),delete this[e]);s.size>0&&(this._$Ep=s);}createRenderRoot(){let s=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return as(s,this.constructor.elementStyles),s}connectedCallback(){this.renderRoot??(this.renderRoot=this.createRenderRoot()),this.enableUpdating(true),this._$EO?.forEach(s=>s.hostConnected?.());}enableUpdating(s){}disconnectedCallback(){this._$EO?.forEach(s=>s.hostDisconnected?.());}attributeChangedCallback(s,t,e){this._$AK(s,e);}_$ET(s,t){let e=this.constructor.elementProperties.get(s),r=this.constructor._$Eu(s,e);if(r!==void 0&&e.reflect===true){let i=(e.converter?.toAttribute!==void 0?e.converter:Nt).toAttribute(t,e.type);this._$Em=s,i==null?this.removeAttribute(r):this.setAttribute(r,i),this._$Em=null;}}_$AK(s,t){let e=this.constructor,r=e._$Eh.get(s);if(r!==void 0&&this._$Em!==r){let i=e.getPropertyOptions(r),n=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:Nt;this._$Em=r;let l=n.fromAttribute(t,i.type);this[r]=l??this._$Ej?.get(r)??l,this._$Em=null;}}requestUpdate(s,t,e,r=false,i){if(s!==void 0){let n=this.constructor;if(r===false&&(i=this[s]),e??(e=n.getPropertyOptions(s)),!((e.hasChanged??te)(i,t)||e.useDefault&&e.reflect&&i===this._$Ej?.get(s)&&!this.hasAttribute(n._$Eu(s,e))))return;this.C(s,t,e);}this.isUpdatePending===false&&(this._$ES=this._$EP());}C(s,t,{useDefault:e,reflect:r,wrapped:i},n){e&&!(this._$Ej??(this._$Ej=new Map)).has(s)&&(this._$Ej.set(s,n??t??this[s]),i!==true||n!==void 0)||(this._$AL.has(s)||(this.hasUpdated||e||(t=void 0),this._$AL.set(s,t)),r===true&&this._$Em!==s&&(this._$Eq??(this._$Eq=new Set)).add(s));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}let s=this.scheduleUpdate();return s!=null&&await s,!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 e=this.constructor.elementProperties;if(e.size>0)for(let[r,i]of e){let{wrapped:n}=i,l=this[r];n!==true||this._$AL.has(r)||l===void 0||this.C(r,void 0,i,l);}}let s=false,t=this._$AL;try{s=this.shouldUpdate(t),s?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM();}catch(e){throw s=false,this._$EM(),e}s&&this._$AE(t);}willUpdate(s){}_$AE(s){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(s)),this.updated(s);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(s){return true}update(s){this._$Eq&&(this._$Eq=this._$Eq.forEach(t=>this._$ET(t,this[t]))),this._$EM();}updated(s){}firstUpdated(s){}};j.elementStyles=[],j.shadowRootOptions={mode:"open"},j[Mt("elementProperties")]=new Map,j[Mt("finalized")]=new Map,kr?.({ReactiveElement:j}),(K.reactiveElementVersions??(K.reactiveElementVersions=[])).push("2.1.2");var kt=globalThis,ds=o=>o,ee=kt.trustedTypes,ps=ee?ee.createPolicy("lit-html",{createHTML:o=>o}):void 0,gs="$lit$",z=`lit$${Math.random().toFixed(9).slice(2)}$`,bs="?"+z,Dr=`<${bs}>`,ot=document,Dt=()=>ot.createComment(""),Ht=o=>o===null||typeof o!="object"&&typeof o!="function",Re=Array.isArray,Hr=o=>Re(o)||typeof o?.[Symbol.iterator]=="function",_e=`[
856
- \f\r]`,Ot=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,hs=/-->/g,us=/>/g,rt=RegExp(`>|${_e}(?:([^\\s"'>=/]+)(${_e}*=${_e}*(?:[^
857
- \f\r"'\`<>=]|("|')|))|$)`,"g"),ms=/'/g,fs=/"/g,Es=/^(?:script|style|textarea|title)$/i,Ae=o=>(s,...t)=>({_$litType$:o,strings:s,values:t}),a=Ae(1),O=Ae(2),Y=Symbol.for("lit-noChange"),p=Symbol.for("lit-nothing"),vs=new WeakMap,it=ot.createTreeWalker(ot,129);function ys(o,s){if(!Re(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return ps!==void 0?ps.createHTML(s):s}var Pr=(o,s)=>{let t=o.length-1,e=[],r,i=s===2?"<svg>":s===3?"<math>":"",n=Ot;for(let l=0;l<t;l++){let c=o[l],d,h,m=-1,v=0;for(;v<c.length&&(n.lastIndex=v,h=n.exec(c),h!==null);)v=n.lastIndex,n===Ot?h[1]==="!--"?n=hs:h[1]!==void 0?n=us:h[2]!==void 0?(Es.test(h[2])&&(r=RegExp("</"+h[2],"g")),n=rt):h[3]!==void 0&&(n=rt):n===rt?h[0]===">"?(n=r??Ot,m=-1):h[1]===void 0?m=-2:(m=n.lastIndex-h[2].length,d=h[1],n=h[3]===void 0?rt:h[3]==='"'?fs:ms):n===fs||n===ms?n=rt:n===hs||n===us?n=Ot:(n=rt,r=void 0);let x=n===rt&&o[l+1].startsWith("/>")?" ":"";i+=n===Ot?c+Dr:m>=0?(e.push(d),c.slice(0,m)+gs+c.slice(m)+z+x):c+z+(m===-2?l:x);}return [ys(o,i+(o[t]||"<?>")+(s===2?"</svg>":s===3?"</math>":"")),e]},Pt=class o{constructor({strings:s,_$litType$:t},e){let r;this.parts=[];let i=0,n=0,l=s.length-1,c=this.parts,[d,h]=Pr(s,t);if(this.el=o.createElement(d,e),it.currentNode=this.el.content,t===2||t===3){let m=this.el.content.firstChild;m.replaceWith(...m.childNodes);}for(;(r=it.nextNode())!==null&&c.length<l;){if(r.nodeType===1){if(r.hasAttributes())for(let m of r.getAttributeNames())if(m.endsWith(gs)){let v=h[n++],x=r.getAttribute(m).split(z),y=/([.?@])?(.*)/.exec(v);c.push({type:1,index:i,name:y[2],strings:x,ctor:y[1]==="."?xe:y[1]==="?"?Se:y[1]==="@"?Te:ht}),r.removeAttribute(m);}else m.startsWith(z)&&(c.push({type:6,index:i}),r.removeAttribute(m));if(Es.test(r.tagName)){let m=r.textContent.split(z),v=m.length-1;if(v>0){r.textContent=ee?ee.emptyScript:"";for(let x=0;x<v;x++)r.append(m[x],Dt()),it.nextNode(),c.push({type:2,index:++i});r.append(m[v],Dt());}}}else if(r.nodeType===8)if(r.data===bs)c.push({type:2,index:i});else {let m=-1;for(;(m=r.data.indexOf(z,m+1))!==-1;)c.push({type:7,index:i}),m+=z.length-1;}i++;}}static createElement(s,t){let e=ot.createElement("template");return e.innerHTML=s,e}};function pt(o,s,t=o,e){if(s===Y)return s;let r=e!==void 0?t._$Co?.[e]:t._$Cl,i=Ht(s)?void 0:s._$litDirective$;return r?.constructor!==i&&(r?._$AO?.(false),i===void 0?r=void 0:(r=new i(o),r._$AT(o,t,e)),e!==void 0?(t._$Co??(t._$Co=[]))[e]=r:t._$Cl=r),r!==void 0&&(s=pt(o,r._$AS(o,s.values),r,e)),s}var $e=class{constructor(s,t){this._$AV=[],this._$AN=void 0,this._$AD=s,this._$AM=t;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(s){let{el:{content:t},parts:e}=this._$AD,r=(s?.creationScope??ot).importNode(t,true);it.currentNode=r;let i=it.nextNode(),n=0,l=0,c=e[0];for(;c!==void 0;){if(n===c.index){let d;c.type===2?d=new qt(i,i.nextSibling,this,s):c.type===1?d=new c.ctor(i,c.name,c.strings,this,s):c.type===6&&(d=new we(i,this,s)),this._$AV.push(d),c=e[++l];}n!==c?.index&&(i=it.nextNode(),n++);}return it.currentNode=ot,r}p(s){let t=0;for(let e of this._$AV)e!==void 0&&(e.strings!==void 0?(e._$AI(s,e,t),t+=e.strings.length-2):e._$AI(s[t])),t++;}},qt=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(s,t,e,r){this.type=2,this._$AH=p,this._$AN=void 0,this._$AA=s,this._$AB=t,this._$AM=e,this.options=r,this._$Cv=r?.isConnected??true;}get parentNode(){let s=this._$AA.parentNode,t=this._$AM;return t!==void 0&&s?.nodeType===11&&(s=t.parentNode),s}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(s,t=this){s=pt(this,s,t),Ht(s)?s===p||s==null||s===""?(this._$AH!==p&&this._$AR(),this._$AH=p):s!==this._$AH&&s!==Y&&this._(s):s._$litType$!==void 0?this.$(s):s.nodeType!==void 0?this.T(s):Hr(s)?this.k(s):this._(s);}O(s){return this._$AA.parentNode.insertBefore(s,this._$AB)}T(s){this._$AH!==s&&(this._$AR(),this._$AH=this.O(s));}_(s){this._$AH!==p&&Ht(this._$AH)?this._$AA.nextSibling.data=s:this.T(ot.createTextNode(s)),this._$AH=s;}$(s){let{values:t,_$litType$:e}=s,r=typeof e=="number"?this._$AC(s):(e.el===void 0&&(e.el=Pt.createElement(ys(e.h,e.h[0]),this.options)),e);if(this._$AH?._$AD===r)this._$AH.p(t);else {let i=new $e(r,this),n=i.u(this.options);i.p(t),this.T(n),this._$AH=i;}}_$AC(s){let t=vs.get(s.strings);return t===void 0&&vs.set(s.strings,t=new Pt(s)),t}k(s){Re(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,e,r=0;for(let i of s)r===t.length?t.push(e=new o(this.O(Dt()),this.O(Dt()),this,this.options)):e=t[r],e._$AI(i),r++;r<t.length&&(this._$AR(e&&e._$AB.nextSibling,r),t.length=r);}_$AR(s=this._$AA.nextSibling,t){for(this._$AP?.(false,true,t);s!==this._$AB;){let e=ds(s).nextSibling;ds(s).remove(),s=e;}}setConnected(s){this._$AM===void 0&&(this._$Cv=s,this._$AP?.(s));}},ht=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(s,t,e,r,i){this.type=1,this._$AH=p,this._$AN=void 0,this.element=s,this.name=t,this._$AM=r,this.options=i,e.length>2||e[0]!==""||e[1]!==""?(this._$AH=Array(e.length-1).fill(new String),this.strings=e):this._$AH=p;}_$AI(s,t=this,e,r){let i=this.strings,n=false;if(i===void 0)s=pt(this,s,t,0),n=!Ht(s)||s!==this._$AH&&s!==Y,n&&(this._$AH=s);else {let l=s,c,d;for(s=i[0],c=0;c<i.length-1;c++)d=pt(this,l[e+c],t,c),d===Y&&(d=this._$AH[c]),n||(n=!Ht(d)||d!==this._$AH[c]),d===p?s=p:s!==p&&(s+=(d??"")+i[c+1]),this._$AH[c]=d;}n&&!r&&this.j(s);}j(s){s===p?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,s??"");}},xe=class extends ht{constructor(){super(...arguments),this.type=3;}j(s){this.element[this.name]=s===p?void 0:s;}},Se=class extends ht{constructor(){super(...arguments),this.type=4;}j(s){this.element.toggleAttribute(this.name,!!s&&s!==p);}},Te=class extends ht{constructor(s,t,e,r,i){super(s,t,e,r,i),this.type=5;}_$AI(s,t=this){if((s=pt(this,s,t,0)??p)===Y)return;let e=this._$AH,r=s===p&&e!==p||s.capture!==e.capture||s.once!==e.once||s.passive!==e.passive,i=s!==p&&(e===p||r);r&&this.element.removeEventListener(this.name,this,e),i&&this.element.addEventListener(this.name,this,s),this._$AH=s;}handleEvent(s){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,s):this._$AH.handleEvent(s);}},we=class{constructor(s,t,e){this.element=s,this.type=6,this._$AN=void 0,this._$AM=t,this.options=e;}get _$AU(){return this._$AM._$AU}_$AI(s){pt(this,s);}};var qr=kt.litHtmlPolyfillSupport;qr?.(Pt,qt),(kt.litHtmlVersions??(kt.litHtmlVersions=[])).push("3.3.2");var _s=(o,s,t)=>{let e=t?.renderBefore??s,r=e._$litPart$;if(r===void 0){let i=t?.renderBefore??null;e._$litPart$=r=new qt(s.insertBefore(Dt(),i),i,void 0,t??{});}return r._$AI(o),r};var Ut=globalThis,E=class extends j{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t;let s=super.createRenderRoot();return (t=this.renderOptions).renderBefore??(t.renderBefore=s.firstChild),s}update(s){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(s),this._$Do=_s(t,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return Y}};E._$litElement$=true,E.finalized=true,Ut.litElementHydrateSupport?.({LitElement:E});var Ur=Ut.litElementPolyfillSupport;Ur?.({LitElement:E});(Ut.litElementVersions??(Ut.litElementVersions=[])).push("4.2.2");var S=o=>(s,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(o,s);}):customElements.define(o,s);};var Fr={attribute:true,type:String,converter:Nt,reflect:false,hasChanged:te},Gr=(o=Fr,s,t)=>{let{kind:e,metadata:r}=t,i=globalThis.litPropertyMetadata.get(r);if(i===void 0&&globalThis.litPropertyMetadata.set(r,i=new Map),e==="setter"&&((o=Object.create(o)).wrapped=true),i.set(t.name,o),e==="accessor"){let{name:n}=t;return {set(l){let c=s.get.call(this);s.set.call(this,l),this.requestUpdate(n,c,o,true,l);},init(l){return l!==void 0&&this.C(n,void 0,o,l),l}}}if(e==="setter"){let{name:n}=t;return function(l){let c=this[n];s.call(this,l),this.requestUpdate(n,c,o,true,l);}}throw Error("Unsupported decorator location: "+e)};function L(o){return (s,t)=>typeof t=="object"?Gr(o,s,t):((e,r,i)=>{let n=r.hasOwnProperty(i);return r.constructor.createProperty(i,e),n?Object.getOwnPropertyDescriptor(r,i):void 0})(o,s,t)}function b(o){return L({...o,state:true,attribute:false})}var Ft=class extends E{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([L()],Ft.prototype,"method",2),Ft=u([S("bk-method-badge")],Ft);var P="/__brakit/api",F="/__brakit",w={flows:`${P}/flows`,requests:`${P}/requests`,events:`${P}/events`,clear:`${P}/clear`,fetches:`${P}/fetches`,errors:`${P}/errors`,logs:`${P}/logs`,queries:`${P}/queries`,metricsLive:`${P}/metrics/live`,insights:`${P}/insights`,tab:`${P}/tab`,activity:`${P}/activity`,graph:`${P}/graph`};var ut="polling",re="static",Br="auth-handshake",Wr="auth-check",Qr="middleware",Gt={[Br]:1,[Wr]:1,[Qr]:1};var ie="fetch";var oe="error_event",ne="query",ae="issues";var Ie={overview:"Overview",actions:"Actions",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",performance:"Performance",security:"Security",graph:"Graph"},Ce={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",graph:"Runtime dependency graph of your application"};var Me=100,mt=300,ft=800,Ne=2e3,Oe=100,ke=50,De=500;var J="__all__",pe={SELECT:"var(--blue)",INSERT:"var(--green)",UPDATE:"var(--amber)",DELETE:"var(--red)",COUNT:"var(--text-muted)"},As={error:"var(--red)",warn:"var(--amber)",info:"var(--blue)",debug:"var(--text-muted)",log:"var(--text-dim)"},qe=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],Bt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},gt=[{max:Me,label:"Fast",color:"var(--green)",bg:"rgba(22,163,74,0.08)",border:"rgba(22,163,74,0.2)"},{max:mt,label:"Good",color:"var(--green)",bg:"rgba(22,163,74,0.06)",border:"rgba(22,163,74,0.15)"},{max:ft,label:"OK",color:"var(--amber)",bg:"rgba(217,119,6,0.06)",border:"rgba(217,119,6,0.15)"},{max:Ne,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)"}],Is="rgba(228,228,231,0.8)",Ue="rgba(113,113,122,0.7)",Cs="10px monospace",Fe="9px monospace";var Ls={top:16,right:16,bottom:28,left:52},Ms={fetch:"var(--blue)",log:"var(--text-muted)",error:"var(--red)",query:"var(--accent)"},Ns={fetch:"FETCH",log:"LOG",error:"ERROR",query:"QUERY"},Os=new Set(["cookie","set-cookie","authorization","proxy-authorization","x-api-key","x-auth-token"]),ks={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"},Ds=new Set(["host","connection","accept-encoding"]),Z={critical:{icon:"\u2717",cls:"critical",sort:0},warning:{icon:"\u26A0",cls:"warning",sort:1},info:{icon:"\u2139",cls:"info",sort:2}};function _(o){return o<1e3?o+"ms":(o/1e3).toFixed(1)+"s"}function et(o){return !o||o===0?"":o<1024?o+"b":(o/1024).toFixed(1)+"kb"}function tt(o){return o?o.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;"):""}function bt(o){return o>=500?"status-pill-5xx":o>=400?"status-pill-4xx":o>=300?"status-pill-3xx":"status-pill-2xx"}function Hs(o){return ks[o]||(o>=500?"Server Error":o>=400?"Client Error":"OK")}function jr(o,s){if(Os.has(o.toLowerCase())){let t=String(s);return t.length<=8?"****":t.slice(0,4)+"..."+t.slice(-4)+" ("+t.length+" chars)"}return String(s)}function Et(o){return !o||Object.keys(o).length===0?'<span style="color:var(--text-muted)">No headers</span>':Object.entries(o).map(([s,t])=>'<span class="json-key">'+tt(s)+"</span>: "+tt(jr(s,t))).join(`
858
- `)}function nt(o){if(!o)return '<span style="color:var(--text-muted)">No body</span>';try{let s=JSON.parse(o);return Yr(JSON.stringify(s,null,2))}catch{return tt(o)}}function Yr(o){return tt(o).replace(/("(?:[^"\\]|\\.)*")(\s*:)?|\b(true|false)\b|\bnull\b|(-?\d+\.?\d*(?:[eE][+-]?\d+)?)/g,(s,t,e,r,i)=>t?e?'<span class="json-key">'+t+"</span>"+e:'<span class="json-str">'+t+"</span>":r?'<span class="json-bool">'+s+"</span>":i?'<span class="json-num">'+s+"</span>":s==="null"?'<span class="json-null">null</span>':s)}var Wt=class extends E{constructor(){super(...arguments);this.code=0;}createRenderRoot(){return this}render(){let t=bt(this.code);return a`<span class="status-pill ${t}">${this.code}</span>`}};u([L({type:Number})],Wt.prototype,"code",2),Wt=u([S("bk-status-pill")],Wt);var Qt=class extends E{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return a`<span class="req-duration">${_(this.ms)}</span>`}};u([L({type:Number})],Qt.prototype,"ms",2),Qt=u([S("bk-duration-label")],Qt);var yt=class extends E{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return a`
906
+ <script>(function(){'use strict';var Or=Object.defineProperty;var Nr=Object.getOwnPropertyDescriptor;var u=(o,r,t,e)=>{for(var s=e>1?void 0:e?Nr(r,t):r,i=o.length-1,n;i>=0;i--)(n=o[i])&&(s=(e?n(r,t,s):n(s))||s);return e&&s&&Or(r,t,s),s};var oe=globalThis,ae=oe.ShadowRoot&&(oe.ShadyCSS===void 0||oe.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,ms=Symbol(),us=new WeakMap,ne=class{constructor(r,t,e){if(this._$cssResult$=true,e!==ms)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=r,this.t=t;}get styleSheet(){let r=this.o,t=this.t;if(ae&&r===void 0){let e=t!==void 0&&t.length===1;e&&(r=us.get(t)),r===void 0&&((this.o=r=new CSSStyleSheet).replaceSync(this.cssText),e&&us.set(t,r));}return r}toString(){return this.cssText}},fs=o=>new ne(typeof o=="string"?o:o+"",void 0,ms);var vs=(o,r)=>{if(ae)o.adoptedStyleSheets=r.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(let t of r){let e=document.createElement("style"),s=oe.litNonce;s!==void 0&&e.setAttribute("nonce",s),e.textContent=t.cssText,o.appendChild(e);}},Ae=ae?o=>o:o=>o instanceof CSSStyleSheet?(r=>{let t="";for(let e of r.cssRules)t+=e.cssText;return fs(t)})(o):o;var{is:Dr,defineProperty:Pr,getOwnPropertyDescriptor:Hr,getOwnPropertyNames:qr,getOwnPropertySymbols:Ur,getPrototypeOf:Fr}=Object,et=globalThis,gs=et.trustedTypes,Gr=gs?gs.emptyScript:"",Br=et.reactiveElementPolyfillSupport,Pt=(o,r)=>o,Ht={toAttribute(o,r){switch(r){case Boolean:o=o?Gr:null;break;case Object:case Array:o=o==null?o:JSON.stringify(o);}return o},fromAttribute(o,r){let t=o;switch(r){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}},le=(o,r)=>!Dr(o,r),bs={attribute:true,type:String,converter:Ht,reflect:false,useDefault:false,hasChanged:le};Symbol.metadata??(Symbol.metadata=Symbol("metadata")),et.litPropertyMetadata??(et.litPropertyMetadata=new WeakMap);var K=class extends HTMLElement{static addInitializer(r){this._$Ei(),(this.l??(this.l=[])).push(r);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(r,t=bs){if(t.state&&(t.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(r)&&((t=Object.create(t)).wrapped=true),this.elementProperties.set(r,t),!t.noAccessor){let e=Symbol(),s=this.getPropertyDescriptor(r,e,t);s!==void 0&&Pr(this.prototype,r,s);}}static getPropertyDescriptor(r,t,e){let{get:s,set:i}=Hr(this.prototype,r)??{get(){return this[t]},set(n){this[t]=n;}};return {get:s,set(n){let a=s?.call(this);i?.call(this,n),this.requestUpdate(r,a,e);},configurable:true,enumerable:true}}static getPropertyOptions(r){return this.elementProperties.get(r)??bs}static _$Ei(){if(this.hasOwnProperty(Pt("elementProperties")))return;let r=Fr(this);r.finalize(),r.l!==void 0&&(this.l=[...r.l]),this.elementProperties=new Map(r.elementProperties);}static finalize(){if(this.hasOwnProperty(Pt("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(Pt("properties"))){let t=this.properties,e=[...qr(t),...Ur(t)];for(let s of e)this.createProperty(s,t[s]);}let r=this[Symbol.metadata];if(r!==null){let t=litPropertyMetadata.get(r);if(t!==void 0)for(let[e,s]of t)this.elementProperties.set(e,s);}this._$Eh=new Map;for(let[t,e]of this.elementProperties){let s=this._$Eu(t,e);s!==void 0&&this._$Eh.set(s,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(r){let t=[];if(Array.isArray(r)){let e=new Set(r.flat(1/0).reverse());for(let s of e)t.unshift(Ae(s));}else r!==void 0&&t.push(Ae(r));return t}static _$Eu(r,t){let e=t.attribute;return e===false?void 0:typeof e=="string"?e:typeof r=="string"?r.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(r=>this.enableUpdating=r),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(r=>r(this));}addController(r){(this._$EO??(this._$EO=new Set)).add(r),this.renderRoot!==void 0&&this.isConnected&&r.hostConnected?.();}removeController(r){this._$EO?.delete(r);}_$E_(){let r=new Map,t=this.constructor.elementProperties;for(let e of t.keys())this.hasOwnProperty(e)&&(r.set(e,this[e]),delete this[e]);r.size>0&&(this._$Ep=r);}createRenderRoot(){let r=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return vs(r,this.constructor.elementStyles),r}connectedCallback(){this.renderRoot??(this.renderRoot=this.createRenderRoot()),this.enableUpdating(true),this._$EO?.forEach(r=>r.hostConnected?.());}enableUpdating(r){}disconnectedCallback(){this._$EO?.forEach(r=>r.hostDisconnected?.());}attributeChangedCallback(r,t,e){this._$AK(r,e);}_$ET(r,t){let e=this.constructor.elementProperties.get(r),s=this.constructor._$Eu(r,e);if(s!==void 0&&e.reflect===true){let i=(e.converter?.toAttribute!==void 0?e.converter:Ht).toAttribute(t,e.type);this._$Em=r,i==null?this.removeAttribute(s):this.setAttribute(s,i),this._$Em=null;}}_$AK(r,t){let e=this.constructor,s=e._$Eh.get(r);if(s!==void 0&&this._$Em!==s){let i=e.getPropertyOptions(s),n=typeof i.converter=="function"?{fromAttribute:i.converter}:i.converter?.fromAttribute!==void 0?i.converter:Ht;this._$Em=s;let a=n.fromAttribute(t,i.type);this[s]=a??this._$Ej?.get(s)??a,this._$Em=null;}}requestUpdate(r,t,e,s=false,i){if(r!==void 0){let n=this.constructor;if(s===false&&(i=this[r]),e??(e=n.getPropertyOptions(r)),!((e.hasChanged??le)(i,t)||e.useDefault&&e.reflect&&i===this._$Ej?.get(r)&&!this.hasAttribute(n._$Eu(r,e))))return;this.C(r,t,e);}this.isUpdatePending===false&&(this._$ES=this._$EP());}C(r,t,{useDefault:e,reflect:s,wrapped:i},n){e&&!(this._$Ej??(this._$Ej=new Map)).has(r)&&(this._$Ej.set(r,n??t??this[r]),i!==true||n!==void 0)||(this._$AL.has(r)||(this.hasUpdated||e||(t=void 0),this._$AL.set(r,t)),s===true&&this._$Em!==r&&(this._$Eq??(this._$Eq=new Set)).add(r));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}let r=this.scheduleUpdate();return r!=null&&await r,!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[s,i]of this._$Ep)this[s]=i;this._$Ep=void 0;}let e=this.constructor.elementProperties;if(e.size>0)for(let[s,i]of e){let{wrapped:n}=i,a=this[s];n!==true||this._$AL.has(s)||a===void 0||this.C(s,void 0,i,a);}}let r=false,t=this._$AL;try{r=this.shouldUpdate(t),r?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM();}catch(e){throw r=false,this._$EM(),e}r&&this._$AE(t);}willUpdate(r){}_$AE(r){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(r)),this.updated(r);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(r){return true}update(r){this._$Eq&&(this._$Eq=this._$Eq.forEach(t=>this._$ET(t,this[t]))),this._$EM();}updated(r){}firstUpdated(r){}};K.elementStyles=[],K.shadowRootOptions={mode:"open"},K[Pt("elementProperties")]=new Map,K[Pt("finalized")]=new Map,Br?.({ReactiveElement:K}),(et.reactiveElementVersions??(et.reactiveElementVersions=[])).push("2.1.2");var Ut=globalThis,Es=o=>o,ce=Ut.trustedTypes,ys=ce?ce.createPolicy("lit-html",{createHTML:o=>o}):void 0,ws="$lit$",st=`lit$${Math.random().toFixed(9).slice(2)}$`,Rs="?"+st,Wr=`<${Rs}>`,ct=document,Ft=()=>ct.createComment(""),Gt=o=>o===null||typeof o!="object"&&typeof o!="function",Ne=Array.isArray,jr=o=>Ne(o)||typeof o?.[Symbol.iterator]=="function",Ce=`[
907
+ \f\r]`,qt=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,$s=/-->/g,_s=/>/g,at=RegExp(`>|${Ce}(?:([^\\s"'>=/]+)(${Ce}*=${Ce}*(?:[^
908
+ \f\r"'\`<>=]|("|')|))|$)`,"g"),xs=/'/g,Ss=/"/g,As=/^(?:script|style|textarea|title)$/i,De=o=>(r,...t)=>({_$litType$:o,strings:r,values:t}),l=De(1),O=De(2),z=Symbol.for("lit-noChange"),d=Symbol.for("lit-nothing"),Ts=new WeakMap,lt=ct.createTreeWalker(ct,129);function Cs(o,r){if(!Ne(o)||!o.hasOwnProperty("raw"))throw Error("invalid template strings array");return ys!==void 0?ys.createHTML(r):r}var Qr=(o,r)=>{let t=o.length-1,e=[],s,i=r===2?"<svg>":r===3?"<math>":"",n=qt;for(let a=0;a<t;a++){let c=o[a],p,h,m=-1,f=0;for(;f<c.length&&(n.lastIndex=f,h=n.exec(c),h!==null);)f=n.lastIndex,n===qt?h[1]==="!--"?n=$s:h[1]!==void 0?n=_s:h[2]!==void 0?(As.test(h[2])&&(s=RegExp("</"+h[2],"g")),n=at):h[3]!==void 0&&(n=at):n===at?h[0]===">"?(n=s??qt,m=-1):h[1]===void 0?m=-2:(m=n.lastIndex-h[2].length,p=h[1],n=h[3]===void 0?at:h[3]==='"'?Ss:xs):n===Ss||n===xs?n=at:n===$s||n===_s?n=qt:(n=at,s=void 0);let S=n===at&&o[a+1].startsWith("/>")?" ":"";i+=n===qt?c+Wr:m>=0?(e.push(p),c.slice(0,m)+ws+c.slice(m)+st+S):c+st+(m===-2?a:S);}return [Cs(o,i+(o[t]||"<?>")+(r===2?"</svg>":r===3?"</math>":"")),e]},Bt=class o{constructor({strings:r,_$litType$:t},e){let s;this.parts=[];let i=0,n=0,a=r.length-1,c=this.parts,[p,h]=Qr(r,t);if(this.el=o.createElement(p,e),lt.currentNode=this.el.content,t===2||t===3){let m=this.el.content.firstChild;m.replaceWith(...m.childNodes);}for(;(s=lt.nextNode())!==null&&c.length<a;){if(s.nodeType===1){if(s.hasAttributes())for(let m of s.getAttributeNames())if(m.endsWith(ws)){let f=h[n++],S=s.getAttribute(m).split(st),R=/([.?@])?(.*)/.exec(f);c.push({type:1,index:i,name:R[2],strings:S,ctor:R[1]==="."?Le:R[1]==="?"?Me:R[1]==="@"?ke:gt}),s.removeAttribute(m);}else m.startsWith(st)&&(c.push({type:6,index:i}),s.removeAttribute(m));if(As.test(s.tagName)){let m=s.textContent.split(st),f=m.length-1;if(f>0){s.textContent=ce?ce.emptyScript:"";for(let S=0;S<f;S++)s.append(m[S],Ft()),lt.nextNode(),c.push({type:2,index:++i});s.append(m[f],Ft());}}}else if(s.nodeType===8)if(s.data===Rs)c.push({type:2,index:i});else {let m=-1;for(;(m=s.data.indexOf(st,m+1))!==-1;)c.push({type:7,index:i}),m+=st.length-1;}i++;}}static createElement(r,t){let e=ct.createElement("template");return e.innerHTML=r,e}};function vt(o,r,t=o,e){if(r===z)return r;let s=e!==void 0?t._$Co?.[e]:t._$Cl,i=Gt(r)?void 0:r._$litDirective$;return s?.constructor!==i&&(s?._$AO?.(false),i===void 0?s=void 0:(s=new i(o),s._$AT(o,t,e)),e!==void 0?(t._$Co??(t._$Co=[]))[e]=s:t._$Cl=s),s!==void 0&&(r=vt(o,s._$AS(o,r.values),s,e)),r}var Ie=class{constructor(r,t){this._$AV=[],this._$AN=void 0,this._$AD=r,this._$AM=t;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(r){let{el:{content:t},parts:e}=this._$AD,s=(r?.creationScope??ct).importNode(t,true);lt.currentNode=s;let i=lt.nextNode(),n=0,a=0,c=e[0];for(;c!==void 0;){if(n===c.index){let p;c.type===2?p=new Wt(i,i.nextSibling,this,r):c.type===1?p=new c.ctor(i,c.name,c.strings,this,r):c.type===6&&(p=new Oe(i,this,r)),this._$AV.push(p),c=e[++a];}n!==c?.index&&(i=lt.nextNode(),n++);}return lt.currentNode=ct,s}p(r){let t=0;for(let e of this._$AV)e!==void 0&&(e.strings!==void 0?(e._$AI(r,e,t),t+=e.strings.length-2):e._$AI(r[t])),t++;}},Wt=class o{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(r,t,e,s){this.type=2,this._$AH=d,this._$AN=void 0,this._$AA=r,this._$AB=t,this._$AM=e,this.options=s,this._$Cv=s?.isConnected??true;}get parentNode(){let r=this._$AA.parentNode,t=this._$AM;return t!==void 0&&r?.nodeType===11&&(r=t.parentNode),r}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(r,t=this){r=vt(this,r,t),Gt(r)?r===d||r==null||r===""?(this._$AH!==d&&this._$AR(),this._$AH=d):r!==this._$AH&&r!==z&&this._(r):r._$litType$!==void 0?this.$(r):r.nodeType!==void 0?this.T(r):jr(r)?this.k(r):this._(r);}O(r){return this._$AA.parentNode.insertBefore(r,this._$AB)}T(r){this._$AH!==r&&(this._$AR(),this._$AH=this.O(r));}_(r){this._$AH!==d&&Gt(this._$AH)?this._$AA.nextSibling.data=r:this.T(ct.createTextNode(r)),this._$AH=r;}$(r){let{values:t,_$litType$:e}=r,s=typeof e=="number"?this._$AC(r):(e.el===void 0&&(e.el=Bt.createElement(Cs(e.h,e.h[0]),this.options)),e);if(this._$AH?._$AD===s)this._$AH.p(t);else {let i=new Ie(s,this),n=i.u(this.options);i.p(t),this.T(n),this._$AH=i;}}_$AC(r){let t=Ts.get(r.strings);return t===void 0&&Ts.set(r.strings,t=new Bt(r)),t}k(r){Ne(this._$AH)||(this._$AH=[],this._$AR());let t=this._$AH,e,s=0;for(let i of r)s===t.length?t.push(e=new o(this.O(Ft()),this.O(Ft()),this,this.options)):e=t[s],e._$AI(i),s++;s<t.length&&(this._$AR(e&&e._$AB.nextSibling,s),t.length=s);}_$AR(r=this._$AA.nextSibling,t){for(this._$AP?.(false,true,t);r!==this._$AB;){let e=Es(r).nextSibling;Es(r).remove(),r=e;}}setConnected(r){this._$AM===void 0&&(this._$Cv=r,this._$AP?.(r));}},gt=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(r,t,e,s,i){this.type=1,this._$AH=d,this._$AN=void 0,this.element=r,this.name=t,this._$AM=s,this.options=i,e.length>2||e[0]!==""||e[1]!==""?(this._$AH=Array(e.length-1).fill(new String),this.strings=e):this._$AH=d;}_$AI(r,t=this,e,s){let i=this.strings,n=false;if(i===void 0)r=vt(this,r,t,0),n=!Gt(r)||r!==this._$AH&&r!==z,n&&(this._$AH=r);else {let a=r,c,p;for(r=i[0],c=0;c<i.length-1;c++)p=vt(this,a[e+c],t,c),p===z&&(p=this._$AH[c]),n||(n=!Gt(p)||p!==this._$AH[c]),p===d?r=d:r!==d&&(r+=(p??"")+i[c+1]),this._$AH[c]=p;}n&&!s&&this.j(r);}j(r){r===d?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,r??"");}},Le=class extends gt{constructor(){super(...arguments),this.type=3;}j(r){this.element[this.name]=r===d?void 0:r;}},Me=class extends gt{constructor(){super(...arguments),this.type=4;}j(r){this.element.toggleAttribute(this.name,!!r&&r!==d);}},ke=class extends gt{constructor(r,t,e,s,i){super(r,t,e,s,i),this.type=5;}_$AI(r,t=this){if((r=vt(this,r,t,0)??d)===z)return;let e=this._$AH,s=r===d&&e!==d||r.capture!==e.capture||r.once!==e.once||r.passive!==e.passive,i=r!==d&&(e===d||s);s&&this.element.removeEventListener(this.name,this,e),i&&this.element.addEventListener(this.name,this,r),this._$AH=r;}handleEvent(r){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,r):this._$AH.handleEvent(r);}},Oe=class{constructor(r,t,e){this.element=r,this.type=6,this._$AN=void 0,this._$AM=t,this.options=e;}get _$AU(){return this._$AM._$AU}_$AI(r){vt(this,r);}};var Yr=Ut.litHtmlPolyfillSupport;Yr?.(Bt,Wt),(Ut.litHtmlVersions??(Ut.litHtmlVersions=[])).push("3.3.2");var Is=(o,r,t)=>{let e=t?.renderBefore??r,s=e._$litPart$;if(s===void 0){let i=t?.renderBefore??null;e._$litPart$=s=new Wt(r.insertBefore(Ft(),i),i,void 0,t??{});}return s._$AI(o),s};var jt=globalThis,E=class extends K{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){var t;let r=super.createRenderRoot();return (t=this.renderOptions).renderBefore??(t.renderBefore=r.firstChild),r}update(r){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(r),this._$Do=Is(t,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(true);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(false);}render(){return z}};E._$litElement$=true,E.finalized=true,jt.litElementHydrateSupport?.({LitElement:E});var Xr=jt.litElementPolyfillSupport;Xr?.({LitElement:E});(jt.litElementVersions??(jt.litElementVersions=[])).push("4.2.2");var _=o=>(r,t)=>{t!==void 0?t.addInitializer(()=>{customElements.define(o,r);}):customElements.define(o,r);};var Vr={attribute:true,type:String,converter:Ht,reflect:false,hasChanged:le},Kr=(o=Vr,r,t)=>{let{kind:e,metadata:s}=t,i=globalThis.litPropertyMetadata.get(s);if(i===void 0&&globalThis.litPropertyMetadata.set(s,i=new Map),e==="setter"&&((o=Object.create(o)).wrapped=true),i.set(t.name,o),e==="accessor"){let{name:n}=t;return {set(a){let c=r.get.call(this);r.set.call(this,a),this.requestUpdate(n,c,o,true,a);},init(a){return a!==void 0&&this.C(n,void 0,o,a),a}}}if(e==="setter"){let{name:n}=t;return function(a){let c=this[n];r.call(this,a),this.requestUpdate(n,c,o,true,a);}}throw Error("Unsupported decorator location: "+e)};function L(o){return (r,t)=>typeof t=="object"?Kr(o,r,t):((e,s,i)=>{let n=s.hasOwnProperty(i);return s.constructor.createProperty(i,e),n?Object.getOwnPropertyDescriptor(s,i):void 0})(o,r,t)}function b(o){return L({...o,state:true,attribute:false})}var Qt=class extends E{constructor(){super(...arguments);this.method="";}createRenderRoot(){return this}render(){let t=this.method.toUpperCase();return l`<span class="method-badge method-badge-${t}">${t}</span>`}};u([L()],Qt.prototype,"method",2),Qt=u([_("bk-method-badge")],Qt);var q="/__brakit/api",U="/__brakit",T={flows:`${q}/flows`,requests:`${q}/requests`,events:`${q}/events`,clear:`${q}/clear`,fetches:`${q}/fetches`,errors:`${q}/errors`,logs:`${q}/logs`,queries:`${q}/queries`,metricsLive:`${q}/metrics/live`,insights:`${q}/insights`,tab:`${q}/tab`,activity:`${q}/activity`,graph:`${q}/graph`};var bt="polling",pe="static",zr="auth-handshake",Jr="auth-check",Zr="middleware",Yt={[zr]:1,[Jr]:1,[Zr]:1};var he="fetch";var ue="error_event",me="query",fe="issues";var Pe={overview:"Overview",actions:"Actions",insights:"Insights",performance:"Performance",graph:"Graph",explorer:"Explorer",requests:"Requests",fetches:"Server Fetches",queries:"Queries",errors:"Errors",logs:"Logs",security:"Security"},He={overview:"Live summary of your application",actions:"User actions captured as sequences of HTTP requests",insights:"Security findings, error patterns, and issue tracking",performance:"Endpoint health and response time trends",graph:"Runtime dependency graph of your application",explorer:"Browse raw requests, fetches, queries, logs, and errors",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",security:"Security findings and recommendations"},ve=[{key:"requests",label:"Requests"},{key:"fetches",label:"Fetches"},{key:"queries",label:"Queries"},{key:"logs",label:"Logs"},{key:"errors",label:"Errors"}];var Ls=new Set(["exposed-secret","token-in-url","stack-trace-leak","error-info-leak","insecure-cookie","sensitive-logs","cors-credentials","response-pii-leak"]),Ms=new Set(["slow-endpoint","n1","high-query-count"]);function Xt(o){let r=o.issue.rule;return Ls.has(r)?"security":Ms.has(r)?"performance":"reliability"}var N={CLEAR_CONFIRM:"This will clear all data including performance metrics history. Continue?",CLEARED_TOAST:"Cleared",EMPTY_TITLE:"Waiting for requests...",EMPTY_SUBTITLE_OVERVIEW:"Start using your app to see your dashboard here",ALL_CLEAR:"All clear",ALL_CLEAR_DETAIL:"No issues detected",NO_ACTIONS:"No actions captured yet",NO_REQUEST_DATA:"No request data yet",ALL_FAST:"All fast",NO_SLOW_ENDPOINTS:"No slow endpoints detected",ZERO_ERRORS:"0 errors",ALL_REQUESTS_OK:"All requests successful",BUILD_GRAPH:"Navigate your app to build the graph",REVIEW_RECOMMENDED:"review recommended"};var Fe=100,yt=300,$t=800,Ge=2e3,Be=100,We=50,je=500;var rt="__all__",ti={SELECT:"var(--blue)",INSERT:"var(--green)",UPDATE:"var(--amber)",DELETE:"var(--red)",OTHER:"var(--text-muted)"},be=ti,ei={error:"var(--red)",warn:"var(--amber)",info:"var(--blue)",debug:"var(--text-muted)",log:"var(--text-dim)"},qs=ei,Xe=["#2563eb","#7c3aed","#16a34a","#d97706","#dc2626","#0891b2","#ea580c","#c026d3","#059669","#db2777"],Vt={green:"#4ade80",amber:"#fbbf24",red:"#f87171"},xt=[{max:Fe,label:"Fast",color:"var(--green)",bg:"var(--green-bg)",border:"var(--green-border)"},{max:yt,label:"Good",color:"var(--green)",bg:"var(--green-bg-subtle)",border:"var(--green-border-subtle)"},{max:$t,label:"OK",color:"var(--amber)",bg:"var(--amber-bg)",border:"var(--amber-border)"},{max:Ge,label:"Slow",color:"var(--red)",bg:"var(--red-bg)",border:"var(--red-border)"},{max:1/0,label:"Critical",color:"var(--red)",bg:"var(--red-bg)",border:"var(--red-border)"}],Us="rgba(228,228,231,0.8)",Ve="rgba(113,113,122,0.7)",Fs="10px monospace",Ke="9px monospace";var Gs={top:16,right:16,bottom:28,left:52},Bs={fetch:"var(--blue)",log:"var(--text-muted)",error:"var(--red)",query:"var(--accent)"},Ws={fetch:"FETCH",log:"LOG",error:"ERROR",query:"QUERY"},js=new Set(["cookie","set-cookie","authorization","proxy-authorization","x-api-key","x-auth-token"]),Qs={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"},Ys=new Set(["host","connection","accept-encoding"]),Y={critical:{icon:"\u2717",cls:"critical",sort:0},warning:{icon:"\u26A0",cls:"warning",sort:1},info:{icon:"\u2139",cls:"info",sort:2}};function y(o){return o<1e3?o+"ms":(o/1e3).toFixed(1)+"s"}function ot(o){return !o||o===0?"":o<1024?o+"b":(o/1024).toFixed(1)+"kb"}function it(o){return o?o.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;"):""}function St(o){return o>=500?"status-pill-5xx":o>=400?"status-pill-4xx":o>=300?"status-pill-3xx":"status-pill-2xx"}function Xs(o){return Qs[o]||(o>=500?"Server Error":o>=400?"Client Error":"OK")}function si(o,r){if(js.has(o.toLowerCase())){let t=String(r);return t.length<=8?"****":t.slice(0,4)+"..."+t.slice(-4)+" ("+t.length+" chars)"}return String(r)}function Tt(o){return !o||Object.keys(o).length===0?'<span style="color:var(--text-muted)">No headers</span>':Object.entries(o).map(([r,t])=>'<span class="json-key">'+it(r)+"</span>: "+it(si(r,t))).join(`
909
+ `)}function dt(o){if(!o)return '<span style="color:var(--text-muted)">No body</span>';try{let r=JSON.parse(o);return ri(JSON.stringify(r,null,2))}catch{return it(o)}}function ri(o){return it(o).replace(/("(?:[^"\\]|\\.)*")(\s*:)?|\b(true|false)\b|\bnull\b|(-?\d+\.?\d*(?:[eE][+-]?\d+)?)/g,(r,t,e,s,i)=>t?e?'<span class="json-key">'+t+"</span>"+e:'<span class="json-str">'+t+"</span>":s?'<span class="json-bool">'+r+"</span>":i?'<span class="json-num">'+r+"</span>":r==="null"?'<span class="json-null">null</span>':r)}var Kt=class extends E{constructor(){super(...arguments);this.code=0;}createRenderRoot(){return this}render(){let t=St(this.code);return l`<span class="status-pill ${t}">${this.code}</span>`}};u([L({type:Number})],Kt.prototype,"code",2),Kt=u([_("bk-status-pill")],Kt);var zt=class extends E{constructor(){super(...arguments);this.ms=0;}createRenderRoot(){return this}render(){return l`<span class="req-duration">${y(this.ms)}</span>`}};u([L({type:Number})],zt.prototype,"ms",2),zt=u([_("bk-duration-label")],zt);var wt=class extends E{constructor(){super(...arguments);this.title="";this.subtitle="";}createRenderRoot(){return this}render(){return l`
859
910
  <div class="empty">
860
911
  <span class="empty-title">${this.title}</span>
861
912
  <span class="empty-sub">${this.subtitle}</span>
862
913
  </div>
863
- `}};u([L()],yt.prototype,"title",2),u([L()],yt.prototype,"subtitle",2),yt=u([S("bk-empty-state")],yt);var D=class extends E{constructor(){super(...arguments);this.message="";this.visible=false;}createRenderRoot(){return this}static show(t){let e=document.querySelector("bk-toast");e&&e.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([b()],D.prototype,"message",2),u([b()],D.prototype,"visible",2),D=u([S("bk-toast")],D);var at=class extends E{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),D.show(this.toastMessage);}catch{}}render(){return a`<button class="query-detail-copy" @click=${this.copy}>${this.label}</button>`}};u([L()],at.prototype,"text",2),u([L()],at.prototype,"label",2),u([L({attribute:"toast-message"})],at.prototype,"toastMessage",2),at=u([S("bk-copy-button")],at);var lt=class extends E{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return a`
914
+ `}};u([L()],wt.prototype,"title",2),u([L()],wt.prototype,"subtitle",2),wt=u([_("bk-empty-state")],wt);var D=class extends E{constructor(){super(...arguments);this.message="";this.visible=false;}createRenderRoot(){return this}static show(t){let e=document.querySelector("bk-toast");e&&e.showMessage(t);}showMessage(t){this.hideTimer&&clearTimeout(this.hideTimer),this.message=t,this.visible=true,this.hideTimer=setTimeout(()=>{this.visible=false;},2e3);}render(){return l`<div class="toast ${this.visible?"show":""}">${this.message}</div>`}};u([b()],D.prototype,"message",2),u([b()],D.prototype,"visible",2),D=u([_("bk-toast")],D);var pt=class extends E{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),D.show(this.toastMessage);}catch{}}render(){return l`<button class="query-detail-copy" @click=${this.copy}>${this.label}</button>`}};u([L()],pt.prototype,"text",2),u([L()],pt.prototype,"label",2),u([L({attribute:"toast-message"})],pt.prototype,"toastMessage",2),pt=u([_("bk-copy-button")],pt);var ht=class extends E{constructor(){super(...arguments);this.value="";this.label="";this.color="";}createRenderRoot(){return this}render(){return l`
864
915
  <div class="fetch-stat">
865
916
  <span class="fetch-stat-value" style="color:${this.color}">${this.value}</span>
866
917
  <span class="fetch-stat-label">${this.label}</span>
867
918
  </div>
868
- `}};u([L()],lt.prototype,"value",2),u([L()],lt.prototype,"label",2),u([L()],lt.prototype,"color",2),lt=u([S("bk-stat-card")],lt);var st=class extends Event{constructor(s,t,e,r){super("context-request",{bubbles:true,composed:true}),this.context=s,this.contextTarget=t,this.callback=e,this.subscribe=r??false;}};var _t=class{constructor(s,t,e,r){if(this.subscribe=false,this.provided=false,this.value=void 0,this.t=(i,n)=>{this.unsubscribe&&(this.unsubscribe!==n&&(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,n)),this.unsubscribe=n;},this.host=s,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=e,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 st(this.context,this.host,this.t,this.subscribe));}};var he=class{get value(){return this.o}set value(s){this.setValue(s);}setValue(s,t=false){let e=t||!Object.is(s,this.o);this.o=s,e&&this.updateObservers();}constructor(s){this.subscriptions=new Map,this.updateObservers=()=>{for(let[t,{disposer:e}]of this.subscriptions)t(this.o,e);},s!==void 0&&(this.value=s);}addCallback(s,t,e){if(!e)return void s(this.value);this.subscriptions.has(s)||this.subscriptions.set(s,{disposer:()=>{this.subscriptions.delete(s);},consumerHost:t});let{disposer:r}=this.subscriptions.get(s);s(this.value,r);}clearCallbacks(){this.subscriptions.clear();}};var Ge=class extends Event{constructor(s,t){super("context-provider",{bubbles:true,composed:true}),this.context=s,this.contextTarget=t;}},$t=class extends he{constructor(s,t,e){super(t.context!==void 0?t.initialValue:e),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[n,{consumerHost:l}]of this.subscriptions)i.has(n)||(i.add(n),l.dispatchEvent(new st(this.context,l,n,true)));r.stopPropagation();},this.host=s,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 Be({context:o}){return (s,t)=>{let e=new WeakMap;if(typeof t=="object")return {get(){return s.get.call(this)},set(r){return e.get(this).setValue(r),s.set.call(this,r)},init(r){return e.set(this,new $t(this,{context:o,initialValue:r})),r}};{s.constructor.addInitializer((n=>{e.set(n,new $t(n,{context:o}));}));let r=Object.getOwnPropertyDescriptor(s,t),i;if(r===void 0){let n=new WeakMap;i={get(){return n.get(this)},set(l){e.get(this).setValue(l),n.set(this,l);},configurable:true,enumerable:true};}else {let n=r.set;i={...r,set(l){e.get(this).setValue(l),n?.call(this,l);}};}return void Object.defineProperty(s,t,i)}}}function I({context:o,subscribe:s}){return (t,e)=>{typeof e=="object"?e.addInitializer((function(){new _t(this,{context:o,callback:r=>{t.set.call(this,r);},subscribe:s});})):t.constructor.addInitializer((r=>{new _t(r,{context:o,callback:i=>{r[e]=i;},subscribe:s});}));}}var A="dashboard-store",ue=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 e=[t,...this._state.requests.slice(0,999)];this._state={...this._state,requests:e},this.notify("requests");}prependFetch(t){let e=[t,...this._state.fetches.slice(0,999)];this._state={...this._state,fetches:e},this.notify("fetches");}prependError(t){let e=[t,...this._state.errors.slice(0,999)];this._state={...this._state,errors:e},this.notify("errors");}prependLog(t){let e=[t,...this._state.logs.slice(0,999)];this._state={...this._state,logs:e},this.notify("logs");}prependQuery(t){let e=[t,...this._state.queries.slice(0,999)];this._state={...this._state,queries:e},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 xt=class extends E{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,e){let r=new Date(t.timestamp).toLocaleTimeString(),i=this.expandedIdx===e;return a`
919
+ `}};u([L()],ht.prototype,"value",2),u([L()],ht.prototype,"label",2),u([L()],ht.prototype,"color",2),ht=u([_("bk-stat-card")],ht);var nt=class extends Event{constructor(r,t,e,s){super("context-request",{bubbles:true,composed:true}),this.context=r,this.contextTarget=t,this.callback=e,this.subscribe=s??false;}};var Rt=class{constructor(r,t,e,s){if(this.subscribe=false,this.provided=false,this.value=void 0,this.t=(i,n)=>{this.unsubscribe&&(this.unsubscribe!==n&&(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,n)),this.unsubscribe=n;},this.host=r,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=e,this.subscribe=s??false;this.host.addController(this);}hostConnected(){this.dispatchRequest();}hostDisconnected(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=void 0);}dispatchRequest(){this.host.dispatchEvent(new nt(this.context,this.host,this.t,this.subscribe));}};var Ee=class{get value(){return this.o}set value(r){this.setValue(r);}setValue(r,t=false){let e=t||!Object.is(r,this.o);this.o=r,e&&this.updateObservers();}constructor(r){this.subscriptions=new Map,this.updateObservers=()=>{for(let[t,{disposer:e}]of this.subscriptions)t(this.o,e);},r!==void 0&&(this.value=r);}addCallback(r,t,e){if(!e)return void r(this.value);this.subscriptions.has(r)||this.subscriptions.set(r,{disposer:()=>{this.subscriptions.delete(r);},consumerHost:t});let{disposer:s}=this.subscriptions.get(r);r(this.value,s);}clearCallbacks(){this.subscriptions.clear();}};var ze=class extends Event{constructor(r,t){super("context-provider",{bubbles:true,composed:true}),this.context=r,this.contextTarget=t;}},At=class extends Ee{constructor(r,t,e){super(t.context!==void 0?t.initialValue:e),this.onContextRequest=s=>{if(s.context!==this.context)return;let i=s.contextTarget??s.composedPath()[0];i!==this.host&&(s.stopPropagation(),this.addCallback(s.callback,i,s.subscribe));},this.onProviderRequest=s=>{if(s.context!==this.context||(s.contextTarget??s.composedPath()[0])===this.host)return;let i=new Set;for(let[n,{consumerHost:a}]of this.subscriptions)i.has(n)||(i.add(n),a.dispatchEvent(new nt(this.context,a,n,true)));s.stopPropagation();},this.host=r,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 ze(this.context,this.host));}};function Je({context:o}){return (r,t)=>{let e=new WeakMap;if(typeof t=="object")return {get(){return r.get.call(this)},set(s){return e.get(this).setValue(s),r.set.call(this,s)},init(s){return e.set(this,new At(this,{context:o,initialValue:s})),s}};{r.constructor.addInitializer((n=>{e.set(n,new At(n,{context:o}));}));let s=Object.getOwnPropertyDescriptor(r,t),i;if(s===void 0){let n=new WeakMap;i={get(){return n.get(this)},set(a){e.get(this).setValue(a),n.set(this,a);},configurable:true,enumerable:true};}else {let n=s.set;i={...s,set(a){e.get(this).setValue(a),n?.call(this,a);}};}return void Object.defineProperty(r,t,i)}}}function C({context:o,subscribe:r}){return (t,e)=>{typeof e=="object"?e.addInitializer((function(){new Rt(this,{context:o,callback:s=>{t.set.call(this,s);},subscribe:r});})):t.constructor.addInitializer((s=>{new Rt(s,{context:o,callback:i=>{s[e]=i;},subscribe:r});}));}}var A="dashboard-store",ye=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}setState(t,e){this._state={...this._state,[t]:e},this.notify(t);}setFlows(t){this.setState("flows",t);}setRequests(t){this.setState("requests",t);}setFetches(t){this.setState("fetches",t);}setErrors(t){this.setState("errors",t);}setLogs(t){this.setState("logs",t);}setQueries(t){this.setState("queries",t);}setIssues(t){this.setState("issues",t);}setMetrics(t){this.setState("metrics",t);}prependRequest(t){let e=[t,...this._state.requests.slice(0,999)];this._state={...this._state,requests:e},this.notify("requests");}prependFetch(t){let e=[t,...this._state.fetches.slice(0,999)];this._state={...this._state,fetches:e},this.notify("fetches");}prependError(t){let e=[t,...this._state.errors.slice(0,999)];this._state={...this._state,errors:e},this.notify("errors");}prependLog(t){let e=[t,...this._state.logs.slice(0,999)];this._state={...this._state,logs:e},this.notify("logs");}prependQuery(t){let e=[t,...this._state.queries.slice(0,999)];this._state={...this._state,queries:e},this.notify("queries");}setActiveView(t){this.setState("activeView",t);}setViewMode(t){this.setState("viewMode",t);}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 E{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,e){let s=new Date(t.timestamp).toLocaleTimeString(),i=this.expandedIdx===e;return l`
869
920
  <div
870
921
  class="req-row tel-clickable ${i?"expanded":""}"
871
922
  @click=${()=>this.toggleError(e)}
872
923
  >
873
924
  <span class="tel-error-name" title=${t.name}>${t.name}</span>
874
925
  <span class="tel-message" title=${t.message}>${t.message}</span>
875
- <span class="tel-timestamp">${r}</span>
926
+ <span class="tel-timestamp">${s}</span>
876
927
  </div>
877
- ${i&&t.stack?a`<div class="error-stack">${t.stack}</div>`:p}
878
- `}render(){let t=this.store.state.errors;return t.length===0?a`<bk-empty-state
928
+ ${i&&t.stack?l`<div class="error-stack">${t.stack}</div>`:d}
929
+ `}render(){let t=this.store.state.errors;return t.length===0?l`<bk-empty-state
879
930
  title="No errors"
880
931
  subtitle="No errors have been captured yet"
881
- ></bk-empty-state>`:a`
932
+ ></bk-empty-state>`:l`
882
933
  <div class="col-header">
883
934
  <span style="width:180px">Type</span>
884
935
  <span style="flex:1">Message</span>
885
936
  <span style="width:130px;text-align:right">Time</span>
886
937
  </div>
887
938
  <div id="error-list">
888
- ${t.map((e,r)=>this.renderErrorRow(e,r))}
939
+ ${t.map((e,s)=>this.renderErrorRow(e,s))}
889
940
  </div>
890
- `}};u([I({context:A})],xt.prototype,"store",2),u([b()],xt.prototype,"expandedIdx",2),xt=u([S("bk-errors-view")],xt);var jt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}renderAnalysis(s){if(s.length===0)return p;let t={error:0,warn:0,info:0,debug:0,log:0};for(let e of s)t[e.level]!==void 0&&t[e.level]++;return a`
941
+ `}};u([C({context:A})],Ct.prototype,"store",2),u([b()],Ct.prototype,"expandedIdx",2),Ct=u([_("bk-errors-view")],Ct);var Jt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}renderAnalysis(r){if(r.length===0)return d;let t={error:0,warn:0,info:0,debug:0,log:0};for(let e of r)t[e.level]!==void 0&&t[e.level]++;return l`
891
942
  <div id="log-analysis">
892
943
  <div class="fetch-summary">
893
- <bk-stat-card value=${String(s.length)} label="Total Logs"></bk-stat-card>
894
- ${t.error>0?a`<bk-stat-card value=${String(t.error)} label="Errors" color="var(--red)"></bk-stat-card>`:p}
895
- ${t.warn>0?a`<bk-stat-card value=${String(t.warn)} label="Warnings" color="var(--amber)"></bk-stat-card>`:p}
944
+ <bk-stat-card value=${String(r.length)} label="Total Logs"></bk-stat-card>
945
+ ${t.error>0?l`<bk-stat-card value=${String(t.error)} label="Errors" color="var(--red)"></bk-stat-card>`:d}
946
+ ${t.warn>0?l`<bk-stat-card value=${String(t.warn)} label="Warnings" color="var(--amber)"></bk-stat-card>`:d}
896
947
  <bk-stat-card value=${String(t.info)} label="Info"></bk-stat-card>
897
- ${t.debug>0?a`<bk-stat-card value=${String(t.debug)} label="Debug"></bk-stat-card>`:p}
898
- ${t.log>0?a`<bk-stat-card value=${String(t.log)} label="Log"></bk-stat-card>`:p}
948
+ ${t.debug>0?l`<bk-stat-card value=${String(t.debug)} label="Debug"></bk-stat-card>`:d}
949
+ ${t.log>0?l`<bk-stat-card value=${String(t.log)} label="Log"></bk-stat-card>`:d}
899
950
  </div>
900
951
  </div>
901
- `}renderLogRow(s){let t=new Date(s.timestamp).toLocaleTimeString();return a`
952
+ `}renderLogRow(r){let t=new Date(r.timestamp).toLocaleTimeString();return l`
902
953
  <div class="req-row">
903
- <span class="tel-level tel-level-${s.level}">${s.level.toUpperCase()}</span>
904
- <span class="tel-message tel-mono" title=${s.message}>${s.message}</span>
954
+ <span class="tel-level tel-level-${r.level}">${r.level.toUpperCase()}</span>
955
+ <span class="tel-message tel-mono" title=${r.message}>${r.message}</span>
905
956
  <span class="tel-timestamp">${t}</span>
906
957
  </div>
907
- `}render(){let s=this.store.state.logs;return s.length===0?a`<bk-empty-state
958
+ `}render(){let r=this.store.state.logs;return r.length===0?l`<bk-empty-state
908
959
  title="No logs"
909
960
  subtitle="No console output has been captured yet"
910
- ></bk-empty-state>`:a`
911
- ${this.renderAnalysis(s)}
961
+ ></bk-empty-state>`:l`
962
+ ${this.renderAnalysis(r)}
912
963
  <div class="col-header">
913
964
  <span style="width:52px">Level</span>
914
965
  <span style="flex:1">Message</span>
915
966
  <span style="width:130px;text-align:right">Time</span>
916
967
  </div>
917
968
  <div id="log-list">
918
- ${s.map(t=>this.renderLogRow(t))}
969
+ ${r.map(t=>this.renderLogRow(t))}
919
970
  </div>
920
- `}};u([I({context:A})],jt.prototype,"store",2),jt=u([S("bk-logs-view")],jt);var Ps={CHILD:2},qs=o=>(...s)=>({_$litDirective$:o,values:s}),me=class{constructor(s){}get _$AU(){return this._$AM._$AU}_$AT(s,t,e){this._$Ct=s,this._$AM=t,this._$Ci=e;}_$AS(s,t){return this.update(s,t)}update(s,t){return this.render(...t)}};var Yt=class extends me{constructor(s){if(super(s),this.it=p,s.type!==Ps.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(s){if(s===p||s==null)return this._t=void 0,this.it=s;if(s===Y)return s;if(typeof s!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(s===this.it)return this._t;this.it=s;let t=[s];return t.raw=t,this._t={_$litType$:this.constructor.resultType,strings:t,values:[]}}};Yt.directiveName="unsafeHTML",Yt.resultType=1;var U=qs(Yt);var Vr=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 Us(o){let s=o.trimStart().split(/\s/)[0];return s?s.toUpperCase():"?"}function Fs(o){let s=o.replace(/\s+/g," ").trim(),t=s.match(/\bFROM\s+["'`]?(\w+)["'`]?/i);if(t)return t[1];let e=s.match(/\bINTO\s+["'`]?(\w+)["'`]?/i);if(e)return e[1];let r=s.match(/\bUPDATE\s+["'`]?(\w+)["'`]?/i);return r?r[1]:""}function Gs(o){return tt(o).replace(/\b\w+\b/g,s=>Vr.has(s.toUpperCase())?'<span class="sql-kw">'+s+"</span>":s)}var St=class extends E{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":_(t)}getQueryInfo(t){let e=(t.normalizedOp||t.operation||(t.sql?Us(t.sql):"?")).toUpperCase(),r=t.table||t.model||(t.sql?Fs(t.sql):""),i=t.sql||e+" "+r;return {op:e,table:r,sqlText:i}}renderQueryRow(t,e){let{op:r,table:i,sqlText:n}=this.getQueryInfo(t),l=pe[r]||"var(--text-dim)",c=t.durationMs>Oe,d=t.sql||r+" "+i,h=this.expandedIdx===e;return a`
971
+ `}};u([C({context:A})],Jt.prototype,"store",2),Jt=u([_("bk-logs-view")],Jt);var Vs={CHILD:2},Ks=o=>(...r)=>({_$litDirective$:o,values:r}),$e=class{constructor(r){}get _$AU(){return this._$AM._$AU}_$AT(r,t,e){this._$Ct=r,this._$AM=t,this._$Ci=e;}_$AS(r,t){return this.update(r,t)}update(r,t){return this.render(...t)}};var Zt=class extends $e{constructor(r){if(super(r),this.it=d,r.type!==Vs.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===d||r==null)return this._t=void 0,this.it=r;if(r===z)return r;if(typeof r!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this._t;this.it=r;let t=[r];return t.raw=t,this._t={_$litType$:this.constructor.resultType,strings:t,values:[]}}};Zt.directiveName="unsafeHTML",Zt.resultType=1;var G=Ks(Zt);var oi=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 zs(o){let r=o.trimStart().split(/\s/)[0];return r?r.toUpperCase():"?"}function Js(o){let r=o.replace(/\s+/g," ").trim(),t=r.match(/\bFROM\s+["'`]?(\w+)["'`]?/i);if(t)return t[1];let e=r.match(/\bINTO\s+["'`]?(\w+)["'`]?/i);if(e)return e[1];let s=r.match(/\bUPDATE\s+["'`]?(\w+)["'`]?/i);return s?s[1]:""}function Zs(o){return it(o).replace(/\b\w+\b/g,r=>oi.has(r.toUpperCase())?'<span class="sql-kw">'+r+"</span>":r)}var It=class extends E{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":y(t)}getQueryInfo(t){let e=(t.normalizedOp||t.operation||(t.sql?zs(t.sql):"?")).toUpperCase(),s=t.table||t.model||(t.sql?Js(t.sql):""),i=t.sql||e+" "+s;return {op:e,table:s,sqlText:i}}renderQueryRow(t,e){let{op:s,table:i,sqlText:n}=this.getQueryInfo(t),a=be[s]||"var(--text-dim)",c=t.durationMs>Be,p=t.sql||s+" "+i,h=this.expandedIdx===e;return l`
921
972
  <div>
922
973
  <div
923
974
  class="req-row query-row tel-clickable ${h?"expanded":""}"
924
975
  @click=${()=>this.toggleQuery(e)}
925
976
  >
926
- <span class="query-op" title=${r} style="color:${l}">${r}</span>
977
+ <span class="query-op" title=${s} style="color:${a}">${s}</span>
927
978
  <span class="query-table" title=${i}>${i}</span>
928
- <span class="query-preview" title=${d}>${d}</span>
979
+ <span class="query-preview" title=${p}>${p}</span>
929
980
  <span class="query-dur${c?" query-slow":""}">${this.queryDuration(t.durationMs)}</span>
930
981
  </div>
931
982
  <div class="query-detail ${h?"open":""}">
932
- ${h?a`
933
- <pre class="query-detail-sql">${U(Gs(n))}</pre>
983
+ ${h?l`
984
+ <pre class="query-detail-sql">${G(Zs(n))}</pre>
934
985
  <bk-copy-button .text=${n} label="Copy"></bk-copy-button>
935
- `:p}
986
+ `:d}
936
987
  </div>
937
988
  </div>
938
- `}render(){let t=this.store.state.queries;return t.length===0?a`<bk-empty-state
989
+ `}render(){let t=this.store.state.queries;return t.length===0?l`<bk-empty-state
939
990
  title="No queries"
940
991
  subtitle="No database queries have been captured yet"
941
- ></bk-empty-state>`:a`
992
+ ></bk-empty-state>`:l`
942
993
  <div class="col-header">
943
994
  <span style="width:70px;border-right:1px solid var(--border);padding-right:16px">Operation</span>
944
995
  <span style="width:170px;border-right:1px solid var(--border);padding-right:16px">Table</span>
@@ -946,37 +997,37 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
946
997
  <span style="width:60px;text-align:right">Time</span>
947
998
  </div>
948
999
  <div id="query-list">
949
- ${t.map((e,r)=>this.renderQueryRow(e,r))}
1000
+ ${t.map((e,s)=>this.renderQueryRow(e,s))}
950
1001
  </div>
951
- `}};u([I({context:A})],St.prototype,"store",2),u([b()],St.prototype,"expandedIdx",2),St=u([S("bk-queries-view")],St);function We(o){return o.replaceAll("'","'\\''")}function Kr(o,s){let t=Object.entries(o.headers||{}).filter(([i])=>!Ds.has(i)).map(([i,n])=>`-H '${We(i)}: ${We(n)}'`).join(" "),e=o.requestBody?` -d '${We(o.requestBody)}'`:"",r=s?`http://localhost:${s}`:"";return `curl -X ${o.method} ${t}${e} '${r}${o.url}'`}function Tt(o){let s=window.__BRAKIT_CONFIG__?.port??"",t=Kr(o,s);navigator.clipboard.writeText(t).then(()=>D.show("Copied cURL command"));}var wt=class extends E{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,e){e.stopPropagation(),Tt(t);}renderDetail(t){return a`
1002
+ `}};u([C({context:A})],It.prototype,"store",2),u([b()],It.prototype,"expandedIdx",2),It=u([_("bk-queries-view")],It);function Ze(o){return o.replaceAll("'","'\\''")}function ni(o,r){let t=Object.entries(o.headers||{}).filter(([i])=>!Ys.has(i)).map(([i,n])=>`-H '${Ze(i)}: ${Ze(n)}'`).join(" "),e=o.requestBody?` -d '${Ze(o.requestBody)}'`:"",s=r?`http://localhost:${r}`:"";return `curl -X ${o.method} ${t}${e} '${s}${o.url}'`}function Lt(o){let r=window.__BRAKIT_CONFIG__?.port??"",t=ni(o,r);navigator.clipboard.writeText(t).then(()=>D.show("Copied cURL command"));}var Mt=class extends E{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,e){e.stopPropagation(),Lt(t);}renderDetail(t){return l`
952
1003
  <div class="detail-meta">
953
1004
  <span><bk-method-badge .method=${t.method}></bk-method-badge> ${t.url}</span>
954
1005
  <span><bk-status-pill .code=${t.statusCode}></bk-status-pill></span>
955
1006
  <span>${t.durationMs}ms</span>
956
- ${t.responseSize?a`<span>${et(t.responseSize)}</span>`:p}
1007
+ ${t.responseSize?l`<span>${ot(t.responseSize)}</span>`:d}
957
1008
  </div>
958
1009
  <div class="request-timeline tl-hidden" data-request-id=${t.id} data-request-started=${String(t.startedAt)}></div>
959
1010
  <div class="detail-grid">
960
- <div class="detail-section"><h4>Request Headers</h4><pre>${U(Et(t.headers))}</pre></div>
961
- <div class="detail-section"><h4>Response Headers</h4><pre>${U(Et(t.responseHeaders))}</pre></div>
962
- <div class="detail-section"><h4>Request Body</h4><pre>${U(nt(t.requestBody))}</pre></div>
963
- <div class="detail-section"><h4>Response Body</h4><pre>${U(nt(t.responseBody))}</pre></div>
1011
+ <div class="detail-section"><h4>Request Headers</h4><pre>${G(Tt(t.headers))}</pre></div>
1012
+ <div class="detail-section"><h4>Response Headers</h4><pre>${G(Tt(t.responseHeaders))}</pre></div>
1013
+ <div class="detail-section"><h4>Request Body</h4><pre>${G(dt(t.requestBody))}</pre></div>
1014
+ <div class="detail-section"><h4>Response Body</h4><pre>${G(dt(t.responseBody))}</pre></div>
964
1015
  </div>
965
1016
  <div class="detail-actions">
966
1017
  <button class="btn btn-curl" @click=${e=>this.handleCopyAsCurl(t,e)}>Copy cURL</button>
967
1018
  </div>
968
- `}renderRequestRow(t){let e=this.expandedId===t.id;return a`
1019
+ `}renderRequestRow(t){let e=this.expandedId===t.id;return l`
969
1020
  <div class="req-row ${e?"expanded":""}" @click=${()=>this.toggleRequest(t.id)}>
970
1021
  <div class="req-summary">
971
1022
  <bk-method-badge .method=${t.method}></bk-method-badge>
972
1023
  <span class="req-url">${t.url}</span>
973
1024
  <bk-status-pill .code=${t.statusCode}></bk-status-pill>
974
1025
  <bk-duration-label .ms=${t.durationMs}></bk-duration-label>
975
- <span class="req-size">${et(t.responseSize)}</span>
1026
+ <span class="req-size">${ot(t.responseSize)}</span>
976
1027
  </div>
977
1028
  </div>
978
- <div class="req-detail ${e?"open":""}">${e?this.renderDetail(t):p}</div>
979
- `}render(){let t=this.store.state.requests.filter(e=>!e.path?.startsWith(F));return t.length===0?a`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:a`
1029
+ <div class="req-detail ${e?"open":""}">${e?this.renderDetail(t):d}</div>
1030
+ `}render(){let t=this.store.state.requests.filter(e=>!e.path?.startsWith(U));return t.length===0?l`<bk-empty-state title="No requests" subtitle="No HTTP requests have been captured yet"></bk-empty-state>`:l`
980
1031
  <div class="col-header">
981
1032
  <span style="width:60px">Method</span>
982
1033
  <span style="flex:1">URL</span>
@@ -985,53 +1036,53 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
985
1036
  <span style="width:60px;text-align:right">Size</span>
986
1037
  </div>
987
1038
  <div id="request-list">${t.map(e=>this.renderRequestRow(e))}</div>
988
- `}};u([I({context:A})],wt.prototype,"store",2),u([b()],wt.prototype,"expandedId",2),wt=u([S("bk-requests-view")],wt);var Xt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}buildGroups(s,t){let e=new Map;for(let i of t)e.set(i.id,i);let r={};for(let i of s){let n=i.method+" "+i.url;r[n]||(r[n]={method:i.method,url:i.url,count:0,totalDur:0,maxDur:0,errors:0,callers:{},statusCodes:{},firstTs:i.timestamp,lastTs:i.timestamp});let l=r[n];if(l.count++,l.totalDur+=i.durationMs,i.durationMs>l.maxDur&&(l.maxDur=i.durationMs),i.statusCode>=400&&l.errors++,l.statusCodes[i.statusCode]=(l.statusCodes[i.statusCode]||0)+1,i.timestamp<l.firstTs&&(l.firstTs=i.timestamp),i.timestamp>l.lastTs&&(l.lastTs=i.timestamp),i.parentRequestId){let c=e.get(i.parentRequestId);c&&(l.callers[c.method+" "+(c.path||c.url)]=1);}}return Object.values(r).sort((i,n)=>n.count-i.count)}renderSummary(s){let t=new Set,e=0,r=0;for(let n of s)t.add(n.url),n.statusCode>=400&&e++,r+=n.durationMs;let i=Math.round(r/s.length);return a`
1039
+ `}};u([C({context:A})],Mt.prototype,"store",2),u([b()],Mt.prototype,"expandedId",2),Mt=u([_("bk-requests-view")],Mt);var te=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}buildGroups(r,t){let e=new Map;for(let i of t)e.set(i.id,i);let s={};for(let i of r){let n=i.method+" "+i.url;s[n]||(s[n]={method:i.method,url:i.url,count:0,totalDur:0,maxDur:0,errors:0,callers:{},statusCodes:{},firstTs:i.timestamp,lastTs:i.timestamp});let a=s[n];if(a.count++,a.totalDur+=i.durationMs,i.durationMs>a.maxDur&&(a.maxDur=i.durationMs),i.statusCode>=400&&a.errors++,a.statusCodes[i.statusCode]=(a.statusCodes[i.statusCode]||0)+1,i.timestamp<a.firstTs&&(a.firstTs=i.timestamp),i.timestamp>a.lastTs&&(a.lastTs=i.timestamp),i.parentRequestId){let c=e.get(i.parentRequestId);c&&(a.callers[c.method+" "+(c.path||c.url)]=1);}}return Object.values(s).sort((i,n)=>n.count-i.count)}renderSummary(r){let t=new Set,e=0,s=0;for(let n of r)t.add(n.url),n.statusCode>=400&&e++,s+=n.durationMs;let i=Math.round(s/r.length);return l`
989
1040
  <div class="fetch-summary">
990
- <bk-stat-card value=${String(s.length)} label="Total Fetches"></bk-stat-card>
1041
+ <bk-stat-card value=${String(r.length)} label="Total Fetches"></bk-stat-card>
991
1042
  <bk-stat-card value=${String(t.size)} label="Unique URLs"></bk-stat-card>
992
1043
  <bk-stat-card value=${String(e)} label="Errors" color=${e>0?"var(--red)":""}></bk-stat-card>
993
- <bk-stat-card value=${_(i)} label="Avg Duration"></bk-stat-card>
1044
+ <bk-stat-card value=${y(i)} label="Avg Duration"></bk-stat-card>
994
1045
  </div>
995
- `}formatTime(s){return new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}renderGroup(s){let t=Math.round(s.totalDur/s.count),e=s.count>0?Math.round(s.errors/s.count*100):0,r=Object.keys(s.callers),i=Object.entries(s.statusCodes),n=i.length>0?Number(i.sort((l,c)=>c[1]-l[1])[0][0]):0;return a`
1046
+ `}formatTime(r){return new Date(r).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}renderGroup(r){let t=Math.round(r.totalDur/r.count),e=r.count>0?Math.round(r.errors/r.count*100):0,s=Object.keys(r.callers),i=Object.entries(r.statusCodes),n=i.length>0?Number(i.sort((a,c)=>c[1]-a[1])[0][0]):0;return l`
996
1047
  <div class="fetch-group">
997
1048
  <div class="fetch-group-header">
998
- <bk-method-badge .method=${s.method}></bk-method-badge>
999
- <span class="fetch-group-url" title=${s.url}>${s.url}</span>
1000
- ${n>0?a`<bk-status-pill .code=${n}></bk-status-pill>`:p}
1001
- <span class="fetch-group-count">${s.count}x</span>
1049
+ <bk-method-badge .method=${r.method}></bk-method-badge>
1050
+ <span class="fetch-group-url" title=${r.url}>${r.url}</span>
1051
+ ${n>0?l`<bk-status-pill .code=${n}></bk-status-pill>`:d}
1052
+ <span class="fetch-group-count">${r.count}x</span>
1002
1053
  </div>
1003
1054
  <div class="fetch-group-meta">
1004
- <span>avg ${_(t)}</span>
1055
+ <span>avg ${y(t)}</span>
1005
1056
  <span class="fetch-group-sep">\u00b7</span>
1006
- <span>max ${_(s.maxDur)}</span>
1057
+ <span>max ${y(r.maxDur)}</span>
1007
1058
  <span class="fetch-group-sep">\u00b7</span>
1008
- ${e>0?a`<span class="fetch-group-err">${e}% errors</span>`:a`<span class="fetch-group-ok">0% errors</span>`}
1059
+ ${e>0?l`<span class="fetch-group-err">${e}% errors</span>`:l`<span class="fetch-group-ok">0% errors</span>`}
1009
1060
  </div>
1010
- ${s.firstTs>0?a`
1061
+ ${r.firstTs>0?l`
1011
1062
  <div class="fetch-group-timeline">
1012
1063
  <span class="fetch-group-timeline-dot"></span>
1013
1064
  <span class="fetch-group-timeline-range">
1014
- ${this.formatTime(s.firstTs)}${s.firstTs!==s.lastTs?a` \u2192 ${this.formatTime(s.lastTs)}`:p}
1065
+ ${this.formatTime(r.firstTs)}${r.firstTs!==r.lastTs?l` \u2192 ${this.formatTime(r.lastTs)}`:d}
1015
1066
  </span>
1016
- </div>`:p}
1017
- ${r.length>0?a`
1067
+ </div>`:d}
1068
+ ${s.length>0?l`
1018
1069
  <div class="fetch-group-callers">
1019
1070
  <span class="fetch-group-callers-label">Called by</span>
1020
- ${r.map(l=>a`<span class="fetch-group-caller-pill">${l}</span>`)}
1021
- </div>`:p}
1071
+ ${s.map(a=>l`<span class="fetch-group-caller-pill">${a}</span>`)}
1072
+ </div>`:d}
1022
1073
  </div>
1023
- `}render(){let s=this.store.state.fetches,t=this.store.state.requests;if(s.length===0)return a`<bk-empty-state title="No fetches" subtitle="No outbound HTTP calls have been captured yet"></bk-empty-state>`;let e=this.buildGroups(s,t);return a`
1074
+ `}render(){let r=this.store.state.fetches,t=this.store.state.requests;if(r.length===0)return l`<bk-empty-state title="No fetches" subtitle="No outbound HTTP calls have been captured yet"></bk-empty-state>`;let e=this.buildGroups(r,t);return l`
1024
1075
  <div class="fetch-analysis" id="fetch-analysis">
1025
- ${this.renderSummary(s)}
1026
- ${e.length>0?a`
1076
+ ${this.renderSummary(r)}
1077
+ ${e.length>0?l`
1027
1078
  <div class="fetch-groups-title">Grouped by URL (${e.length})</div>
1028
- <div class="fetch-groups">${e.map(r=>this.renderGroup(r))}</div>
1029
- `:p}
1079
+ <div class="fetch-groups">${e.map(s=>this.renderGroup(s))}</div>
1080
+ `:d}
1030
1081
  </div>
1031
- `}};u([I({context:A})],Xt.prototype,"store",2),Xt=u([S("bk-fetches-view")],Xt);function Bs(o,s){if(s>=400)return "var(--red)";switch(o){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 Qe(o){return o==="query"?"var(--accent)":"var(--cyan)"}function ti(o){return o.type==="query"||o.type==="fetch"}function ei(o){let s=(o.normalizedOp||o.operation||"QUERY").toUpperCase(),t=o.table||o.model||"";return {label:`${s} ${t}`,tooltip:o.sql||`${s} ${t}`}}function si(o){return {label:`${o.method} ${o.url}`,tooltip:`${o.method} ${o.url}`}}function ri(o,s,t,e,r,i){let n=o.data.durationMs||0,l,c;if(i){let d=Math.max(o.timestamp-e,0);l=Math.min(d/r*100,95),c=Math.max(n/r*100,1.5);}else {let d=t[0].timestamp,m=t[t.length-1].timestamp-d;l=m>0?(o.timestamp-d)/m*85:s/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 ii(o,s){let t=o.timeline.filter(ti);if(t.length===0)return [];let e=s.startedAt,r=s.durationMs||1,i=Math.abs(t[0].timestamp-e)<r*10;return t.map((n,l)=>{let c=n.data.durationMs||0,{leftPct:d,widthPct:h}=ri(n,l,t,e,r,i),m=n.type==="query"?ei(n.data):si(n.data);return {type:n.type,label:m.label,durMs:c,durLabel:_(c),tooltip:m.tooltip,leftPct:d,widthPct:h}})}function Qs(o,s){let t=o.requests.filter(l=>!l.isStrictModeDupe);if(t.length===0)return {rows:[],totalMs:0};let e=Math.min(...t.map(l=>l.startedAt)),i=Math.max(...t.map(l=>l.startedAt+l.durationMs))-e;return i===0?{rows:[],totalMs:0}:{rows:t.map(l=>{let c=(l.startedAt-e)/i*100,d=Math.max(l.durationMs/i*100,.5),h=s?.activities?.[l.id],m=h?ii(h,l):[];return {label:`${l.method} ${l.label}`,leftPct:c,widthPct:d,color:Bs(l.method,l.statusCode),durMs:l.durationMs,durLabel:_(l.durationMs),tooltip:`${l.method} ${l.label} (${_(l.durationMs)})`,subEvents:m}}),totalMs:i}}function js(o){let s=o.requests,t=[],e=[],r=[],i=[],n=new Map;for(let d of s){let h=d.label,m=d.pollingDurationMs||d.durationMs;if(!Gt[d.category||""]){if(d.isDuplicate){let v=n.get(h);v?(v.count++,v.wastedMs+=m):n.set(h,{name:h,count:2,wastedMs:m});continue}if(d.statusCode>=400){e.push(h+" ("+Hs(d.statusCode)+")");continue}d.responseSize>51200&&r.push("Large response: "+h+" returned "+et(d.responseSize)),t.push(h);}}for(let d of n.values())i.push(d);let l="";if(i.length>0){let d=i.map(m=>m.name).join(", "),h=i.reduce((m,v)=>m+v.wastedMs,0);l="Your app fetches "+d+" multiple times on this page. This wastes ~"+_(h)+". Try caching these calls, deduplicating with React Query/SWR, or moving them to a shared layout.";}else e.length>0&&(l="Some requests are failing. Check your API routes and make sure the endpoints exist.");let c=s.filter(d=>d.durationMs>2e3&&d.category!==ut);return c.length>0&&!l&&(l=c.map(d=>d.label).join(", ")+` is taking over ${_(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:t,errors:e,warnings:r,duplicates:i,tip:l}}var W=class extends E{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 e=t.requests.filter(r=>r.statusCode>=400).length;return {text:e+" error"+(e!==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,e){e.stopPropagation(),this.expandedSubReqIdx=this.expandedSubReqIdx===t?-1:t;}toggleBodyBlock(t){t.stopPropagation();let e=t.currentTarget,r=e.parentElement;if(!r)return;e.classList.toggle("open");let i=r.querySelector("pre");i&&i.classList.toggle("open");}switchTab(t,e,r){r.stopPropagation(),this.flowDetailTab=t,t==="timeline"&&!this.flowTimeline&&this.loadFlowTimeline(e);}async loadFlowTimeline(t){if(this.flowTimelineLoading)return;let e=t.requests.map(r=>r.id).filter(Boolean);if(e.length!==0){this.flowTimelineLoading=true;try{let r=await fetch(`${w.activity}?requestIds=${e.join(",")}`);if(!r.ok){this.flowTimelineLoading=!1;return}this.flowTimeline=await r.json();}catch{}this.flowTimelineLoading=false;}}loadTimelineForContainer(t){let e=t.querySelectorAll(".request-timeline");for(let r of e){let i=r.getAttribute("data-request-id");if(i&&!r.hasAttribute("data-loaded")){r.setAttribute("data-loaded","1");let n=document.createElement("bk-timeline-panel");n.setAttribute("request-id",i),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
1082
+ `}};u([C({context:A})],te.prototype,"store",2),te=u([_("bk-fetches-view")],te);function tr(o,r){if(r>=400)return "var(--red)";switch(o){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 ts(o){return o==="query"?"var(--accent)":"var(--cyan)"}function di(o){return o.type==="query"||o.type==="fetch"}function pi(o){let r=(o.normalizedOp||o.operation||"QUERY").toUpperCase(),t=o.table||o.model||"";return {label:`${r} ${t}`,tooltip:o.sql||`${r} ${t}`}}function hi(o){return {label:`${o.method} ${o.url}`,tooltip:`${o.method} ${o.url}`}}function ui(o,r,t,e,s,i){let n=o.data.durationMs||0,a,c;if(i){let p=Math.max(o.timestamp-e,0);a=Math.min(p/s*100,95),c=Math.max(n/s*100,1.5);}else {let p=t[0].timestamp,m=t[t.length-1].timestamp-p;a=m>0?(o.timestamp-p)/m*85:r/Math.max(t.length-1,1)*85,c=Math.max(n/s*100,1.5);}return a+c>100&&(c=Math.max(100-a,1.5)),{leftPct:a,widthPct:c}}function mi(o,r){let t=o.timeline.filter(di);if(t.length===0)return [];let e=r.startedAt,s=r.durationMs||1,i=Math.abs(t[0].timestamp-e)<s*10;return t.map((n,a)=>{let c=n.data.durationMs||0,{leftPct:p,widthPct:h}=ui(n,a,t,e,s,i),m=n.type==="query"?pi(n.data):hi(n.data);return {type:n.type,label:m.label,durMs:c,durLabel:y(c),tooltip:m.tooltip,leftPct:p,widthPct:h}})}function sr(o,r){let t=o.requests.filter(a=>!a.isStrictModeDupe);if(t.length===0)return {rows:[],totalMs:0};let e=Math.min(...t.map(a=>a.startedAt)),i=Math.max(...t.map(a=>a.startedAt+a.durationMs))-e;return i===0?{rows:[],totalMs:0}:{rows:t.map(a=>{let c=(a.startedAt-e)/i*100,p=Math.max(a.durationMs/i*100,.5),h=r?.activities?.[a.id],m=h?mi(h,a):[];return {label:`${a.method} ${a.label}`,leftPct:c,widthPct:p,color:tr(a.method,a.statusCode),durMs:a.durationMs,durLabel:y(a.durationMs),tooltip:`${a.method} ${a.label} (${y(a.durationMs)})`,subEvents:m}}),totalMs:i}}function rr(o){let r=o.requests,t=[],e=[],s=[],i=[],n=new Map;for(let p of r){let h=p.label,m=p.pollingDurationMs||p.durationMs;if(!Yt[p.category||""]){if(p.isDuplicate){let f=n.get(h);f?(f.count++,f.wastedMs+=m):n.set(h,{name:h,count:2,wastedMs:m});continue}if(p.statusCode>=400){e.push(h+" ("+Xs(p.statusCode)+")");continue}p.responseSize>51200&&s.push("Large response: "+h+" returned "+ot(p.responseSize)),t.push(h);}}for(let p of n.values())i.push(p);let a="";if(i.length>0){let p=i.map(m=>m.name).join(", "),h=i.reduce((m,f)=>m+f.wastedMs,0);a="Your app fetches "+p+" multiple times on this page. This wastes ~"+y(h)+". Try caching these calls, deduplicating with React Query/SWR, or moving them to a shared layout.";}else e.length>0&&(a="Some requests are failing. Check your API routes and make sure the endpoints exist.");let c=r.filter(p=>p.durationMs>2e3&&p.category!==bt);return c.length>0&&!a&&(a=c.map(p=>p.label).join(", ")+` is taking over ${y(2e3)}. Consider adding caching or optimizing the backend query.`),{successes:t,errors:e,warnings:s,duplicates:i,tip:a}}var X=class extends E{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 e=t.requests.filter(s=>s.statusCode>=400).length;return {text:e+" error"+(e!==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,e){e.stopPropagation(),this.expandedSubReqIdx=this.expandedSubReqIdx===t?-1:t;}toggleBodyBlock(t){t.stopPropagation();let e=t.currentTarget,s=e.parentElement;if(!s)return;e.classList.toggle("open");let i=s.querySelector("pre");i&&i.classList.toggle("open");}switchTab(t,e,s){s.stopPropagation(),this.flowDetailTab=t,t==="timeline"&&!this.flowTimeline&&this.loadFlowTimeline(e);}async loadFlowTimeline(t){if(this.flowTimelineLoading)return;let e=t.requests.map(s=>s.id).filter(Boolean);if(e.length!==0){this.flowTimelineLoading=true;try{let s=await fetch(`${T.activity}?requestIds=${e.join(",")}`);if(!s.ok){this.flowTimelineLoading=!1;return}this.flowTimeline=await s.json();}catch{}this.flowTimelineLoading=false;}}loadTimelineForContainer(t){let e=t.querySelectorAll(".request-timeline");for(let s of e){let i=s.getAttribute("data-request-id");if(i&&!s.hasAttribute("data-loaded")){s.setAttribute("data-loaded","1");let n=document.createElement("bk-timeline-panel");n.setAttribute("request-id",i),n.setAttribute("request-started",s.getAttribute("data-request-started")||"0"),s.appendChild(n),s.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?l`<bk-empty-state
1032
1083
  title="No actions yet"
1033
1084
  subtitle="Start using your app to see user action flows here"
1034
- ></bk-empty-state>`:a`
1085
+ ></bk-empty-state>`:l`
1035
1086
  <div id="flow-col-header" class="col-header">
1036
1087
  <span style="width:8px"></span>
1037
1088
  <span style="flex:1">Action</span>
@@ -1040,11 +1091,11 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1040
1091
  <span style="width:70px;text-align:right">Time</span>
1041
1092
  </div>
1042
1093
  <div id="flow-list">
1043
- ${t.map((e,r)=>this.renderFlowRow(e,r))}
1094
+ ${t.map((e,s)=>this.renderFlowRow(e,s))}
1044
1095
  </div>
1045
- `}renderFlowRow(t,e){let r=this.expandedFlowIdx===e,i=this.flowDotClass(t),n=this.flowBadgeInfo(t);return a`
1096
+ `}renderFlowRow(t,e){let s=this.expandedFlowIdx===e,i=this.flowDotClass(t),n=this.flowBadgeInfo(t);return l`
1046
1097
  <div
1047
- class="flow-row ${r?"expanded":""}"
1098
+ class="flow-row ${s?"expanded":""}"
1048
1099
  @click=${()=>this.toggleFlow(e)}
1049
1100
  >
1050
1101
  <div class="flow-summary-row">
@@ -1056,39 +1107,39 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1056
1107
  >
1057
1108
  <span class="flow-badge-pill ${n.cls}">${n.text}</span>
1058
1109
  <span class="flow-duration"
1059
- >${_(t.totalDurationMs)}</span
1110
+ >${y(t.totalDurationMs)}</span
1060
1111
  >
1061
1112
  </div>
1062
1113
  </div>
1063
- <div class="flow-expand ${r?"open":""}">
1064
- ${r?this.renderFlowDetail(t):p}
1114
+ <div class="flow-expand ${s?"open":""}">
1115
+ ${s?this.renderFlowDetail(t):d}
1065
1116
  </div>
1066
- `}renderFlowDetail(t){let e=this.viewMode==="simple"?"Insights":"Details";return a`
1117
+ `}renderFlowDetail(t){let e=this.viewMode==="simple"?"Insights":"Details";return l`
1067
1118
  <div class="flow-detail-tabs">
1068
1119
  <button
1069
1120
  class="flow-tab ${this.flowDetailTab==="insights"?"active":""}"
1070
- @click=${r=>this.switchTab("insights",t,r)}
1121
+ @click=${s=>this.switchTab("insights",t,s)}
1071
1122
  >
1072
1123
  ${e}
1073
1124
  </button>
1074
1125
  <button
1075
1126
  class="flow-tab ${this.flowDetailTab==="timeline"?"active":""}"
1076
- @click=${r=>this.switchTab("timeline",t,r)}
1127
+ @click=${s=>this.switchTab("timeline",t,s)}
1077
1128
  >
1078
1129
  Timeline
1079
1130
  </button>
1080
1131
  </div>
1081
1132
  ${this.flowDetailTab==="insights"?this.viewMode==="simple"?this.renderFlowInsights(t):this.renderFlowSubReqs(t):this.renderFlowWaterfall(t)}
1082
- `}renderFlowWaterfall(t){if(this.flowTimelineLoading)return a`<div class="wf-loading">Loading timeline...</div>`;let{rows:e,totalMs:r}=Qs(t,this.flowTimeline);if(e.length===0)return p;let i=[];for(let n=0;n<=5;n++)i.push(_(r/5*n));return a`
1133
+ `}renderFlowWaterfall(t){if(this.flowTimelineLoading)return l`<div class="wf-loading">Loading timeline...</div>`;let{rows:e,totalMs:s}=sr(t,this.flowTimeline);if(e.length===0)return d;let i=[];for(let n=0;n<=5;n++)i.push(y(s/5*n));return l`
1083
1134
  <div class="flow-waterfall">
1084
1135
  <div class="wf-time-axis">
1085
- ${i.map(n=>a`<span>${n}</span>`)}
1136
+ ${i.map(n=>l`<span>${n}</span>`)}
1086
1137
  </div>
1087
1138
  <div class="wf-rows">
1088
1139
  ${e.map(n=>this.renderWaterfallGroup(n))}
1089
1140
  </div>
1090
1141
  </div>
1091
- `}renderWaterfallGroup(t){return a`
1142
+ `}renderWaterfallGroup(t){return l`
1092
1143
  <div class="wf-request-group">
1093
1144
  <div class="wf-req-row" title="${t.tooltip}">
1094
1145
  <div class="wf-req-label">${t.label}</div>
@@ -1100,48 +1151,48 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1100
1151
  </div>
1101
1152
  <div class="wf-req-dur">${t.durLabel}</div>
1102
1153
  </div>
1103
- ${t.subEvents.length>0?t.subEvents.map(e=>a`
1154
+ ${t.subEvents.length>0?t.subEvents.map(e=>l`
1104
1155
  <div class="wf-sub-row" title="${e.tooltip}">
1105
1156
  <div class="wf-sub-label">
1106
1157
  <span
1107
1158
  class="wf-sub-dot"
1108
- style="background:${Qe(e.type)}"
1159
+ style="background:${ts(e.type)}"
1109
1160
  ></span>
1110
1161
  ${e.label}
1111
1162
  </div>
1112
1163
  <div class="wf-bar-track">
1113
1164
  <div
1114
1165
  class="wf-bar wf-sub-bar-sized"
1115
- style="left:${t.leftPct+e.leftPct/100*t.widthPct}%;width:${e.widthPct/100*t.widthPct}%;background:${Qe(e.type)}"
1166
+ style="left:${t.leftPct+e.leftPct/100*t.widthPct}%;width:${e.widthPct/100*t.widthPct}%;background:${ts(e.type)}"
1116
1167
  ></div>
1117
1168
  </div>
1118
1169
  <div class="wf-sub-dur">${e.durLabel}</div>
1119
1170
  </div>
1120
- `):p}
1171
+ `):d}
1121
1172
  </div>
1122
- `}renderFlowInsights(t){let e=js(t),r=e.errors.length>0||e.duplicates.length>0||e.warnings.length>0||!!e.tip;return a`
1173
+ `}renderFlowInsights(t){let e=rr(t),s=e.errors.length>0||e.duplicates.length>0||e.warnings.length>0||!!e.tip;return l`
1123
1174
  <div>
1124
1175
  <div class="flow-traffic">
1125
1176
  ${t.requests.map(i=>this.renderTrafficCard(i))}
1126
1177
  </div>
1127
- ${r?a`
1178
+ ${s?l`
1128
1179
  <div class="flow-divider"></div>
1129
1180
  <div class="flow-insights">
1130
- ${e.errors.map(i=>a`<div class="insight-line insight-error">
1181
+ ${e.errors.map(i=>l`<div class="insight-line insight-error">
1131
1182
  ✗ ${i}
1132
1183
  </div>`)}
1133
- ${e.duplicates.map(i=>a`<div class="insight-line insight-warn">
1184
+ ${e.duplicates.map(i=>l`<div class="insight-line insight-warn">
1134
1185
  ⚠ ${i.name} — loaded ${i.count}x (wasting
1135
- ~${_(i.wastedMs)})
1186
+ ~${y(i.wastedMs)})
1136
1187
  </div>`)}
1137
- ${e.warnings.map(i=>a`<div class="insight-line insight-warn">⚠ ${i}</div>`)}
1138
- ${e.tip?a`<div class="insight-line insight-tip">
1188
+ ${e.warnings.map(i=>l`<div class="insight-line insight-warn">⚠ ${i}</div>`)}
1189
+ ${e.tip?l`<div class="insight-line insight-tip">
1139
1190
  Tip: ${e.tip}
1140
- </div>`:p}
1191
+ </div>`:d}
1141
1192
  </div>
1142
- `:p}
1193
+ `:d}
1143
1194
  </div>
1144
- `}renderTrafficCard(t){if(Gt[t.category||""])return p;let e=bt(t.statusCode),r=_(t.pollingDurationMs||t.durationMs),i=!t.isDuplicate&&t.category!==re&&t.category!==ut||t.requestBody&&t.method!=="GET"||!!t.responseBody;return a`
1195
+ `}renderTrafficCard(t){if(Yt[t.category||""])return d;let e=St(t.statusCode),s=y(t.pollingDurationMs||t.durationMs),i=!t.isDuplicate&&t.category!==pe&&t.category!==bt||t.requestBody&&t.method!=="GET"||!!t.responseBody;return l`
1145
1196
  <div
1146
1197
  class="traffic-card ${t.isStrictModeDupe?"strict-mode-dupe":""}"
1147
1198
  >
@@ -1151,58 +1202,58 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1151
1202
  >${t.label}</span
1152
1203
  >
1153
1204
  <span class="status-pill ${e}">${t.statusCode}</span>
1154
- <span class="traffic-card-dur">${r}</span>
1155
- ${t.isDuplicate?a`<span class="traffic-card-dup">duplicate</span>`:a`<span class="traffic-card-size"
1156
- >${et(t.responseSize)}</span
1205
+ <span class="traffic-card-dur">${s}</span>
1206
+ ${t.isDuplicate?l`<span class="traffic-card-dup">duplicate</span>`:l`<span class="traffic-card-size"
1207
+ >${ot(t.responseSize)}</span
1157
1208
  >`}
1158
1209
  </div>
1159
- ${t.isStrictModeDupe?a`<div class="strict-mode-banner">
1210
+ ${t.isStrictModeDupe?l`<div class="strict-mode-banner">
1160
1211
  React Strict Mode duplicate — does not happen in production
1161
- </div>`:p}
1162
- ${!t.isDuplicate&&t.category!==re&&t.category!==ut?a`<div
1212
+ </div>`:d}
1213
+ ${!t.isDuplicate&&t.category!==pe&&t.category!==bt?l`<div
1163
1214
  class="request-timeline tl-hidden"
1164
1215
  data-request-id=${t.id}
1165
1216
  data-request-started=${String(t.startedAt)}
1166
- ></div>`:p}
1167
- ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):p}
1168
- ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):p}
1217
+ ></div>`:d}
1218
+ ${t.requestBody&&t.method!=="GET"?this.renderBodyToggle("out","Request Body",t.requestBody):d}
1219
+ ${t.responseBody?this.renderBodyToggle("in","Response Body",t.responseBody):d}
1169
1220
  </div>
1170
- `}renderBodyToggle(t,e,r){let i=t==="out"?"\u2192":"\u2190";return a`
1221
+ `}renderBodyToggle(t,e,s){let i=t==="out"?"\u2192":"\u2190";return l`
1171
1222
  <div class="traffic-body">
1172
1223
  <button class="traffic-body-toggle" @click=${this.toggleBodyBlock}>
1173
1224
  <span class="chevron">▸</span
1174
1225
  ><span class="arrow-${t}">${i}</span> ${e}
1175
1226
  </button>
1176
- <pre>${U(nt(r))}</pre>
1227
+ <pre>${G(dt(s))}</pre>
1177
1228
  </div>
1178
- `}renderFlowSubReqs(t){return a`<div class="flow-subreqs">
1179
- ${t.requests.map((e,r)=>this.renderSubReqRow(e,r))}
1180
- </div>`}renderSubReqRow(t,e){let r=this.expandedSubReqIdx===e,i=bt(t.statusCode),n=t.pollingDurationMs?_(t.pollingDurationMs):_(t.durationMs);return a`
1229
+ `}renderFlowSubReqs(t){return l`<div class="flow-subreqs">
1230
+ ${t.requests.map((e,s)=>this.renderSubReqRow(e,s))}
1231
+ </div>`}renderSubReqRow(t,e){let s=this.expandedSubReqIdx===e,i=St(t.statusCode),n=t.pollingDurationMs?y(t.pollingDurationMs):y(t.durationMs);return l`
1181
1232
  <div
1182
- class="flow-subreq ${r?"expanded":""}"
1183
- @click=${l=>this.toggleSubReq(e,l)}
1233
+ class="flow-subreq ${s?"expanded":""}"
1234
+ @click=${a=>this.toggleSubReq(e,a)}
1184
1235
  >
1185
1236
  <bk-method-badge .method=${t.method}></bk-method-badge>
1186
1237
  <span class="subreq-label ${t.isDuplicate?"is-dup":""}"
1187
1238
  >${t.path||t.url}</span
1188
1239
  >
1189
- ${t.isDuplicate?a`<span class="subreq-dup-tag">duplicate</span>`:p}
1240
+ ${t.isDuplicate?l`<span class="subreq-dup-tag">duplicate</span>`:d}
1190
1241
  <span class="status-pill ${i}">${t.statusCode}</span>
1191
1242
  <span class="subreq-dur">${n}</span>
1192
1243
  </div>
1193
- <div class="flow-subreq-detail ${r?"open":""}">
1194
- ${r?this.renderSubReqDetail(t):p}
1244
+ <div class="flow-subreq-detail ${s?"open":""}">
1245
+ ${s?this.renderSubReqDetail(t):d}
1195
1246
  </div>
1196
- `}renderSubReqDetail(t){let e=bt(t.statusCode);return a`
1247
+ `}renderSubReqDetail(t){let e=St(t.statusCode);return l`
1197
1248
  <div class="detail-meta">
1198
1249
  <span
1199
- ><bk-method-badge .method=${t.method}></bk-method-badge> ${tt(t.url)}</span
1250
+ ><bk-method-badge .method=${t.method}></bk-method-badge> ${it(t.url)}</span
1200
1251
  >
1201
1252
  <span
1202
1253
  ><span class="status-pill ${e}">${t.statusCode}</span></span
1203
1254
  >
1204
1255
  <span>${t.durationMs}ms</span>
1205
- ${t.responseSize?a`<span>${et(t.responseSize)}</span>`:p}
1256
+ ${t.responseSize?l`<span>${ot(t.responseSize)}</span>`:d}
1206
1257
  </div>
1207
1258
  <div
1208
1259
  class="request-timeline tl-hidden"
@@ -1212,30 +1263,30 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1212
1263
  <div class="detail-grid">
1213
1264
  <div class="detail-section">
1214
1265
  <h4>Request Headers</h4>
1215
- <pre>${U(Et(t.headers))}</pre>
1266
+ <pre>${G(Tt(t.headers))}</pre>
1216
1267
  </div>
1217
1268
  <div class="detail-section">
1218
1269
  <h4>Response Headers</h4>
1219
- <pre>${U(Et(t.responseHeaders))}</pre>
1270
+ <pre>${G(Tt(t.responseHeaders))}</pre>
1220
1271
  </div>
1221
1272
  <div class="detail-section">
1222
1273
  <h4>Request Body</h4>
1223
- <pre>${U(nt(t.requestBody))}</pre>
1274
+ <pre>${G(dt(t.requestBody))}</pre>
1224
1275
  </div>
1225
1276
  <div class="detail-section">
1226
1277
  <h4>Response Body</h4>
1227
- <pre>${U(nt(t.responseBody))}</pre>
1278
+ <pre>${G(dt(t.responseBody))}</pre>
1228
1279
  </div>
1229
1280
  </div>
1230
1281
  <div class="detail-actions">
1231
1282
  <button
1232
1283
  class="btn btn-curl"
1233
- @click=${r=>{r.stopPropagation(),Tt(t);}}
1284
+ @click=${s=>{s.stopPropagation(),Lt(t);}}
1234
1285
  >
1235
1286
  Copy cURL
1236
1287
  </button>
1237
1288
  </div>
1238
- `}};u([I({context:A})],W.prototype,"store",2),u([b()],W.prototype,"expandedFlowIdx",2),u([b()],W.prototype,"expandedSubReqIdx",2),u([b()],W.prototype,"flowDetailTab",2),u([b()],W.prototype,"flowTimeline",2),u([b()],W.prototype,"flowTimelineLoading",2),W=u([S("bk-flows-view")],W);var Vt=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}render(){let s=(this.store.state.issues||[]).slice(),t=s.filter(l=>l.state==="open"||l.state==="fixing"||l.state==="regressed"),e=s.filter(l=>l.state==="resolved");if(t.length===0&&e.length===0)return this.store.state.requests.length>0||this.store.state.logs.length>0||this.store.state.queries.length>0?a`
1289
+ `}};u([C({context:A})],X.prototype,"store",2),u([b()],X.prototype,"expandedFlowIdx",2),u([b()],X.prototype,"expandedSubReqIdx",2),u([b()],X.prototype,"flowDetailTab",2),u([b()],X.prototype,"flowTimeline",2),u([b()],X.prototype,"flowTimelineLoading",2),X=u([_("bk-flows-view")],X);var ee=class extends E{createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}render(){let r=(this.store.state.issues||[]).slice(),t=r.filter(a=>a.state==="open"||a.state==="fixing"||a.state==="regressed"),e=r.filter(a=>a.state==="resolved");if(t.length===0&&e.length===0)return this.store.state.requests.length>0||this.store.state.logs.length>0||this.store.state.queries.length>0?l`
1239
1290
  <div class="sec-clear">
1240
1291
  <span class="sec-clear-icon">\u2713</span>
1241
1292
  <div class="sec-clear-text">
@@ -1243,10 +1294,10 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1243
1294
  <div class="sec-clear-sub">No security or quality issues detected this session</div>
1244
1295
  </div>
1245
1296
  </div>
1246
- `:a`<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,n=0;for(let l of t){let c=l.issue.severity;c==="critical"?r++:c==="info"?n++:i++;}return a`
1297
+ `:l`<bk-empty-state title="Waiting for requests..." subtitle="Start using your app to see security findings here"></bk-empty-state>`;let s=0,i=0,n=0;for(let a of t){let c=a.issue.severity;c==="critical"?s++:c==="info"?n++:i++;}return l`
1247
1298
  <div id="security-content">
1248
- ${this.renderSummary(t.length,e.length,r,i,n)}
1249
- ${t.length===0&&e.length>0?a`
1299
+ ${this.renderSummary(t.length,e.length,s,i,n)}
1300
+ ${t.length===0&&e.length>0?l`
1250
1301
  <div class="sec-clear">
1251
1302
  <span class="sec-clear-icon">\u2713</span>
1252
1303
  <div class="sec-clear-text">
@@ -1254,152 +1305,114 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1254
1305
  <div class="sec-clear-sub">${e.length} finding${e.length!==1?"s were":" was"} detected and fixed</div>
1255
1306
  </div>
1256
1307
  </div>
1257
- `:p}
1258
- ${t.length>0?this.renderOpenGroups(t):p}
1259
- ${e.length>0?this.renderResolved(e):p}
1308
+ `:d}
1309
+ ${t.length>0?this.renderOpenGroups(t):d}
1310
+ ${e.length>0?this.renderResolved(e):d}
1260
1311
  </div>
1261
- `}renderSummary(s,t,e,r,i){return a`
1312
+ `}renderSummary(r,t,e,s,i){return l`
1262
1313
  <div class="sec-summary">
1263
1314
  <div class="sec-summary-left">
1264
- <span class="sec-summary-count">${s}</span>
1265
- <span class="sec-summary-label">open issue${s!==1?"s":""}</span>
1266
- ${t>0?a`<span class="sec-resolved-badge">${t} resolved</span>`:p}
1315
+ <span class="sec-summary-count">${r}</span>
1316
+ <span class="sec-summary-label">open issue${r!==1?"s":""}</span>
1317
+ ${t>0?l`<span class="sec-resolved-badge">${t} resolved</span>`:d}
1267
1318
  </div>
1268
1319
  <div class="sec-summary-right">
1269
- ${e>0?a`<span class="sec-badge critical">${e} critical</span>`:p}
1270
- ${r>0?a`<span class="sec-badge warning">${r} warning</span>`:p}
1271
- ${i>0?a`<span class="sec-badge info">${i} info</span>`:p}
1320
+ ${e>0?l`<span class="sec-badge critical">${e} critical</span>`:d}
1321
+ ${s>0?l`<span class="sec-badge warning">${s} warning</span>`:d}
1322
+ ${i>0?l`<span class="sec-badge info">${i} info</span>`:d}
1272
1323
  </div>
1273
1324
  </div>
1274
- `}renderOpenGroups(s){let t={},e=[];for(let r of s){let i=r.issue,n=i.rule||i.type;t[n]||(t[n]={rule:n,title:i.title,severity:i.severity,hint:i.hint,items:[]},e.push(n)),t[n].items.push(r);}return e.sort((r,i)=>{let n=Z[t[r].severity]?.sort??2,l=Z[t[i].severity]?.sort??2;return n!==l?n-l:t[i].items.length-t[r].items.length}),a`${e.map(r=>this.renderGroup(t[r]))}`}renderGroup(s){let t=Z[s.severity]||Z.info;return a`
1325
+ `}renderOpenGroups(r){let t={},e=[];for(let s of r){let i=s.issue,n=i.rule;t[n]||(t[n]={rule:n,title:i.title,severity:i.severity,hint:i.hint,items:[]},e.push(n)),t[n].items.push(s);}return e.sort((s,i)=>{let n=Y[t[s].severity]?.sort??2,a=Y[t[i].severity]?.sort??2;return n!==a?n-a:t[i].items.length-t[s].items.length}),l`${e.map(s=>this.renderGroup(t[s]))}`}renderGroup(r){let t=Y[r.severity]||Y.info;return l`
1275
1326
  <div class="sec-group">
1276
1327
  <div class="sec-group-header">
1277
1328
  <span class="sec-group-icon ${t.cls}">${t.icon}</span>
1278
- <span class="sec-group-title">${s.title}</span>
1279
- <span class="sec-group-count">${s.items.length}</span>
1329
+ <span class="sec-group-title">${r.title}</span>
1330
+ <span class="sec-group-count">${r.items.length}</span>
1280
1331
  </div>
1281
- ${s.hint?a`<div class="sec-hint">${s.hint}</div>`:p}
1282
- <div class="sec-items">${s.items.map(e=>this.renderIssueItem(e))}</div>
1332
+ ${r.hint?l`<div class="sec-hint">${r.hint}</div>`:d}
1333
+ <div class="sec-items">${r.items.map(e=>this.renderIssueItem(e))}</div>
1283
1334
  </div>
1284
- `}renderIssueItem(s){let t=s.issue;return a`
1335
+ `}renderIssueItem(r){let t=r.issue;return l`
1285
1336
  <div class="sec-item">
1286
1337
  <div class="sec-item-desc">${t.desc}</div>
1287
- ${s.occurrences>1?a`<span class="sec-item-count">${s.occurrences}x</span>`:p}
1288
- ${s.state==="fixing"&&s.aiStatus==="fixed"?a`<span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>`:s.aiStatus==="wont_fix"?a`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:s.state==="regressed"?a`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:p}
1289
- ${s.aiNotes?a`<div class="sec-ai-notes">${s.aiNotes}</div>`:p}
1338
+ ${r.occurrences>1?l`<span class="sec-item-count">${r.occurrences}x</span>`:d}
1339
+ ${r.state==="fixing"&&r.aiStatus==="fixed"?l`<span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>`:r.aiStatus==="wont_fix"?l`<span class="sec-ai-badge sec-ai-wontfix">AI: won\u2019t fix</span>`:r.state==="regressed"?l`<span class="sec-ai-badge sec-ai-fixing" style="background:var(--red)">regressed</span>`:d}
1340
+ ${r.aiNotes?l`<div class="sec-ai-notes">${r.aiNotes}</div>`:d}
1290
1341
  </div>
1291
- `}renderResolved(s){return a`
1342
+ `}renderResolved(r){return l`
1292
1343
  <div class="sec-resolved-title">
1293
1344
  <span class="sec-resolved-check">\u2713</span> Resolved
1294
- <span class="sec-resolved-count">${s.length}</span>
1345
+ <span class="sec-resolved-count">${r.length}</span>
1295
1346
  </div>
1296
1347
  <div class="sec-group sec-group-resolved">
1297
1348
  <div class="sec-items">
1298
- ${s.map(t=>a`
1349
+ ${r.map(t=>l`
1299
1350
  <div class="sec-item sec-item-resolved">
1300
1351
  <span class="sec-resolved-item-icon">\u2713</span>
1301
1352
  <div class="sec-item-desc">${t.issue.title} \u2014 ${t.issue.endpoint||"global"}</div>
1302
- ${t.aiStatus==="fixed"?a`<span class="sec-ai-badge sec-ai-verified">Verified fix</span>`:p}
1303
- ${t.aiNotes?a`<div class="sec-ai-notes">${t.aiNotes}</div>`:p}
1353
+ ${t.aiStatus==="fixed"?l`<span class="sec-ai-badge sec-ai-verified">Verified fix</span>`:d}
1354
+ ${t.aiNotes?l`<div class="sec-ai-notes">${t.aiNotes}</div>`:d}
1304
1355
  </div>
1305
1356
  `)}
1306
1357
  </div>
1307
1358
  </div>
1308
- `}};u([I({context:A})],Vt.prototype,"store",2),Vt=u([S("bk-security-view")],Vt);var Rt=class extends E{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,e=t.requests.filter(y=>!y.isStatic&&!y.isHealthCheck&&(!y.path||y.path.indexOf(F)!==0));if(!(e.length>0||t.queries.length>0||t.errors.length>0))return a`<bk-empty-state
1309
- title="Waiting for requests..."
1310
- subtitle="Start using your app to see insights here"
1311
- ></bk-empty-state>`;let i=e.filter(y=>y.statusCode>=400).length,n=new Set(["data-fetch","api-call","server-action","page-load"]),l=e.filter(y=>y.category&&n.has(y.category)),c=l.length>0?l:e,d=c.length>0?Math.round(c.reduce((y,k)=>y+k.durationMs,0)/c.length):0,h=t.issues||[],m=h.filter(y=>y.state==="open"||y.state==="regressed"),v=h.filter(y=>y.state==="fixing"),x=h.filter(y=>y.state==="resolved");return a`
1312
- <div class="ov-container" id="overview-content">
1313
- ${this.renderSummary(e.length,t.flows.length,d,t.queries.length,i,t.fetches.length)}
1314
- ${m.length===0&&v.length===0&&x.length===0?a`<div class="ov-clear">
1315
- <span class="ov-clear-icon">\u2713</span>All clear \u2014 no issues detected
1316
- </div>`:p}
1317
- ${m.length===0&&x.length>0?a`<div class="ov-clear">
1318
- <span class="ov-clear-icon">\u2713</span>All issues resolved \u2014
1319
- ${x.length} finding${x.length!==1?"s were":" was"} detected and
1320
- fixed
1321
- </div>`:p}
1322
- ${m.length>0?this.renderOpenIssues(m):p}
1323
- ${v.length>0?this.renderVerifying(v):p}
1324
- ${x.length>0?this.renderResolvedIssues(x):p}
1325
- </div>
1326
- `}renderSummary(t,e,r,i,n,l){return a`
1327
- <div class="ov-summary">
1328
- <div class="ov-stat"><span class="ov-stat-value">${t}</span><span class="ov-stat-label">Requests</span></div>
1329
- <div class="ov-stat"><span class="ov-stat-value">${e}</span><span class="ov-stat-label">Actions</span></div>
1330
- <div class="ov-stat"><span class="ov-stat-value">${_(r)}</span><span class="ov-stat-label">Avg Response</span></div>
1331
- <div class="ov-stat"><span class="ov-stat-value">${i}</span><span class="ov-stat-label">Queries</span></div>
1332
- <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>
1333
- <div class="ov-stat"><span class="ov-stat-value">${l}</span><span class="ov-stat-label">Fetches</span></div>
1334
- </div>
1335
- `}renderOpenIssues(t){return a`
1336
- <div class="ov-section-title">Issues Found <span class="ov-issue-count">${t.length}</span></div>
1337
- <div class="ov-cards">${t.map((e,r)=>this.renderIssueCard(e,r))}</div>
1338
- `}renderIssueCard(t,e){let r=t.issue,i=Z[r.severity]||Z.info,n=this.expandedCardIdx===e,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>`:p,c=t.cleanHitsSinceLastSeen>0?a`<div class="ov-card-resolving">Resolving\u2026 ${t.cleanHitsSinceLastSeen}/${5} clean requests</div>`:p;return a`
1339
- <div class="ov-card ${n?"expanded":""}" @click=${()=>this.toggleCard(e)}>
1340
- <span class="ov-card-icon ${i.cls}">${i.icon}</span>
1341
- <div class="ov-card-body">
1342
- <div class="ov-card-title">${r.title}${l}</div>
1343
- <div class="ov-card-desc">${r.desc}</div>
1344
- ${r.detail?a`<div class="ov-card-detail">${r.detail}</div>`:p}
1345
- ${c}
1346
- ${n&&r.hint?a`<div class="ov-card-hint">${r.hint}</div>`:p}
1359
+ `}};u([C({context:A})],ee.prototype,"store",2),ee=u([_("bk-security-view")],ee);var J=class extends E{constructor(){super(...arguments);this.handleStateChanged=()=>this.requestUpdate();}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.store.addEventListener("state-changed",this.handleStateChanged);}disconnectedCallback(){super.disconnectedCallback(),this.store.removeEventListener("state-changed",this.handleStateChanged);}};u([C({context:A})],J.prototype,"store",2);async function j(o){let r=await fetch(o);if(!r.ok)throw new Error(`HTTP ${r.status}: ${o}`);return r.json()}function B(o,r,t){return o===1?r:t??`${r}s`}function ir(o){return o.state!=="stale"}function _e(o){return (o.state==="open"||o.state==="regressed")&&o.aiStatus!=="wont_fix"}var se=class extends J{constructor(){super(...arguments);this.graphSummary=null;}connectedCallback(){super.connectedCallback(),this.loadGraphSummary();}async loadGraphSummary(){try{let e=(await j(`${T.graph}?level=endpoints`)).nodes||[];this.graphSummary={endpoints:e.filter(s=>s.type==="endpoint").length,tables:e.filter(s=>s.type==="table").length,externals:e.filter(s=>s.type==="external").length};}catch{}}navigateTo(t){this.store.setActiveView(t);}navigateToExplorerErrors(){this.store.setActiveView("explorer"),window.dispatchEvent(new CustomEvent("navigate-explorer",{detail:"errors"}));}render(){let t=this.store.state,e=t.requests.filter(i=>!i.isStatic&&!i.isHealthCheck&&(!i.path||i.path.indexOf(U)!==0));return e.length>0||t.queries.length>0?l`
1360
+ <div class="ov-container">
1361
+ <div class="ov-grid">
1362
+ ${this.renderActionsCard(t.flows)}
1363
+ ${this.renderInsightsCard(t.issues)}
1364
+ ${this.renderPerformanceCard(e)}
1365
+ ${this.renderErrorsCard(e)}
1366
+ ${this.renderGraphCard()}
1347
1367
  </div>
1348
- ${r.hint?a`<span class="ov-card-arrow">${n?"\u2193":"\u2192"}</span>`:p}
1349
- </div>
1350
- `}renderVerifying(t){return a`
1351
- <div class="ov-section-title ov-resolved-title">
1352
- <span style="color:var(--yellow,#f5a623)">\u29d7</span> Awaiting Verification
1353
- <span class="ov-issue-count">${t.length}</span>
1354
- </div>
1355
- <div class="ov-cards">
1356
- ${t.map(e=>{let r=e.issue,i=e.cleanHitsSinceLastSeen>0?a`<div class="ov-card-resolving">Verifying\u2026 ${e.cleanHitsSinceLastSeen}/${5} clean requests</div>`:p;return a`
1357
- <div class="ov-card ov-card-resolved">
1358
- <span class="ov-card-icon resolved">\u29d7</span>
1359
- <div class="ov-card-body">
1360
- <div class="ov-card-title" style="color:var(--text-muted)">
1361
- ${r.title}
1362
- <span class="sec-ai-badge sec-ai-fixing">AI fixed \u2014 awaiting verification</span>
1363
- </div>
1364
- <div class="ov-card-desc">${r.desc}</div>
1365
- ${i}
1366
- </div>
1367
- </div>
1368
- `})}
1369
1368
  </div>
1370
- `}renderResolvedIssues(t){return a`
1371
- <div class="ov-section-title ov-resolved-title">
1372
- <span style="color:var(--green)">\u2713</span> Resolved
1373
- <span class="ov-issue-count">${t.length}</span>
1374
- </div>
1375
- <div class="ov-cards">
1376
- ${t.map(e=>a`
1377
- <div class="ov-card ov-card-resolved">
1378
- <span class="ov-card-icon resolved">\u2713</span>
1379
- <div class="ov-card-body">
1380
- <div class="ov-card-title" style="text-decoration:line-through;color:var(--text-muted)">${e.issue.title}</div>
1381
- <div class="ov-card-desc">${e.issue.desc}</div>
1382
- </div>
1383
- </div>
1384
- `)}
1369
+ `:l`<bk-empty-state
1370
+ title="${N.EMPTY_TITLE}"
1371
+ subtitle="${N.EMPTY_SUBTITLE_OVERVIEW}"
1372
+ ></bk-empty-state>`}renderActionsCard(t){let e=t.length;if(e===0)return this.renderEmptyCard("\u25B6","Actions",N.NO_ACTIONS,"actions");let s=Math.round(t.reduce((n,a)=>n+a.totalDurationMs,0)/e),i=t[0]?.label||"";return this.renderCard("\u25B6",`${e} ${B(e,"action")}`,`avg ${y(s)}${i?` \xB7 "${i}"`:""}`,"actions","var(--accent)")}renderInsightsCard(t){let e=(t||[]).filter(_e);if(e.length===0)return this.renderCard("\u2713",N.ALL_CLEAR,N.ALL_CLEAR_DETAIL,"insights","var(--green)");let s=e.filter(a=>a.issue.severity==="critical").length,i=e.filter(a=>a.issue.severity==="warning").length,n=[];return s>0&&n.push(`${s} critical`),i>0&&n.push(`${i} warning`),this.renderCard("\u{1F4A1}",`${e.length} ${B(e.length,"issue")}`,n.join(" \xB7 ")||N.REVIEW_RECOMMENDED,"insights","var(--amber)")}renderPerformanceCard(t){if(t.length===0)return this.renderEmptyCard("\u26A1","Performance",N.NO_REQUEST_DATA,"performance");let e=new Map;for(let n of t){let a=`${n.method} ${n.path}`,c=e.get(a);c||(c=[],e.set(a,c)),c.push(n.durationMs);}let s=[];for(let[n,a]of e){let c=Math.round(a.reduce((p,h)=>p+h,0)/a.length);c>2e3&&s.push({key:n,avg:c});}if(s.sort((n,a)=>a.avg-n.avg),s.length===0)return this.renderCard("\u26A1",N.ALL_FAST,N.NO_SLOW_ENDPOINTS,"performance","var(--green)");let i=s[0];return this.renderCard("\u26A1",`${s.length} slow ${B(s.length,"endpoint")}`,`worst: ${i.key} \xB7 ${y(i.avg)}`,"performance","var(--amber)")}renderErrorsCard(t){let e=t.filter(n=>n.statusCode>=400);if(e.length===0)return this.renderCard("\u2713",N.ZERO_ERRORS,N.ALL_REQUESTS_OK,"explorer","var(--green)");let s=new Map;for(let n of e)s.set(n.statusCode,(s.get(n.statusCode)||0)+1);let i=[...s.entries()].sort((n,a)=>a[1]-n[1]).slice(0,3).map(([n,a])=>`${a}\xD7 ${n}`);return l`
1373
+ <div class="ov-card-nav" @click=${()=>this.navigateToExplorerErrors()}>
1374
+ <div class="ov-card-icon-lg" style="color:var(--red)">\u2715</div>
1375
+ <div class="ov-card-content">
1376
+ <div class="ov-card-headline">${e.length} ${B(e.length,"error")}</div>
1377
+ <div class="ov-card-context">${i.join(" \xB7 ")}</div>
1378
+ </div>
1379
+ <span class="ov-card-arrow">\u2192</span>
1380
+ </div>
1381
+ `}renderGraphCard(){let t=this.graphSummary;if(!t||t.endpoints===0&&t.tables===0)return this.renderEmptyCard("\u25CE","Graph",N.BUILD_GRAPH,"graph");let e=[];t.endpoints>0&&e.push(`${t.endpoints} ${B(t.endpoints,"endpoint")}`),t.tables>0&&e.push(`${t.tables} ${B(t.tables,"table")}`);let s=t.externals>0?`${t.externals} external ${B(t.externals,"service")}`:"";return this.renderCard("\u25CE",e.join(" \xB7 "),s,"graph","var(--accent)")}renderCard(t,e,s,i,n){return l`
1382
+ <div class="ov-card-nav" @click=${()=>this.navigateTo(i)}>
1383
+ <div class="ov-card-icon-lg" style="color:${n}">${t}</div>
1384
+ <div class="ov-card-content">
1385
+ <div class="ov-card-headline">${e}</div>
1386
+ ${s?l`<div class="ov-card-context">${s}</div>`:d}
1387
+ </div>
1388
+ <span class="ov-card-arrow">\u2192</span>
1389
+ </div>
1390
+ `}renderEmptyCard(t,e,s,i){return l`
1391
+ <div class="ov-card-nav ov-card-empty" @click=${()=>this.navigateTo(i)}>
1392
+ <div class="ov-card-icon-lg">${t}</div>
1393
+ <div class="ov-card-content">
1394
+ <div class="ov-card-headline">${e}</div>
1395
+ <div class="ov-card-context">${s}</div>
1396
+ </div>
1397
+ <span class="ov-card-arrow">\u2192</span>
1385
1398
  </div>
1386
- `}};u([I({context:A})],Rt.prototype,"store",2),u([b()],Rt.prototype,"expandedCardIdx",2),Rt=u([S("bk-overview-view")],Rt);function Ys(o){return o<1?"<1ms":o<1e3?Math.round(o)+"ms":(o/1e3).toFixed(1)+"s"}function oi(o){return o<mt?Bt.green:o<ft?Bt.amber:Bt.red}function ni(o){return o.statusCode>=400?Bt.red:oi(o.durationMs)}function Xs(o){return [parseInt(o.slice(1,3),16),parseInt(o.slice(3,5),16),parseInt(o.slice(5,7),16)]}function ai(o){let s=o.getContext("2d");if(!s)return null;let t=window.devicePixelRatio||1,e=o.clientWidth,r=o.clientHeight;return o.width=e*t,o.height=r*t,s.scale(t,t),{ctx:s,w:e,h:r}}function li(o,s,t,e,r){let[i,n,l]=Xs(r);o.beginPath(),o.arc(s,t,e+2,0,Math.PI*2),o.fillStyle=`rgba(${i},${n},${l},0.25)`,o.fill(),o.beginPath(),o.arc(s,t,e,0,Math.PI*2),o.fillStyle=r,o.fill();}function ci(o,s,t,e,r,i){let[n,l,c]=Xs(r);o.strokeStyle=`rgba(${n},${l},${c},0.3)`,o.lineWidth=i+2,o.beginPath(),o.moveTo(s-e,t-e),o.lineTo(s+e,t+e),o.moveTo(s+e,t-e),o.lineTo(s-e,t+e),o.stroke(),o.strokeStyle=r,o.lineWidth=i,o.beginPath(),o.moveTo(s-e,t-e),o.lineTo(s+e,t+e),o.moveTo(s+e,t-e),o.lineTo(s-e,t+e),o.stroke();}function Vs(o,s){let t=[],e=ai(o);if(!e||s.length===0)return t;let{ctx:r,w:i,h:n}=e,l=Ls,c=i-l.left-l.right,d=n-l.top-l.bottom,h=0,m=s[0].timestamp,v=s[0].timestamp;for(let $ of s)$.durationMs>h&&(h=$.durationMs),$.timestamp<m&&(m=$.timestamp),$.timestamp>v&&(v=$.timestamp);h=Math.max(h,10),h=Math.ceil(h*1.15/10)*10;let x=v-m||1;r.strokeStyle=Is,r.lineWidth=1;let y=4;for(let $=0;$<=y;$++){let f=l.top+d-$/y*d;r.beginPath(),r.moveTo(l.left,f),r.lineTo(l.left+c,f),r.stroke(),r.fillStyle=Ue,r.font=Cs,r.textAlign="right",r.fillText(Ys(Math.round($/y*h)),l.left-8,f+3);}for(let $ of [{ms:mt},{ms:ft}]){if($.ms>=h)continue;let f=l.top+d-$.ms/h*d;r.beginPath(),r.setLineDash([4,4]),r.strokeStyle="rgba(113,113,122,0.3)",r.lineWidth=1,r.moveTo(l.left,f),r.lineTo(l.left+c,f),r.stroke(),r.setLineDash([]),r.fillStyle="rgba(113,113,122,0.5)",r.font=Fe,r.textAlign="left",r.fillText(Ys($.ms),l.left+c+2,f+3);}for(let $=0;$<s.length;$++){let f=s[$],g=s.length===1?l.left+c/2:l.left+(f.timestamp-m)/x*c,T=l.top+d-f.durationMs/h*d,R=ni(f);t.push({x:g,y:T,idx:$,r:f}),f.statusCode>=400?ci(r,g,T,4,R,2):li(r,g,T,4,R);}r.fillStyle=Ue,r.font=Fe,r.textAlign="center";let k=[m,m+x/2,v];for(let $=0;$<k.length;$++){let f=l.left+$/2*c,g=new Date(k[$]);r.fillText(g.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),f,l.top+d+14);}return t}var fi={max:1/0,label:"Pending",color:"var(--text-muted)",bg:"var(--bg-muted)",border:"var(--border)"};function Ks(o,s,t){return t>=20?o:s}function Ye(o,s){if(!s||s<=0)return fi;let t=o/s;return t<.7?gt[0]:t<1.2?gt[1]:t<2?gt[2]:t<3?gt[3]:gt[4]}var Q=class extends E{constructor(){super(...arguments);this.selectedEndpoint=J;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 e=await(await fetch(w.metricsLive)).json();this.graphData=e.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===J)&&(this.selectedEndpoint=J);}catch{this.loadError=true;}}healthGradeForEndpoint(t){let e=Ks(t.summary.p95Ms,t.summary.medianMs,t.summary.totalRequests);return Ye(e,t.baselineP95Ms)}healthGradeForDuration(t,e){return Ye(t,e)}getCallers(t){let e=this.store.state.flows,r=new Map;for(let i of e)for(let n of i.requests)if(`${n.method} ${n.path}`===t||this.normalizeEndpoint(n)===t){let c=r.get(i.label);c?(c.count++,c.totalMs+=n.durationMs):r.set(i.label,{count:1,totalMs:n.durationMs});}return [...r.entries()].map(([i,n])=>({label:i,count:n.count,avgMs:Math.round(n.totalMs/n.count)})).sort((i,n)=>n.count-i.count)}normalizeEndpoint(t){let r=t.path.split("?")[0].split("/").map(i=>{if(!i)return i;let n=i.length>0;for(let l=0;l<i.length;l++){let c=i.charCodeAt(l);if(c<48||c>57){n=false;break}}return n||i.length===36&&i[8]==="-"&&i[13]==="-"&&i[18]==="-"&&i[23]==="-"?":id":i}).join("/");return `${t.method} ${r}`}async loadQueryBreakdown(t){if(this.queryBreakdownLoading)return;let r=this.store.state.requests.filter(i=>`${i.method} ${i.path}`===t||this.normalizeEndpoint(i)===t).slice(-20).map(i=>i.id).filter(Boolean);if(r.length===0){this.queryBreakdown=[];return}this.queryBreakdownLoading=true;try{let i=await fetch(`${w.activity}?requestIds=${r.join(",")}`);if(!i.ok){this.queryBreakdownLoading=!1;return}let n=await i.json(),l=new Map;for(let c of Object.values(n.activities))for(let d of c.timeline){if(d.type!=="query")continue;let h=d.data,m=(h.normalizedOp||h.operation||"QUERY").toUpperCase(),v=h.table||h.model||"",x=`${m} ${v}`.trim(),y=l.get(x);y?(y.totalMs+=h.durationMs,y.count++):l.set(x,{label:x,totalMs:h.durationMs,count:1});}this.queryBreakdown=[...l.values()].map(c=>({...c,avgMs:Math.round(c.totalMs/c.count)})).sort((c,d)=>d.totalMs-c.totalMs);}catch{}this.queryBreakdownLoading=false;}renderScatterChart(t,e){this.scatterDots=Vs(t,e),t.style.cursor="pointer",t.onclick=r=>{let i=t.getBoundingClientRect(),n=r.clientX-i.left,l=r.clientY-i.top,c=null,d=1/0;for(let h of this.scatterDots){let m=Math.sqrt((h.x-n)**2+(h.y-l)**2);m<d&&(d=m,c=h);}c&&d<16&&this.highlightRow(c.idx);};}highlightRow(t){let e=this.querySelector(".perf-hist-row-hl");e&&e.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===J)return;let t=this.querySelector("#perf-detail-canvas");if(t){let e=this.graphData.find(r=>r.endpoint===this.selectedEndpoint);e&&this.renderScatterChart(t,e.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`
1399
+ `}};u([b()],se.prototype,"graphSummary",2),se=u([_("bk-overview-view")],se);function or(o){return o<1?"<1ms":o<1e3?Math.round(o)+"ms":(o/1e3).toFixed(1)+"s"}function fi(o){return o<yt?Vt.green:o<$t?Vt.amber:Vt.red}function vi(o){return o.statusCode>=400?Vt.red:fi(o.durationMs)}function nr(o){return [parseInt(o.slice(1,3),16),parseInt(o.slice(3,5),16),parseInt(o.slice(5,7),16)]}function gi(o){let r=o.getContext("2d");if(!r)return null;let t=window.devicePixelRatio||1,e=o.clientWidth,s=o.clientHeight;return o.width=e*t,o.height=s*t,r.scale(t,t),{ctx:r,w:e,h:s}}function bi(o,r,t,e,s){let[i,n,a]=nr(s);o.beginPath(),o.arc(r,t,e+2,0,Math.PI*2),o.fillStyle=`rgba(${i},${n},${a},0.25)`,o.fill(),o.beginPath(),o.arc(r,t,e,0,Math.PI*2),o.fillStyle=s,o.fill();}function Ei(o,r,t,e,s,i){let[n,a,c]=nr(s);o.strokeStyle=`rgba(${n},${a},${c},0.3)`,o.lineWidth=i+2,o.beginPath(),o.moveTo(r-e,t-e),o.lineTo(r+e,t+e),o.moveTo(r+e,t-e),o.lineTo(r-e,t+e),o.stroke(),o.strokeStyle=s,o.lineWidth=i,o.beginPath(),o.moveTo(r-e,t-e),o.lineTo(r+e,t+e),o.moveTo(r+e,t-e),o.lineTo(r-e,t+e),o.stroke();}function ar(o,r){let t=[],e=gi(o);if(!e||r.length===0)return t;let{ctx:s,w:i,h:n}=e,a=Gs,c=i-a.left-a.right,p=n-a.top-a.bottom,h=0,m=r[0].timestamp,f=r[0].timestamp;for(let $ of r)$.durationMs>h&&(h=$.durationMs),$.timestamp<m&&(m=$.timestamp),$.timestamp>f&&(f=$.timestamp);h=Math.max(h,10),h=Math.ceil(h*1.15/10)*10;let S=f-m||1;s.strokeStyle=Us,s.lineWidth=1;let R=4;for(let $=0;$<=R;$++){let v=a.top+p-$/R*p;s.beginPath(),s.moveTo(a.left,v),s.lineTo(a.left+c,v),s.stroke(),s.fillStyle=Ve,s.font=Fs,s.textAlign="right",s.fillText(or(Math.round($/R*h)),a.left-8,v+3);}for(let $ of [{ms:yt},{ms:$t}]){if($.ms>=h)continue;let v=a.top+p-$.ms/h*p;s.beginPath(),s.setLineDash([4,4]),s.strokeStyle="rgba(113,113,122,0.3)",s.lineWidth=1,s.moveTo(a.left,v),s.lineTo(a.left+c,v),s.stroke(),s.setLineDash([]),s.fillStyle="rgba(113,113,122,0.5)",s.font=Ke,s.textAlign="left",s.fillText(or($.ms),a.left+c+2,v+3);}for(let $=0;$<r.length;$++){let v=r[$],g=r.length===1?a.left+c/2:a.left+(v.timestamp-m)/S*c,x=a.top+p-v.durationMs/h*p,w=vi(v);t.push({x:g,y:x,idx:$,r:v}),v.statusCode>=400?Ei(s,g,x,4,w,2):bi(s,g,x,4,w);}s.fillStyle=Ve,s.font=Ke,s.textAlign="center";let P=[m,m+S/2,f];for(let $=0;$<P.length;$++){let v=a.left+$/2*c,g=new Date(P[$]);s.fillText(g.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),v,a.top+p+14);}return t}var Ti={max:1/0,label:"Pending",color:"var(--text-muted)",bg:"var(--bg-muted)",border:"var(--border)"};function lr(o,r,t){return t>=20?o:r}function ss(o,r){if(!r||r<=0)return Ti;let t=o/r;return t<.7?xt[0]:t<1.2?xt[1]:t<2?xt[2]:t<3?xt[3]:xt[4]}var V=class extends E{constructor(){super(...arguments);this.selectedEndpoint=rt;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 e=await(await fetch(T.metricsLive)).json();this.graphData=e.endpoints||[],this.loadError=!1,(!this.selectedEndpoint||this.selectedEndpoint===rt)&&(this.selectedEndpoint=rt);}catch{this.loadError=true;}}healthGradeForEndpoint(t){let e=lr(t.summary.p95Ms,t.summary.medianMs,t.summary.totalRequests);return ss(e,t.baselineP95Ms)}healthGradeForDuration(t,e){return ss(t,e)}getCallers(t){let e=this.store.state.flows,s=new Map;for(let i of e)for(let n of i.requests)if(`${n.method} ${n.path}`===t||this.normalizeEndpoint(n)===t){let c=s.get(i.label);c?(c.count++,c.totalMs+=n.durationMs):s.set(i.label,{count:1,totalMs:n.durationMs});}return [...s.entries()].map(([i,n])=>({label:i,count:n.count,avgMs:Math.round(n.totalMs/n.count)})).sort((i,n)=>n.count-i.count)}normalizeEndpoint(t){let s=t.path.split("?")[0].split("/").map(i=>{if(!i)return i;let n=i.length>0;for(let a=0;a<i.length;a++){let c=i.charCodeAt(a);if(c<48||c>57){n=false;break}}return n||i.length===36&&i[8]==="-"&&i[13]==="-"&&i[18]==="-"&&i[23]==="-"?":id":i}).join("/");return `${t.method} ${s}`}async loadQueryBreakdown(t){if(this.queryBreakdownLoading)return;let s=this.store.state.requests.filter(i=>`${i.method} ${i.path}`===t||this.normalizeEndpoint(i)===t).slice(-20).map(i=>i.id).filter(Boolean);if(s.length===0){this.queryBreakdown=[];return}this.queryBreakdownLoading=true;try{let i=await fetch(`${T.activity}?requestIds=${s.join(",")}`);if(!i.ok){this.queryBreakdownLoading=!1;return}let n=await i.json(),a=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(),f=h.table||h.model||"",S=`${m} ${f}`.trim(),R=a.get(S);R?(R.totalMs+=h.durationMs,R.count++):a.set(S,{label:S,totalMs:h.durationMs,count:1});}this.queryBreakdown=[...a.values()].map(c=>({...c,avgMs:Math.round(c.totalMs/c.count)})).sort((c,p)=>p.totalMs-c.totalMs);}catch{}this.queryBreakdownLoading=false;}renderScatterChart(t,e){this.scatterDots=ar(t,e),t.style.cursor="pointer",t.onclick=s=>{let i=t.getBoundingClientRect(),n=s.clientX-i.left,a=s.clientY-i.top,c=null,p=1/0;for(let h of this.scatterDots){let m=Math.sqrt((h.x-n)**2+(h.y-a)**2);m<p&&(p=m,c=h);}c&&p<16&&this.highlightRow(c.idx);};}highlightRow(t){let e=this.querySelector(".perf-hist-row-hl");e&&e.classList.remove("perf-hist-row-hl");let s=this.querySelector(`[data-req-idx="${t}"]`);s&&(s.classList.add("perf-hist-row-hl"),s.scrollIntoView({behavior:"smooth",block:"center"}));}updated(){if(this.selectedEndpoint===rt)return;let t=this.querySelector("#perf-detail-canvas");if(t){let e=this.graphData.find(s=>s.endpoint===this.selectedEndpoint);e&&this.renderScatterChart(t,e.requests);}}render(){return !this.graphData||this.graphData.length===0?l`<bk-empty-state title="No performance data yet" subtitle="Hit some endpoints and data will appear here"></bk-empty-state>`:l`
1387
1400
  <div id="graph-content">
1388
1401
  ${this.renderSelector()}
1389
- ${this.selectedEndpoint===J?this.renderOverview():this.renderDetail()}
1402
+ ${this.selectedEndpoint===rt?this.renderOverview():this.renderDetail()}
1390
1403
  </div>
1391
- `}renderSelector(){return a`
1404
+ `}renderSelector(){return l`
1392
1405
  <div class="perf-selector">
1393
- <button class="perf-selector-btn ${this.selectedEndpoint===J?"active":""}"
1394
- @click=${()=>{this.selectedEndpoint=J;}}>Overview</button>
1395
- ${this.graphData.map((t,e)=>a`
1406
+ <button class="perf-selector-btn ${this.selectedEndpoint===rt?"active":""}"
1407
+ @click=${()=>{this.selectedEndpoint=rt;}}>Overview</button>
1408
+ ${this.graphData.map((t,e)=>l`
1396
1409
  <button class="perf-selector-btn ${t.endpoint===this.selectedEndpoint?"active":""}"
1397
1410
  @click=${()=>{this.selectedEndpoint=t.endpoint,this.queryBreakdown=[],this.loadQueryBreakdown(t.endpoint);}}>
1398
- <span class="perf-dot" style="background:${qe[e%qe.length]}"></span>${t.endpoint}
1411
+ <span class="perf-dot" style="background:${Xe[e%Xe.length]}"></span>${t.endpoint}
1399
1412
  </button>
1400
1413
  `)}
1401
1414
  </div>
1402
- `}renderOverview(){let t=this.graphData.filter(c=>c.requests.length>0);if(t.length===0)return p;let e=t.reduce((c,d)=>c+d.summary.totalRequests,0),r=e>0?Math.round(t.reduce((c,d)=>c+d.summary.p95Ms*d.summary.totalRequests,0)/e):0,i=t.reduce((c,d)=>c+Math.round(d.summary.errorRate*d.summary.totalRequests),0),n=e>0?i/e:0,l=t[0];return a`
1415
+ `}renderOverview(){let t=this.graphData.filter(c=>c.requests.length>0);if(t.length===0)return d;let e=t.reduce((c,p)=>c+p.summary.totalRequests,0),s=e>0?Math.round(t.reduce((c,p)=>c+p.summary.p95Ms*p.summary.totalRequests,0)/e):0,i=t.reduce((c,p)=>c+Math.round(p.summary.errorRate*p.summary.totalRequests),0),n=e>0?i/e:0,a=t[0];return l`
1403
1416
  <div class="perf-overview">
1404
1417
  <div class="perf-summary-row">
1405
1418
  <div class="perf-summary-card">
@@ -1408,7 +1421,7 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1408
1421
  </div>
1409
1422
  <div class="perf-summary-card">
1410
1423
  <span class="perf-summary-label">Avg P95</span>
1411
- <span class="perf-summary-value" style="color:${this.healthGradeForDuration(r).color}">${_(r)}</span>
1424
+ <span class="perf-summary-value" style="color:${this.healthGradeForDuration(s).color}">${y(s)}</span>
1412
1425
  </div>
1413
1426
  <div class="perf-summary-card">
1414
1427
  <span class="perf-summary-label">Error Rate</span>
@@ -1416,7 +1429,7 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1416
1429
  </div>
1417
1430
  <div class="perf-summary-card">
1418
1431
  <span class="perf-summary-label">Slowest</span>
1419
- <span class="perf-summary-value perf-summary-value-sm">${l?.endpoint??"-"}</span>
1432
+ <span class="perf-summary-value perf-summary-value-sm">${a?.endpoint??"-"}</span>
1420
1433
  </div>
1421
1434
  </div>
1422
1435
 
@@ -1436,50 +1449,50 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1436
1449
  </tbody>
1437
1450
  </table>
1438
1451
  </div>
1439
- `}renderHeatmapRow(t){let e=t.summary,r=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests),n=(e.avgQueryTimeMs||0)+(e.avgFetchTimeMs||0)+(e.avgAppTimeMs||0),l=0,c=0,d=100;return n>0&&(l=Math.round((e.avgQueryTimeMs||0)/n*100),c=Math.round((e.avgFetchTimeMs||0)/n*100),d=Math.max(0,100-l-c)),a`
1452
+ `}renderHeatmapRow(t){let e=t.summary,s=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests),n=(e.avgQueryTimeMs||0)+(e.avgFetchTimeMs||0)+(e.avgAppTimeMs||0),a=0,c=0,p=100;return n>0&&(a=Math.round((e.avgQueryTimeMs||0)/n*100),c=Math.round((e.avgFetchTimeMs||0)/n*100),p=Math.max(0,100-a-c)),l`
1440
1453
  <tr class="perf-table-row" @click=${()=>{this.selectedEndpoint=t.endpoint,this.queryBreakdown=[],this.loadQueryBreakdown(t.endpoint);}}>
1441
1454
  <td class="perf-td-name">${t.endpoint}</td>
1442
1455
  <td class="perf-td-right">${e.totalRequests}</td>
1443
1456
  <td class="perf-td-center">
1444
- <span class="perf-hm-p95" style="color:${r.color};background:${r.bg};border-color:${r.border}">${_(e.p95Ms)}</span>
1457
+ <span class="perf-hm-p95" style="color:${s.color};background:${s.bg};border-color:${s.border}">${y(e.p95Ms)}</span>
1445
1458
  </td>
1446
1459
  <td class="perf-td-center" style="color:${i>0?"var(--red)":"var(--text-muted)"}">${i>0?i:"-"}</td>
1447
1460
  <td class="perf-td-center" style="color:${e.avgQueryCount>5?"var(--amber)":"var(--text-muted)"}">${e.avgQueryCount}</td>
1448
1461
  <td>
1449
1462
  <span class="perf-hm-split-bar">
1450
- ${l>0?a`<span class="perf-breakdown-seg perf-breakdown-db" style="width:${l}%"></span>`:p}
1451
- ${c>0?a`<span class="perf-breakdown-seg perf-breakdown-fetch" style="width:${c}%"></span>`:p}
1452
- ${d>0?a`<span class="perf-breakdown-seg perf-breakdown-app" style="width:${d}%"></span>`:p}
1463
+ ${a>0?l`<span class="perf-breakdown-seg perf-breakdown-db" style="width:${a}%"></span>`:d}
1464
+ ${c>0?l`<span class="perf-breakdown-seg perf-breakdown-fetch" style="width:${c}%"></span>`:d}
1465
+ ${p>0?l`<span class="perf-breakdown-seg perf-breakdown-app" style="width:${p}%"></span>`:d}
1453
1466
  </span>
1454
1467
  </td>
1455
1468
  </tr>
1456
- `}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 e=t.summary,r=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests);return a`
1457
- ${this.renderDetailHeader(t,r)}
1458
- ${this.renderDetailMetrics(e,r,i)}
1469
+ `}renderDetail(){let t=this.graphData.find(n=>n.endpoint===this.selectedEndpoint);if(!t?.requests?.length)return l`<bk-empty-state subtitle="No data for this endpoint"></bk-empty-state>`;let e=t.summary,s=this.healthGradeForEndpoint(t),i=Math.round(e.errorRate*e.totalRequests);return l`
1470
+ ${this.renderDetailHeader(t,s)}
1471
+ ${this.renderDetailMetrics(e,s,i)}
1459
1472
  ${this.renderDetailBreakdown(e)}
1460
1473
  ${this.renderCallers(t.endpoint)}
1461
1474
  ${this.renderQueryBreakdown()}
1462
1475
  ${this.renderTrends(t)}
1463
1476
  ${this.renderDetailChart()}
1464
1477
  ${this.renderDetailHistory(t)}
1465
- `}renderDetailHeader(t,e){return a`
1478
+ `}renderDetailHeader(t,e){return l`
1466
1479
  <div class="perf-detail-header">
1467
1480
  <div class="perf-detail-title">
1468
1481
  <span class="perf-badge perf-badge-lg" style="color:${e.color};background:${e.bg};border-color:${e.border}">${e.label}</span>
1469
1482
  <span>${t.endpoint}</span>
1470
- ${t.baselineP95Ms?a`<span class="perf-baseline-hint">Baseline: ${_(t.baselineP95Ms)}</span>`:p}
1483
+ ${t.baselineP95Ms?l`<span class="perf-baseline-hint">Baseline: ${y(t.baselineP95Ms)}</span>`:d}
1471
1484
  </div>
1472
1485
  </div>
1473
- `}renderDetailMetrics(t,e,r){return a`
1486
+ `}renderDetailMetrics(t,e,s){return l`
1474
1487
  <div class="perf-metric-row">
1475
1488
  <div class="perf-metric-card">
1476
1489
  <span class="perf-metric-label">P95</span>
1477
- <span class="perf-metric-value" style="color:${e.color}">${_(t.p95Ms)}</span>
1490
+ <span class="perf-metric-value" style="color:${e.color}">${y(t.p95Ms)}</span>
1478
1491
  </div>
1479
1492
  <div class="perf-metric-card">
1480
1493
  <span class="perf-metric-label">Errors</span>
1481
- <span class="perf-metric-value" style="color:${r>0?"var(--red)":"var(--green)"}">
1482
- ${r>0?r+" ("+Math.round(t.errorRate*100)+"%)":"0"}
1494
+ <span class="perf-metric-value" style="color:${s>0?"var(--red)":"var(--green)"}">
1495
+ ${s>0?s+" ("+Math.round(t.errorRate*100)+"%)":"0"}
1483
1496
  </span>
1484
1497
  </div>
1485
1498
  <div class="perf-metric-card">
@@ -1487,71 +1500,71 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1487
1500
  <span class="perf-metric-value" style="color:${t.avgQueryCount>5?"var(--amber)":"var(--text)"}">${t.avgQueryCount}</span>
1488
1501
  </div>
1489
1502
  </div>
1490
- `}renderDetailBreakdown(t){let e=(t.avgQueryTimeMs||0)+(t.avgFetchTimeMs||0)+(t.avgAppTimeMs||0);if(e<=0)return p;let r=Math.round((t.avgQueryTimeMs||0)/e*100),i=Math.round((t.avgFetchTimeMs||0)/e*100),n=Math.max(0,100-r-i);return a`
1503
+ `}renderDetailBreakdown(t){let e=(t.avgQueryTimeMs||0)+(t.avgFetchTimeMs||0)+(t.avgAppTimeMs||0);if(e<=0)return d;let s=Math.round((t.avgQueryTimeMs||0)/e*100),i=Math.round((t.avgFetchTimeMs||0)/e*100),n=Math.max(0,100-s-i);return l`
1491
1504
  <div class="perf-breakdown">
1492
1505
  <div class="perf-section-title">Time Breakdown</div>
1493
1506
  <div class="perf-breakdown-bar">
1494
- ${r>0?a`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${r}%"></div>`:p}
1495
- ${i>0?a`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${i}%"></div>`:p}
1496
- ${n>0?a`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${n}%"></div>`:p}
1507
+ ${s>0?l`<div class="perf-breakdown-seg perf-breakdown-db" style="width:${s}%"></div>`:d}
1508
+ ${i>0?l`<div class="perf-breakdown-seg perf-breakdown-fetch" style="width:${i}%"></div>`:d}
1509
+ ${n>0?l`<div class="perf-breakdown-seg perf-breakdown-app" style="width:${n}%"></div>`:d}
1497
1510
  </div>
1498
1511
  <div class="perf-breakdown-legend">
1499
- <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${_(t.avgQueryTimeMs||0)} (${r}%)</span>
1500
- <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${_(t.avgFetchTimeMs||0)} (${i}%)</span>
1501
- <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${_(t.avgAppTimeMs||0)} (${n}%)</span>
1512
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-db"></span>DB ${y(t.avgQueryTimeMs||0)} (${s}%)</span>
1513
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-fetch"></span>Fetch ${y(t.avgFetchTimeMs||0)} (${i}%)</span>
1514
+ <span class="perf-breakdown-item"><span class="perf-breakdown-dot perf-breakdown-app"></span>App ${y(t.avgAppTimeMs||0)} (${n}%)</span>
1502
1515
  </div>
1503
1516
  </div>
1504
- `}renderCallers(t){let e=this.getCallers(t);return e.length===0?p:a`
1517
+ `}renderCallers(t){let e=this.getCallers(t);return e.length===0?d:l`
1505
1518
  <div class="perf-callers">
1506
1519
  <div class="perf-section-title">Called By</div>
1507
1520
  <div class="perf-callers-list">
1508
- ${e.map(r=>a`
1521
+ ${e.map(s=>l`
1509
1522
  <div class="perf-caller-row">
1510
- <span class="perf-caller-name">${r.label}</span>
1511
- <span class="perf-caller-count">${r.count} call${r.count!==1?"s":""}</span>
1512
- <span class="perf-caller-avg">avg ${_(r.avgMs)}</span>
1523
+ <span class="perf-caller-name">${s.label}</span>
1524
+ <span class="perf-caller-count">${s.count} call${s.count!==1?"s":""}</span>
1525
+ <span class="perf-caller-avg">avg ${y(s.avgMs)}</span>
1513
1526
  </div>
1514
1527
  `)}
1515
1528
  </div>
1516
1529
  </div>
1517
- `}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?p:a`
1530
+ `}renderQueryBreakdown(){return this.queryBreakdownLoading?l`<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:l`
1518
1531
  <div class="perf-queries">
1519
1532
  <div class="perf-section-title">DB Queries</div>
1520
1533
  <div class="perf-queries-list">
1521
- ${this.queryBreakdown.map(t=>a`
1534
+ ${this.queryBreakdown.map(t=>l`
1522
1535
  <div class="perf-query-row">
1523
1536
  <span class="perf-query-label">${t.label}</span>
1524
- <span class="perf-query-avg">avg ${_(t.avgMs)}</span>
1537
+ <span class="perf-query-avg">avg ${y(t.avgMs)}</span>
1525
1538
  <span class="perf-query-count">${t.count} call${t.count!==1?"s":""}</span>
1526
1539
  </div>
1527
1540
  `)}
1528
1541
  </div>
1529
1542
  </div>
1530
- `}renderTrends(t){let e=t.sessions;if(!e||e.length===0)return p;let r=e.slice(-10);return a`
1543
+ `}renderTrends(t){let e=t.sessions;if(!e||e.length===0)return d;let s=e.slice(-10);return l`
1531
1544
  <div class="perf-trends">
1532
1545
  <div class="perf-section-title">Session Trend</div>
1533
1546
  <div class="perf-trends-list">
1534
- ${r.map((i,n)=>{let l=n>0?r[n-1].p95DurationMs:null,c=l!==null?i.p95DurationMs>l*1.2?"slower":i.p95DurationMs<l*.8?"faster":"":"",d=this.formatTimeAgo(i.startedAt),h=n===r.length-1,m=this.healthGradeForDuration(i.p95DurationMs,t.baselineP95Ms);return a`
1547
+ ${s.map((i,n)=>{let a=n>0?s[n-1].p95DurationMs:null,c=a!==null?i.p95DurationMs>a*1.2?"slower":i.p95DurationMs<a*.8?"faster":"":"",p=this.formatTimeAgo(i.startedAt),h=n===s.length-1,m=this.healthGradeForDuration(i.p95DurationMs,t.baselineP95Ms);return l`
1535
1548
  <div class="perf-trend-row ${h?"perf-trend-current":""}">
1536
- <span class="perf-trend-time">${h?"Current":d}</span>
1549
+ <span class="perf-trend-time">${h?"Current":p}</span>
1537
1550
  <span class="perf-trend-p95">
1538
1551
  <span class="perf-hm-p95" style="color:${m.color};background:${m.bg};border-color:${m.border}">
1539
- p95: ${_(i.p95DurationMs)}
1552
+ p95: ${y(i.p95DurationMs)}
1540
1553
  </span>
1541
1554
  </span>
1542
1555
  <span class="perf-trend-reqs">${i.requestCount} req${i.requestCount!==1?"s":""}</span>
1543
1556
  <span class="perf-trend-errs" style="color:${i.errorCount>0?"var(--red)":"var(--text-dim)"}">${i.errorCount} err${i.errorCount!==1?"s":""}</span>
1544
- ${c?a`<span class="perf-trend-arrow ${c==="slower"?"perf-trend-slower":"perf-trend-faster"}">${c==="slower"?"\u2191 slower":"\u2193 faster"}</span>`:p}
1557
+ ${c?l`<span class="perf-trend-arrow ${c==="slower"?"perf-trend-slower":"perf-trend-faster"}">${c==="slower"?"\u2191 slower":"\u2193 faster"}</span>`:d}
1545
1558
  </div>
1546
1559
  `})}
1547
1560
  </div>
1548
1561
  </div>
1549
- `}formatTimeAgo(t){let e=Date.now()-t,r=Math.round(e/6e4);if(r<1)return "just now";if(r<60)return `${r}m ago`;let i=Math.round(r/60);return i<24?`${i}h ago`:`${Math.round(i/24)}d ago`}renderDetailChart(){return a`
1562
+ `}formatTimeAgo(t){let e=Date.now()-t,s=Math.round(e/6e4);if(s<1)return "just now";if(s<60)return `${s}m ago`;let i=Math.round(s/60);return i<24?`${i}h ago`:`${Math.round(i/24)}d ago`}renderDetailChart(){return l`
1550
1563
  <div class="perf-chart-wrap">
1551
1564
  <div class="perf-section-title">Response Time</div>
1552
1565
  <canvas id="perf-detail-canvas" class="perf-canvas" style="width:100%;height:240px"></canvas>
1553
1566
  </div>
1554
- `}renderDetailHistory(t){if(t.requests.length===0)return p;let e=[];for(let r=t.requests.length-1;r>=0&&e.length<50;r--)e.push({point:t.requests[r],originalIndex:r});return a`
1567
+ `}renderDetailHistory(t){if(t.requests.length===0)return d;let e=[];for(let s=t.requests.length-1;s>=0&&e.length<50;s--)e.push({point:t.requests[s],originalIndex:s});return l`
1555
1568
  <div class="perf-history-wrap">
1556
1569
  <table class="perf-table">
1557
1570
  <thead>
@@ -1565,39 +1578,39 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1565
1578
  </tr>
1566
1579
  </thead>
1567
1580
  <tbody>
1568
- ${e.map(r=>this.renderHistoryRow(r.point,r.originalIndex,t.baselineP95Ms))}
1581
+ ${e.map(s=>this.renderHistoryRow(s.point,s.originalIndex,t.baselineP95Ms))}
1569
1582
  </tbody>
1570
1583
  </table>
1571
1584
  </div>
1572
- `}renderHistoryRow(t,e,r){let i=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,d=t.fetchTimeMs||0,h=Math.max(0,t.durationMs-c-d);return a`
1573
- <tr class="perf-table-row ${l?"perf-row-err":""}" data-req-idx=${e}>
1585
+ `}renderHistoryRow(t,e,s){let i=this.healthGradeForDuration(t.durationMs,s),n=new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"}),a=t.statusCode>=400,c=t.queryTimeMs||0,p=t.fetchTimeMs||0,h=Math.max(0,t.durationMs-c-p);return l`
1586
+ <tr class="perf-table-row ${a?"perf-row-err":""}" data-req-idx=${e}>
1574
1587
  <td class="perf-td-muted">${n}</td>
1575
1588
  <td>
1576
1589
  <span class="perf-badge perf-badge-sm" style="color:${i.color};background:${i.bg};border-color:${i.border}">${i.label}</span>
1577
1590
  </td>
1578
- <td>${_(t.durationMs)}</td>
1591
+ <td>${y(t.durationMs)}</td>
1579
1592
  <td>
1580
- ${c>0?a`<span class="perf-bd-tag perf-bd-tag-db">DB ${_(c)}</span>`:p}
1581
- ${d>0?a`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${_(d)}</span>`:p}
1582
- <span class="perf-bd-tag perf-bd-tag-app">App ${_(h)}</span>
1593
+ ${c>0?l`<span class="perf-bd-tag perf-bd-tag-db">DB ${y(c)}</span>`:d}
1594
+ ${p>0?l`<span class="perf-bd-tag perf-bd-tag-fetch">Fetch ${y(p)}</span>`:d}
1595
+ <span class="perf-bd-tag perf-bd-tag-app">App ${y(h)}</span>
1583
1596
  </td>
1584
- <td class="perf-td-center" style="color:${l?"var(--red)":"var(--text-muted)"}">${t.statusCode}</td>
1597
+ <td class="perf-td-center" style="color:${a?"var(--red)":"var(--text-muted)"}">${t.statusCode}</td>
1585
1598
  <td class="perf-td-right perf-td-muted">${t.queryCount}</td>
1586
1599
  </tr>
1587
- `}};u([I({context:A})],Q.prototype,"store",2),u([b()],Q.prototype,"selectedEndpoint",2),u([b()],Q.prototype,"graphData",2),u([b()],Q.prototype,"loadError",2),u([b()],Q.prototype,"queryBreakdown",2),u([b()],Q.prototype,"queryBreakdownLoading",2),Q=u([S("bk-performance-view")],Q);var Xe={auth:{label:"Auth",color:"#059669",icon:"\u{1F6E1}",tooltip:"Highlight which endpoints require authentication and which are unprotected"},security:{label:"Security",color:"#dc2626",icon:"\u26A0",tooltip:"Show security findings like exposed secrets, token leaks, and PII exposure"},performance:{label:"Perf",color:"#2563eb",icon:"\u26A1",tooltip:"Color endpoints by P95 latency \u2014 green (fast) to red (slow)"},issues:{label:"Issues",color:"#d97706",icon:"\u25CF",tooltip:"Badge endpoints with open issues like N+1 queries or redundant calls"},heat:{label:"Heat",color:"#ef4444",icon:"\u{1F525}",tooltip:"Color nodes and edges by traffic volume \u2014 blue (low) to red (hot)"}},At={action:{fill:"#faf5ff",stroke:"#a855f7",icon:"\u25B6",columnHeader:"ACTIONS"},endpoint:{fill:"#f8fafc",stroke:"#6366f1",icon:"\u26A1",columnHeader:"ENDPOINTS"},table:{fill:"#f0fdf4",stroke:"#16a34a",icon:"\u229E",columnHeader:"TABLES"},external:{fill:"#fffbeb",stroke:"#d97706",icon:"\u25C6",columnHeader:"EXTERNAL"}},fe={triggers:"#a855f7",reads:"#6366f1",writes:"#ef4444",fetches:"#f59e0b",calls:"#22c55e"},yi=100,_i=300,$i=800;function It(o){return o<yi?"#22c55e":o<_i?"#3b82f6":o<$i?"#eab308":"#ef4444"}var xi=.25,Si=.5,Ti=.75;function Ve(o){return o<xi?"#3b82f6":o<Si?"#22c55e":o<Ti?"#eab308":"#ef4444"}var zs="#4338ca",Js="#e0e7ff",Zs="#818cf8",tr="#eef2ff",Ke="#7c3aed",er="#6366f1",ve="#f97316",sr="#ecfdf5",ze="#059669",rr="#fef2f2",Je="#dc2626",ir="#fffbeb",Ze="#d97706",ct="#ef4444",or=.2,nr=3,ts=1.2,Kt=40;var ar=800,lr=500;function Ci(o){return Math.max(140,o.length*7.2+36)}function es(o,s){return Math.round(36+o.stats.requestCount/s*28)}function Li(o){return o.length>0?Math.max(140,...o.map(s=>Ci(s.label))):0}function dr(o,s,t){let e=[];for(let r of s){let i=r.source===o?r.target:r.target===o?r.source:null;if(i){let n=t.get(i);n&&e.push(n.y+n.h/2);}}return e.length>0?e.reduce((r,i)=>r+i,0)/e.length:1/0}function hr(o,s){let t=f=>o.filter(g=>g.type===f).sort((g,T)=>T.stats.requestCount-g.stats.requestCount),e=t("action"),r=t("endpoint"),i=t("table"),n=t("external"),l=Math.max(1,...o.map(f=>f.stats.requestCount)),c=new Map,d=[],h=[],m=50,v=[{type:"action",items:e},{type:"endpoint",items:r},{type:"table",items:i},{type:"external",items:n}];for(let f of v)if(f.items.length>0){let g=Li(f.items);h.push({type:f.type,items:f.items,width:g,x:m}),m+=g+160;}let x=h[0];if(x){let f=74;for(let g of x.items){let T=es(g,l),R={id:g.id,x:x.x,y:f,w:x.width,h:T,label:g.label,type:g.type,stats:g.stats,annotations:g.annotations};d.push(R),c.set(g.id,R),f+=T+10;}}for(let f=1;f<h.length;f++){let g=h[f],T=[...g.items].sort((C,q)=>dr(C.id,s,c)-dr(q.id,s,c)),R=d.filter(C=>C.x===h[f-1].x),H=Math.min(...R.map(C=>C.y)),B=Math.max(...R.map(C=>C.y+C.h))-H,V=T.reduce((C,q)=>C+es(q,l)+10,-10),G=H+Math.max(0,(B-V)/2);for(let C of T){let q=es(C,l),rs={id:C.id,x:g.x,y:G,w:g.width,h:q,label:C.label,type:C.type,stats:C.stats,annotations:C.annotations};d.push(rs),c.set(C.id,rs),G+=q+10;}}let y=[];for(let f of s){let g=c.get(f.source),T=c.get(f.target);if(!g||!T)continue;let R=g.x<T.x,H=R?g.x+g.w:g.x,X=g.y+g.h/2,B=R?T.x:T.x+T.w,V=T.y+T.h/2,G=[];f.stats.frequency>1&&G.push(`${f.stats.frequency}\xD7`),G.push(f.type),f.stats.avgLatencyMs>0&&G.push(`${f.stats.avgLatencyMs}ms`),y.push({key:f.id,sx:H,sy:X,tx:B,ty:V,label:G.join(" \xB7 "),color:fe[f.type]||"#94a3b8",thickness:Math.min(.75+Math.log2(f.stats.frequency+1)*.35,2.5),dashed:f.type==="reads"||f.type==="writes",data:f});}let k=d.reduce((f,g)=>Math.max(f,g.x+g.w),0),$=d.reduce((f,g)=>Math.max(f,g.y+g.h),0);return {nodes:d,edges:y,width:k+100,height:Math.max($+50,250)}}function ur(o){let s=o.charCodeAt(0);return s>=48&&s<=57||s>=65&&s<=70||s>=97&&s<=102}function Mi(o){if(o.length!==36)return false;for(let s=0;s<o.length;s++)if(s===8||s===13||s===18||s===23){if(o[s]!=="-")return false}else if(!ur(o[s]))return false;return true}function Ni(o){if(!o.length)return false;for(let s=0;s<o.length;s++){let t=o.charCodeAt(s);if(t<48||t>57)return false}return true}function Oi(o){if(o.length<12)return false;for(let s=0;s<o.length;s++)if(!ur(o[s]))return false;return true}function ki(o){if(o.length<8)return false;let s=false,t=false;for(let e=0;e<o.length;e++){let r=o.charCodeAt(e);if(r>=65&&r<=90||r>=97&&r<=122)s=true;else if(r>=48&&r<=57)t=true;else if(r!==95&&r!==45)return false}return s&&t}var Di=":id";function Hi(o){return Mi(o)||Ni(o)||Oi(o)||ki(o)?Di:o}function ss(o,s){let t=s.split("?")[0];return `${o} ${t.split("/").map(e=>e&&Hi(e)).join("/")}`}function mr(o,s,t){let e=[...o],r=[...s],i=new Set(e.map(l=>l.id)),n=new Map;for(let l of t){let c=l.label||"Unknown",d=n.get(c);d||(d={endpointKeys:new Set,count:0,totalMs:0},n.set(c,d)),d.count++,d.totalMs+=l.totalDurationMs;for(let h of l.requests)h.path?.startsWith(F)||d.endpointKeys.add(ss(h.method,h.path));}for(let[l,c]of n){let d=`action:${l}`;i.has(d)||(e.push({id:d,type:"action",label:l,stats:{requestCount:c.count,avgLatencyMs:c.count>0?Math.round(c.totalMs/c.count):0,errorRate:0,avgQueryCount:0}}),i.add(d));for(let h of c.endpointKeys){let m=`endpoint:${h}`;if(i.has(m)){let v=`${d} -> ${m}`;r.find(x=>x.id===v)||r.push({id:v,source:d,target:m,type:"triggers",stats:{frequency:c.count,avgLatencyMs:0}});}}}return {nodes:e,edges:r}}function fr(o){let s=new Map;for(let t of o){let e=t.label||"Unknown",r=s.get(e);r||(r={keys:new Set,count:0,totalMs:0},s.set(e,r)),r.count++,r.totalMs+=t.totalDurationMs;for(let i of t.requests)i.path?.startsWith(F)||r.keys.add(ss(i.method,i.path));}return [...s.entries()].map(([t,e])=>({label:t,occurrences:e.count,endpointKeys:e.keys,avgDurationMs:e.count>0?Math.round(e.totalMs/e.count):0}))}function be(o,s){let t=`event=${encodeURIComponent(o)}${s?`&detail=${encodeURIComponent(s)}`:""}`;fetch(`${w.tab}?${t}`).catch(()=>{});}var M=class extends E{constructor(){super(...arguments);this.graphNodes=[];this.graphEdges=[];this.locked=null;this.hovered=null;this.loading=true;this.activeLayers=new Set;this.searchQuery="";this.viewTransform={x:0,y:0,scale:1};this.isPanning=false;this.panStart={x:0,y:0,vtx:0,vty:0};this.dragging=null;this.wasDragging=false;this.nodePositionOverrides=new Map;this.detailTab="overview";this.consolidatedFlows=[];this.activeFlowIdx=-1;this.focusIdx=-1;this.refreshTimer=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadData(),this.refreshTimer=setInterval(()=>this.loadData(),4e3);}disconnectedCallback(){super.disconnectedCallback(),this.refreshTimer&&clearInterval(this.refreshTimer);}async loadData(){try{let[t,e]=await Promise.all([fetch(`${w.graph}?level=endpoints`),fetch(w.flows)]),r=await t.json(),i=await e.json(),n=mr(r.nodes||[],r.edges||[],i.flows||[]);this.graphNodes=n.nodes,this.graphEdges=n.edges,this.consolidatedFlows=fr(i.flows||[]),this.nodePositionOverrides.size===0&&this.graphNodes.length>0&&this.tryLoadPersistedPositions(),this.loading=!1;}catch{this.loading=false;}}getPositionStorageKey(){let t=this.graphNodes.map(r=>r.id).sort().join(","),e=0;for(let r=0;r<t.length;r++)e=(e<<5)-e+t.charCodeAt(r)|0;return `bk-graph-pos-${e}`}persistPositions(){if(this.nodePositionOverrides.size!==0)try{let t=Object.fromEntries(this.nodePositionOverrides);localStorage.setItem(this.getPositionStorageKey(),JSON.stringify(t));}catch{}}tryLoadPersistedPositions(){try{let t=localStorage.getItem(this.getPositionStorageKey());if(t){let e=JSON.parse(t);this.nodePositionOverrides=new Map(Object.entries(e));}}catch{}}get activeNodeId(){return this.locked??this.hovered}getHighlightedNodeIds(){let t=this.activeNodeId;if(!t)return null;let e=new Set([t]),r=true;for(;r;){r=false;for(let i of this.graphEdges)e.has(i.source)&&!e.has(i.target)&&(e.add(i.target),r=true);}return e}getFlowTraceNodeIds(){if(this.activeFlowIdx<0||this.activeFlowIdx>=this.consolidatedFlows.length)return null;let t=this.consolidatedFlows[this.activeFlowIdx],e=new Set;e.add(`action:${t.label}`);for(let r of t.endpointKeys)e.add(`endpoint:${r}`);for(let r of this.graphEdges)e.has(r.source)&&e.add(r.target);return e}getFlowTraceEdgeIds(){let t=this.getFlowTraceNodeIds();if(!t)return null;let e=new Set;for(let r of this.graphEdges)t.has(r.source)&&t.has(r.target)&&e.add(r.id);return e}matchesSearch(t){return this.searchQuery?t.toLowerCase().includes(this.searchQuery.toLowerCase()):true}handlePanStart(t){t.button===0&&(t.target.closest(".graph-g")||(this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY,vtx:this.viewTransform.x,vty:this.viewTransform.y}));}handlePanMove(t){if(this.dragging){let e=t.currentTarget.getBoundingClientRect(),r=(t.clientX-e.left-this.viewTransform.x)/this.viewTransform.scale,i=(t.clientY-e.top-this.viewTransform.y)/this.viewTransform.scale;this.nodePositionOverrides.set(this.dragging.nodeId,{x:r-this.dragging.offsetX,y:i-this.dragging.offsetY}),this.requestUpdate();return}this.isPanning&&(this.viewTransform={...this.viewTransform,x:this.panStart.vtx+(t.clientX-this.panStart.x),y:this.panStart.vty+(t.clientY-this.panStart.y)});}handlePanEnd(){this.dragging&&(this.persistPositions(),this.dragging=null,this.wasDragging=true,requestAnimationFrame(()=>{this.wasDragging=false;})),this.isPanning=false;}resetView(){this.viewTransform={x:0,y:0,scale:1};}zoomIn(){this.viewTransform={...this.viewTransform,scale:Math.min(nr,this.viewTransform.scale*ts)};}zoomOut(){this.viewTransform={...this.viewTransform,scale:Math.max(or,this.viewTransform.scale/ts)};}resetLayout(){this.nodePositionOverrides.clear();try{localStorage.removeItem(this.getPositionStorageKey());}catch{}this.viewTransform={x:0,y:0,scale:1},this.requestUpdate(),be("layout_reset");}startNodeDrag(t,e,r){t.stopPropagation();let i=t.currentTarget.closest("svg").getBoundingClientRect(),n=(t.clientX-i.left-this.viewTransform.x)/this.viewTransform.scale,l=(t.clientY-i.top-this.viewTransform.y)/this.viewTransform.scale;this.dragging={nodeId:e,offsetX:n-r.x,offsetY:l-r.y};}handleKeyDown(t){let e=this.graphNodes;if(t.key==="/"){t.preventDefault(),this.querySelector(".graph-search-input")?.focus();return}if(t.key==="Escape"){this.locked=null,this.searchQuery="",this.focusIdx=-1,this.activeFlowIdx=-1;return}if(t.key==="Tab"){t.preventDefault(),this.focusIdx=t.shiftKey?this.focusIdx<=0?e.length-1:this.focusIdx-1:(this.focusIdx+1)%e.length,this.hovered=e[this.focusIdx]?.id??null;return}if(t.key==="Enter"&&this.focusIdx>=0){let r=e[this.focusIdx];r&&(this.locked=this.locked===r.id?null:r.id);return}if(t.key==="+"||t.key==="="){this.zoomIn();return}if(t.key==="-"){this.zoomOut();return}if(t.key==="ArrowUp"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y+Kt};return}if(t.key==="ArrowDown"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y-Kt};return}if(t.key==="ArrowLeft"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x+Kt};return}if(t.key==="ArrowRight"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x-Kt};return}}render(){if(this.loading&&this.graphNodes.length===0)return a`<div class="graph-loading">Loading graph…</div>`;if(this.graphNodes.length===0)return a`
1600
+ `}};u([C({context:A})],V.prototype,"store",2),u([b()],V.prototype,"selectedEndpoint",2),u([b()],V.prototype,"graphData",2),u([b()],V.prototype,"loadError",2),u([b()],V.prototype,"queryBreakdown",2),u([b()],V.prototype,"queryBreakdownLoading",2),V=u([_("bk-performance-view")],V);var rs={auth:{label:"Auth",color:"#059669",icon:"\u{1F6E1}",tooltip:"Highlight which endpoints require authentication and which are unprotected"},security:{label:"Security",color:"#dc2626",icon:"\u26A0",tooltip:"Show security findings like exposed secrets, token leaks, and PII exposure"},performance:{label:"Perf",color:"#2563eb",icon:"\u26A1",tooltip:"Color endpoints by P95 latency \u2014 green (fast) to red (slow)"},issues:{label:"Issues",color:"#d97706",icon:"\u25CF",tooltip:"Badge endpoints with open issues like N+1 queries or redundant calls"},heat:{label:"Heat",color:"#ef4444",icon:"\u{1F525}",tooltip:"Color nodes and edges by traffic volume \u2014 blue (low) to red (hot)"}},kt={action:{fill:"#faf5ff",stroke:"#a855f7",icon:"\u25B6",columnHeader:"ACTIONS"},endpoint:{fill:"#f8fafc",stroke:"#6366f1",icon:"\u26A1",columnHeader:"ENDPOINTS"},table:{fill:"#f0fdf4",stroke:"#16a34a",icon:"\u229E",columnHeader:"TABLES"},external:{fill:"#fffbeb",stroke:"#d97706",icon:"\u25C6",columnHeader:"EXTERNAL"}},xe={triggers:"#a855f7",reads:"#6366f1",writes:"#ef4444",fetches:"#f59e0b",calls:"#22c55e"},Ii=100,Li=300,Mi=800;function Ot(o){return o<Ii?"#22c55e":o<Li?"#3b82f6":o<Mi?"#eab308":"#ef4444"}var ki=.25,Oi=.5,Ni=.75;function is(o){return o<ki?"#3b82f6":o<Oi?"#22c55e":o<Ni?"#eab308":"#ef4444"}var cr="#4338ca",dr="#e0e7ff",pr="#818cf8",hr="#eef2ff",os="#7c3aed",ur="#6366f1",Se="#f97316",mr="#ecfdf5",ns="#059669",fr="#fef2f2",as="#dc2626",vr="#fffbeb",ls="#d97706",ut="#ef4444",gr=.2,br=3,cs=1.2,re=40;var Er=800,yr=500;function Ui(o){return Math.max(140,o.length*7.2+36)}function ds(o,r){return Math.round(36+o.stats.requestCount/r*28)}function Fi(o){return o.length>0?Math.max(140,...o.map(r=>Ui(r.label))):0}function _r(o,r,t){let e=[];for(let s of r){let i=s.source===o?s.target:s.target===o?s.source:null;if(i){let n=t.get(i);n&&e.push(n.y+n.h/2);}}return e.length>0?e.reduce((s,i)=>s+i,0)/e.length:1/0}function Sr(o,r){let t=v=>o.filter(g=>g.type===v).sort((g,x)=>x.stats.requestCount-g.stats.requestCount),e=t("action"),s=t("endpoint"),i=t("table"),n=t("external"),a=Math.max(1,...o.map(v=>v.stats.requestCount)),c=new Map,p=[],h=[],m=50,f=[{type:"action",items:e},{type:"endpoint",items:s},{type:"table",items:i},{type:"external",items:n}];for(let v of f)if(v.items.length>0){let g=Fi(v.items);h.push({type:v.type,items:v.items,width:g,x:m}),m+=g+160;}let S=h[0];if(S){let v=74;for(let g of S.items){let x=ds(g,a),w={id:g.id,x:S.x,y:v,w:S.width,h:x,label:g.label,type:g.type,stats:g.stats,annotations:g.annotations};p.push(w),c.set(g.id,w),v+=x+10;}}for(let v=1;v<h.length;v++){let g=h[v],x=[...g.items].sort((I,F)=>_r(I.id,r,c)-_r(F.id,r,c)),w=p.filter(I=>I.x===h[v-1].x),H=Math.min(...w.map(I=>I.y)),Q=Math.max(...w.map(I=>I.y+I.h))-H,tt=x.reduce((I,F)=>I+ds(F,a)+10,-10),W=H+Math.max(0,(Q-tt)/2);for(let I of x){let F=ds(I,a),hs={id:I.id,x:g.x,y:W,w:g.width,h:F,label:I.label,type:I.type,stats:I.stats,annotations:I.annotations};p.push(hs),c.set(I.id,hs),W+=F+10;}}let R=[];for(let v of r){let g=c.get(v.source),x=c.get(v.target);if(!g||!x)continue;let w=g.x<x.x,H=w?g.x+g.w:g.x,Z=g.y+g.h/2,Q=w?x.x:x.x+x.w,tt=x.y+x.h/2,W=[];v.stats.frequency>1&&W.push(`${v.stats.frequency}\xD7`),W.push(v.type),v.stats.avgLatencyMs>0&&W.push(`${v.stats.avgLatencyMs}ms`),R.push({key:v.id,sx:H,sy:Z,tx:Q,ty:tt,label:W.join(" \xB7 "),color:xe[v.type]||"#94a3b8",thickness:Math.min(.75+Math.log2(v.stats.frequency+1)*.35,2.5),dashed:v.type==="reads"||v.type==="writes",data:v});}let P=p.reduce((v,g)=>Math.max(v,g.x+g.w),0),$=p.reduce((v,g)=>Math.max(v,g.y+g.h),0);return {nodes:p,edges:R,width:P+100,height:Math.max($+50,250)}}function Tr(o){let r=o.charCodeAt(0);return r>=48&&r<=57||r>=65&&r<=70||r>=97&&r<=102}function Gi(o){if(o.length!==36)return false;for(let r=0;r<o.length;r++)if(r===8||r===13||r===18||r===23){if(o[r]!=="-")return false}else if(!Tr(o[r]))return false;return true}function Bi(o){if(!o.length)return false;for(let r=0;r<o.length;r++){let t=o.charCodeAt(r);if(t<48||t>57)return false}return true}function Wi(o){if(o.length<12)return false;for(let r=0;r<o.length;r++)if(!Tr(o[r]))return false;return true}function ji(o){if(o.length<8)return false;let r=false,t=false;for(let e=0;e<o.length;e++){let s=o.charCodeAt(e);if(s>=65&&s<=90||s>=97&&s<=122)r=true;else if(s>=48&&s<=57)t=true;else if(s!==95&&s!==45)return false}return r&&t}var Qi=":id";function Yi(o){return Gi(o)||Bi(o)||Wi(o)||ji(o)?Qi:o}function ps(o,r){let t=r.split("?")[0];return `${o} ${t.split("/").map(e=>e&&Yi(e)).join("/")}`}function wr(o,r,t){let e=[...o],s=[...r],i=new Set(e.map(a=>a.id)),n=new Map;for(let a of t){let c=a.label||"Unknown",p=n.get(c);p||(p={endpointKeys:new Set,count:0,totalMs:0},n.set(c,p)),p.count++,p.totalMs+=a.totalDurationMs;for(let h of a.requests)h.path?.startsWith(U)||p.endpointKeys.add(ps(h.method,h.path));}for(let[a,c]of n){let p=`action:${a}`;i.has(p)||(e.push({id:p,type:"action",label:a,stats:{requestCount:c.count,avgLatencyMs:c.count>0?Math.round(c.totalMs/c.count):0,errorRate:0,avgQueryCount:0}}),i.add(p));for(let h of c.endpointKeys){let m=`endpoint:${h}`;if(i.has(m)){let f=`${p} -> ${m}`;s.find(S=>S.id===f)||s.push({id:f,source:p,target:m,type:"triggers",stats:{frequency:c.count,avgLatencyMs:0}});}}}return {nodes:e,edges:s}}function Rr(o){let r=new Map;for(let t of o){let e=t.label||"Unknown",s=r.get(e);s||(s={keys:new Set,count:0,totalMs:0},r.set(e,s)),s.count++,s.totalMs+=t.totalDurationMs;for(let i of t.requests)i.path?.startsWith(U)||s.keys.add(ps(i.method,i.path));}return [...r.entries()].map(([t,e])=>({label:t,occurrences:e.count,endpointKeys:e.keys,avgDurationMs:e.count>0?Math.round(e.totalMs/e.count):0}))}function we(o,r){let t=`event=${encodeURIComponent(o)}${r?`&detail=${encodeURIComponent(r)}`:""}`;fetch(`${T.tab}?${t}`).catch(()=>{});}var M=class extends E{constructor(){super(...arguments);this.graphNodes=[];this.graphEdges=[];this.locked=null;this.hovered=null;this.loading=true;this.activeLayers=new Set;this.searchQuery="";this.viewTransform={x:0,y:0,scale:1};this.isPanning=false;this.panStart={x:0,y:0,vtx:0,vty:0};this.dragging=null;this.wasDragging=false;this.nodePositionOverrides=new Map;this.detailTab="overview";this.consolidatedFlows=[];this.activeFlowIdx=-1;this.focusIdx=-1;this.refreshTimer=null;}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadData(),this.refreshTimer=setInterval(()=>this.loadData(),4e3);}disconnectedCallback(){super.disconnectedCallback(),this.refreshTimer&&clearInterval(this.refreshTimer);}async loadData(){try{let[t,e]=await Promise.all([fetch(`${T.graph}?level=endpoints`),fetch(T.flows)]),s=await t.json(),i=await e.json(),n=wr(s.nodes||[],s.edges||[],i.flows||[]);this.graphNodes=n.nodes,this.graphEdges=n.edges,this.consolidatedFlows=Rr(i.flows||[]),this.nodePositionOverrides.size===0&&this.graphNodes.length>0&&this.tryLoadPersistedPositions(),this.loading=!1;}catch{this.loading=false;}}getPositionStorageKey(){let t=this.graphNodes.map(s=>s.id).sort().join(","),e=0;for(let s=0;s<t.length;s++)e=(e<<5)-e+t.charCodeAt(s)|0;return `bk-graph-pos-${e}`}persistPositions(){if(this.nodePositionOverrides.size!==0)try{let t=Object.fromEntries(this.nodePositionOverrides);localStorage.setItem(this.getPositionStorageKey(),JSON.stringify(t));}catch{}}tryLoadPersistedPositions(){try{let t=localStorage.getItem(this.getPositionStorageKey());if(t){let e=JSON.parse(t);this.nodePositionOverrides=new Map(Object.entries(e));}}catch{}}get activeNodeId(){return this.locked??this.hovered}getHighlightedNodeIds(){let t=this.activeNodeId;if(!t)return null;let e=new Set([t]),s=true;for(;s;){s=false;for(let i of this.graphEdges)e.has(i.source)&&!e.has(i.target)&&(e.add(i.target),s=true);}return e}getFlowTraceNodeIds(){if(this.activeFlowIdx<0||this.activeFlowIdx>=this.consolidatedFlows.length)return null;let t=this.consolidatedFlows[this.activeFlowIdx],e=new Set;e.add(`action:${t.label}`);for(let s of t.endpointKeys)e.add(`endpoint:${s}`);for(let s of this.graphEdges)e.has(s.source)&&e.add(s.target);return e}getFlowTraceEdgeIds(){let t=this.getFlowTraceNodeIds();if(!t)return null;let e=new Set;for(let s of this.graphEdges)t.has(s.source)&&t.has(s.target)&&e.add(s.id);return e}matchesSearch(t){return this.searchQuery?t.toLowerCase().includes(this.searchQuery.toLowerCase()):true}handlePanStart(t){t.button===0&&(t.target.closest(".graph-g")||(this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY,vtx:this.viewTransform.x,vty:this.viewTransform.y}));}handlePanMove(t){if(this.dragging){let e=t.currentTarget.getBoundingClientRect(),s=(t.clientX-e.left-this.viewTransform.x)/this.viewTransform.scale,i=(t.clientY-e.top-this.viewTransform.y)/this.viewTransform.scale;this.nodePositionOverrides.set(this.dragging.nodeId,{x:s-this.dragging.offsetX,y:i-this.dragging.offsetY}),this.requestUpdate();return}this.isPanning&&(this.viewTransform={...this.viewTransform,x:this.panStart.vtx+(t.clientX-this.panStart.x),y:this.panStart.vty+(t.clientY-this.panStart.y)});}handlePanEnd(){this.dragging&&(this.persistPositions(),this.dragging=null,this.wasDragging=true,requestAnimationFrame(()=>{this.wasDragging=false;})),this.isPanning=false;}resetView(){this.viewTransform={x:0,y:0,scale:1};}zoomIn(){this.viewTransform={...this.viewTransform,scale:Math.min(br,this.viewTransform.scale*cs)};}zoomOut(){this.viewTransform={...this.viewTransform,scale:Math.max(gr,this.viewTransform.scale/cs)};}resetLayout(){this.nodePositionOverrides.clear();try{localStorage.removeItem(this.getPositionStorageKey());}catch{}this.viewTransform={x:0,y:0,scale:1},this.requestUpdate(),we("layout_reset");}startNodeDrag(t,e,s){t.stopPropagation();let i=t.currentTarget.closest("svg").getBoundingClientRect(),n=(t.clientX-i.left-this.viewTransform.x)/this.viewTransform.scale,a=(t.clientY-i.top-this.viewTransform.y)/this.viewTransform.scale;this.dragging={nodeId:e,offsetX:n-s.x,offsetY:a-s.y};}handleKeyDown(t){let e=this.graphNodes;if(t.key==="/"){t.preventDefault(),this.querySelector(".graph-search-input")?.focus();return}if(t.key==="Escape"){this.locked=null,this.searchQuery="",this.focusIdx=-1,this.activeFlowIdx=-1;return}if(t.key==="Tab"){t.preventDefault(),this.focusIdx=t.shiftKey?this.focusIdx<=0?e.length-1:this.focusIdx-1:(this.focusIdx+1)%e.length,this.hovered=e[this.focusIdx]?.id??null;return}if(t.key==="Enter"&&this.focusIdx>=0){let s=e[this.focusIdx];s&&(this.locked=this.locked===s.id?null:s.id);return}if(t.key==="+"||t.key==="="){this.zoomIn();return}if(t.key==="-"){this.zoomOut();return}if(t.key==="ArrowUp"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y+re};return}if(t.key==="ArrowDown"){this.viewTransform={...this.viewTransform,y:this.viewTransform.y-re};return}if(t.key==="ArrowLeft"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x+re};return}if(t.key==="ArrowRight"){this.viewTransform={...this.viewTransform,x:this.viewTransform.x-re};return}}render(){if(this.loading&&this.graphNodes.length===0)return l`<div class="graph-loading">Loading graph…</div>`;if(this.graphNodes.length===0)return l`
1588
1601
  <div class="graph-empty">
1589
1602
  <div class="graph-empty-icon">◎</div>
1590
1603
  <div class="graph-empty-title">No data yet</div>
1591
1604
  <div class="graph-empty-desc">Navigate your app to build the dependency graph.</div>
1592
1605
  </div>
1593
- `;let t=hr(this.graphNodes,this.graphEdges);this.applyPositionOverrides(t);let e=this.getSelectedNodeDetail(),r=this.getHighlightedNodeIds(),i=this.getFlowTraceNodeIds(),n=this.getFlowTraceEdgeIds(),l=this.deduplicateColumnHeaders(t.nodes),c=Math.max(1,...this.graphNodes.map(h=>h.stats.requestCount)),d=this.viewTransform;return a`
1606
+ `;let t=Sr(this.graphNodes,this.graphEdges);this.applyPositionOverrides(t);let e=this.getSelectedNodeDetail(),s=this.getHighlightedNodeIds(),i=this.getFlowTraceNodeIds(),n=this.getFlowTraceEdgeIds(),a=this.deduplicateColumnHeaders(t.nodes),c=Math.max(1,...this.graphNodes.map(h=>h.stats.requestCount)),p=this.viewTransform;return l`
1594
1607
  <div class="graph-wrapper" tabindex="0" @keydown=${this.handleKeyDown}
1595
1608
  @click=${h=>{let m=h.target;m.closest(".graph-detail")||m.closest(".graph-toolbar")||m.closest(".graph-float")||m.closest(".graph-g")||(this.locked=null);}}>
1596
1609
  ${this.renderToolbar()}
1597
1610
  <div class="graph-body">
1598
1611
  <div class="graph-canvas" style="position:relative">
1599
1612
  <svg width="100%" height="100%"
1600
- viewBox="0 0 ${Math.max(t.width,ar)} ${Math.max(t.height,lr)}"
1613
+ viewBox="0 0 ${Math.max(t.width,Er)} ${Math.max(t.height,yr)}"
1601
1614
  class="graph-svg"
1602
1615
  style="cursor:${this.isPanning?"grabbing":"grab"}"
1603
1616
  @mousedown=${this.handlePanStart}
@@ -1605,26 +1618,26 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1605
1618
  @mouseup=${this.handlePanEnd}
1606
1619
  @mouseleave=${this.handlePanEnd}>
1607
1620
 
1608
- <g transform="translate(${d.x},${d.y}) scale(${d.scale})">
1609
- ${O`${l.map(h=>O`
1621
+ <g transform="translate(${p.x},${p.y}) scale(${p.scale})">
1622
+ ${O`${a.map(h=>O`
1610
1623
  <text x="${h.x}" y="${58}" class="graph-col-header">${h.label}</text>
1611
1624
  `)}`}
1612
1625
 
1613
- ${t.edges.map(h=>this.renderEdge(h,r,n,c))}
1614
- ${t.nodes.map(h=>this.renderNode(h,r,i,c))}
1626
+ ${t.edges.map(h=>this.renderEdge(h,s,n,c))}
1627
+ ${t.nodes.map(h=>this.renderNode(h,s,i,c))}
1615
1628
  </g>
1616
1629
  </svg>
1617
1630
  ${this.renderFloatingControls()}
1618
1631
  </div>
1619
- ${e?this.renderDetailPanel(e):p}
1632
+ ${e?this.renderDetailPanel(e):d}
1620
1633
  </div>
1621
1634
  </div>
1622
- `}applyPositionOverrides(t){for(let r of t.nodes){let i=this.nodePositionOverrides.get(r.id);i&&(r.x=i.x,r.y=i.y);}let e=new Map(t.nodes.map(r=>[r.id,r]));for(let r of t.edges){let i=e.get(r.data.source),n=e.get(r.data.target);if(i&&n){let l=i.x<n.x;r.sx=l?i.x+i.w:i.x,r.sy=i.y+i.h/2,r.tx=l?n.x:n.x+n.w,r.ty=n.y+n.h/2;}}}deduplicateColumnHeaders(t){let e=[],r=new Set;for(let i of t)r.has(i.type)||(r.add(i.type),e.push({x:i.x,label:At[i.type]?.columnHeader||i.type.toUpperCase()}));return e}renderToolbar(){return a`
1635
+ `}applyPositionOverrides(t){for(let s of t.nodes){let i=this.nodePositionOverrides.get(s.id);i&&(s.x=i.x,s.y=i.y);}let e=new Map(t.nodes.map(s=>[s.id,s]));for(let s of t.edges){let i=e.get(s.data.source),n=e.get(s.data.target);if(i&&n){let a=i.x<n.x;s.sx=a?i.x+i.w:i.x,s.sy=i.y+i.h/2,s.tx=a?n.x:n.x+n.w,s.ty=n.y+n.h/2;}}}deduplicateColumnHeaders(t){let e=[],s=new Set;for(let i of t)s.has(i.type)||(s.add(i.type),e.push({x:i.x,label:kt[i.type]?.columnHeader||i.type.toUpperCase()}));return e}renderToolbar(){return l`
1623
1636
  <div class="graph-toolbar">
1624
1637
  <div class="graph-layer-toggles">
1625
- ${Object.keys(Xe).map(t=>{let e=Xe[t],r=this.activeLayers.has(t);return a`
1626
- <button class="graph-layer-btn ${r?"active":""}"
1627
- style="${r?`border-color:${e.color};color:${e.color}`:""}"
1638
+ ${Object.keys(rs).map(t=>{let e=rs[t],s=this.activeLayers.has(t);return l`
1639
+ <button class="graph-layer-btn ${s?"active":""}"
1640
+ style="${s?`border-color:${e.color};color:${e.color}`:""}"
1628
1641
  @click=${()=>this.toggleLayer(t)}
1629
1642
  title="${e.tooltip}">
1630
1643
  ${e.icon} ${e.label}
@@ -1637,382 +1650,479 @@ span.perf-breakdown-dot.perf-breakdown-app{background:var(--breakdown-app)}
1637
1650
  <input class="graph-search-input" type="text" placeholder="Search nodes… ( / )"
1638
1651
  .value=${this.searchQuery}
1639
1652
  @input=${t=>{this.searchQuery=t.target.value;}}>
1640
- ${this.searchQuery?a`
1653
+ ${this.searchQuery?l`
1641
1654
  <button class="graph-search-clear" @click=${()=>{this.searchQuery="";}}>✕</button>
1642
- `:p}
1655
+ `:d}
1643
1656
  </div>
1644
1657
 
1645
- ${this.consolidatedFlows.length>0?a`
1646
- <select class="graph-flow-picker" @change=${t=>{this.activeFlowIdx=parseInt(t.target.value,10),this.activeFlowIdx>=0&&be("flow_traced");}}>
1658
+ ${this.consolidatedFlows.length>0?l`
1659
+ <select class="graph-flow-picker" @change=${t=>{this.activeFlowIdx=parseInt(t.target.value,10),this.activeFlowIdx>=0&&we("flow_traced");}}>
1647
1660
  <option value="-1">Trace flow…</option>
1648
- ${this.consolidatedFlows.map((t,e)=>a`
1661
+ ${this.consolidatedFlows.map((t,e)=>l`
1649
1662
  <option value="${e}" ?selected=${this.activeFlowIdx===e}>${t.label} → ${t.endpointKeys.size} ep · ${t.occurrences}×</option>
1650
1663
  `)}
1651
1664
  </select>
1652
- `:p}
1665
+ `:d}
1653
1666
 
1654
- ${this.activeLayers.has("auth")?a`
1667
+ ${this.activeLayers.has("auth")?l`
1655
1668
  <div class="graph-auth-legend">
1656
- <span class="graph-auth-legend-item"><span style="color:${ze}">🛡</span> protected</span>
1657
- <span class="graph-auth-legend-item"><span style="color:${ve};font-weight:700">!</span> no auth</span>
1669
+ <span class="graph-auth-legend-item"><span style="color:${ns}">🛡</span> protected</span>
1670
+ <span class="graph-auth-legend-item"><span style="color:${Se};font-weight:700">!</span> no auth</span>
1658
1671
  </div>
1659
- `:p}
1672
+ `:d}
1660
1673
  </div>
1661
- `}renderFloatingControls(){let t=this.nodePositionOverrides.size>0,e=Math.round(this.viewTransform.scale*100);return a`
1674
+ `}renderFloatingControls(){let t=this.nodePositionOverrides.size>0,e=Math.round(this.viewTransform.scale*100);return l`
1662
1675
  <div class="graph-float">
1663
1676
  <button class="graph-float-btn" @click=${this.zoomOut} title="Zoom out (-)">−</button>
1664
1677
  <span class="graph-float-zoom">${e}%</span>
1665
1678
  <button class="graph-float-btn" @click=${this.zoomIn} title="Zoom in (+)">+</button>
1666
1679
  <span class="graph-float-sep"></span>
1667
1680
  <button class="graph-float-btn" @click=${this.resetView} title="Reset pan & zoom">⊙</button>
1668
- ${t?a`
1681
+ ${t?l`
1669
1682
  <span class="graph-float-sep"></span>
1670
1683
  <button class="graph-float-btn graph-float-btn-accent" @click=${()=>this.resetLayout()} title="Reset layout to auto-arrange">
1671
1684
  ⟲ Reformat
1672
1685
  </button>
1673
- `:p}
1686
+ `:d}
1674
1687
  <span class="graph-float-sep"></span>
1675
1688
  <button class="graph-float-btn" @click=${()=>this.captureScreenshot()} title="Save graph as PNG">
1676
1689
  📷
1677
1690
  </button>
1678
1691
  </div>
1679
- `}async captureScreenshot(){be("screenshot_captured");let t=this.querySelector(".graph-svg");if(!t)return;let e=t.cloneNode(true);e.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.style.cssText="",e.removeAttribute("class");let r=document.createElement("style");r.textContent=`
1692
+ `}async captureScreenshot(){we("screenshot_captured");let t=this.querySelector(".graph-svg");if(!t)return;let e=t.cloneNode(true);e.setAttribute("xmlns","http://www.w3.org/2000/svg"),e.style.cssText="",e.removeAttribute("class");let s=document.createElement("style");s.textContent=`
1680
1693
  text { font-family: 'Inter', system-ui, -apple-system, sans-serif; }
1681
1694
  .graph-col-header { fill: #c4c4cc; font-size: 9px; font-weight: 600; letter-spacing: 1.5px; }
1682
1695
  .graph-flow-edge { stroke-dasharray: 6,4; }
1683
1696
  .graph-pulse { }
1684
- `,e.insertBefore(r,e.firstChild);let n=document.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("width","100%"),n.setAttribute("height","100%"),n.setAttribute("fill","#ffffff"),e.insertBefore(n,e.firstChild);let l=e.getAttribute("viewBox")||"0 0 800 500",[,,c,d]=l.split(" ").map(Number),h=2,m=c*h,v=d*h,x=new XMLSerializer().serializeToString(e),y=new Blob([x],{type:"image/svg+xml;charset=utf-8"}),k=URL.createObjectURL(y),$=new Image;$.onload=()=>{let f=document.createElement("canvas");f.width=m,f.height=v;let g=f.getContext("2d");g.fillStyle="#ffffff",g.fillRect(0,0,m,v),g.drawImage($,0,0,m,v),URL.revokeObjectURL(k),f.toBlob(T=>{if(!T)return;let R=document.createElement("a");R.href=URL.createObjectURL(T),R.download=`brakit-graph-${new Date().toISOString().slice(0,19).replace(/[T:]/g,"-")}.png`,document.body.appendChild(R),R.click(),document.body.removeChild(R),URL.revokeObjectURL(R.href);},"image/png");},$.src=k;}toggleLayer(t){let e=new Set(this.activeLayers);e.has(t)?e.delete(t):(e.add(t),be("layer_toggled",t)),this.activeLayers=e;}renderNode(t,e,r,i){let n=this.activeNodeId,l=e===null||e.has(t.id),c=n===t.id,d=this.locked===t.id,h=r?.has(t.id)??false,m=this.matchesSearch(t.label),v=At[t.type]||At.endpoint,x=d?zs:c?Zs:v.stroke,y=d?Js:c?tr:v.fill,k=d?2:c?1.5:.75,$=l?1:.08;this.searchQuery&&!m&&($=.05),r&&!h&&($=Math.min($,.08)),h&&($=1,x=Ke);let f=this.searchQuery&&m,g=t.annotations,T=this.activeLayers;T.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint"&&(y=It(g.p95Ms)+"18"),T.has("heat")&&(y=Ve(t.stats.requestCount/i)+"20");let R=T.has("auth")&&t.type==="endpoint"&&!g?.hasAuth,H=T.has("auth")&&g?.hasAuth,X=T.has("security")?g?.securityFindings?.length??0:0,B=g?.securityFindings?.some(q=>q.severity==="critical"),V=T.has("issues")?g?.openIssueCount??0:0,G=this.nodeSubtitle(t),C=T.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint";return O`
1697
+ `,e.insertBefore(s,e.firstChild);let n=document.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("width","100%"),n.setAttribute("height","100%"),n.setAttribute("fill","#ffffff"),e.insertBefore(n,e.firstChild);let a=e.getAttribute("viewBox")||"0 0 800 500",[,,c,p]=a.split(" ").map(Number),h=2,m=c*h,f=p*h,S=new XMLSerializer().serializeToString(e),R=new Blob([S],{type:"image/svg+xml;charset=utf-8"}),P=URL.createObjectURL(R),$=new Image;$.onload=()=>{let v=document.createElement("canvas");v.width=m,v.height=f;let g=v.getContext("2d");g.fillStyle="#ffffff",g.fillRect(0,0,m,f),g.drawImage($,0,0,m,f),URL.revokeObjectURL(P),v.toBlob(x=>{if(!x)return;let w=document.createElement("a");w.href=URL.createObjectURL(x),w.download=`brakit-graph-${new Date().toISOString().slice(0,19).replace(/[T:]/g,"-")}.png`,document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL(w.href);},"image/png");},$.src=P;}toggleLayer(t){let e=new Set(this.activeLayers);e.has(t)?e.delete(t):(e.add(t),we("layer_toggled",t)),this.activeLayers=e;}renderNode(t,e,s,i){let n=this.activeNodeId,a=e===null||e.has(t.id),c=n===t.id,p=this.locked===t.id,h=s?.has(t.id)??false,m=this.matchesSearch(t.label),f=kt[t.type]||kt.endpoint,S=p?cr:c?pr:f.stroke,R=p?dr:c?hr:f.fill,P=p?2:c?1.5:.75,$=a?1:.08;this.searchQuery&&!m&&($=.05),s&&!h&&($=Math.min($,.08)),h&&($=1,S=os);let v=this.searchQuery&&m,g=t.annotations,x=this.activeLayers;x.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint"&&(R=Ot(g.p95Ms)+"18"),x.has("heat")&&(R=is(t.stats.requestCount/i)+"20");let w=x.has("auth")&&t.type==="endpoint"&&!g?.hasAuth,H=x.has("auth")&&g?.hasAuth,Z=x.has("security")?g?.securityFindings?.length??0:0,Q=g?.securityFindings?.some(F=>F.severity==="critical"),tt=x.has("issues")?g?.openIssueCount??0:0,W=this.nodeSubtitle(t),I=x.has("performance")&&g?.p95Ms!==void 0&&t.type==="endpoint";return O`
1685
1698
  <g class="graph-g" transform="translate(${t.x},${t.y})" style="opacity:${$};cursor:pointer;transition:opacity .15s,transform .1s"
1686
- @click=${q=>{q.stopPropagation(),!this.wasDragging&&(this.locked=this.locked===t.id?null:t.id,this.detailTab="overview");}}
1699
+ @click=${F=>{F.stopPropagation(),!this.wasDragging&&(this.locked=this.locked===t.id?null:t.id,this.detailTab="overview");}}
1687
1700
  @mouseenter=${()=>{this.hovered=t.id;}}
1688
1701
  @mouseleave=${()=>{this.hovered=null;}}
1689
- @mousedown=${q=>{q.detail>=2||this.startNodeDrag(q,t.id,t);}}>
1702
+ @mousedown=${F=>{F.detail>=2||this.startNodeDrag(F,t.id,t);}}>
1690
1703
 
1691
- ${f?O`
1704
+ ${v?O`
1692
1705
  <rect x="-3" y="-3" width="${t.w+6}" height="${t.h+6}" rx="9" fill="none"
1693
- stroke="${er}" stroke-width="2" stroke-dasharray="4,2"/>
1694
- `:p}
1706
+ stroke="${ur}" stroke-width="2" stroke-dasharray="4,2"/>
1707
+ `:d}
1695
1708
 
1696
- ${R?O`
1697
- <rect width="${t.w}" height="${t.h}" rx="8" fill="${y}" stroke="${ve}"
1709
+ ${w?O`
1710
+ <rect width="${t.w}" height="${t.h}" rx="8" fill="${R}" stroke="${Se}"
1698
1711
  stroke-width="1.2" stroke-dasharray="5,3"/>
1699
1712
  `:O`
1700
- <rect width="${t.w}" height="${t.h}" rx="8" fill="${y}" stroke="${x}" stroke-width="${k}"/>
1713
+ <rect width="${t.w}" height="${t.h}" rx="8" fill="${R}" stroke="${S}" stroke-width="${P}"/>
1701
1714
  `}
1702
1715
 
1703
1716
  <text x="12" y="${t.h/2-4}" fill="#1e293b" font-size="11.5" font-weight="600"
1704
- font-family="'Inter',system-ui,sans-serif">${v.icon} ${t.label}</text>
1717
+ font-family="'Inter',system-ui,sans-serif">${f.icon} ${t.label}</text>
1705
1718
  <text x="12" y="${t.h/2+10}" fill="#a1a1aa" font-size="9"
1706
- font-family="ui-monospace,monospace">${G}</text>
1719
+ font-family="ui-monospace,monospace">${W}</text>
1707
1720
 
1708
- ${C?O`
1709
- <text x="${t.w-8}" y="${t.h-6}" fill="${It(g.p95Ms)}" font-size="9"
1721
+ ${I?O`
1722
+ <text x="${t.w-8}" y="${t.h-6}" fill="${Ot(g.p95Ms)}" font-size="9"
1710
1723
  font-family="ui-monospace,monospace" text-anchor="end">p95: ${g.p95Ms}ms</text>
1711
- `:p}
1724
+ `:d}
1712
1725
 
1713
1726
  ${H?O`
1714
1727
  <g transform="translate(${t.w-24},3)">
1715
1728
  <title>Auth protected</title>
1716
- <rect width="18" height="18" rx="3" fill="${sr}" stroke="${ze}" stroke-width="0.5"/>
1729
+ <rect width="18" height="18" rx="3" fill="${mr}" stroke="${ns}" stroke-width="0.5"/>
1717
1730
  <text x="9" y="13" text-anchor="middle" font-size="10">🛡</text>
1718
1731
  </g>
1719
- `:p}
1732
+ `:d}
1720
1733
 
1721
- ${R?O`
1734
+ ${w?O`
1722
1735
  <g transform="translate(${t.w-24},3)">
1723
1736
  <title>No auth detected — this endpoint may be unprotected</title>
1724
- <rect width="18" height="18" rx="3" fill="#fff7ed" stroke="${ve}" stroke-width="0.5"/>
1737
+ <rect width="18" height="18" rx="3" fill="#fff7ed" stroke="${Se}" stroke-width="0.5"/>
1725
1738
  <text x="9" y="13" text-anchor="middle" font-size="10" fill="#ea580c">!</text>
1726
1739
  </g>
1727
- `:p}
1740
+ `:d}
1728
1741
 
1729
- ${X>0?O`
1730
- <g transform="translate(${t.w-(H||R?46:24)},3)">
1731
- <rect width="18" height="18" rx="3" fill="${B?rr:ir}"
1732
- stroke="${B?Je:Ze}" stroke-width="0.5"
1733
- class="${B?"graph-pulse":""}"/>
1742
+ ${Z>0?O`
1743
+ <g transform="translate(${t.w-(H||w?46:24)},3)">
1744
+ <rect width="18" height="18" rx="3" fill="${Q?fr:vr}"
1745
+ stroke="${Q?as:ls}" stroke-width="0.5"
1746
+ class="${Q?"graph-pulse":""}"/>
1734
1747
  <text x="9" y="13" text-anchor="middle" font-size="9" font-weight="600"
1735
- fill="${B?Je:Ze}">${X}</text>
1748
+ fill="${Q?as:ls}">${Z}</text>
1736
1749
  </g>
1737
- `:p}
1750
+ `:d}
1738
1751
 
1739
- ${V>0?O`
1740
- <circle cx="${t.w-8}" cy="8" r="5" fill="${ct}" stroke="white" stroke-width="1"/>
1741
- <text x="${t.w-8}" y="11" text-anchor="middle" font-size="7" fill="white" font-weight="700">${V}</text>
1742
- `:t.stats.errorRate>.05?O`<circle cx="${t.w-12}" cy="12" r="4" fill="${ct}"/>`:p}
1752
+ ${tt>0?O`
1753
+ <circle cx="${t.w-8}" cy="8" r="5" fill="${ut}" stroke="white" stroke-width="1"/>
1754
+ <text x="${t.w-8}" y="11" text-anchor="middle" font-size="7" fill="white" font-weight="700">${tt}</text>
1755
+ `:t.stats.errorRate>.05?O`<circle cx="${t.w-12}" cy="12" r="4" fill="${ut}"/>`:d}
1743
1756
 
1744
- ${g?.isMiddleware&&T.has("auth")?O`
1757
+ ${g?.isMiddleware&&x.has("auth")?O`
1745
1758
  <text x="${t.w}" y="${t.h+12}" text-anchor="end" font-size="8" fill="#6b7280"
1746
1759
  font-family="ui-monospace,monospace">middleware</text>
1747
- `:p}
1760
+ `:d}
1748
1761
  </g>
1749
- `}nodeSubtitle(t){switch(t.type){case "endpoint":return `${t.stats.requestCount} req \xB7 ${t.stats.avgLatencyMs}ms${t.stats.avgQueryCount>0?` \xB7 ${t.stats.avgQueryCount}q`:""}`;case "action":return `${t.stats.requestCount}\xD7 \xB7 ${t.stats.avgLatencyMs}ms`;case "table":return "table";default:return "service"}}renderEdge(t,e,r,i){let n=this.activeNodeId,l=e===null||e.has(t.data.source)&&e.has(t.data.target),c=r?.has(t.key)??false,d=l?n===null?.25:.6:.04,h=l&&n!==null,m=t.color,v=t.thickness;if(r&&!c&&(d=.04),c&&(d=.85,m=Ke,v=Math.max(v,1.8)),this.activeLayers.has("heat")&&!c){let V=Math.max(1,...this.graphEdges.map(C=>C.stats.frequency)),G=t.data.stats.frequency/V;m=Ve(G),l&&(d=Math.max(d,.4));}let x=this.activeLayers.has("issues")&&t.data.annotations?.hasIssue,y=Math.abs(t.tx-t.sx),k=Math.min(y*.45,120),$=t.sx<t.tx,f=$?t.sx+k:t.sx-k,g=$?t.tx-k:t.tx+k,T=(t.sx+t.tx)/2,R=(t.sy+t.ty)/2,H=4,X=x?ct:m,B=x?Math.max(v,1.5):v;return O`
1762
+ `}nodeSubtitle(t){switch(t.type){case "endpoint":return `${t.stats.requestCount} req \xB7 ${t.stats.avgLatencyMs}ms${t.stats.avgQueryCount>0?` \xB7 ${t.stats.avgQueryCount}q`:""}`;case "action":return `${t.stats.requestCount}\xD7 \xB7 ${t.stats.avgLatencyMs}ms`;case "table":return "table";default:return "service"}}renderEdge(t,e,s,i){let n=this.activeNodeId,a=e===null||e.has(t.data.source)&&e.has(t.data.target),c=s?.has(t.key)??false,p=a?n===null?.25:.6:.04,h=a&&n!==null,m=t.color,f=t.thickness;if(s&&!c&&(p=.04),c&&(p=.85,m=os,f=Math.max(f,1.8)),this.activeLayers.has("heat")&&!c){let tt=Math.max(1,...this.graphEdges.map(I=>I.stats.frequency)),W=t.data.stats.frequency/tt;m=is(W),a&&(p=Math.max(p,.4));}let S=this.activeLayers.has("issues")&&t.data.annotations?.hasIssue,R=Math.abs(t.tx-t.sx),P=Math.min(R*.45,120),$=t.sx<t.tx,v=$?t.sx+P:t.sx-P,g=$?t.tx-P:t.tx+P,x=(t.sx+t.tx)/2,w=(t.sy+t.ty)/2,H=4,Z=S?ut:m,Q=S?Math.max(f,1.5):f;return O`
1750
1763
  <g style="transition:opacity .15s">
1751
- <path d="M${t.sx},${t.sy} C${f},${t.sy} ${g},${t.ty} ${t.tx},${t.ty}"
1752
- fill="none" stroke="${X}" stroke-width="${B}"
1753
- stroke-opacity="${d}" stroke-linecap="round"
1764
+ <path d="M${t.sx},${t.sy} C${v},${t.sy} ${g},${t.ty} ${t.tx},${t.ty}"
1765
+ fill="none" stroke="${Z}" stroke-width="${Q}"
1766
+ stroke-opacity="${p}" stroke-linecap="round"
1754
1767
  stroke-dasharray="${c?"6,4":t.dashed?"3,3":"none"}"
1755
1768
  class="${c?"graph-flow-edge":""}"/>
1756
1769
  <polygon points="${t.tx},${t.ty} ${t.tx+($?-H*1.5:H*1.5)},${t.ty-H} ${t.tx+($?-H*1.5:H*1.5)},${t.ty+H}"
1757
- fill="${X}" fill-opacity="${d}"/>
1770
+ fill="${Z}" fill-opacity="${p}"/>
1758
1771
  ${h?O`
1759
- <rect x="${T-t.label.length*2.8-2}" y="${R-7}" width="${t.label.length*5.6+8}" height="14"
1772
+ <rect x="${x-t.label.length*2.8-2}" y="${w-7}" width="${t.label.length*5.6+8}" height="14"
1760
1773
  rx="4" fill="white" fill-opacity="0.92" stroke="${m}" stroke-width="0.4" stroke-opacity="0.15"/>
1761
- <text x="${T}" y="${R+3.5}" fill="${m}" font-size="8" font-weight="500"
1774
+ <text x="${x}" y="${w+3.5}" fill="${m}" font-size="8" font-weight="500"
1762
1775
  font-family="ui-monospace,monospace" text-anchor="middle" opacity="0.85">${t.label}</text>
1763
- `:p}
1764
- ${x?O`
1765
- <text x="${T}" y="${R-10}" fill="${ct}" font-size="8" font-weight="600"
1776
+ `:d}
1777
+ ${S?O`
1778
+ <text x="${x}" y="${w-10}" fill="${ut}" font-size="8" font-weight="600"
1766
1779
  text-anchor="middle">⚠ N+1</text>
1767
- `:p}
1780
+ `:d}
1768
1781
  </g>
1769
- `}renderDetailPanel(t){let{node:e,edges:r}=t,i=At[e.type]||At.endpoint,n=e.annotations,l=(n?.securityFindings?.length??0)>0,c=(n?.openIssueCount??0)>0,d=n?.p95Ms!==void 0,m=[{key:"overview",label:"Overview",show:true},{key:"security",label:`Security${l?` (${n.securityFindings.length})`:""}`,show:l},{key:"performance",label:"Perf",show:d},{key:"issues",label:`Issues${c?` (${n.openIssueCount})`:""}`,show:c}].filter(v=>v.show);return a`
1782
+ `}renderDetailPanel(t){let{node:e,edges:s}=t,i=kt[e.type]||kt.endpoint,n=e.annotations,a=(n?.securityFindings?.length??0)>0,c=(n?.openIssueCount??0)>0,p=n?.p95Ms!==void 0,m=[{key:"overview",label:"Overview",show:true},{key:"security",label:`Security${a?` (${n.securityFindings.length})`:""}`,show:a},{key:"performance",label:"Perf",show:p},{key:"issues",label:`Issues${c?` (${n.openIssueCount})`:""}`,show:c}].filter(f=>f.show);return l`
1770
1783
  <div class="graph-detail">
1771
1784
  <div class="graph-detail-head">
1772
1785
  <div>
1773
1786
  <div class="graph-detail-badge" style="color:${i.stroke}">${i.icon} ${e.type}</div>
1774
1787
  <div class="graph-detail-name">${e.label}</div>
1775
- ${n?.hasAuth?a`<span class="graph-detail-auth-badge">🛡 Authenticated</span>`:p}
1776
- ${n?.isMiddleware?a`<span class="graph-detail-mw-badge">middleware</span>`:p}
1788
+ ${n?.hasAuth?l`<span class="graph-detail-auth-badge">🛡 Authenticated</span>`:d}
1789
+ ${n?.isMiddleware?l`<span class="graph-detail-mw-badge">middleware</span>`:d}
1777
1790
  </div>
1778
1791
  <button class="graph-detail-close" @click=${()=>{this.locked=null;}}>✕</button>
1779
1792
  </div>
1780
1793
 
1781
- ${m.length>1?a`
1794
+ ${m.length>1?l`
1782
1795
  <div class="graph-detail-tabs">
1783
- ${m.map(v=>a`
1784
- <button class="graph-detail-tab ${this.detailTab===v.key?"active":""}"
1785
- @click=${()=>{this.detailTab=v.key;}}>${v.label}</button>
1796
+ ${m.map(f=>l`
1797
+ <button class="graph-detail-tab ${this.detailTab===f.key?"active":""}"
1798
+ @click=${()=>{this.detailTab=f.key;}}>${f.label}</button>
1786
1799
  `)}
1787
1800
  </div>
1788
- `:p}
1801
+ `:d}
1789
1802
 
1790
- ${this.detailTab==="overview"?this.renderOverviewTab(e,r):p}
1791
- ${this.detailTab==="security"?this.renderSecurityTab(n):p}
1792
- ${this.detailTab==="performance"?this.renderPerformanceTab(e,n):p}
1793
- ${this.detailTab==="issues"?this.renderIssuesTab(n):p}
1803
+ ${this.detailTab==="overview"?this.renderOverviewTab(e,s):d}
1804
+ ${this.detailTab==="security"?this.renderSecurityTab(n):d}
1805
+ ${this.detailTab==="performance"?this.renderPerformanceTab(e,n):d}
1806
+ ${this.detailTab==="issues"?this.renderIssuesTab(n):d}
1794
1807
  </div>
1795
- `}renderOverviewTab(t,e){return a`
1808
+ `}renderOverviewTab(t,e){return l`
1796
1809
  <div class="graph-detail-stats">
1797
1810
  <div class="graph-detail-stat">
1798
1811
  <div class="graph-detail-val">${t.stats.requestCount}</div>
1799
1812
  <div class="graph-detail-lbl">${t.type==="action"?"OCCURRENCES":"REQUESTS"}</div>
1800
1813
  </div>
1801
1814
  <div class="graph-detail-stat">
1802
- <div class="graph-detail-val" style="color:${It(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
1815
+ <div class="graph-detail-val" style="color:${Ot(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
1803
1816
  <div class="graph-detail-lbl">AVG LATENCY</div>
1804
1817
  </div>
1805
- ${t.stats.avgQueryCount>0?a`
1818
+ ${t.stats.avgQueryCount>0?l`
1806
1819
  <div class="graph-detail-stat">
1807
1820
  <div class="graph-detail-val">${t.stats.avgQueryCount}</div>
1808
1821
  <div class="graph-detail-lbl">QUERIES/REQ</div>
1809
1822
  </div>
1810
- `:p}
1811
- ${t.stats.errorRate>.01?a`
1823
+ `:d}
1824
+ ${t.stats.errorRate>.01?l`
1812
1825
  <div class="graph-detail-stat">
1813
- <div class="graph-detail-val" style="color:${ct}">${Math.round(t.stats.errorRate*100)}%</div>
1826
+ <div class="graph-detail-val" style="color:${ut}">${Math.round(t.stats.errorRate*100)}%</div>
1814
1827
  <div class="graph-detail-lbl">ERRORS</div>
1815
1828
  </div>
1816
- `:p}
1829
+ `:d}
1817
1830
  </div>
1818
1831
 
1819
- ${e.length>0?a`
1832
+ ${e.length>0?l`
1820
1833
  <div class="graph-detail-sec">Connections</div>
1821
- ${e.map(r=>{let i=r.source===this.locked,n=(i?r.target:r.source).replace(/^(action|endpoint|table|external):/,"");return a`
1834
+ ${e.map(s=>{let i=s.source===this.locked,n=(i?s.target:s.source).replace(/^(action|endpoint|table|external):/,"");return l`
1822
1835
  <div class="graph-detail-conn">
1823
- <span class="graph-detail-edge-dot" style="background:${fe[r.type]}"></span>
1824
- <span class="graph-detail-edge-type">${r.type}</span>
1836
+ <span class="graph-detail-edge-dot" style="background:${xe[s.type]}"></span>
1837
+ <span class="graph-detail-edge-type">${s.type}</span>
1825
1838
  <span>${i?"\u2192":"\u2190"} ${n}</span>
1826
- <span class="graph-detail-dim">${r.stats.frequency}× · ${r.stats.avgLatencyMs}ms</span>
1839
+ <span class="graph-detail-dim">${s.stats.frequency}× · ${s.stats.avgLatencyMs}ms</span>
1827
1840
  </div>
1828
1841
  `})}
1829
- `:p}
1842
+ `:d}
1830
1843
 
1831
- ${e.some(r=>r.patterns?.length)?a`
1844
+ ${e.some(s=>s.patterns?.length)?l`
1832
1845
  <div class="graph-detail-sec">SQL Patterns</div>
1833
- ${e.filter(r=>r.patterns).flatMap(r=>r.patterns).map(r=>a`
1834
- <pre class="graph-detail-sql">${r.length>200?r.slice(0,200)+"\u2026":r}</pre>
1846
+ ${e.filter(s=>s.patterns).flatMap(s=>s.patterns).map(s=>l`
1847
+ <pre class="graph-detail-sql">${s.length>200?s.slice(0,200)+"\u2026":s}</pre>
1835
1848
  `)}
1836
- `:p}
1837
- `}renderSecurityTab(t){return t?.securityFindings?.length?a`
1838
- ${t.securityFindings.map(e=>a`
1849
+ `:d}
1850
+ `}renderSecurityTab(t){return t?.securityFindings?.length?l`
1851
+ ${t.securityFindings.map(e=>l`
1839
1852
  <div class="graph-detail-finding">
1840
1853
  <span class="graph-detail-severity graph-detail-severity-${e.severity}">${e.severity}</span>
1841
1854
  <div class="graph-detail-finding-title">${e.title}</div>
1842
1855
  <div class="graph-detail-finding-meta">${e.rule} · ${e.count} occurrence${e.count!==1?"s":""}</div>
1843
1856
  </div>
1844
1857
  `)}
1845
- `:a`<div class="graph-detail-empty">No security findings</div>`}renderPerformanceTab(t,e){return a`
1858
+ `:l`<div class="graph-detail-empty">No security findings</div>`}renderPerformanceTab(t,e){return l`
1846
1859
  <div class="graph-detail-stats">
1847
- ${e?.p95Ms!==void 0?a`
1860
+ ${e?.p95Ms!==void 0?l`
1848
1861
  <div class="graph-detail-stat">
1849
- <div class="graph-detail-val" style="color:${It(e.p95Ms)}">${e.p95Ms}ms</div>
1862
+ <div class="graph-detail-val" style="color:${Ot(e.p95Ms)}">${e.p95Ms}ms</div>
1850
1863
  <div class="graph-detail-lbl">P95 LATENCY</div>
1851
1864
  </div>
1852
- `:p}
1865
+ `:d}
1853
1866
  <div class="graph-detail-stat">
1854
- <div class="graph-detail-val" style="color:${It(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
1867
+ <div class="graph-detail-val" style="color:${Ot(t.stats.avgLatencyMs)}">${t.stats.avgLatencyMs}ms</div>
1855
1868
  <div class="graph-detail-lbl">AVG LATENCY</div>
1856
1869
  </div>
1857
- ${t.stats.avgQueryCount>0?a`
1870
+ ${t.stats.avgQueryCount>0?l`
1858
1871
  <div class="graph-detail-stat">
1859
1872
  <div class="graph-detail-val">${t.stats.avgQueryCount}</div>
1860
1873
  <div class="graph-detail-lbl">QUERIES/REQ</div>
1861
1874
  </div>
1862
- `:p}
1875
+ `:d}
1863
1876
  <div class="graph-detail-stat">
1864
1877
  <div class="graph-detail-val">${t.stats.requestCount}</div>
1865
1878
  <div class="graph-detail-lbl">TOTAL REQS</div>
1866
1879
  </div>
1867
1880
  </div>
1868
1881
 
1869
- ${(e?.insights?.length??0)>0?a`
1882
+ ${(e?.insights?.length??0)>0?l`
1870
1883
  <div class="graph-detail-sec">Performance Insights</div>
1871
- ${e.insights.map(r=>a`
1884
+ ${e.insights.map(s=>l`
1872
1885
  <div class="graph-detail-finding">
1873
- <span class="graph-detail-severity graph-detail-severity-${r.severity}">${r.severity}</span>
1874
- <div class="graph-detail-finding-title">${r.title}</div>
1875
- <div class="graph-detail-finding-meta">${r.type}</div>
1886
+ <span class="graph-detail-severity graph-detail-severity-${s.severity}">${s.severity}</span>
1887
+ <div class="graph-detail-finding-title">${s.title}</div>
1888
+ <div class="graph-detail-finding-meta">${s.type}</div>
1876
1889
  </div>
1877
1890
  `)}
1878
- `:p}
1879
- `}renderIssuesTab(t){let e=t?.openIssueCount??0;return e===0?a`<div class="graph-detail-empty">No open issues</div>`:a`
1891
+ `:d}
1892
+ `}renderIssuesTab(t){let e=t?.openIssueCount??0;return e===0?l`<div class="graph-detail-empty">No open issues</div>`:l`
1880
1893
  <div class="graph-detail-issue-summary">
1881
1894
  <div class="graph-detail-stat">
1882
- <div class="graph-detail-val" style="color:${ct}">${e}</div>
1895
+ <div class="graph-detail-val" style="color:${ut}">${e}</div>
1883
1896
  <div class="graph-detail-lbl">OPEN ISSUES</div>
1884
1897
  </div>
1885
1898
  </div>
1886
1899
  <p class="graph-detail-hint">View the Issues tab for full details and remediation hints.</p>
1887
- `}getSelectedNodeDetail(){if(!this.locked)return null;let t=this.graphNodes.find(r=>r.id===this.locked);if(!t)return null;let e=this.graphEdges.filter(r=>r.source===this.locked||r.target===this.locked);return {node:t,edges:e}}};u([I({context:A})],M.prototype,"store",2),u([b()],M.prototype,"graphNodes",2),u([b()],M.prototype,"graphEdges",2),u([b()],M.prototype,"locked",2),u([b()],M.prototype,"hovered",2),u([b()],M.prototype,"loading",2),u([b()],M.prototype,"activeLayers",2),u([b()],M.prototype,"searchQuery",2),u([b()],M.prototype,"viewTransform",2),u([b()],M.prototype,"dragging",2),u([b()],M.prototype,"detailTab",2),u([b()],M.prototype,"consolidatedFlows",2),u([b()],M.prototype,"activeFlowIdx",2),u([b()],M.prototype,"focusIdx",2),M=u([S("bk-graph-view")],M);function qi(o){return o===0?"<1ms":_(o)}var N=class extends E{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=N.cache.get(this.requestId);if(t){this.data=t;return}this.loading=true;try{let e=await fetch(`${w.activity}?requestId=${this.requestId}`);if(!e.ok){this.failed=!0,this.loading=!1;return}let r=await e.json();if(N.cache.size>=ke){let i=N.cache.keys().next().value;i!==void 0&&N.cache.delete(i);}N.cache.set(this.requestId,r),this.data=r,this.loading=!1;}catch(e){console.debug("[brakit] timeline load failed:",e),this.failed=true,this.loading=false;}}toggleSql(t,e){e.stopPropagation(),this.expandedSqlIdx=this.expandedSqlIdx===t?-1:t;}copySql(t,e){e.stopPropagation(),navigator.clipboard.writeText(t).then(()=>D.show("SQL copied")).catch(()=>D.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 p;let t=this.data,e=t.timeline[0]?.timestamp??0;return a`
1900
+ `}getSelectedNodeDetail(){if(!this.locked)return null;let t=this.graphNodes.find(s=>s.id===this.locked);if(!t)return null;let e=this.graphEdges.filter(s=>s.source===this.locked||s.target===this.locked);return {node:t,edges:e}}};u([C({context:A})],M.prototype,"store",2),u([b()],M.prototype,"graphNodes",2),u([b()],M.prototype,"graphEdges",2),u([b()],M.prototype,"locked",2),u([b()],M.prototype,"hovered",2),u([b()],M.prototype,"loading",2),u([b()],M.prototype,"activeLayers",2),u([b()],M.prototype,"searchQuery",2),u([b()],M.prototype,"viewTransform",2),u([b()],M.prototype,"dragging",2),u([b()],M.prototype,"detailTab",2),u([b()],M.prototype,"consolidatedFlows",2),u([b()],M.prototype,"activeFlowIdx",2),u([b()],M.prototype,"focusIdx",2),M=u([_("bk-graph-view")],M);var ie=class extends J{constructor(){super(...arguments);this.activeTab="requests";this.handleNavigateExplorer=t=>{let e=t.detail;ve.some(s=>s.key===e)&&(this.activeTab=e);};}connectedCallback(){super.connectedCallback(),window.addEventListener("navigate-explorer",this.handleNavigateExplorer);}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("navigate-explorer",this.handleNavigateExplorer);}switchTab(t){this.activeTab=t,fetch(`${T.tab}?event=explorer.${t}`).catch(()=>{});}getCount(t){let e=this.store.state;switch(t){case "requests":return e.requests.filter(s=>!s.path?.startsWith(U)).length;case "fetches":return e.fetches.length;case "queries":return e.queries.length;case "logs":return e.logs.length;case "errors":return e.errors.length}}render(){return l`
1901
+ <div class="explorer-tabs">
1902
+ ${ve.map(t=>l`
1903
+ <button class="explorer-tab ${this.activeTab===t.key?"active":""}"
1904
+ @click=${()=>this.switchTab(t.key)}>
1905
+ ${t.label}
1906
+ <span class="explorer-tab-count">${this.getCount(t.key)}</span>
1907
+ </button>
1908
+ `)}
1909
+ </div>
1910
+ <div style="display:${this.activeTab==="requests"?"block":"none"}">
1911
+ <bk-requests-view></bk-requests-view>
1912
+ </div>
1913
+ <div style="display:${this.activeTab==="fetches"?"block":"none"}">
1914
+ <bk-fetches-view></bk-fetches-view>
1915
+ </div>
1916
+ <div style="display:${this.activeTab==="queries"?"block":"none"}">
1917
+ <bk-queries-view></bk-queries-view>
1918
+ </div>
1919
+ <div style="display:${this.activeTab==="logs"?"block":"none"}">
1920
+ <bk-logs-view></bk-logs-view>
1921
+ </div>
1922
+ <div style="display:${this.activeTab==="errors"?"block":"none"}">
1923
+ <bk-errors-view></bk-errors-view>
1924
+ </div>
1925
+ `}};u([b()],ie.prototype,"activeTab",2),ie=u([_("bk-explorer-view")],ie);var Vi=[{key:"all",label:"All"},{key:"security",label:"Security"},{key:"performance",label:"Performance"},{key:"reliability",label:"Reliability"}],mt=class extends J{constructor(){super(...arguments);this.filter="all";this.expandedIdx=-1;this.showDismissed=false;}getFilteredIssues(t){return (this.filter==="all"?t:t.filter(s=>Xt(s)===this.filter)).sort((s,i)=>{let n=h=>h==="open"||h==="regressed"?0:h==="fixing"?1:2,a=n(s.state)-n(i.state);if(a!==0)return a;let c=Y[s.issue.severity]?.sort??3,p=Y[i.issue.severity]?.sort??3;return c-p})}getCounts(t){let e={all:t.length,security:0,performance:0,reliability:0};for(let s of t)e[Xt(s)]++;return e}render(){if(!(this.store.state.requests.length>0||this.store.state.queries.length>0))return l`<bk-empty-state
1926
+ title="Waiting for requests..."
1927
+ subtitle="Start using your app to see insights here"
1928
+ ></bk-empty-state>`;let e=(this.store.state.issues||[]).filter(ir),s=this.getFilteredIssues(e),i=this.getCounts(e),n=s.filter(f=>f.state==="open"&&f.aiStatus!=="wont_fix"),a=s.filter(f=>f.state==="regressed"&&f.aiStatus!=="wont_fix"),c=s.filter(f=>f.state==="fixing"),p=s.filter(f=>f.state==="resolved"),h=s.filter(f=>f.aiStatus==="wont_fix"),m=0;return l`
1929
+ <div class="insights-filters">
1930
+ ${Vi.map(f=>l`
1931
+ <button class="insights-chip ${this.filter===f.key?"active":""}"
1932
+ @click=${()=>{this.filter=f.key,this.expandedIdx=-1;}}>
1933
+ ${f.label}
1934
+ ${i[f.key]>0?l`<span class="insights-chip-count">${i[f.key]}</span>`:d}
1935
+ </button>
1936
+ `)}
1937
+ </div>
1938
+
1939
+ ${this.renderSummaryBar(e)}
1940
+
1941
+ <div class="insights-list">
1942
+ ${n.length+a.length>0?l`
1943
+ <div class="insights-ai-hint">Copy to your AI: <code>"Fix brakit findings"</code></div>
1944
+ `:d}
1945
+ ${n.length===0&&a.length===0&&c.length===0&&p.length===0&&h.length===0?l`<div class="insights-empty"><span class="insights-empty-icon">\u2713</span>${this.filter==="all"?"All clear \u2014 no issues detected":`No ${this.filter} issues`}</div>`:d}
1946
+
1947
+ ${a.length>0?l`
1948
+ <div class="insights-section insights-section-regressed">
1949
+ <span class="insights-section-icon">\u21A9</span> Regressed
1950
+ <span class="insights-section-count">${a.length}</span>
1951
+ </div>
1952
+ ${a.map(f=>this.renderIssueCard(f,m++))}
1953
+ `:d}
1954
+
1955
+ ${n.length>0?l`
1956
+ <div class="insights-section">
1957
+ <span class="insights-section-icon">\u25CF</span> Open
1958
+ <span class="insights-section-count">${n.length}</span>
1959
+ </div>
1960
+ ${n.map(f=>this.renderIssueCard(f,m++))}
1961
+ `:d}
1962
+
1963
+ ${c.length>0?l`
1964
+ <div class="insights-section insights-section-verifying">
1965
+ <span class="insights-section-icon">\u29D7</span> Verifying
1966
+ <span class="insights-section-count">${c.length}</span>
1967
+ </div>
1968
+ ${c.map(f=>this.renderIssueCard(f,m++))}
1969
+ `:d}
1970
+
1971
+ ${p.length>0?l`
1972
+ <div class="insights-section insights-section-resolved">
1973
+ <span class="insights-section-icon">\u2713</span> Resolved
1974
+ <span class="insights-section-count">${p.length}</span>
1975
+ </div>
1976
+ ${p.map(f=>this.renderIssueCard(f,m++))}
1977
+ `:d}
1978
+
1979
+ ${h.length>0?l`
1980
+ <div class="insights-section insights-section-dismissed" @click=${()=>{this.showDismissed=!this.showDismissed;}}>
1981
+ <span class="insights-section-icon">${this.showDismissed?"\u25BE":"\u25B8"}</span> Won't Fix
1982
+ <span class="insights-section-count">${h.length}</span>
1983
+ </div>
1984
+ ${this.showDismissed?h.map(f=>this.renderIssueCard(f,m++)):d}
1985
+ `:d}
1986
+ </div>
1987
+ `}renderSummaryBar(t){let e=t.filter(a=>(a.state==="open"||a.state==="regressed")&&a.aiStatus!=="wont_fix"),s=e.filter(a=>a.issue.severity==="critical").length,i=e.filter(a=>a.issue.severity==="warning").length,n=t.filter(a=>a.state==="resolved").length;return s===0&&i===0&&n===0?d:l`
1988
+ <div class="insights-summary">
1989
+ ${s>0?l`<span class="insights-summary-stat critical">${s} critical</span>`:d}
1990
+ ${i>0?l`<span class="insights-summary-stat warning">${i} warning</span>`:d}
1991
+ ${n>0?l`<span class="insights-summary-stat resolved">${n} resolved</span>`:d}
1992
+ </div>
1993
+ `}renderIssueCard(t,e){let s=t.issue,i=Y[s.severity]||Y.info,n=this.expandedIdx===e,a=t.state==="resolved",c=t.state==="fixing",p=Xt(t);return l`
1994
+ <div class="insights-card ${n?"expanded":""} ${a?"resolved":""}"
1995
+ @click=${()=>{this.expandedIdx=this.expandedIdx===e?-1:e;}}>
1996
+ <div class="insights-card-left">
1997
+ <span class="insights-sev ${i.cls}">${i.icon}</span>
1998
+ </div>
1999
+ <div class="insights-card-body">
2000
+ <div class="insights-card-header">
2001
+ <span class="insights-card-title ${a?"resolved":""}">${s.title}</span>
2002
+ <span class="insights-card-cat">${p}</span>
2003
+ ${s.count?l`<span class="insights-card-count">${s.count}\u00D7</span>`:d}
2004
+ ${t.state==="regressed"?l`<span class="insights-badge-regressed">regressed</span>`:d}
2005
+ ${c?l`<span class="insights-badge-verifying">verifying</span>`:d}
2006
+ ${a?l`<span class="insights-badge-resolved">resolved</span>`:d}
2007
+ </div>
2008
+ <div class="insights-card-desc">${s.desc}</div>
2009
+ ${n?l`
2010
+ ${s.detail?l`<div class="insights-card-detail">${s.detail}</div>`:d}
2011
+ ${t.cleanHitsSinceLastSeen>0?l`
2012
+ <div class="insights-card-progress">${t.cleanHitsSinceLastSeen}/${5} clean requests</div>
2013
+ `:d}
2014
+ ${s.hint?l`<div class="insights-card-hint">${s.hint}</div>`:d}
2015
+ `:d}
2016
+ </div>
2017
+ ${s.hint?l`<span class="insights-card-arrow">${n?"\u2193":"\u2192"}</span>`:d}
2018
+ </div>
2019
+ `}};u([b()],mt.prototype,"filter",2),u([b()],mt.prototype,"expandedIdx",2),u([b()],mt.prototype,"showDismissed",2),mt=u([_("bk-insights-view")],mt);function Ki(o){return o===0?"<1ms":y(o)}var k=class extends E{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=k.cache.get(this.requestId);if(t){this.data=t;return}this.loading=true;try{let e=await fetch(`${T.activity}?requestId=${this.requestId}`);if(!e.ok){this.failed=!0,this.loading=!1;return}let s=await e.json();if(k.cache.size>=We){let i=k.cache.keys().next().value;i!==void 0&&k.cache.delete(i);}k.cache.set(this.requestId,s),this.data=s,this.loading=!1;}catch(e){console.debug("[brakit] timeline load failed:",e),this.failed=true,this.loading=false;}}toggleSql(t,e){e.stopPropagation(),this.expandedSqlIdx=this.expandedSqlIdx===t?-1:t;}copySql(t,e){e.stopPropagation(),navigator.clipboard.writeText(t).then(()=>D.show("SQL copied")).catch(()=>D.show("Copy failed"));}render(){if(this.loading)return l`<div class="tl-loading">Loading activity...</div>`;if(this.failed||!this.data||this.data.total===0)return d;let t=this.data,e=t.timeline[0]?.timestamp??0;return l`
1888
2020
  <div class="tl-header">
1889
2021
  <span class="tl-title">Activity Timeline</span>
1890
2022
  <span class="tl-counts">
1891
- ${t.counts.queries>0?a`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:p}
1892
- ${t.counts.fetches>0?a`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:p}
1893
- ${t.counts.logs>0?a`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:p}
1894
- ${t.counts.errors>0?a`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:p}
2023
+ ${t.counts.queries>0?l`<span class="tl-count tl-count-query">${t.counts.queries} quer${t.counts.queries===1?"y":"ies"}</span>`:d}
2024
+ ${t.counts.fetches>0?l`<span class="tl-count tl-count-fetch">${t.counts.fetches} fetch${t.counts.fetches===1?"":"es"}</span>`:d}
2025
+ ${t.counts.logs>0?l`<span class="tl-count tl-count-log">${t.counts.logs} log${t.counts.logs===1?"":"s"}</span>`:d}
2026
+ ${t.counts.errors>0?l`<span class="tl-count tl-count-error">${t.counts.errors} error${t.counts.errors===1?"":"s"}</span>`:d}
1895
2027
  </span>
1896
2028
  </div>
1897
2029
  <div class="tl-events">${this.renderTimeline(t.timeline,e)}</div>
1898
- `}renderTimeline(t,e){let r=new Map,i=[];for(let l of t){let c=l.type==="query"?l.data.parentFetchId:void 0;if(l.type==="query"&&c){let d=r.get(c);d||(d=[],r.set(c,d)),d.push(l);}else i.push(l);}let n=0;return i.map(l=>{let c=n++,d=l.type==="fetch"?l.data.fetchId:void 0,h=d?r.get(d):void 0;if(h&&h.length>0){let m=h.length;return a`
1899
- ${this.renderEvent(l,c,e)}
2030
+ `}renderTimeline(t,e){let s=new Map,i=[];for(let a of t){let c=a.type==="query"?a.data.parentFetchId:void 0;if(a.type==="query"&&c){let p=s.get(c);p||(p=[],s.set(c,p)),p.push(a);}else i.push(a);}let n=0;return i.map(a=>{let c=n++,p=a.type==="fetch"?a.data.fetchId:void 0,h=p?s.get(p):void 0;if(h&&h.length>0){let m=h.length;return l`
2031
+ ${this.renderEvent(a,c,e)}
1900
2032
  <div class="tl-nested">
1901
2033
  <span class="tl-nested-label">${m} nested quer${m===1?"y":"ies"}</span>
1902
- ${h.map(v=>{let x=n++;return this.renderEvent(v,x,e,true)})}
2034
+ ${h.map(f=>{let S=n++;return this.renderEvent(f,S,e,true)})}
1903
2035
  </div>
1904
- `}return this.renderEvent(l,c,e)})}renderEvent(t,e,r,i=false){let n=Ms[t.type]||"var(--text-dim)",l=Ns[t.type]||t.type,c="+"+_(Math.round(t.timestamp-r)),d=t.type==="query"?t.data.sql:void 0,h=!!d,m=this.expandedSqlIdx===e;return a`
2036
+ `}return this.renderEvent(a,c,e)})}renderEvent(t,e,s,i=false){let n=Bs[t.type]||"var(--text-dim)",a=Ws[t.type]||t.type,c="+"+y(Math.round(t.timestamp-s)),p=t.type==="query"?t.data.sql:void 0,h=!!p,m=this.expandedSqlIdx===e;return l`
1905
2037
  <div class="tl-event ${h?"tl-clickable":""} ${i?"tl-nested-event":""}"
1906
2038
  style="${h?"":`border-left-color:${n}`}"
1907
- @click=${h?v=>this.toggleSql(e,v):p}>
2039
+ @click=${h?f=>this.toggleSql(e,f):d}>
1908
2040
  <span class="tl-event-time">${c}</span>
1909
- <span class="tl-event-type" style="color:${n}">${l}</span>
2041
+ <span class="tl-event-type" style="color:${n}">${a}</span>
1910
2042
  ${this.renderEventContent(t)}
1911
- ${d?a`
2043
+ ${p?l`
1912
2044
  <div class="tl-event-sql ${m?"open":""}">
1913
- <button class="tl-sql-copy" @click=${v=>this.copySql(d,v)}>Copy</button>
1914
- ${d}
1915
- </div>`:p}
2045
+ <button class="tl-sql-copy" @click=${f=>this.copySql(p,f)}>Copy</button>
2046
+ ${p}
2047
+ </div>`:d}
1916
2048
  </div>
1917
- `}renderEventContent(t){switch(t.type){case "fetch":{let e=t.data,r=e.statusCode>=400;return a`
2049
+ `}renderEventContent(t){switch(t.type){case "fetch":{let e=t.data,s=e.statusCode>=400;return l`
1918
2050
  <span class="tl-event-summary">${e.method} ${e.url}</span>
1919
- <span class="tl-event-status" style="${r?"color:var(--red)":""}">${e.statusCode}</span>
1920
- <span class="tl-event-dur">${_(e.durationMs)}</span>
1921
- `}case "query":{let e=t.data,r=(e.normalizedOp||e.operation||"?").toUpperCase(),i=e.table||e.model||"",n=pe[r]||"var(--text-dim)";return a`
1922
- <span class="tl-event-summary"><span style="color:${n};font-weight:600">${r}</span> ${i}</span>
1923
- <span class="tl-event-dur">${qi(e.durationMs)}</span>
1924
- `}case "log":{let e=t.data,r=As[e.level]||"var(--text-dim)";return a`<span class="tl-event-summary"><span style="color:${r}">${e.level.toUpperCase()}</span> ${e.message}</span>`}case "error":{let e=t.data;return a`<span class="tl-event-summary" style="color:var(--red)">${e.name}: ${e.message}</span>`}default:return p}}};N.cache=new Map,u([I({context:A})],N.prototype,"store",2),u([L({attribute:"request-id"})],N.prototype,"requestId",2),u([L({attribute:"request-started",type:Number})],N.prototype,"requestStarted",2),u([b()],N.prototype,"data",2),u([b()],N.prototype,"loading",2),u([b()],N.prototype,"failed",2),u([b()],N.prototype,"expandedSqlIdx",2),N=u([S("bk-timeline-panel")],N);function Lt(o){try{return JSON.parse(o)}catch{return null}}var Ee=class{constructor(s,t){this.host=s;this.store=t;this.retryCount=0;this.boundHandlers={fetch:s=>{let t=Lt(s.data);t&&this.store.prependFetch(t);},log:s=>{let t=Lt(s.data);t&&this.store.prependLog(t);},error:s=>{let t=Lt(s.data);t&&this.store.prependError(t);},query:s=>{let t=Lt(s.data);t&&this.store.prependQuery(t);},issues:s=>{let t=Lt(s.data);t&&this.store.setIssues(t);}};s.addController(this);}hostConnected(){this.connect();}hostDisconnected(){this.removeListeners(),this.eventSource?.close(),clearTimeout(this.reloadTimer),clearTimeout(this.perfReloadTimer),clearTimeout(this.reconnectTimer);}removeListeners(){this.eventSource&&(this.eventSource.removeEventListener(ie,this.boundHandlers.fetch),this.eventSource.removeEventListener("log",this.boundHandlers.log),this.eventSource.removeEventListener(oe,this.boundHandlers.error),this.eventSource.removeEventListener(ne,this.boundHandlers.query),this.eventSource.removeEventListener(ae,this.boundHandlers.issues));}connect(){this.removeListeners(),this.eventSource?.close(),this.eventSource=new EventSource(w.events),this.eventSource.onopen=()=>{this.retryCount=0;},this.eventSource.onerror=()=>{this.eventSource?.close(),this.scheduleReconnect();},this.eventSource.onmessage=s=>{let t=Lt(s.data);t&&(t.path?.startsWith(F)||(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(),De))));},this.eventSource.addEventListener(ie,this.boundHandlers.fetch),this.eventSource.addEventListener("log",this.boundHandlers.log),this.eventSource.addEventListener(oe,this.boundHandlers.error),this.eventSource.addEventListener(ne,this.boundHandlers.query),this.eventSource.addEventListener(ae,this.boundHandlers.issues);}scheduleReconnect(){if(this.retryCount>=10)return;let s=Math.min(1e3*2**this.retryCount,3e4);this.retryCount++,this.reconnectTimer=setTimeout(()=>this.connect(),s);}async reloadFlows(){try{let t=await(await fetch(w.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch(w.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function vr(){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 gr(){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 br(){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 Er(){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 yr(){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 _r(){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 $r(){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 xr(){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 Sr(){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>`}function Tr(){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="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="18" r="3"/><line x1="9" y1="6" x2="15" y2="6"/><line x1="6" y1="9" x2="6" y2="15"/><line x1="18" y1="9" x2="18" y2="15"/><line x1="9" y1="18" x2="15" y2="18"/></svg>`}var dt=class extends E{constructor(){super(...arguments);this.store=new ue;this.activeView="overview";this.viewMode="simple";this.sse=new Ee(this,this.store);}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadInitialData(),this.store.addEventListener("state-changed",()=>this.requestUpdate());}async loadInitialData(){try{let[t,e]=await Promise.all([fetch(w.flows),fetch(w.requests)]),[r,i]=await Promise.all([t.json(),e.json()]);this.store.setFlows(r.flows),this.store.setRequests(i.requests);}catch(t){console.warn("[brakit]",t);}try{let[t,e,r,i,n]=await Promise.all([fetch(w.fetches),fetch(w.errors),fetch(w.logs),fetch(w.queries),fetch(w.metricsLive)]),[l,c,d,h,m]=await Promise.all([t.json(),e.json(),r.json(),i.json(),n.json()]);this.store.setFetches(l.entries),this.store.setErrors(c.entries),this.store.setLogs(d.entries),this.store.setQueries(h.entries),this.store.setMetrics(m.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let e=await(await fetch(w.insights)).json();this.store.setIssues(e.issues||[]);}catch(t){console.warn("[brakit]",t);}}switchView(t){t!==this.activeView&&(this.activeView=t,this.store.setActiveView(t),fetch(`${w.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(w.clear,{method:"POST"}),this.store.clearAll(),D.show("Cleared"));}handleCopyAsCurl(t){Tt(t);}render(){let t=this.store.state,e=t.requests.filter(c=>!c.path?.startsWith(F)),r=e.filter(c=>c.statusCode>=400).length,i=e.length>0?Math.round(e.reduce((c,d)=>c+d.durationMs,0)/e.length):0,n=(t.issues||[]).filter(c=>c.state!=="resolved"&&c.state!=="stale").length,l=window.__BRAKIT_CONFIG__;return a`
2051
+ <span class="tl-event-status" style="${s?"color:var(--red)":""}">${e.statusCode}</span>
2052
+ <span class="tl-event-dur">${y(e.durationMs)}</span>
2053
+ `}case "query":{let e=t.data,s=(e.normalizedOp||e.operation||"?").toUpperCase(),i=e.table||e.model||"",n=be[s]||"var(--text-dim)";return l`
2054
+ <span class="tl-event-summary"><span style="color:${n};font-weight:600">${s}</span> ${i}</span>
2055
+ <span class="tl-event-dur">${Ki(e.durationMs)}</span>
2056
+ `}case "log":{let e=t.data,s=qs[e.level]||"var(--text-dim)";return l`<span class="tl-event-summary"><span style="color:${s}">${e.level.toUpperCase()}</span> ${e.message}</span>`}case "error":{let e=t.data;return l`<span class="tl-event-summary" style="color:var(--red)">${e.name}: ${e.message}</span>`}default:return d}}};k.cache=new Map,u([C({context:A})],k.prototype,"store",2),u([L({attribute:"request-id"})],k.prototype,"requestId",2),u([L({attribute:"request-started",type:Number})],k.prototype,"requestStarted",2),u([b()],k.prototype,"data",2),u([b()],k.prototype,"loading",2),u([b()],k.prototype,"failed",2),u([b()],k.prototype,"expandedSqlIdx",2),k=u([_("bk-timeline-panel")],k);function Dt(o){try{return JSON.parse(o)}catch{return null}}var Re=class{constructor(r,t){this.host=r;this.store=t;this.retryCount=0;this.boundHandlers={fetch:r=>{let t=Dt(r.data);t&&this.store.prependFetch(t);},log:r=>{let t=Dt(r.data);t&&this.store.prependLog(t);},error:r=>{let t=Dt(r.data);t&&this.store.prependError(t);},query:r=>{let t=Dt(r.data);t&&this.store.prependQuery(t);},issues:r=>{let t=Dt(r.data);t&&this.store.setIssues(t);}};r.addController(this);}hostConnected(){this.connect();}hostDisconnected(){this.removeListeners(),this.eventSource?.close(),clearTimeout(this.reloadTimer),clearTimeout(this.perfReloadTimer),clearTimeout(this.reconnectTimer);}removeListeners(){this.eventSource&&(this.eventSource.removeEventListener(he,this.boundHandlers.fetch),this.eventSource.removeEventListener("log",this.boundHandlers.log),this.eventSource.removeEventListener(ue,this.boundHandlers.error),this.eventSource.removeEventListener(me,this.boundHandlers.query),this.eventSource.removeEventListener(fe,this.boundHandlers.issues));}connect(){this.removeListeners(),this.eventSource?.close(),this.eventSource=new EventSource(T.events),this.eventSource.onopen=()=>{this.retryCount=0;},this.eventSource.onerror=()=>{this.eventSource?.close(),this.scheduleReconnect();},this.eventSource.onmessage=r=>{let t=Dt(r.data);t&&(t.path?.startsWith(U)||(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(),je))));},this.eventSource.addEventListener(he,this.boundHandlers.fetch),this.eventSource.addEventListener("log",this.boundHandlers.log),this.eventSource.addEventListener(ue,this.boundHandlers.error),this.eventSource.addEventListener(me,this.boundHandlers.query),this.eventSource.addEventListener(fe,this.boundHandlers.issues);}scheduleReconnect(){if(this.retryCount>=10)return;let r=Math.min(1e3*2**this.retryCount,3e4);this.retryCount++,this.reconnectTimer=setTimeout(()=>this.connect(),r);}async reloadFlows(){try{let t=await(await fetch(T.flows)).json();this.store.setFlows(t.flows);}catch{}}async reloadMetrics(){try{let t=await(await fetch(T.metricsLive)).json();this.store.setMetrics(t.endpoints||[]);}catch{}}};function Ar(){return l`<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 Cr(){return l`<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 Ir(){return l`<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>`}function Lr(){return l`<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="M9 18h6"/><path d="M10 22h4"/><path d="M12 2a7 7 0 0 0-4 12.7V17h8v-2.3A7 7 0 0 0 12 2z"/></svg>`}function Mr(){return l`<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="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>`}function kr(){return l`<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="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="18" r="3"/><line x1="9" y1="6" x2="15" y2="6"/><line x1="6" y1="9" x2="6" y2="15"/><line x1="18" y1="9" x2="18" y2="15"/><line x1="9" y1="18" x2="15" y2="18"/></svg>`}var ft=class extends E{constructor(){super(...arguments);this.store=new ye;this.activeView="overview";this.viewMode="simple";this.sse=new Re(this,this.store);this.handleStateChanged=t=>{t.detail==="activeView"&&(this.activeView=this.store.state.activeView),this.requestUpdate();};}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this.loadInitialData(),this.store.addEventListener("state-changed",this.handleStateChanged);}disconnectedCallback(){super.disconnectedCallback(),this.store.removeEventListener("state-changed",this.handleStateChanged);}async loadInitialData(){try{let[t,e]=await Promise.all([j(T.flows),j(T.requests)]);this.store.setFlows(t.flows),this.store.setRequests(e.requests);}catch(t){console.warn("[brakit]",t);}try{let[t,e,s,i,n]=await Promise.all([j(T.fetches),j(T.errors),j(T.logs),j(T.queries),j(T.metricsLive)]);this.store.setFetches(t.entries),this.store.setErrors(e.entries),this.store.setLogs(s.entries),this.store.setQueries(i.entries),this.store.setMetrics(n.endpoints||[]);}catch(t){console.warn("[brakit]",t);}try{let t=await j(T.insights);this.store.setIssues(t.issues||[]);}catch(t){console.warn("[brakit]",t);}}switchView(t){t!==this.activeView&&(this.activeView=t,this.store.setActiveView(t),fetch(`${T.tab}?tab=${encodeURIComponent(t)}`).catch(()=>{}),t==="performance"&&this.sse.reloadMetrics());}async handleClear(){confirm(N.CLEAR_CONFIRM)&&(await fetch(T.clear,{method:"POST"}),this.store.clearAll(),D.show(N.CLEARED_TOAST));}handleCopyAsCurl(t){Lt(t);}render(){let t=this.store.state,e=t.requests.filter(c=>!c.path?.startsWith(U)),s=e.filter(c=>c.statusCode>=400).length,i=e.length>0?Math.round(e.reduce((c,p)=>c+p.durationMs,0)/e.length):0,n=(t.issues||[]).filter(_e).length,a=window.__BRAKIT_CONFIG__;return l`
1925
2057
  <div class="app" id="app">
1926
2058
  <aside class="sidebar">
1927
2059
  <div class="sidebar-logo">
1928
2060
  <span class="logo-text">brakit</span>
1929
- <span class="logo-version">v${l?.version??""}</span>
2061
+ <span class="logo-version">v${a?.version??""}</span>
1930
2062
  </div>
1931
2063
  <nav class="sidebar-nav">
1932
- ${this.renderSidebarItem("overview","Overview",vr(),void 0)}
1933
- <div class="sidebar-section">Monitor</div>
1934
- ${this.renderSidebarItem("actions","Actions",gr(),t.flows.length)}
1935
- ${this.renderSidebarItem("requests","Requests",br(),e.length)}
1936
- ${this.renderSidebarItem("fetches","Fetches",Er(),t.fetches.length)}
1937
- <div class="sidebar-section">Insights</div>
1938
- ${this.renderSidebarItem("queries","Queries",yr(),t.queries.length)}
1939
- ${this.renderSidebarItem("errors","Errors",_r(),t.errors.length)}
1940
- ${this.renderSidebarItem("logs","Logs",$r(),t.logs.length)}
1941
- ${this.renderSidebarItem("security","Security",xr(),n,n===0)}
1942
- ${this.renderSidebarItem("performance","Performance",Sr(),void 0)}
1943
- <div class="sidebar-section">Topology</div>
1944
- <button class="sidebar-item ${this.activeView==="graph"?"active":""}" @click=${()=>this.switchView("graph")}>
1945
- <span class="item-icon">${Tr()}</span>
1946
- <span class="item-label">Graph</span>
1947
- <span class="sidebar-beta">beta</span>
1948
- </button>
2064
+ ${this.renderSidebarItem("overview","Overview",Ar(),void 0)}
2065
+ ${this.renderSidebarItem("actions","Actions",Cr(),t.flows.length)}
2066
+ ${this.renderSidebarItem("insights","Insights",Lr(),n,n===0)}
2067
+ ${this.renderSidebarItem("performance","Performance",Ir(),void 0)}
2068
+ ${this.renderSidebarItem("graph","Graph",kr(),void 0)}
2069
+ <div class="sidebar-divider"></div>
2070
+ ${this.renderSidebarItem("explorer","Explorer",Mr(),e.length+t.fetches.length+t.queries.length+t.logs.length+t.errors.length)}
1949
2071
  </nav>
1950
- <div class="sidebar-footer">:${l?.port??""}</div>
2072
+ <div class="sidebar-footer">:${a?.port??""}</div>
1951
2073
  </aside>
1952
2074
  <div class="main-panel">
1953
2075
  <div class="header">
1954
2076
  <div class="header-left">
1955
- <span class="header-title" id="header-title">${Ie[this.activeView]||this.activeView}</span>
1956
- <span class="header-sub" id="header-sub">${Ce[this.activeView]||""}</span>
2077
+ <span class="header-title" id="header-title">${Pe[this.activeView]||this.activeView}</span>
2078
+ <span class="header-sub" id="header-sub">${He[this.activeView]||""}</span>
1957
2079
  </div>
1958
2080
  <div class="header-right">
1959
- ${this.activeView==="actions"?a`
2081
+ ${this.activeView==="actions"?l`
1960
2082
  <div class="segmented-control" id="mode-toggle">
1961
2083
  <button class="segmented-btn ${this.viewMode==="simple"?"active":""}" @click=${()=>{this.viewMode="simple",this.store.setViewMode("simple");}}>Quick</button>
1962
2084
  <button class="segmented-btn ${this.viewMode==="detailed"?"active":""}" @click=${()=>{this.viewMode="detailed",this.store.setViewMode("detailed");}}>Detailed</button>
1963
2085
  </div>
1964
- `:p}
2086
+ `:d}
1965
2087
  <button class="btn btn-danger" @click=${this.handleClear}>Clear</button>
1966
2088
  </div>
1967
2089
  </div>
1968
2090
  <div class="main-content">
1969
- <div id="overview-container" style="display:${this.activeView==="overview"?"block":"none"}">
2091
+ <div style="display:${this.activeView==="overview"?"block":"none"}">
1970
2092
  <bk-overview-view></bk-overview-view>
1971
2093
  </div>
1972
- <div class="view-flows" id="flow-container" style="display:${this.activeView==="actions"?"block":"none"}">
2094
+ <div style="display:${this.activeView==="actions"?"block":"none"}">
1973
2095
  <bk-flows-view></bk-flows-view>
1974
2096
  </div>
1975
- <div class="view-requests" id="request-container" style="display:${this.activeView==="requests"?"block":"none"}">
1976
- <bk-requests-view></bk-requests-view>
1977
- </div>
1978
- <div class="view-telemetry" id="fetch-container" style="display:${this.activeView==="fetches"?"block":"none"}">
1979
- <bk-fetches-view></bk-fetches-view>
1980
- </div>
1981
- <div class="view-telemetry" id="query-container" style="display:${this.activeView==="queries"?"block":"none"}">
1982
- <bk-queries-view></bk-queries-view>
1983
- </div>
1984
- <div class="view-telemetry" id="error-container" style="display:${this.activeView==="errors"?"block":"none"}">
1985
- <bk-errors-view></bk-errors-view>
2097
+ <div style="display:${this.activeView==="insights"?"block":"none"}">
2098
+ <bk-insights-view></bk-insights-view>
1986
2099
  </div>
1987
- <div class="view-telemetry" id="log-container" style="display:${this.activeView==="logs"?"block":"none"}">
1988
- <bk-logs-view></bk-logs-view>
1989
- </div>
1990
- <div class="view-telemetry" id="security-container" style="display:${this.activeView==="security"?"block":"none"}">
1991
- <bk-security-view></bk-security-view>
1992
- </div>
1993
- <div class="view-telemetry" id="performance-container" style="display:${this.activeView==="performance"?"block":"none"}">
2100
+ <div style="display:${this.activeView==="performance"?"block":"none"}">
1994
2101
  <bk-performance-view></bk-performance-view>
1995
2102
  </div>
1996
- <div class="view-telemetry" id="graph-container" style="display:${this.activeView==="graph"?"block":"none"}">
2103
+ <div style="display:${this.activeView==="graph"?"block":"none"}">
1997
2104
  <bk-graph-view></bk-graph-view>
1998
2105
  </div>
2106
+ <div style="display:${this.activeView==="explorer"?"block":"none"}">
2107
+ <bk-explorer-view></bk-explorer-view>
2108
+ </div>
1999
2109
  </div>
2000
2110
  <div class="footer">
2001
- <span id="stat-total">${e.length} request${e.length!==1?"s":""}</span>
2002
- <span id="stat-flows">${t.flows.length} action${t.flows.length!==1?"s":""}</span>
2003
- <span id="stat-errors" class="error-count">${r} error${r!==1?"s":""}</span>
2111
+ <span id="stat-total">${e.length} ${B(e.length,"request")}</span>
2112
+ <span id="stat-flows">${t.flows.length} ${B(t.flows.length,"action")}</span>
2113
+ <span id="stat-errors" class="error-count">${s} ${B(s,"error")}</span>
2004
2114
  <span id="stat-avg">Avg: ${i}ms</span>
2005
2115
  </div>
2006
2116
  </div>
2007
2117
  </div>
2008
2118
  <bk-toast></bk-toast>
2009
- `}renderSidebarItem(t,e,r,i,n=false){return a`
2119
+ `}renderSidebarItem(t,e,s,i,n=false){return l`
2010
2120
  <button class="sidebar-item ${this.activeView===t?"active":""}" @click=${()=>this.switchView(t)}>
2011
- <span class="item-icon">${r}</span>
2121
+ <span class="item-icon">${s}</span>
2012
2122
  <span class="item-label">${e}</span>
2013
- ${i!==void 0?a`<span class="item-count" style="display:${n?"none":""}">${i}</span>`:p}
2123
+ ${i!==void 0?l`<span class="item-count" style="display:${n?"none":""}">${i}</span>`:d}
2014
2124
  </button>
2015
- `}};u([Be({context:A})],dt.prototype,"store",2),u([b()],dt.prototype,"activeView",2),u([b()],dt.prototype,"viewMode",2),dt=u([S("bk-dashboard")],dt);
2125
+ `}};u([Je({context:A})],ft.prototype,"store",2),u([b()],ft.prototype,"activeView",2),u([b()],ft.prototype,"viewMode",2),ft=u([_("bk-dashboard")],ft);
2016
2126
  /*! Bundled license information:
2017
2127
 
2018
2128
  @lit/reactive-element/css-tag.js: