diff --git a/internal/webassets/dist/assets/DashboardPage-t2pmmhQz.js b/internal/webassets/dist/assets/DashboardPage-BaPuikNo.js similarity index 96% rename from internal/webassets/dist/assets/DashboardPage-t2pmmhQz.js rename to internal/webassets/dist/assets/DashboardPage-BaPuikNo.js index dd4c8f5..fa14656 100644 --- a/internal/webassets/dist/assets/DashboardPage-t2pmmhQz.js +++ b/internal/webassets/dist/assets/DashboardPage-BaPuikNo.js @@ -1,4 +1,4 @@ -import{j as w,T as f1,a as Jf,r as rt,I as Mr,d as h1,b as wr,U as Zo,f as Wt,c as Ot,e as Mu,g as ks}from"./index-B9YDBDoG.js";const Mc="https://github.com/Willxup/flowlens",c1="https://github.com/Willxup";function v1(e){const t=e?.trim();return t?`Version: ${t}`:void 0}function d1({version:e}){const t=v1(e);return w.jsxs("footer",{className:"app-footer",children:[w.jsxs("div",{className:"app-footer-line app-footer-meta",children:[w.jsx("span",{children:"© 2026"}),w.jsx("a",{href:Mc,target:"_blank",rel:"noreferrer",children:"FlowLens"}),w.jsx("span",{"aria-hidden":"true",children:"·"}),w.jsx("a",{href:`${Mc}/blob/main/LICENSE`,target:"_blank",rel:"noreferrer",children:"License"})]}),w.jsxs("div",{className:"app-footer-line app-footer-powered",children:[w.jsx("span",{children:"Powered By"}),w.jsxs("a",{href:c1,target:"_blank",rel:"noreferrer","aria-label":"Willxup GitHub 主页",children:[w.jsx(p1,{}),w.jsx("span",{children:"Willxup"})]}),t?w.jsxs(w.Fragment,{children:[w.jsx("span",{className:"app-footer-version-separator","aria-hidden":"true",children:"·"}),w.jsx("span",{className:"app-footer-version",children:t})]}):null]})]})}function p1(){return w.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:[w.jsx("path",{d:"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"}),w.jsx("path",{d:"M9 18c-4.51 2-5-2-7-2"})]})}function g1({status:e,version:t,sourceMode:r,authEnabled:n,onLogout:i,logoutFailed:a,children:o}){const s=a?"退出失败,请重试":"退出";return w.jsxs("main",{className:"app","data-source-mode":r,children:[w.jsxs("header",{className:"topbar",children:[w.jsxs("a",{className:"brand",href:"https://github.com/Willxup/flowlens",target:"_blank",rel:"noreferrer","aria-label":"FlowLens GitHub 仓库",children:[w.jsx("div",{className:"brand-mark","aria-hidden":"true"}),w.jsxs("div",{children:[w.jsx("strong",{children:"FlowLens"}),w.jsx("span",{className:"eyebrow",children:"edge telemetry"})]})]}),w.jsxs("div",{className:"top-actions",children:[w.jsxs("span",{className:`live-status ${e}`,children:[w.jsx("i",{}),e==="ok"?"采集正常":e==="degraded"?"采集降级":"采集失败"]}),w.jsx(f1,{}),n?w.jsx(Jf,{content:s,children:w.jsxs("button",{className:`logout-button${a?" failed":""}`,type:"button","aria-label":s,onClick:i,children:[w.jsx("svg",{viewBox:"0 0 24 24","aria-hidden":"true",children:w.jsx("path",{d:"M10 4H5.5A1.5 1.5 0 0 0 4 5.5v13A1.5 1.5 0 0 0 5.5 20H10M14.5 8.5 18 12l-3.5 3.5M9 12h9"})}),w.jsx("span",{children:a?"重试退出":"退出"})]})}):null]})]}),o,w.jsx(d1,{version:t})]})}function m1({source:e,labels:t,candidates:r,onChanged:n,onClose:i}){const[a,o]=rt.useState({}),[s,l]=rt.useState(!1),[u,f]=rt.useState(null),h=rt.useMemo(()=>{const c=new Map(r.map(g=>[Ln(g.label_type,g.match_value),g])),d=[],p=new Set;for(const g of t){const m=Ln(g.label_type,g.match_value);p.add(m),d.push(c.get(m)??{label_type:g.label_type,match_value:g.match_value,display_name:g.display_name,upload_bytes:"0",download_bytes:"0"})}for(const g of r)p.has(Ln(g.label_type,g.match_value))||d.push(g);return d},[r,t]);rt.useEffect(()=>{const c={};for(const d of h){const p=t.find(g=>g.label_type===d.label_type&&g.match_value===d.match_value);c[Ln(d.label_type,d.match_value)]=p?.display_name??""}o(c)},[h,t]);async function v(c,d){const p=Ln(c.label_type,c.match_value),g=(a[p]??"").trim();if(!(e.demo||g===""&&d===void 0)){f(p),l(!1);try{g===""?await e.deleteLabel(d.id):d===void 0?await e.createLabel({label_type:c.label_type,match_value:c.match_value,display_name:g}):await e.updateLabel(d.id,g),await n()}catch{l(!0)}finally{f(null)}}}return w.jsx("div",{className:"dialog-backdrop",role:"presentation",children:w.jsxs("section",{className:"dialog-shell",role:"dialog","aria-modal":"true","aria-labelledby":"alias-title",children:[w.jsxs("header",{className:"dialog-head",children:[w.jsxs("div",{children:[w.jsx("span",{className:"eyebrow",children:"Display aliases"}),w.jsxs("div",{className:"heading-with-tooltip",children:[w.jsx("h2",{id:"alias-title",children:"目标别名"}),w.jsx(Mr,{content:"别名只改变 FlowLens 展示;清空后保存即可恢复原始名称。",label:"查看“目标别名”说明"})]})]}),w.jsx(Jf,{content:"关闭别名",children:w.jsx("button",{type:"button","aria-label":"关闭别名",onClick:i,children:w.jsx("svg",{viewBox:"0 0 24 24","aria-hidden":"true",children:w.jsx("path",{d:"m7 7 10 10M17 7 7 17"})})})})]}),w.jsxs("div",{className:"dialog-body",children:[e.demo?w.jsx("p",{className:"demo-notice",children:"Demo 为只读,别名修改仅在生产模式提供。"}):null,s?w.jsx("p",{className:"form-error",role:"alert",children:"别名保存失败,请重试。"}):null,w.jsx("div",{className:"alias-list",children:h.map(c=>{const d=t.find(g=>g.label_type===c.label_type&&g.match_value===c.match_value),p=Ln(c.label_type,c.match_value);return w.jsxs("div",{className:"alias-row",children:[w.jsxs("div",{className:"alias-identity",children:[w.jsx("strong",{children:c.match_value}),w.jsxs("span",{children:[c.label_type," 别名"]})]}),w.jsx("input",{className:"alias-field","aria-label":`${c.match_value} 显示名称`,value:a[p]??"",onChange:g=>o(m=>({...m,[p]:g.target.value})),maxLength:64,disabled:e.demo}),w.jsx("div",{className:"alias-actions",children:w.jsx("button",{type:"button","aria-label":`${c.match_value} 保存`,disabled:e.demo||u!==null||d===void 0&&(a[p]??"").trim()==="",onClick:()=>void v(c,d),children:"保存"})})]},p)})})]})]})})}function Ln(e,t){return`${e}:${t}`}const y1=[{label:"实时",value:{kind:"live"}},{label:"今天",value:{kind:"preset",preset:"today"}},{label:"昨天",value:{kind:"preset",preset:"yesterday"}},{label:"7 天",value:{kind:"preset",preset:"7d"}},{label:"30 天",value:{kind:"preset",preset:"30d"}},{label:"90 天",value:{kind:"preset",preset:"90d"}},{label:"今年",value:{kind:"preset",preset:"year"}}],_1=["日","一","二","三","四","五","六"];function b1({value:e,now:t,timezone:r="UTC",onChange:n}){const[i,a]=rt.useState(!1),o=h1(t,r),[s,l]=rt.useState(o),[u,f]=rt.useState(o),[h,v]=rt.useState("from"),[c,d]=rt.useState({..._i(o)}),p=S=>JSON.stringify(S)===JSON.stringify(e),g=s!==""&&u!==""&&s<=u&&u<=o;function m(){e.kind==="custom"?(l(e.from),f(e.to),d(_i(e.from))):(l(o),f(o),d(_i(o))),v("from"),a(!0)}function y(S){v(S),d(_i(S==="from"?s:u))}function _(S){if(h==="from"){l(S),S>u&&f(S),v("to");return}Sw.jsx("button",{type:"button","aria-pressed":!i&&p(S.value),onClick:()=>{a(!1),n(S.value)},children:S.label},S.label)),w.jsx("button",{type:"button","aria-pressed":i||e.kind==="custom",onClick:m,children:"自定义"})]}),i?w.jsxs("section",{className:"custom-range-dialog",role:"dialog","aria-labelledby":"custom-range-title",children:[w.jsxs("header",{className:"custom-range-head",children:[w.jsx("h2",{id:"custom-range-title",children:"选择自定义日期"}),w.jsx("span",{children:r})]}),w.jsxs("div",{className:"custom-date-grid",children:[w.jsxs("button",{className:"custom-date-card",type:"button","aria-label":`开始日期 ${s}`,"aria-pressed":h==="from",onClick:()=>y("from"),children:[w.jsx("span",{children:"开始日期"}),w.jsx("strong",{children:Ga(s)})]}),w.jsxs("button",{className:"custom-date-card",type:"button","aria-label":`结束日期 ${u}`,"aria-pressed":h==="to",onClick:()=>y("to"),children:[w.jsx("span",{children:"结束日期"}),w.jsx("strong",{children:Ga(u)})]})]}),w.jsxs("section",{className:"calendar-card","aria-label":"日期选择器",children:[w.jsxs("header",{className:"calendar-head",children:[w.jsx("button",{type:"button","aria-label":"上个月",onClick:()=>d(Ac(c,-1)),children:"‹"}),w.jsx("h3",{children:`${c.year} 年 ${c.month} 月`}),w.jsx("button",{type:"button","aria-label":"下个月",onClick:()=>d(Ac(c,1)),children:"›"})]}),w.jsx("div",{className:"calendar-weekdays","aria-hidden":"true",children:_1.map(S=>w.jsx("span",{children:S},S))}),w.jsx("div",{className:"calendar-days",children:b.map(S=>{const x=S.value===s||S.value===u,T=S.value>=s&&S.value<=u;return w.jsx("button",{className:["calendar-day",S.currentMonth?"":"outside-month",T?"in-range":"",x?"range-endpoint":""].filter(Boolean).join(" "),type:"button",disabled:S.value>o,"aria-label":S.value,"aria-pressed":x,onClick:()=>{_(S.value),S.currentMonth||d(_i(S.value))},children:S.day},S.value)})})]}),w.jsxs("footer",{className:"custom-range-actions",children:[w.jsx("span",{children:`${Ga(s)} — ${Ga(u)}`}),w.jsxs("div",{children:[w.jsx("button",{className:"soft-button",type:"button",onClick:()=>a(!1),children:"取消"}),w.jsx("button",{className:"primary-button",type:"button",disabled:!g,onClick:()=>{n({kind:"custom",from:s,to:u}),a(!1)},children:"应用"})]})]})]}):null]})}function _i(e){const{year:t,month:r}=Wg(e);return{year:t,month:r}}function Ac(e,t){const r=new Date(Date.UTC(e.year,e.month-1+t,1));return{year:r.getUTCFullYear(),month:r.getUTCMonth()+1}}function S1(e){const r=1-new Date(Date.UTC(e.year,e.month-1,1)).getUTCDay();return Array.from({length:42},(n,i)=>{const a=new Date(Date.UTC(e.year,e.month-1,r+i));return{value:x1(a),day:a.getUTCDate(),currentMonth:a.getUTCMonth()===e.month-1}})}function x1(e){return[e.getUTCFullYear(),String(e.getUTCMonth()+1).padStart(2,"0"),String(e.getUTCDate()).padStart(2,"0")].join("-")}function Ga(e){const{year:t,month:r,day:n}=Wg(e);return`${t}年${r}月${n}日`}function Wg(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))throw new Error("invalid date");return{year:Number(e.slice(0,4)),month:Number(e.slice(5,7)),day:Number(e.slice(8,10))}}function w1(e){const t=e.items.map(r=>({rawValue:r.raw_value,displayName:r.display_name,networkCode:r.network_code,uploadBytes:r.upload_bytes,downloadBytes:r.download_bytes,totalBytes:wr(r.upload_bytes,r.download_bytes)})).sort((r,n)=>T1(n.totalBytes,r.totalBytes)||r.rawValue.localeCompare(n.rawValue));return{by:e.by,available:e.available,noTraffic:e.no_traffic,approximate:e.approximate,connectionCoverage:e.connection_coverage,dimensionRetention:e.dimension_retention,globalBytes:wr(e.global.upload_bytes,e.global.download_bytes),otherBytes:wr(e.other.upload_bytes,e.other.download_bytes),unattributedBytes:wr(e.unattributed.upload_bytes,e.unattributed.download_bytes),items:t}}function T1(e,t){const r=BigInt(e),n=BigInt(t);return rn?1:0}function C1(e,t,r){let n="0";const i=t.points.map(h=>(n=wr(n,h.upload_bytes,h.download_bytes),{start:h.bucket_start,end:h.bucket_end,upload:h.upload_bytes,download:h.download_bytes,cumulative:n,uploadRate:h.speed_sample_count>0?h.average_upload_bytes_per_second:null,downloadRate:h.speed_sample_count>0?h.average_download_bytes_per_second:null,resolution:h.source_resolution_sec})),a=t.points.reduce((h,v)=>h+v.counter_observed_seconds,0),o=t.points.reduce((h,v)=>h+v.elapsed_seconds,0),s=t.points.reduce((h,v)=>h+v.active_connections_samples,0),l=t.points.reduce((h,v)=>h+v.active_connections_sum,0),u=t.points.reduce((h,v)=>wr(h,v.recovered_upload_bytes,v.recovered_download_bytes),"0"),f=t.points.reduce((h,v)=>wr(h,v.unattributed_upload_bytes,v.unattributed_download_bytes),"0");return{uploadBytes:e.current.upload_bytes,downloadBytes:e.current.download_bytes,totalBytes:wr(e.current.upload_bytes,e.current.download_bytes),previousBytes:e.previous.total_bytes,completeness:o>0?Math.min(1,a/o):null,averageUpload:Lc(t,"speed_upload_sample_sum"),averageDownload:Lc(t,"speed_download_sample_sum"),peakUpload:Pc(t,"peak_upload_bytes_per_second"),peakDownload:Pc(t,"peak_download_bytes_per_second"),averageConnections:s>0?l/s:null,peakConnections:s>0?t.points.reduce((h,v)=>v.active_connections_samples>0?Math.max(h,v.active_connections_max):h,0):null,boundaryApproximate:e.boundary_approximate||t.boundary_approximate,qualityEvents:r.events,recoveredBytes:u,unattributedBytes:f,resetCount:t.points.reduce((h,v)=>h+v.reset_count,0),chart:i}}function Lc(e,t){const r=e.points.reduce((a,o)=>a+o.speed_sample_count,0);if(r===0)return null;const n=e.points.reduce((a,o)=>a+BigInt(o[t]),0n),i=BigInt(r);return Number(n/i)+Number(n%i)/r}function Pc(e,t){const r=e.points.filter(n=>n.speed_sample_count>0);return r.length===0?null:r.reduce((n,i)=>Math.max(n,i[t]),0)}function D1(e,t,r,n,i=0){const[a,o]=rt.useState({loading:!1,error:!1,view:null,breakdown:null});return rt.useEffect(()=>{if(t.kind==="live")return;const s=t,l=new AbortController;let u=!0,f=!1;const h=async()=>{o(c=>f?{...c,loading:!0,error:!1}:{loading:!0,error:!1,view:null,breakdown:null});try{const[c,d,p,g]=await Promise.all([e.overview(s,l.signal),e.series(s,l.signal),e.quality(s,l.signal),e.breakdown(s,r,l.signal)]);u&&(f=!0,o({loading:!1,error:!1,view:C1(c,d,p),breakdown:g}))}catch(c){c instanceof Zo?n():u&&!l.signal.aborted&&o(d=>({loading:!1,error:!0,view:f?d.view:null,breakdown:f?d.breakdown:null}))}};h();const v=t.kind==="preset"&&t.preset==="today"?window.setInterval(h,6e4):void 0;return()=>{u=!1,l.abort(),v!==void 0&&window.clearInterval(v)}},[r,n,i,t,e]),{...a,targets:a.breakdown===null?null:w1(a.breakdown)}}function M1(e,t,r,n){const i=[...e].filter(A1).sort((s,l)=>s.timestamp-l.timestamp).slice(-3600),a=i.at(-1),o=L1(i);return{currentUpload:a?.upload_bytes_per_second??null,currentDownload:a?.download_bytes_per_second??null,averageUpload1m:Va(i.slice(-60),"upload_bytes_per_second"),averageDownload1m:Va(i.slice(-60),"download_bytes_per_second"),averageUpload5m:Va(i.slice(-300),"upload_bytes_per_second"),averageDownload5m:Va(i.slice(-300),"download_bytes_per_second"),peakUpload60m:Ic(i,"upload_bytes_per_second"),peakDownload60m:Ic(i,"download_bytes_per_second"),activeConnections:a?.active_connections??r?.active_connections??null,connectionCoverage:r?.connection_coverage??null,status:t,connected:n,observedAt:r?.observed_at??null,intervalMillis:r?.interval_millis??null,targetGlobalRate:r===null?null:r.global_upload_bytes_per_second+r.global_download_bytes_per_second,hasGap:o.some(s=>s.upload===null),chart:o,targets:r?.targets??[]}}function A1(e){return Number.isSafeInteger(e.timestamp)&&e.timestamp>0&&e.upload_bytes_per_second>=0&&e.download_bytes_per_second>=0&&e.active_connections>=0}function Va(e,t){return e.length===0?null:e.reduce((r,n)=>r+n[t],0)/e.length}function Ic(e,t){return e.length===0?null:e.reduce((r,n)=>Math.max(r,n[t]),0)}function L1(e){const t=[];let r=0;for(const n of e)r>0&&n.timestamp-r>2.5&&t.push({timestamp:r+1,upload:null,download:null}),t.push({timestamp:n.timestamp,upload:n.upload_bytes_per_second,download:n.download_bytes_per_second}),r=n.timestamp;return t}function P1(e,t,r,n,i){const[a,o]=rt.useState([]),[s,l]=rt.useState(null),[u,f]=rt.useState(!1);return rt.useEffect(()=>{if(!r)return;let h=!0;const v=async()=>{try{const p=await e.liveTargets();h&&l(p)}catch(p){p instanceof Zo&&i()}};v();const c=window.setInterval(v,1e4),d=e.subscribeLive(p=>{h&&(p.type==="snapshot"&&o(p.samples),p.type==="sample"&&o(g=>[...g,p.sample].slice(-3600)),p.type==="status"&&n(p.status,p.reason))},f);return()=>{h=!1,window.clearInterval(c),d(),f(!1)}},[r,n,i,e]),rt.useMemo(()=>M1(a,t,s,u),[u,a,t,s])}function I1({value:e}){if(e===null)return w.jsx("p",{className:"empty-state",children:"存储状态正在加载。"});const t=e.last_rollup_cleanup,r=e.protecting?"数据库已进入容量保护,请检查空间和保留策略。":t===null?"数据库空间正常,暂无聚合清理记录。":t.successful?"数据库空间充足,最近一次聚合清理已经顺利完成。":"数据库空间正常,但最近一次聚合清理失败。";return w.jsxs("section",{className:"panel storage-panel","aria-labelledby":"storage-title",children:[w.jsxs("div",{className:"storage-lead",children:[w.jsx("span",{className:"eyebrow",children:"Storage health"}),w.jsxs("div",{className:"heading-with-tooltip",children:[w.jsx("h2",{id:"storage-title",children:"存储健康"}),w.jsx(Mr,{content:r,label:"查看“存储健康”说明"})]})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"SQLite"}),w.jsx("strong",{children:Wt(e.database_bytes)})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"WAL"}),w.jsx("strong",{children:Wt(e.wal_bytes)})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"软上限"}),w.jsx("strong",{children:Wt(e.soft_limit_bytes)})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"容量保护"}),w.jsx("strong",{children:e.protecting?"已启用":"正常"})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"最近清理"}),w.jsx("strong",{children:t===null?"暂无记录":t.successful?"成功":"失败"})]})]})}function kc({live:e,liveTotalRate:t,historical:r}){const n=e!==void 0?e.map(a=>{const o=Rc(a.raw_endpoint,a.display_name);return{key:a.raw_endpoint,...o,network:Mu(a.network_code),download:Ot(a.download_bytes_per_second),upload:Ot(a.upload_bytes_per_second),share:k1(a,t),value:Ot(a.upload_bytes_per_second+a.download_bytes_per_second),magnitude:a.upload_bytes_per_second+a.download_bytes_per_second}}):(r??[]).map(a=>{const o=Rc(a.rawValue,a.displayName);return{key:a.rawValue,...o,network:Mu(a.networkCode),download:Wt(a.downloadBytes),upload:Wt(a.uploadBytes),share:null,value:Wt(a.totalBytes),magnitude:Number(BigInt(a.totalBytes)>10000000000n?10000000000n:BigInt(a.totalBytes))}}),i=Math.max(1,...n.map(a=>a.magnitude));return w.jsx("div",{className:"target-list",children:n.length===0?w.jsx("p",{className:"empty-state",children:"当前没有可展示的目标。"}):n.slice(0,8).map((a,o)=>w.jsxs("div",{className:"target-item",children:[w.jsx("div",{className:"target-icon target-rank","aria-label":`第 ${o+1} 名`,children:o+1}),w.jsxs("div",{className:"target-main",children:[w.jsx("strong",{children:a.name}),w.jsxs("span",{className:"target-detail",children:[a.rawDetail===null?null:w.jsxs(w.Fragment,{children:[w.jsx("span",{children:a.rawDetail}),w.jsx("i",{"aria-hidden":"true",children:"·"})]}),w.jsx("span",{children:a.network}),w.jsx("i",{"aria-hidden":"true",children:"·"}),w.jsxs("span",{"aria-label":`下载 ${a.download}`,children:[w.jsx("b",{className:"target-download","aria-hidden":"true",children:"↓"})," ",a.download]}),w.jsx("i",{"aria-hidden":"true",children:"·"}),w.jsxs("span",{"aria-label":`上传 ${a.upload}`,children:[w.jsx("b",{className:"target-upload","aria-hidden":"true",children:"↑"})," ",a.upload]}),a.share===null?null:w.jsxs(w.Fragment,{children:[w.jsx("i",{"aria-hidden":"true",children:"·"}),w.jsx("span",{children:a.share})]})]}),w.jsx("div",{className:"target-bar",children:w.jsx("i",{style:{width:`${Math.max(4,a.magnitude/i*100)}%`}})})]}),w.jsx("strong",{className:"target-value",children:a.value})]},a.key))})}function Rc(e,t){const r=` · ${e}`,n=t.endsWith(r)?t.slice(0,-r.length).trim():t.trim(),i=n===""?e:n;return{name:i,rawDetail:i===e?null:e}}function k1(e,t){return t==null||t<=0?null:`占全局 ${ks((e.upload_bytes_per_second+e.download_bytes_per_second)/t)}`}const R1={target:"目标 IP",endpoint:"Endpoint",port:"端口",network:"TCP/UDP",source:"来源网段",domain:"域名"};function E1({by:e,rows:t}){const r=t.reduce((n,i)=>O1(n,i.totalBytes),"1");return w.jsx("div",{className:"breakdown-distribution","aria-label":`${R1[e]}分布`,children:t.length===0?w.jsx("p",{className:"empty-state",children:"当前范围没有可展示的数据。"}):t.slice(0,8).map(n=>w.jsxs("div",{className:"distribution-row",children:[w.jsxs("div",{className:"distribution-label",children:[w.jsxs("div",{children:[w.jsx("strong",{children:n.displayName}),w.jsxs("span",{children:[n.rawValue,n.networkCode>0?` · ${Mu(n.networkCode)}`:""]})]}),w.jsx("strong",{children:Wt(n.totalBytes)})]}),w.jsxs("div",{className:"distribution-track","aria-hidden":"true",children:[w.jsx("i",{className:"distribution-download",style:{width:`${Ec(n.downloadBytes,r)}%`}}),w.jsx("i",{className:"distribution-upload",style:{width:`${Ec(n.uploadBytes,r)}%`}})]}),w.jsxs("div",{className:"distribution-detail",children:[w.jsxs("span",{children:["↓ ",Wt(n.downloadBytes)]}),w.jsxs("span",{children:["↑ ",Wt(n.uploadBytes)]})]})]},n.rawValue))})}function O1(e,t){return BigInt(e)>=BigInt(t)?e:t}function Ec(e,t){return Number(BigInt(e)*1000n/BigInt(t))/10}function N1({targets:e}){const t=e.slice(0,3),r=162.5+(t.length-1)*50;return w.jsxs("div",{className:"topology","aria-label":"流量拓扑:来源网络经过代理网关到目标服务",children:[w.jsxs("svg",{className:"topology-desktop-flow",viewBox:"0 0 900 300",preserveAspectRatio:"none","aria-hidden":"true",children:[w.jsx("path",{className:"flow-path",d:"M0 72 C260 72 300 150 450 150"}),w.jsx("path",{className:"flow-path secondary",d:"M0 232 C260 232 300 150 450 150"}),t.map((n,i)=>w.jsx("path",{className:"flow-path target",d:`M450 150 C600 150 640 ${50+i*100} 900 ${50+i*100}`},i))]}),w.jsxs("svg",{className:"topology-mobile-flow",viewBox:"0 0 300 285",preserveAspectRatio:"none","aria-hidden":"true",children:[w.jsx("defs",{children:w.jsx("marker",{id:"topology-mobile-arrow",viewBox:"0 0 6 6",refX:"5.5",refY:"3",markerWidth:"5",markerHeight:"5",orient:"auto",children:w.jsx("path",{className:"mobile-flow-arrow",d:"M0 0L6 3L0 6Z"})})}),w.jsx("path",{className:"flow-path",d:"M75 50V60H138V72"}),w.jsx("path",{className:"flow-path secondary",d:"M225 50V60H162V72"}),t.length>0?w.jsx("path",{className:"flow-path target mobile-target-trunk",d:`M150 120V128H14V${r}`}):null,t.map((n,i)=>w.jsx("path",{className:"flow-path target mobile-target-path",d:`M14 ${162.5+i*50}H24`,markerEnd:"url(#topology-mobile-arrow)"},i))]}),w.jsxs("div",{className:"flow-node node-source-one",children:[w.jsx("strong",{children:"来源网络"}),w.jsx("span",{children:"采样可见来源"})]}),w.jsxs("div",{className:"flow-node node-source-two",children:[w.jsx("strong",{children:"其他来源"}),w.jsx("span",{children:"Top 20 合并展示"})]}),w.jsxs("div",{className:"flow-node node-gateway",children:[w.jsx("strong",{children:"代理网关"}),w.jsx("span",{children:"network edge"})]}),t.map((n,i)=>w.jsxs("div",{className:`flow-node node-target node-target-${i}`,children:[w.jsx("strong",{children:n.displayName}),w.jsx("span",{children:n.rawValue})]},n.rawValue))]})}/*! ***************************************************************************** +import{j as w,T as f1,a as Jf,r as rt,I as Mr,d as h1,b as wr,U as Zo,f as Wt,c as Ot,e as Mu,g as ks}from"./index-DlKVpUwn.js";const Mc="https://github.com/Willxup/flowlens",c1="https://github.com/Willxup";function v1(e){const t=e?.trim();return t?`Version: ${t}`:void 0}function d1({version:e}){const t=v1(e);return w.jsxs("footer",{className:"app-footer",children:[w.jsxs("div",{className:"app-footer-line app-footer-meta",children:[w.jsx("span",{children:"© 2026"}),w.jsx("a",{href:Mc,target:"_blank",rel:"noreferrer",children:"FlowLens"}),w.jsx("span",{"aria-hidden":"true",children:"·"}),w.jsx("a",{href:`${Mc}/blob/main/LICENSE`,target:"_blank",rel:"noreferrer",children:"License"})]}),w.jsxs("div",{className:"app-footer-line app-footer-powered",children:[w.jsx("span",{children:"Powered By"}),w.jsxs("a",{href:c1,target:"_blank",rel:"noreferrer","aria-label":"Willxup GitHub 主页",children:[w.jsx(p1,{}),w.jsx("span",{children:"Willxup"})]}),t?w.jsxs(w.Fragment,{children:[w.jsx("span",{className:"app-footer-version-separator","aria-hidden":"true",children:"·"}),w.jsx("span",{className:"app-footer-version",children:t})]}):null]})]})}function p1(){return w.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:[w.jsx("path",{d:"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"}),w.jsx("path",{d:"M9 18c-4.51 2-5-2-7-2"})]})}function g1({status:e,version:t,sourceMode:r,authEnabled:n,onLogout:i,logoutFailed:a,children:o}){const s=a?"退出失败,请重试":"退出";return w.jsxs("div",{className:"app-shell","data-source-mode":r,children:[w.jsxs("header",{className:"topbar",children:[w.jsxs("a",{className:"brand",href:"https://github.com/Willxup/flowlens",target:"_blank",rel:"noreferrer","aria-label":"FlowLens GitHub 仓库",children:[w.jsx("div",{className:"brand-mark","aria-hidden":"true"}),w.jsxs("div",{children:[w.jsx("strong",{children:"FlowLens"}),w.jsx("span",{className:"eyebrow",children:"network telemetry"})]})]}),w.jsxs("div",{className:"top-actions",children:[w.jsxs("span",{className:`live-status ${e}`,children:[w.jsx("i",{}),e==="ok"?"采集正常":e==="degraded"?"采集降级":"采集失败"]}),w.jsx(f1,{}),n?w.jsx(Jf,{content:s,children:w.jsxs("button",{className:`logout-button${a?" failed":""}`,type:"button","aria-label":s,onClick:i,children:[w.jsx("svg",{viewBox:"0 0 24 24","aria-hidden":"true",children:w.jsx("path",{d:"M10 4H5.5A1.5 1.5 0 0 0 4 5.5v13A1.5 1.5 0 0 0 5.5 20H10M14.5 8.5 18 12l-3.5 3.5M9 12h9"})}),w.jsx("span",{children:a?"重试退出":"退出"})]})}):null]})]}),w.jsx("main",{className:"app",children:o}),w.jsx(d1,{version:t})]})}function m1({source:e,labels:t,candidates:r,onChanged:n,onClose:i}){const[a,o]=rt.useState({}),[s,l]=rt.useState(!1),[u,f]=rt.useState(null),h=rt.useMemo(()=>{const c=new Map(r.map(g=>[Ln(g.label_type,g.match_value),g])),d=[],p=new Set;for(const g of t){const m=Ln(g.label_type,g.match_value);p.add(m),d.push(c.get(m)??{label_type:g.label_type,match_value:g.match_value,display_name:g.display_name,upload_bytes:"0",download_bytes:"0"})}for(const g of r)p.has(Ln(g.label_type,g.match_value))||d.push(g);return d},[r,t]);rt.useEffect(()=>{const c={};for(const d of h){const p=t.find(g=>g.label_type===d.label_type&&g.match_value===d.match_value);c[Ln(d.label_type,d.match_value)]=p?.display_name??""}o(c)},[h,t]);async function v(c,d){const p=Ln(c.label_type,c.match_value),g=(a[p]??"").trim();if(!(e.demo||g===""&&d===void 0)){f(p),l(!1);try{g===""?await e.deleteLabel(d.id):d===void 0?await e.createLabel({label_type:c.label_type,match_value:c.match_value,display_name:g}):await e.updateLabel(d.id,g),await n()}catch{l(!0)}finally{f(null)}}}return w.jsx("div",{className:"dialog-backdrop",role:"presentation",children:w.jsxs("section",{className:"dialog-shell",role:"dialog","aria-modal":"true","aria-labelledby":"alias-title",children:[w.jsxs("header",{className:"dialog-head",children:[w.jsxs("div",{children:[w.jsx("span",{className:"eyebrow",children:"Display aliases"}),w.jsxs("div",{className:"heading-with-tooltip",children:[w.jsx("h2",{id:"alias-title",children:"目标别名"}),w.jsx(Mr,{content:"别名只改变 FlowLens 展示;清空后保存即可恢复原始名称。",label:"查看“目标别名”说明"})]})]}),w.jsx(Jf,{content:"关闭别名",children:w.jsx("button",{type:"button","aria-label":"关闭别名",onClick:i,children:w.jsx("svg",{viewBox:"0 0 24 24","aria-hidden":"true",children:w.jsx("path",{d:"m7 7 10 10M17 7 7 17"})})})})]}),w.jsxs("div",{className:"dialog-body",children:[e.demo?w.jsx("p",{className:"demo-notice",children:"Demo 为只读,别名修改仅在生产模式提供。"}):null,s?w.jsx("p",{className:"form-error",role:"alert",children:"别名保存失败,请重试。"}):null,w.jsx("div",{className:"alias-list",children:h.map(c=>{const d=t.find(g=>g.label_type===c.label_type&&g.match_value===c.match_value),p=Ln(c.label_type,c.match_value);return w.jsxs("div",{className:"alias-row",children:[w.jsxs("div",{className:"alias-identity",children:[w.jsx("strong",{children:c.match_value}),w.jsxs("span",{children:[c.label_type," 别名"]})]}),w.jsx("input",{className:"alias-field","aria-label":`${c.match_value} 显示名称`,value:a[p]??"",onChange:g=>o(m=>({...m,[p]:g.target.value})),maxLength:64,disabled:e.demo}),w.jsx("div",{className:"alias-actions",children:w.jsx("button",{type:"button","aria-label":`${c.match_value} 保存`,disabled:e.demo||u!==null||d===void 0&&(a[p]??"").trim()==="",onClick:()=>void v(c,d),children:"保存"})})]},p)})})]})]})})}function Ln(e,t){return`${e}:${t}`}const y1=[{label:"实时",value:{kind:"live"}},{label:"今天",value:{kind:"preset",preset:"today"}},{label:"昨天",value:{kind:"preset",preset:"yesterday"}},{label:"7 天",value:{kind:"preset",preset:"7d"}},{label:"30 天",value:{kind:"preset",preset:"30d"}},{label:"90 天",value:{kind:"preset",preset:"90d"}},{label:"今年",value:{kind:"preset",preset:"year"}}],_1=["日","一","二","三","四","五","六"];function b1({value:e,now:t,timezone:r="UTC",onChange:n}){const[i,a]=rt.useState(!1),o=h1(t,r),[s,l]=rt.useState(o),[u,f]=rt.useState(o),[h,v]=rt.useState("from"),[c,d]=rt.useState({..._i(o)}),p=S=>JSON.stringify(S)===JSON.stringify(e),g=s!==""&&u!==""&&s<=u&&u<=o;function m(){e.kind==="custom"?(l(e.from),f(e.to),d(_i(e.from))):(l(o),f(o),d(_i(o))),v("from"),a(!0)}function y(S){v(S),d(_i(S==="from"?s:u))}function _(S){if(h==="from"){l(S),S>u&&f(S),v("to");return}Sw.jsx("button",{type:"button","aria-pressed":!i&&p(S.value),onClick:()=>{a(!1),n(S.value)},children:S.label},S.label)),w.jsx("button",{type:"button","aria-pressed":i||e.kind==="custom",onClick:m,children:"自定义"})]}),i?w.jsxs("section",{className:"custom-range-dialog",role:"dialog","aria-labelledby":"custom-range-title",children:[w.jsxs("header",{className:"custom-range-head",children:[w.jsx("h2",{id:"custom-range-title",children:"选择自定义日期"}),w.jsx("span",{children:r})]}),w.jsxs("div",{className:"custom-date-grid",children:[w.jsxs("button",{className:"custom-date-card",type:"button","aria-label":`开始日期 ${s}`,"aria-pressed":h==="from",onClick:()=>y("from"),children:[w.jsx("span",{children:"开始日期"}),w.jsx("strong",{children:Ga(s)})]}),w.jsxs("button",{className:"custom-date-card",type:"button","aria-label":`结束日期 ${u}`,"aria-pressed":h==="to",onClick:()=>y("to"),children:[w.jsx("span",{children:"结束日期"}),w.jsx("strong",{children:Ga(u)})]})]}),w.jsxs("section",{className:"calendar-card","aria-label":"日期选择器",children:[w.jsxs("header",{className:"calendar-head",children:[w.jsx("button",{type:"button","aria-label":"上个月",onClick:()=>d(Ac(c,-1)),children:"‹"}),w.jsx("h3",{children:`${c.year} 年 ${c.month} 月`}),w.jsx("button",{type:"button","aria-label":"下个月",onClick:()=>d(Ac(c,1)),children:"›"})]}),w.jsx("div",{className:"calendar-weekdays","aria-hidden":"true",children:_1.map(S=>w.jsx("span",{children:S},S))}),w.jsx("div",{className:"calendar-days",children:b.map(S=>{const x=S.value===s||S.value===u,T=S.value>=s&&S.value<=u;return w.jsx("button",{className:["calendar-day",S.currentMonth?"":"outside-month",T?"in-range":"",x?"range-endpoint":""].filter(Boolean).join(" "),type:"button",disabled:S.value>o,"aria-label":S.value,"aria-pressed":x,onClick:()=>{_(S.value),S.currentMonth||d(_i(S.value))},children:S.day},S.value)})})]}),w.jsxs("footer",{className:"custom-range-actions",children:[w.jsx("span",{children:`${Ga(s)} — ${Ga(u)}`}),w.jsxs("div",{children:[w.jsx("button",{className:"soft-button",type:"button",onClick:()=>a(!1),children:"取消"}),w.jsx("button",{className:"primary-button",type:"button",disabled:!g,onClick:()=>{n({kind:"custom",from:s,to:u}),a(!1)},children:"应用"})]})]})]}):null]})}function _i(e){const{year:t,month:r}=Wg(e);return{year:t,month:r}}function Ac(e,t){const r=new Date(Date.UTC(e.year,e.month-1+t,1));return{year:r.getUTCFullYear(),month:r.getUTCMonth()+1}}function S1(e){const r=1-new Date(Date.UTC(e.year,e.month-1,1)).getUTCDay();return Array.from({length:42},(n,i)=>{const a=new Date(Date.UTC(e.year,e.month-1,r+i));return{value:x1(a),day:a.getUTCDate(),currentMonth:a.getUTCMonth()===e.month-1}})}function x1(e){return[e.getUTCFullYear(),String(e.getUTCMonth()+1).padStart(2,"0"),String(e.getUTCDate()).padStart(2,"0")].join("-")}function Ga(e){const{year:t,month:r,day:n}=Wg(e);return`${t}年${r}月${n}日`}function Wg(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))throw new Error("invalid date");return{year:Number(e.slice(0,4)),month:Number(e.slice(5,7)),day:Number(e.slice(8,10))}}function w1(e){const t=e.items.map(r=>({rawValue:r.raw_value,displayName:r.display_name,networkCode:r.network_code,uploadBytes:r.upload_bytes,downloadBytes:r.download_bytes,totalBytes:wr(r.upload_bytes,r.download_bytes)})).sort((r,n)=>T1(n.totalBytes,r.totalBytes)||r.rawValue.localeCompare(n.rawValue));return{by:e.by,available:e.available,noTraffic:e.no_traffic,approximate:e.approximate,connectionCoverage:e.connection_coverage,dimensionRetention:e.dimension_retention,globalBytes:wr(e.global.upload_bytes,e.global.download_bytes),otherBytes:wr(e.other.upload_bytes,e.other.download_bytes),unattributedBytes:wr(e.unattributed.upload_bytes,e.unattributed.download_bytes),items:t}}function T1(e,t){const r=BigInt(e),n=BigInt(t);return rn?1:0}function C1(e,t,r){let n="0";const i=t.points.map(h=>(n=wr(n,h.upload_bytes,h.download_bytes),{start:h.bucket_start,end:h.bucket_end,upload:h.upload_bytes,download:h.download_bytes,cumulative:n,uploadRate:h.speed_sample_count>0?h.average_upload_bytes_per_second:null,downloadRate:h.speed_sample_count>0?h.average_download_bytes_per_second:null,resolution:h.source_resolution_sec})),a=t.points.reduce((h,v)=>h+v.counter_observed_seconds,0),o=t.points.reduce((h,v)=>h+v.elapsed_seconds,0),s=t.points.reduce((h,v)=>h+v.active_connections_samples,0),l=t.points.reduce((h,v)=>h+v.active_connections_sum,0),u=t.points.reduce((h,v)=>wr(h,v.recovered_upload_bytes,v.recovered_download_bytes),"0"),f=t.points.reduce((h,v)=>wr(h,v.unattributed_upload_bytes,v.unattributed_download_bytes),"0");return{uploadBytes:e.current.upload_bytes,downloadBytes:e.current.download_bytes,totalBytes:wr(e.current.upload_bytes,e.current.download_bytes),previousBytes:e.previous.total_bytes,completeness:o>0?Math.min(1,a/o):null,averageUpload:Lc(t,"speed_upload_sample_sum"),averageDownload:Lc(t,"speed_download_sample_sum"),peakUpload:Pc(t,"peak_upload_bytes_per_second"),peakDownload:Pc(t,"peak_download_bytes_per_second"),averageConnections:s>0?l/s:null,peakConnections:s>0?t.points.reduce((h,v)=>v.active_connections_samples>0?Math.max(h,v.active_connections_max):h,0):null,boundaryApproximate:e.boundary_approximate||t.boundary_approximate,qualityEvents:r.events,recoveredBytes:u,unattributedBytes:f,resetCount:t.points.reduce((h,v)=>h+v.reset_count,0),chart:i}}function Lc(e,t){const r=e.points.reduce((a,o)=>a+o.speed_sample_count,0);if(r===0)return null;const n=e.points.reduce((a,o)=>a+BigInt(o[t]),0n),i=BigInt(r);return Number(n/i)+Number(n%i)/r}function Pc(e,t){const r=e.points.filter(n=>n.speed_sample_count>0);return r.length===0?null:r.reduce((n,i)=>Math.max(n,i[t]),0)}function D1(e,t,r,n,i=0){const[a,o]=rt.useState({loading:!1,error:!1,view:null,breakdown:null});return rt.useEffect(()=>{if(t.kind==="live")return;const s=t,l=new AbortController;let u=!0,f=!1;const h=async()=>{o(c=>f?{...c,loading:!0,error:!1}:{loading:!0,error:!1,view:null,breakdown:null});try{const[c,d,p,g]=await Promise.all([e.overview(s,l.signal),e.series(s,l.signal),e.quality(s,l.signal),e.breakdown(s,r,l.signal)]);u&&(f=!0,o({loading:!1,error:!1,view:C1(c,d,p),breakdown:g}))}catch(c){c instanceof Zo?n():u&&!l.signal.aborted&&o(d=>({loading:!1,error:!0,view:f?d.view:null,breakdown:f?d.breakdown:null}))}};h();const v=t.kind==="preset"&&t.preset==="today"?window.setInterval(h,6e4):void 0;return()=>{u=!1,l.abort(),v!==void 0&&window.clearInterval(v)}},[r,n,i,t,e]),{...a,targets:a.breakdown===null?null:w1(a.breakdown)}}function M1(e,t,r,n){const i=[...e].filter(A1).sort((s,l)=>s.timestamp-l.timestamp).slice(-3600),a=i.at(-1),o=L1(i);return{currentUpload:a?.upload_bytes_per_second??null,currentDownload:a?.download_bytes_per_second??null,averageUpload1m:Va(i.slice(-60),"upload_bytes_per_second"),averageDownload1m:Va(i.slice(-60),"download_bytes_per_second"),averageUpload5m:Va(i.slice(-300),"upload_bytes_per_second"),averageDownload5m:Va(i.slice(-300),"download_bytes_per_second"),peakUpload60m:Ic(i,"upload_bytes_per_second"),peakDownload60m:Ic(i,"download_bytes_per_second"),activeConnections:a?.active_connections??r?.active_connections??null,connectionCoverage:r?.connection_coverage??null,status:t,connected:n,observedAt:r?.observed_at??null,intervalMillis:r?.interval_millis??null,targetGlobalRate:r===null?null:r.global_upload_bytes_per_second+r.global_download_bytes_per_second,hasGap:o.some(s=>s.upload===null),chart:o,targets:r?.targets??[]}}function A1(e){return Number.isSafeInteger(e.timestamp)&&e.timestamp>0&&e.upload_bytes_per_second>=0&&e.download_bytes_per_second>=0&&e.active_connections>=0}function Va(e,t){return e.length===0?null:e.reduce((r,n)=>r+n[t],0)/e.length}function Ic(e,t){return e.length===0?null:e.reduce((r,n)=>Math.max(r,n[t]),0)}function L1(e){const t=[];let r=0;for(const n of e)r>0&&n.timestamp-r>2.5&&t.push({timestamp:r+1,upload:null,download:null}),t.push({timestamp:n.timestamp,upload:n.upload_bytes_per_second,download:n.download_bytes_per_second}),r=n.timestamp;return t}function P1(e,t,r,n,i){const[a,o]=rt.useState([]),[s,l]=rt.useState(null),[u,f]=rt.useState(!1);return rt.useEffect(()=>{if(!r)return;let h=!0;const v=async()=>{try{const p=await e.liveTargets();h&&l(p)}catch(p){p instanceof Zo&&i()}};v();const c=window.setInterval(v,1e4),d=e.subscribeLive(p=>{h&&(p.type==="snapshot"&&o(p.samples),p.type==="sample"&&o(g=>[...g,p.sample].slice(-3600)),p.type==="status"&&n(p.status,p.reason))},f);return()=>{h=!1,window.clearInterval(c),d(),f(!1)}},[r,n,i,e]),rt.useMemo(()=>M1(a,t,s,u),[u,a,t,s])}function I1({value:e}){if(e===null)return w.jsx("p",{className:"empty-state",children:"存储状态正在加载。"});const t=e.last_rollup_cleanup,r=e.protecting?"数据库已进入容量保护,请检查空间和保留策略。":t===null?"数据库空间正常,暂无聚合清理记录。":t.successful?"数据库空间充足,最近一次聚合清理已经顺利完成。":"数据库空间正常,但最近一次聚合清理失败。";return w.jsxs("section",{className:"panel storage-panel","aria-labelledby":"storage-title",children:[w.jsxs("div",{className:"storage-lead",children:[w.jsx("span",{className:"eyebrow",children:"Storage health"}),w.jsxs("div",{className:"heading-with-tooltip",children:[w.jsx("h2",{id:"storage-title",children:"存储健康"}),w.jsx(Mr,{content:r,label:"查看“存储健康”说明"})]})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"SQLite"}),w.jsx("strong",{children:Wt(e.database_bytes)})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"WAL"}),w.jsx("strong",{children:Wt(e.wal_bytes)})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"软上限"}),w.jsx("strong",{children:Wt(e.soft_limit_bytes)})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"容量保护"}),w.jsx("strong",{children:e.protecting?"已启用":"正常"})]}),w.jsxs("div",{className:"storage-stat",children:[w.jsx("span",{children:"最近清理"}),w.jsx("strong",{children:t===null?"暂无记录":t.successful?"成功":"失败"})]})]})}function kc({live:e,liveTotalRate:t,historical:r}){const n=e!==void 0?e.map(a=>{const o=Rc(a.raw_endpoint,a.display_name);return{key:a.raw_endpoint,...o,network:Mu(a.network_code),download:Ot(a.download_bytes_per_second),upload:Ot(a.upload_bytes_per_second),share:k1(a,t),value:Ot(a.upload_bytes_per_second+a.download_bytes_per_second),magnitude:a.upload_bytes_per_second+a.download_bytes_per_second}}):(r??[]).map(a=>{const o=Rc(a.rawValue,a.displayName);return{key:a.rawValue,...o,network:Mu(a.networkCode),download:Wt(a.downloadBytes),upload:Wt(a.uploadBytes),share:null,value:Wt(a.totalBytes),magnitude:Number(BigInt(a.totalBytes)>10000000000n?10000000000n:BigInt(a.totalBytes))}}),i=Math.max(1,...n.map(a=>a.magnitude));return w.jsx("div",{className:"target-list",children:n.length===0?w.jsx("p",{className:"empty-state",children:"当前没有可展示的目标。"}):n.slice(0,8).map((a,o)=>w.jsxs("div",{className:"target-item",children:[w.jsx("div",{className:"target-icon target-rank","aria-label":`第 ${o+1} 名`,children:o+1}),w.jsxs("div",{className:"target-main",children:[w.jsx("strong",{children:a.name}),w.jsxs("span",{className:"target-detail",children:[a.rawDetail===null?null:w.jsxs(w.Fragment,{children:[w.jsx("span",{children:a.rawDetail}),w.jsx("i",{"aria-hidden":"true",children:"·"})]}),w.jsx("span",{children:a.network}),w.jsx("i",{"aria-hidden":"true",children:"·"}),w.jsxs("span",{"aria-label":`下载 ${a.download}`,children:[w.jsx("b",{className:"target-download","aria-hidden":"true",children:"↓"})," ",a.download]}),w.jsx("i",{"aria-hidden":"true",children:"·"}),w.jsxs("span",{"aria-label":`上传 ${a.upload}`,children:[w.jsx("b",{className:"target-upload","aria-hidden":"true",children:"↑"})," ",a.upload]}),a.share===null?null:w.jsxs(w.Fragment,{children:[w.jsx("i",{"aria-hidden":"true",children:"·"}),w.jsx("span",{children:a.share})]})]}),w.jsx("div",{className:"target-bar",children:w.jsx("i",{style:{width:`${Math.max(4,a.magnitude/i*100)}%`}})})]}),w.jsx("strong",{className:"target-value",children:a.value})]},a.key))})}function Rc(e,t){const r=` · ${e}`,n=t.endsWith(r)?t.slice(0,-r.length).trim():t.trim(),i=n===""?e:n;return{name:i,rawDetail:i===e?null:e}}function k1(e,t){return t==null||t<=0?null:`占全局 ${ks((e.upload_bytes_per_second+e.download_bytes_per_second)/t)}`}const R1={target:"目标 IP",endpoint:"Endpoint",port:"端口",network:"TCP/UDP",source:"来源网段",domain:"域名"};function E1({by:e,rows:t}){const r=t.reduce((n,i)=>O1(n,i.totalBytes),"1");return w.jsx("div",{className:"breakdown-distribution","aria-label":`${R1[e]}分布`,children:t.length===0?w.jsx("p",{className:"empty-state",children:"当前范围没有可展示的数据。"}):t.slice(0,8).map(n=>w.jsxs("div",{className:"distribution-row",children:[w.jsxs("div",{className:"distribution-label",children:[w.jsxs("div",{children:[w.jsx("strong",{children:n.displayName}),w.jsxs("span",{children:[n.rawValue,n.networkCode>0?` · ${Mu(n.networkCode)}`:""]})]}),w.jsx("strong",{children:Wt(n.totalBytes)})]}),w.jsxs("div",{className:"distribution-track","aria-hidden":"true",children:[w.jsx("i",{className:"distribution-download",style:{width:`${Ec(n.downloadBytes,r)}%`}}),w.jsx("i",{className:"distribution-upload",style:{width:`${Ec(n.uploadBytes,r)}%`}})]}),w.jsxs("div",{className:"distribution-detail",children:[w.jsxs("span",{children:["↓ ",Wt(n.downloadBytes)]}),w.jsxs("span",{children:["↑ ",Wt(n.uploadBytes)]})]})]},n.rawValue))})}function O1(e,t){return BigInt(e)>=BigInt(t)?e:t}function Ec(e,t){return Number(BigInt(e)*1000n/BigInt(t))/10}function N1({targets:e}){const t=e.slice(0,3),r=162.5+(t.length-1)*50;return w.jsxs("div",{className:"topology","aria-label":"流量拓扑:来源网络经过代理网关到目标服务",children:[w.jsxs("svg",{className:"topology-desktop-flow",viewBox:"0 0 900 300",preserveAspectRatio:"none","aria-hidden":"true",children:[w.jsx("path",{className:"flow-path",d:"M0 72 C260 72 300 150 450 150"}),w.jsx("path",{className:"flow-path secondary",d:"M0 232 C260 232 300 150 450 150"}),t.map((n,i)=>w.jsx("path",{className:"flow-path target",d:`M450 150 C600 150 640 ${50+i*100} 900 ${50+i*100}`},i))]}),w.jsxs("svg",{className:"topology-mobile-flow",viewBox:"0 0 300 285",preserveAspectRatio:"none","aria-hidden":"true",children:[w.jsx("defs",{children:w.jsx("marker",{id:"topology-mobile-arrow",viewBox:"0 0 6 6",refX:"5.5",refY:"3",markerWidth:"5",markerHeight:"5",orient:"auto",children:w.jsx("path",{className:"mobile-flow-arrow",d:"M0 0L6 3L0 6Z"})})}),w.jsx("path",{className:"flow-path",d:"M75 50V60H138V72"}),w.jsx("path",{className:"flow-path secondary",d:"M225 50V60H162V72"}),t.length>0?w.jsx("path",{className:"flow-path target mobile-target-trunk",d:`M150 120V128H14V${r}`}):null,t.map((n,i)=>w.jsx("path",{className:"flow-path target mobile-target-path",d:`M14 ${162.5+i*50}H24`,markerEnd:"url(#topology-mobile-arrow)"},i))]}),w.jsxs("div",{className:"flow-node node-source-one",children:[w.jsx("strong",{children:"来源网络"}),w.jsx("span",{children:"采样可见来源"})]}),w.jsxs("div",{className:"flow-node node-source-two",children:[w.jsx("strong",{children:"其他来源"}),w.jsx("span",{children:"Top 20 合并展示"})]}),w.jsxs("div",{className:"flow-node node-gateway",children:[w.jsx("strong",{children:"代理网关"}),w.jsx("span",{children:"network edge"})]}),t.map((n,i)=>w.jsxs("div",{className:`flow-node node-target node-target-${i}`,children:[w.jsx("strong",{children:n.displayName}),w.jsx("span",{children:n.rawValue})]},n.rawValue))]})}/*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any diff --git a/internal/webassets/dist/assets/index-DYhF9AXz.css b/internal/webassets/dist/assets/index-DYhF9AXz.css new file mode 100644 index 0000000..836a8e2 --- /dev/null +++ b/internal/webassets/dist/assets/index-DYhF9AXz.css @@ -0,0 +1 @@ +:root{color-scheme:light;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,SF Pro Display,PingFang SC,Helvetica Neue,Segoe UI,system-ui,sans-serif;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "PingFang SC", "Helvetica Neue", "Segoe UI", system-ui, sans-serif;--font-mono: "SFMono-Regular", "SF Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;--page: #f1f4f8;--page-deep: #e7ecf3;--page-glow-primary: rgba(37, 99, 235, .1);--page-glow-accent: rgba(217, 119, 6, .09);--surface: rgba(255, 255, 255, .92);--surface-strong: #ffffff;--surface-soft: #f6f8fb;--surface-raised: #fbfcfe;--ink: #172033;--ink-soft: #344054;--muted: #667085;--faint: #8993a4;--line: #dfe5ed;--line-strong: #cbd4e1;--shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 12px 32px rgba(16, 24, 40, .07);--shadow-soft: 0 1px 2px rgba(16, 24, 40, .035), 0 6px 18px rgba(16, 24, 40, .045);--shadow-float: 0 20px 56px rgba(16, 24, 40, .16);--download: #2563eb;--download-strong: #1d4ed8;--download-soft: rgba(37, 99, 235, .1);--download-card-tint: rgba(37, 99, 235, .1);--download-card-border: color-mix(in srgb, var(--download) 22%, var(--line));--upload: #d97706;--upload-strong: #b45309;--upload-soft: rgba(217, 119, 6, .11);--upload-card-tint: rgba(217, 119, 6, .1);--upload-card-border: color-mix(in srgb, var(--upload) 22%, var(--line));--green: #0f9d78;--green-soft: rgba(15, 157, 120, .11);--success-card-tint: rgba(15, 157, 120, .09);--success-card-border: color-mix(in srgb, var(--green) 20%, var(--line));--cyan: #0891b2;--cyan-soft: rgba(8, 145, 178, .1);--violet: #7c3aed;--danger: #c4323e;--danger-soft: rgba(196, 50, 62, .1);--focus-ring: rgba(37, 99, 235, .24);--chart-tooltip-bg: #172033;--chart-tooltip-ink: #f8fafc;--radius-xl: 20px;--radius-lg: 16px;--radius-md: 12px;--radius-sm: 9px;--motion-fast: .16s;--motion-base: .22s;--ease-out: cubic-bezier(.22, 1, .36, 1);--layer-page-control: 30;--layer-header: 40;--layer-modal: 50;--layer-tooltip: 100}:root[data-theme=dark]{color-scheme:dark;--page: #101012;--page-deep: #09090b;--page-glow-primary: rgba(255, 255, 255, .018);--page-glow-accent: rgba(255, 255, 255, .008);--surface: rgba(24, 24, 27, .94);--surface-strong: #1f1f22;--surface-soft: #27272a;--surface-raised: #2d2d31;--ink: #fafafa;--ink-soft: #e4e4e7;--muted: #a1a1aa;--faint: #71717a;--line: #343438;--line-strong: #4a4a50;--shadow: 0 1px 2px rgba(0, 0, 0, .2), 0 18px 46px rgba(0, 0, 0, .28);--shadow-soft: 0 1px 2px rgba(0, 0, 0, .18), 0 8px 24px rgba(0, 0, 0, .2);--shadow-float: 0 24px 64px rgba(0, 0, 0, .46);--download: #60a5fa;--download-strong: #93c5fd;--download-soft: rgba(96, 165, 250, .13);--download-card-tint: rgba(255, 255, 255, .012);--download-card-border: var(--line);--upload: #fbbf24;--upload-strong: #fcd34d;--upload-soft: rgba(251, 191, 36, .13);--upload-card-tint: rgba(255, 255, 255, .012);--upload-card-border: var(--line);--green: #34d399;--green-soft: rgba(52, 211, 153, .13);--success-card-tint: rgba(255, 255, 255, .012);--success-card-border: var(--line);--cyan: #22d3ee;--cyan-soft: rgba(34, 211, 238, .12);--violet: #a78bfa;--danger: #fb7185;--danger-soft: rgba(251, 113, 133, .13);--focus-ring: rgba(96, 165, 250, .3);--chart-tooltip-bg: #020617;--chart-tooltip-ink: #f8fafc}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){color-scheme:dark;--page: #101012;--page-deep: #09090b;--page-glow-primary: rgba(255, 255, 255, .018);--page-glow-accent: rgba(255, 255, 255, .008);--surface: rgba(24, 24, 27, .94);--surface-strong: #1f1f22;--surface-soft: #27272a;--surface-raised: #2d2d31;--ink: #fafafa;--ink-soft: #e4e4e7;--muted: #a1a1aa;--faint: #71717a;--line: #343438;--line-strong: #4a4a50;--shadow: 0 1px 2px rgba(0, 0, 0, .2), 0 18px 46px rgba(0, 0, 0, .28);--shadow-soft: 0 1px 2px rgba(0, 0, 0, .18), 0 8px 24px rgba(0, 0, 0, .2);--shadow-float: 0 24px 64px rgba(0, 0, 0, .46);--download: #60a5fa;--download-strong: #93c5fd;--download-soft: rgba(96, 165, 250, .13);--download-card-tint: rgba(255, 255, 255, .012);--download-card-border: var(--line);--upload: #fbbf24;--upload-strong: #fcd34d;--upload-soft: rgba(251, 191, 36, .13);--upload-card-tint: rgba(255, 255, 255, .012);--upload-card-border: var(--line);--green: #34d399;--green-soft: rgba(52, 211, 153, .13);--success-card-tint: rgba(255, 255, 255, .012);--success-card-border: var(--line);--cyan: #22d3ee;--cyan-soft: rgba(34, 211, 238, .12);--violet: #a78bfa;--danger: #fb7185;--danger-soft: rgba(251, 113, 133, .13);--focus-ring: rgba(96, 165, 250, .3);--chart-tooltip-bg: #020617;--chart-tooltip-ink: #f8fafc}}*{box-sizing:border-box}html{min-height:100%;background:radial-gradient(circle at 4% 0,var(--page-glow-primary),transparent 34rem),radial-gradient(circle at 96% 4rem,var(--page-glow-accent),transparent 30rem),linear-gradient(180deg,var(--page) 0,var(--page-deep) 100%);background-attachment:fixed;background-repeat:no-repeat}body{margin:0;min-height:100vh;color:var(--ink);background:transparent;font-family:var(--font-sans);font-size:16px}button,input,select{font:inherit}button,select{color:inherit}button{cursor:pointer;touch-action:manipulation}h1,h2,h3,p{margin-top:0}p{color:var(--muted);line-height:1.6}.eyebrow{display:block;color:var(--muted);font-size:.68rem;font-weight:700;letter-spacing:.11em;line-height:1.25;text-transform:uppercase}.micro{color:var(--muted);font-size:.72rem;font-variant-numeric:tabular-nums}::selection{color:#fff;background:var(--download)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{border:3px solid transparent;border-radius:999px;background:var(--line-strong);background-clip:padding-box}.app-shell{width:min(1360px,calc(100% - 48px));margin:20px auto 48px}.app{min-width:0}.app-footer{display:grid;gap:6px;justify-items:center;padding:26px 24px 0;color:var(--muted);font-size:.68rem;line-height:1.5;text-align:center}.app-footer-line{width:100%;display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap}.app-footer a{display:inline-flex;align-items:center;gap:4px;border-radius:5px;color:inherit;text-decoration:none;transition:color var(--motion-fast) ease}.app-footer a:hover{color:var(--download-strong)}.app-footer a:focus-visible{outline:3px solid var(--focus-ring);outline-offset:3px}.app-footer-powered svg{flex:0 0 auto}.app-footer-version{white-space:nowrap}.topbar{min-height:54px;padding:8px 9px 8px 14px;display:grid;grid-template-columns:minmax(190px,1fr) auto;align-items:center;gap:18px;border:1px solid var(--line);border-radius:14px;background:var(--surface);box-shadow:var(--shadow-soft);backdrop-filter:blur(14px) saturate(135%);-webkit-backdrop-filter:blur(14px) saturate(135%);position:sticky;top:12px;z-index:var(--layer-header);isolation:isolate}.brand{width:fit-content;display:flex;align-items:center;gap:11px;border-radius:10px;color:inherit;text-decoration:none}.brand:focus-visible{outline:3px solid var(--download-soft);outline-offset:4px}.brand>div:last-child{display:flex;flex-direction:column;gap:1px}.brand strong{color:var(--ink);font-size:.94rem;font-weight:700;letter-spacing:-.025em}.brand-mark{width:36px;height:36px;position:relative;flex:0 0 auto;border:1px solid var(--line);border-radius:12px;background:conic-gradient(from 215deg,var(--download),var(--cyan),var(--green),var(--upload),var(--download));box-shadow:inset 0 0 0 7px var(--surface-strong),0 4px 12px var(--download-soft)}.brand-mark:after{content:"";position:absolute;inset:13px;border-radius:50%;background:var(--ink)}.topbar .brand-mark{width:30px;height:30px;border-radius:9px;background:linear-gradient(135deg,var(--cyan) 0 54%,var(--upload) 54% 100%);box-shadow:inset 0 0 0 5px var(--surface-strong),0 3px 9px var(--download-soft)}.topbar .brand-mark:after{inset:11px}.topbar .brand .eyebrow{font-size:.62rem;letter-spacing:.08em}.segmented button{border:0;border-radius:9px;background:transparent;color:var(--muted);min-height:36px;padding:7px 11px;font-size:.74rem;font-weight:650;white-space:nowrap;transition:color var(--motion-fast) ease,background-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease}.segmented button:hover{color:var(--ink);background:var(--surface-soft)}.segmented button[aria-pressed=true]{color:var(--download-strong);background:var(--surface-strong);box-shadow:var(--shadow-soft)}.top-actions{display:flex;align-items:center;justify-content:flex-end;gap:6px}.topbar .top-actions .live-status{margin-right:2px}.topbar .theme-toggle{padding:2px;border-radius:10px;background:var(--surface-soft)}.topbar .theme-button{width:32px;height:32px;border-radius:7px}.topbar .logout-button{min-width:36px;min-height:36px;justify-content:center;border:1px solid var(--line);border-radius:9px;background:var(--surface-soft);padding:0}.topbar .logout-button span{display:none}.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;margin:24px 4px 16px}.page-title{width:fit-content;margin:8px 0 2px;display:flex;align-items:center;gap:10px;font-size:clamp(1.65rem,2.2vw,2.05rem);font-weight:740;line-height:1.05;letter-spacing:-.045em}.page-title:before{content:"";width:7px;height:7px;flex:0 0 auto;border-radius:50%;background:var(--download);box-shadow:0 0 0 5px var(--download-soft)}.range-wrap{position:relative;z-index:var(--layer-page-control);display:flex;flex-direction:column;align-items:flex-end;gap:10px;max-width:100%}.segmented{max-width:min(100%,760px);padding:4px;display:flex;overflow-x:auto;border:1px solid var(--line);border-radius:14px;background:var(--surface-soft);box-shadow:inset 0 1px #ffffff59;scrollbar-width:none}.custom-range-dialog{position:absolute;top:calc(100% + 12px);right:0;width:min(430px,calc(100vw - 36px));padding:16px;border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--surface-strong);box-shadow:var(--shadow-float);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}.custom-range-head{text-align:center}.custom-range-head h2{margin:0;font-size:1rem;letter-spacing:-.02em}.custom-range-head span{display:block;margin-top:3px;color:var(--muted);font-size:.66rem}.custom-date-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:12px}.custom-date-card{min-width:0;display:grid;gap:4px;min-height:58px;padding:10px 12px;border:1px solid var(--line);border-radius:12px;color:var(--ink);background:var(--surface-soft);text-align:left}.custom-date-card[aria-pressed=true]{border-color:var(--download);background:var(--surface-strong);box-shadow:0 0 0 3px var(--focus-ring)}.custom-date-card span{color:var(--muted);font-size:.6rem;font-weight:800;letter-spacing:.08em}.custom-date-card strong{font-size:.78rem;font-weight:750}.calendar-card{margin-top:10px;padding:8px;border:1px solid var(--line);border-radius:14px;background:var(--surface-soft)}.calendar-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.calendar-head h3{margin:0;font-size:.8rem}.calendar-head button{width:36px;height:36px;border:1px solid var(--line);border-radius:10px;color:var(--ink);background:var(--surface-strong);font-size:1rem}.calendar-weekdays,.calendar-days{display:grid;grid-template-columns:repeat(7,minmax(0,1fr))}.calendar-weekdays{margin:8px 0 3px}.calendar-weekdays span{color:var(--muted);text-align:center;font-size:.6rem;font-weight:750}.calendar-days{gap:2px}.calendar-day{min-width:0;height:30px;border:0;border-radius:9px;color:var(--ink);background:transparent;font-size:.68rem;font-weight:700}.calendar-day.outside-month{color:var(--line-strong)}.calendar-day.in-range{background:var(--line)}.calendar-day.range-endpoint{color:#fff;background:var(--download)}.calendar-day:hover{background:var(--download-soft)}.calendar-day.range-endpoint:hover{background:var(--download-strong)}.custom-range-actions{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:10px;color:var(--muted);font-size:.64rem}.custom-range-actions>div{display:flex;gap:8px}.custom-range-actions button{min-height:38px;padding:7px 12px;border-radius:10px;font-size:.72rem}.dashboard{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:14px}.panel{border:1px solid var(--line);border-radius:var(--radius-lg);background:var(--surface);box-shadow:var(--shadow-soft);backdrop-filter:blur(16px) saturate(135%);-webkit-backdrop-filter:blur(16px) saturate(135%);padding:clamp(18px,1.6vw,22px);overflow:hidden}.hero-panel,.storage-panel{grid-column:1 / -1}.topology-panel{grid-column:span 7;align-self:stretch}.targets-panel{grid-column:1 / -1}.confidence-panel{grid-column:span 5;align-self:stretch}.dashboard[data-dashboard-mode=history] .topology-panel{grid-column:1 / -1}.dashboard[data-dashboard-mode=history] .confidence-panel{grid-column:span 5}.dashboard[data-dashboard-mode=history] .targets-panel{grid-column:span 7}.panel-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:20px}.panel-head h2,.confidence-panel h2,.storage-panel h2{margin:4px 0;color:var(--ink);font-size:1.05rem;font-weight:710;letter-spacing:-.03em}.panel-head select{min-height:38px;padding:7px 10px;font-size:.74rem}.panel-head .icon-button{width:40px;min-height:40px}.chart-summary{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:10px}.metric-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px;margin-bottom:10px}.metric-grid .chart-value{min-height:66px;padding:11px 12px}.metric-grid .chart-value strong{font-size:.94rem}.chart-toggle,.dimension-tabs{display:flex;flex-wrap:wrap;gap:3px;padding:4px;border:1px solid var(--line);border-radius:12px;background:var(--surface-soft)}.chart-toggle{width:fit-content;margin:0 0 8px auto}.chart-toggle button,.dimension-tabs button{min-height:34px;border:0;border-radius:8px;color:var(--muted);background:transparent;padding:6px 10px;font-size:.72rem;font-weight:680;transition:color var(--motion-fast) ease,background-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease}.chart-toggle button:hover,.dimension-tabs button:hover{color:var(--ink)}.chart-toggle button[aria-pressed=true],.dimension-tabs button[aria-pressed=true]{color:var(--download-strong);background:var(--surface-strong);box-shadow:var(--shadow-soft)}.chart-value{min-width:0;padding:13px 14px;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-raised);box-shadow:inset 0 1px #ffffff47}.chart-summary .chart-value:first-child{border-color:var(--download-card-border);background:linear-gradient(135deg,var(--download-card-tint),var(--surface-raised))}.chart-summary .chart-value:nth-child(2){border-color:var(--upload-card-border);background:linear-gradient(135deg,var(--upload-card-tint),var(--surface-raised))}.chart-summary .chart-value:nth-child(3){border-color:var(--success-card-border);background:linear-gradient(135deg,var(--success-card-tint),var(--surface-raised))}.chart-value span{display:block;margin-bottom:5px;color:var(--muted);font-size:.72rem;font-weight:540}.chart-value strong{display:block;overflow:hidden;color:var(--ink);font-family:var(--font-sans);font-size:clamp(1.08rem,1.8vw,1.58rem);font-weight:720;font-variant-numeric:tabular-nums;letter-spacing:-.04em;text-overflow:ellipsis;white-space:nowrap}.chart-summary .chart-value:first-child strong{color:var(--download-strong)}.chart-summary .chart-value:nth-child(2) strong{color:var(--upload-strong)}.chart-shell{width:100%;height:250px;margin-top:4px}.confidence-panel{display:flex;flex-direction:column}.storage-panel{display:grid;grid-template-columns:minmax(210px,1.5fr) repeat(5,minmax(96px,.65fr));gap:10px;align-items:stretch;padding:14px}.storage-lead,.storage-stat{padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-raised)}.storage-lead{background:linear-gradient(135deg,var(--success-card-tint),var(--surface-raised))}.storage-stat{display:flex;flex-direction:column;justify-content:space-between;gap:8px}.storage-stat span{color:var(--muted);font-size:.7rem}.storage-stat strong{color:var(--ink-soft);font-size:.94rem;font-variant-numeric:tabular-nums}.login-page{min-height:100dvh;display:grid;place-items:center;padding:24px;position:relative}.loading-screen{min-height:100dvh;display:grid;place-items:center;color:var(--muted)}.login-theme{position:fixed;top:24px;right:24px}.login-card{width:min(430px,100%);padding:42px;border:1px solid var(--line);border-radius:var(--radius-xl);background:var(--surface-strong);box-shadow:var(--shadow);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}.login-card .brand-mark{margin-bottom:34px}.login-card h1{margin:10px 0;font-size:2.1rem;font-weight:740;letter-spacing:-.05em}.login-card form{display:grid;gap:14px;margin-top:28px}@media(max-width:980px){.app-shell{width:calc(100% - 32px)}.topbar{grid-template-columns:1fr auto}.page-head{align-items:stretch;flex-direction:column;margin-top:28px}.range-wrap{align-items:stretch}.dashboard{grid-template-columns:1fr}.hero-panel,.topology-panel,.storage-panel,.confidence-panel,.targets-panel,.dashboard[data-dashboard-mode=history] .topology-panel,.dashboard[data-dashboard-mode=history] .confidence-panel,.dashboard[data-dashboard-mode=history] .targets-panel{grid-column:auto}.storage-panel{grid-template-columns:repeat(2,1fr)}.metric-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.storage-lead{grid-column:1 / -1}}@media(max-width:620px){.app-shell{width:calc(100% - 20px);margin-top:8px;margin-bottom:28px}.app-footer{padding:22px 14px 0}.app-footer-line{gap:7px}.app-footer-version-separator{display:none}.app-footer-version{display:block;flex-basis:100%;text-align:center}.topbar{top:6px;min-height:56px;padding:6px 7px 6px 10px;gap:10px}.topbar .theme-button,.topbar .logout-button{width:44px;min-width:44px;height:44px;min-height:44px}.brand .eyebrow,.top-actions .live-status,.top-actions .soft-button{display:none}.top-actions{gap:4px}.page-head{margin:22px 2px 14px}.page-title{font-size:1.72rem}.panel{border-radius:15px;padding:16px}.chart-summary{grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.chart-summary .chart-value{min-height:68px;padding:10px}.chart-summary .chart-value strong{font-size:clamp(.78rem,3.6vw,.88rem);line-height:1.15}.chart-summary .chart-value span,.metric-grid .chart-value span{margin-bottom:4px;font-size:.64rem}.metric-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.metric-grid .chart-value{min-height:64px;padding:10px}.metric-grid .chart-value strong{font-size:clamp(.8rem,3.6vw,.9rem);line-height:1.2}.chart-shell{height:220px}.storage-panel{grid-template-columns:repeat(2,minmax(0,1fr))}.storage-lead{grid-column:1 / -1}.custom-range-dialog{width:100%;padding:14px}.custom-date-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.custom-range-actions{align-items:stretch;flex-direction:column}.custom-range-actions>div{justify-content:flex-end}.login-card{padding:28px 22px}.segmented button,.chart-toggle button,.dimension-tabs button,.calendar-head button,.calendar-day,.custom-range-actions button{min-height:44px}}@media(max-width:340px){.brand>div:last-child{display:none}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}.panel-head select,input{min-height:40px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);color:var(--ink);background:var(--surface-strong);padding:8px 10px;outline:none;transition:border-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease,background-color var(--motion-fast) ease}input:focus-visible,button:focus-visible,select:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px}.tooltip-anchor{display:inline-flex;align-items:center}.tooltip-popup{width:max-content;max-width:min(320px,calc(100vw - 20px));position:fixed;z-index:var(--layer-tooltip);display:block;padding:8px 11px;border:1px solid var(--line-strong);border-radius:10px;color:#f8fafc;background:var(--ink);box-shadow:var(--shadow-float);font-size:.72rem;font-weight:600;line-height:1.5;pointer-events:none;animation:tooltip-in .1s ease-out}.heading-with-tooltip,.label-with-tooltip{width:fit-content;display:inline-flex;align-items:center;gap:5px}.info-tooltip-trigger,.heading-with-tooltip .info-tooltip-trigger,.label-with-tooltip .info-tooltip-trigger{width:24px;min-height:24px;display:grid;place-items:center;border:0;border-radius:50%;color:var(--faint);background:transparent;padding:0;position:relative}.info-tooltip-trigger:before{content:"";position:absolute;inset:-10px;border-radius:50%}.info-tooltip-trigger:hover,.info-tooltip-trigger:focus-visible{color:var(--download-strong);background:var(--download-soft)}.info-tooltip-trigger svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.35;stroke-linecap:round;stroke-linejoin:round}@keyframes tooltip-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.primary-button,.soft-button,.icon-button,.dialog-head button{min-height:40px;border:1px solid transparent;border-radius:var(--radius-sm);padding:8px 13px;font-weight:680;transition:color var(--motion-fast) ease,border-color var(--motion-fast) ease,background-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease,transform var(--motion-fast) var(--ease-out)}.primary-button{color:#fff;background:var(--download);box-shadow:0 6px 16px var(--download-soft)}.primary-button:hover:not(:disabled){background:var(--download-strong);box-shadow:0 8px 20px var(--focus-ring)}.primary-button:disabled{cursor:not-allowed;opacity:.45}.soft-button,.icon-button,.dialog-head button{border-color:var(--line);color:var(--ink);background:var(--surface-raised)}.soft-button:hover,.icon-button:hover,.dialog-head button:hover{border-color:var(--line-strong);background:var(--surface-soft)}.icon-button,.dialog-head button{width:40px;padding:0;font-size:1rem}.icon-button svg,.logout-button svg,.theme-button svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}.theme-toggle{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--line);border-radius:12px;background:var(--surface-soft)}.theme-button{width:36px;height:34px;display:grid;place-items:center;border:0;border-radius:9px;color:var(--muted);background:transparent;padding:0;transition:color var(--motion-fast) ease,background-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease}.theme-button:hover{color:var(--ink)}.theme-button[aria-pressed=true]{color:var(--download-strong);background:var(--surface-strong);box-shadow:var(--shadow-soft)}.logout-button{min-width:40px;min-height:40px;display:inline-flex;align-items:center;gap:7px;border:0;border-radius:10px;color:var(--muted);background:transparent;padding:6px 8px;font-size:.76rem;font-weight:650;transition:color var(--motion-fast) ease,background-color var(--motion-fast) ease}.logout-button:hover{color:var(--ink);background:var(--surface-soft)}.logout-button.failed,.logout-button.failed:hover{color:var(--danger);background:var(--danger-soft)}.live-status{display:inline-flex;align-items:center;gap:7px;min-height:34px;padding:6px 10px;border:1px solid color-mix(in srgb,var(--green) 22%,var(--line));border-radius:999px;color:var(--green);background:var(--green-soft);font-size:.74rem;font-weight:680}.top-actions .live-status{margin-right:10px}.live-status i{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 0 5px var(--green-soft)}.live-status.ok i{animation:status-pulse 2.4s ease-in-out infinite}.live-status.degraded i{background:var(--upload);box-shadow:0 0 0 5px var(--upload-soft)}.live-status.degraded{border-color:color-mix(in srgb,var(--upload) 22%,var(--line));color:var(--upload-strong);background:var(--upload-soft)}.live-status.failed i{background:var(--danger)}.live-status.failed{border-color:color-mix(in srgb,var(--danger) 22%,var(--line));color:var(--danger);background:var(--danger-soft)}@keyframes status-pulse{0%,to{opacity:.72;transform:scale(.86);box-shadow:0 0 0 3px var(--green-soft)}50%{opacity:1;transform:scale(1.12);box-shadow:0 0 0 7px var(--green-soft)}}.coverage-list{display:grid;gap:16px}.coverage-label{display:flex;justify-content:space-between;gap:10px;margin-bottom:8px;font-size:.78rem}.coverage-label span{font-weight:800}.coverage-track{height:8px;overflow:hidden;border-radius:99px;background:var(--line)}.coverage-track i{display:block;width:var(--coverage);height:100%;border-radius:inherit;background:linear-gradient(90deg,var(--green),var(--cyan));box-shadow:0 0 12px var(--green-soft)}.confidence-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin:16px 0 0;padding-top:16px;border-top:1px solid var(--line)}.confidence-stats div{padding:10px 11px;border:1px solid var(--line);border-radius:11px;background:var(--surface-raised)}.confidence-stats dt{color:var(--muted);font-size:.66rem}.confidence-stats dd{margin:3px 0 0;color:var(--ink-soft);font-size:.78rem;font-weight:720;font-variant-numeric:tabular-nums}.dashboard[data-dashboard-mode=live] .confidence-stats{margin-top:auto}.confidence-panel>.heading-with-tooltip{margin-bottom:18px}.target-list{display:grid;gap:8px}.target-item{display:grid;grid-template-columns:36px minmax(0,1fr) auto;align-items:center;gap:11px;padding:7px 9px;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-raised);transition:border-color var(--motion-fast) ease,background-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease}.target-item:hover{border-color:var(--line-strong);background:var(--surface-strong);box-shadow:var(--shadow-soft)}.target-icon{width:36px;height:36px;display:grid;place-items:center;border-radius:11px;color:var(--download);background:var(--download-soft);font-weight:800}.target-rank{border:1px solid var(--line);color:var(--muted);background:var(--surface-strong);font-variant-numeric:tabular-nums}.target-item:first-child .target-rank{border-color:transparent;color:var(--download);background:var(--download-soft);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--download) 16%,transparent)}.target-main{min-width:0;display:grid;gap:3px}.target-main strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);font-size:.8rem;line-height:1.2}.target-main>span{color:var(--muted);font-size:.68rem;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.target-detail i,.target-detail b{font-style:normal}.target-detail i{margin:0 3px;color:var(--faint)}.target-detail b{font-weight:900}.target-download{color:var(--download)}.target-upload{color:var(--upload)}.target-bar{height:4px;margin-top:3px;border-radius:99px;background:var(--line);overflow:hidden}.target-bar i{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,var(--download),var(--cyan))}.target-value{color:var(--ink-soft);font-size:.76rem;font-variant-numeric:tabular-nums;font-weight:680;white-space:nowrap}.breakdown-distribution,.runtime-session-list{display:grid;gap:9px}.distribution-row,.runtime-session{padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-raised)}.distribution-label,.runtime-sessions-head,.runtime-session>div{display:flex;align-items:center;justify-content:space-between;gap:9px}.distribution-label>div,.runtime-session>div{min-width:0}.distribution-label strong,.distribution-label span{display:block}.distribution-label span,.distribution-detail,.runtime-session>span,.runtime-session>div span{color:var(--muted);font-size:.7rem}.distribution-label>div strong,.distribution-label>div span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.distribution-track{display:flex;height:7px;margin:7px 0 5px;overflow:hidden;border-radius:99px;background:var(--line)}.distribution-track i{display:block;height:100%}.distribution-download{background:var(--download)}.distribution-upload{background:var(--upload)}.distribution-detail{display:flex;gap:12px}.runtime-sessions{margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}.runtime-sessions-head{margin-bottom:12px}.runtime-session{display:grid;grid-template-columns:minmax(180px,1fr) auto auto;align-items:center;gap:8px}.topology{height:252px;position:relative;border:1px solid var(--line);border-radius:var(--radius-md);background:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px),var(--surface-soft);background-size:28px 28px;overflow:hidden}.topology svg{width:100%;height:100%;overflow:visible}.topology svg.topology-desktop-flow{position:absolute;inset:0 132px;width:calc(100% - 264px)}.topology-mobile-flow{display:none}.flow-path{fill:none;stroke:var(--download);stroke-width:8;stroke-linecap:round;opacity:.3}.flow-path.secondary{stroke:var(--upload);stroke-width:6}.flow-path.target{stroke:var(--cyan);stroke-width:7}.flow-node{position:absolute;width:136px;padding:10px 11px;border:1px solid var(--line-strong);border-radius:var(--radius-md);background:var(--surface-strong);box-shadow:var(--shadow-soft);transition:transform var(--motion-fast) var(--ease-out),border-color var(--motion-fast) ease,box-shadow var(--motion-fast) ease}.flow-node:hover{transform:translateY(-2px);border-color:var(--line-strong);box-shadow:var(--shadow)}.flow-node strong,.flow-node span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.flow-node strong{color:var(--ink);font-size:.74rem}.flow-node span{margin-top:3px;color:var(--muted);font-size:.64rem}.node-source-one{left:0;top:35px}.node-source-two{left:0;bottom:35px}.node-gateway{left:50%;top:50%;transform:translate(-50%,-50%)}.node-gateway:hover{transform:translate(-50%,calc(-50% - 2px))}.node-target{right:0}.node-target-0{top:15px}.node-target-1{top:50%;transform:translateY(-50%)}.node-target-1:hover{transform:translateY(calc(-50% - 2px))}.node-target-2{bottom:15px}.field{display:grid;gap:7px;color:var(--muted);font-size:.78rem;font-weight:650}.field input{width:100%;font-size:1rem}.form-error{margin:0;color:var(--danger);font-size:.78rem;font-weight:600}.dialog-backdrop{position:fixed;inset:0;z-index:var(--layer-modal);display:grid;place-items:center;padding:18px;background:#080f1c8f;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.dialog-shell{width:min(680px,100%);max-height:min(720px,calc(100dvh - 36px));display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden;border:1px solid var(--line);border-radius:var(--radius-xl);background:var(--surface-strong);box-shadow:var(--shadow-float)}.dialog-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:18px 18px 14px;border-bottom:1px solid var(--line)}.dialog-head h2{margin:4px 0;font-size:1.1rem;font-weight:720;letter-spacing:-.025em}.dialog-head button{width:32px;height:32px;min-height:32px;flex:0 0 32px;display:grid;place-items:center;border-radius:10px;padding:0}.dialog-head button svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}.dialog-body{min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:14px 18px 18px}.demo-notice{margin:0 0 10px;padding:11px 13px;border-radius:var(--radius-sm);border:1px solid color-mix(in srgb,var(--download) 18%,var(--line));background:var(--download-soft);color:var(--ink-soft);font-size:.8rem}.alias-list{display:grid;gap:8px}.alias-row{display:grid;grid-template-columns:minmax(150px,.72fr) minmax(200px,1fr) auto;align-items:center;gap:10px;padding:10px 11px;border:1px solid var(--line);border-radius:var(--radius-md);background:var(--surface-raised)}.alias-identity{min-width:0;display:grid;gap:3px}.alias-identity strong,.alias-identity span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.alias-identity strong{font-size:.78rem}.alias-identity span{color:var(--muted);font-size:.64rem}.alias-field{width:100%;min-height:34px;padding:6px 9px;font-size:.76rem}.alias-actions{display:flex;align-items:center;justify-content:flex-end;gap:5px}.alias-actions button{min-height:32px;border:1px solid var(--line);border-radius:8px;color:var(--ink);background:var(--surface-strong);padding:5px 9px;font-size:.72rem;font-weight:650;transition:border-color var(--motion-fast) ease,background-color var(--motion-fast) ease}.alias-actions button:hover:not(:disabled){border-color:var(--line-strong);background:var(--surface-soft)}.alias-actions button:disabled{cursor:not-allowed;opacity:.48}.empty-state{padding:30px;text-align:center;border:1px dashed var(--line-strong);border-radius:var(--radius-md);background:var(--surface-soft);color:var(--muted)}@media(max-width:620px){.theme-button,.logout-button{width:44px;min-width:44px;height:44px;min-height:44px}.logout-button span{display:none}.topology{height:285px;display:block;border:0}.topology svg{display:none}.topology svg.topology-mobile-flow{position:absolute;inset:0;display:block;pointer-events:none}.topology-mobile-flow .flow-path{stroke-width:2;opacity:.68;vector-effect:non-scaling-stroke}.mobile-flow-arrow{fill:var(--cyan)}.flow-node{position:absolute;width:auto;min-width:0;transform:none;transition:none}.node-source-one{left:0;top:0;width:calc(50% - 4px);height:50px}.node-source-two{inset:0 0 auto auto;width:calc(50% - 4px);height:50px}.node-gateway{left:0;top:72px;width:100%;height:48px;border-color:color-mix(in srgb,var(--download) 52%,var(--line));background:var(--download-soft);text-align:center}.node-target{left:24px;right:0;width:auto;height:45px;border-left:3px solid var(--cyan)}.node-target-0{top:140px}.node-target-1{top:190px}.node-target-2{top:240px;bottom:auto}.flow-node:hover,.node-gateway:hover,.node-target-1:hover{transform:none}.dialog-backdrop{padding:8px}.dialog-shell{max-height:calc(100dvh - 16px);border-radius:17px}.dialog-head{gap:10px;padding:14px 14px 11px}.dialog-head h2{font-size:1rem}.dialog-body{padding:10px}.demo-notice{padding:8px 10px;font-size:.7rem}.alias-row{grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:7px;padding:9px}.alias-identity{grid-column:1 / -1}.alias-field{grid-column:1;min-width:0}.alias-actions{grid-column:2;justify-self:end}.target-item{grid-template-columns:40px minmax(0,1fr)}.target-icon{width:40px;height:40px}.target-value{grid-column:2}} diff --git a/internal/webassets/dist/assets/index-B9YDBDoG.js b/internal/webassets/dist/assets/index-DlKVpUwn.js similarity index 99% rename from internal/webassets/dist/assets/index-B9YDBDoG.js rename to internal/webassets/dist/assets/index-DlKVpUwn.js index 3181a84..fe64f16 100644 --- a/internal/webassets/dist/assets/index-B9YDBDoG.js +++ b/internal/webassets/dist/assets/index-DlKVpUwn.js @@ -46,4 +46,4 @@ `+o[a].replace(" at new "," at ");return t.displayName&&p.includes("")&&(p=p.replace("",t.displayName)),p}while(1<=a&&0<=u);break}}}finally{ei=!1,Error.prepareStackTrace=e}return(e=t?t.displayName||t.name:"")?Ve(e):""}function ld(t){switch(t.tag){case 26:case 27:case 5:return Ve(t.type);case 16:return Ve("Lazy");case 13:return Ve("Suspense");case 19:return Ve("SuspenseList");case 0:case 15:return ai(t.type,!1);case 11:return ai(t.type.render,!1);case 1:return ai(t.type,!0);case 31:return Ve("Activity");default:return""}}function xf(t){try{var l="";do l+=ld(t),t=t.return;while(t);return l}catch(e){return` Error generating stack: `+e.message+` `+e.stack}}function ol(t){switch(typeof t){case"bigint":case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function wf(t){var l=t.type;return(t=t.nodeName)&&t.toLowerCase()==="input"&&(l==="checkbox"||l==="radio")}function ed(t){var l=wf(t)?"checked":"value",e=Object.getOwnPropertyDescriptor(t.constructor.prototype,l),a=""+t[l];if(!t.hasOwnProperty(l)&&typeof e<"u"&&typeof e.get=="function"&&typeof e.set=="function"){var u=e.get,n=e.set;return Object.defineProperty(t,l,{configurable:!0,get:function(){return u.call(this)},set:function(i){a=""+i,n.call(this,i)}}),Object.defineProperty(t,l,{enumerable:e.enumerable}),{getValue:function(){return a},setValue:function(i){a=""+i},stopTracking:function(){t._valueTracker=null,delete t[l]}}}}function Bu(t){t._valueTracker||(t._valueTracker=ed(t))}function Yf(t){if(!t)return!1;var l=t._valueTracker;if(!l)return!0;var e=l.getValue(),a="";return t&&(a=wf(t)?t.checked?"true":"false":t.value),t=a,t!==e?(l.setValue(t),!0):!1}function xu(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}var ad=/[\n"\\]/g;function rl(t){return t.replace(ad,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function ui(t,l,e,a,u,n,i,c){t.name="",i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"?t.type=i:t.removeAttribute("type"),l!=null?i==="number"?(l===0&&t.value===""||t.value!=l)&&(t.value=""+ol(l)):t.value!==""+ol(l)&&(t.value=""+ol(l)):i!=="submit"&&i!=="reset"||t.removeAttribute("value"),l!=null?ni(t,i,ol(l)):e!=null?ni(t,i,ol(e)):a!=null&&t.removeAttribute("value"),u==null&&n!=null&&(t.defaultChecked=!!n),u!=null&&(t.checked=u&&typeof u!="function"&&typeof u!="symbol"),c!=null&&typeof c!="function"&&typeof c!="symbol"&&typeof c!="boolean"?t.name=""+ol(c):t.removeAttribute("name")}function jf(t,l,e,a,u,n,i,c){if(n!=null&&typeof n!="function"&&typeof n!="symbol"&&typeof n!="boolean"&&(t.type=n),l!=null||e!=null){if(!(n!=="submit"&&n!=="reset"||l!=null))return;e=e!=null?""+ol(e):"",l=l!=null?""+ol(l):e,c||l===t.value||(t.value=l),t.defaultValue=l}a=a??u,a=typeof a!="function"&&typeof a!="symbol"&&!!a,t.checked=c?t.checked:!!a,t.defaultChecked=!!a,i!=null&&typeof i!="function"&&typeof i!="symbol"&&typeof i!="boolean"&&(t.name=i)}function ni(t,l,e){l==="number"&&xu(t.ownerDocument)===t||t.defaultValue===""+e||(t.defaultValue=""+e)}function Ke(t,l,e,a){if(t=t.options,l){l={};for(var u=0;u"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),oi=!1;if(Hl)try{var qa={};Object.defineProperty(qa,"passive",{get:function(){oi=!0}}),window.addEventListener("test",qa,qa),window.removeEventListener("test",qa,qa)}catch{oi=!1}var $l=null,ri=null,Yu=null;function Vf(){if(Yu)return Yu;var t,l=ri,e=l.length,a,u="value"in $l?$l.value:$l.textContent,n=u.length;for(t=0;t=xa),Ff=" ",If=!1;function Pf(t,l){switch(t){case"keyup":return Nd.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function ts(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var $e=!1;function Hd(t,l){switch(t){case"compositionend":return ts(l);case"keypress":return l.which!==32?null:(If=!0,Ff);case"textInput":return t=l.data,t===Ff&&If?null:t;default:return null}}function Bd(t,l){if($e)return t==="compositionend"||!vi&&Pf(t,l)?(t=Vf(),Yu=ri=$l=null,$e=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:e,offset:l-t};t=a}t:{for(;e;){if(e.nextSibling){e=e.nextSibling;break t}e=e.parentNode}e=void 0}e=fs(e)}}function os(t,l){return t&&l?t===l?!0:t&&t.nodeType===3?!1:l&&l.nodeType===3?os(t,l.parentNode):"contains"in t?t.contains(l):t.compareDocumentPosition?!!(t.compareDocumentPosition(l)&16):!1:!1}function rs(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var l=xu(t.document);l instanceof t.HTMLIFrameElement;){try{var e=typeof l.contentWindow.location.href=="string"}catch{e=!1}if(e)t=l.contentWindow;else break;l=xu(t.document)}return l}function gi(t){var l=t&&t.nodeName&&t.nodeName.toLowerCase();return l&&(l==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||l==="textarea"||t.contentEditable==="true")}var Qd=Hl&&"documentMode"in document&&11>=document.documentMode,Fe=null,Si=null,Ga=null,pi=!1;function ds(t,l,e){var a=e.window===e?e.document:e.nodeType===9?e:e.ownerDocument;pi||Fe==null||Fe!==xu(a)||(a=Fe,"selectionStart"in a&&gi(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Ga&&ja(Ga,a)||(Ga=a,a=On(Si,"onSelect"),0>=i,u-=i,xl=1<<32-el(l)+u|e<n?n:8;var i=T.T,c={};T.T=c,ic(t,!1,l,e);try{var o=u(),b=T.S;if(b!==null&&b(c,o),o!==null&&typeof o=="object"&&typeof o.then=="function"){var p=Fd(o,a);tu(t,l,p,fl(t))}else tu(t,l,a,fl(t))}catch(M){tu(t,l,{then:function(){},status:"rejected",reason:M},fl())}finally{N.p=n,T.T=i}}function ey(){}function uc(t,l,e,a){if(t.tag!==5)throw Error(s(476));var u=mo(t).queue;yo(t,u,l,C,e===null?ey:function(){return ho(t),e(a)})}function mo(t){var l=t.memoizedState;if(l!==null)return l;l={memoizedState:C,baseState:C,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Gl,lastRenderedState:C},next:null};var e={};return l.next={memoizedState:e,baseState:e,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Gl,lastRenderedState:e},next:null},t.memoizedState=l,t=t.alternate,t!==null&&(t.memoizedState=l),l}function ho(t){var l=mo(t).next.queue;tu(t,l,{},fl())}function nc(){return Zt(_u)}function vo(){return At().memoizedState}function bo(){return At().memoizedState}function ay(t){for(var l=t.return;l!==null;){switch(l.tag){case 24:case 3:var e=fl();t=Pl(e);var a=te(l,t,e);a!==null&&(sl(a,l,e),ka(a,l,e)),l={cache:xi()},t.payload=l;return}l=l.return}}function uy(t,l,e){var a=fl();e={lane:a,revertLane:0,action:e,hasEagerState:!1,eagerState:null,next:null},fn(t)?go(l,e):(e=Mi(t,l,e,a),e!==null&&(sl(e,t,a),So(e,l,a)))}function _o(t,l,e){var a=fl();tu(t,l,e,a)}function tu(t,l,e,a){var u={lane:a,revertLane:0,action:e,hasEagerState:!1,eagerState:null,next:null};if(fn(t))go(l,u);else{var n=t.alternate;if(t.lanes===0&&(n===null||n.lanes===0)&&(n=l.lastRenderedReducer,n!==null))try{var i=l.lastRenderedState,c=n(i,e);if(u.hasEagerState=!0,u.eagerState=c,al(c,i))return Lu(t,l,u,0),yt===null&&Zu(),!1}catch{}finally{}if(e=Mi(t,l,u,a),e!==null)return sl(e,t,a),So(e,l,a),!0}return!1}function ic(t,l,e,a){if(a={lane:2,revertLane:jc(),action:a,hasEagerState:!1,eagerState:null,next:null},fn(t)){if(l)throw Error(s(479))}else l=Mi(t,e,a,2),l!==null&&sl(l,t,2)}function fn(t){var l=t.alternate;return t===J||l!==null&&l===J}function go(t,l){ca=ln=!0;var e=t.pending;e===null?l.next=l:(l.next=e.next,e.next=l),t.pending=l}function So(t,l,e){if((e&4194048)!==0){var a=l.lanes;a&=t.pendingLanes,e|=a,l.lanes=e,Df(t,e)}}var sn={readContext:Zt,use:an,useCallback:pt,useContext:pt,useEffect:pt,useImperativeHandle:pt,useLayoutEffect:pt,useInsertionEffect:pt,useMemo:pt,useReducer:pt,useRef:pt,useState:pt,useDebugValue:pt,useDeferredValue:pt,useTransition:pt,useSyncExternalStore:pt,useId:pt,useHostTransitionStatus:pt,useFormState:pt,useActionState:pt,useOptimistic:pt,useMemoCache:pt,useCacheRefresh:pt},po={readContext:Zt,use:an,useCallback:function(t,l){return $t().memoizedState=[t,l===void 0?null:l],t},useContext:Zt,useEffect:ao,useImperativeHandle:function(t,l,e){e=e!=null?e.concat([t]):null,cn(4194308,4,co.bind(null,l,t),e)},useLayoutEffect:function(t,l){return cn(4194308,4,t,l)},useInsertionEffect:function(t,l){cn(4,2,t,l)},useMemo:function(t,l){var e=$t();l=l===void 0?null:l;var a=t();if(Be){kl(!0);try{t()}finally{kl(!1)}}return e.memoizedState=[a,l],a},useReducer:function(t,l,e){var a=$t();if(e!==void 0){var u=e(l);if(Be){kl(!0);try{e(l)}finally{kl(!1)}}}else u=l;return a.memoizedState=a.baseState=u,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:u},a.queue=t,t=t.dispatch=uy.bind(null,J,t),[a.memoizedState,t]},useRef:function(t){var l=$t();return t={current:t},l.memoizedState=t},useState:function(t){t=tc(t);var l=t.queue,e=_o.bind(null,J,l);return l.dispatch=e,[t.memoizedState,e]},useDebugValue:ec,useDeferredValue:function(t,l){var e=$t();return ac(e,t,l)},useTransition:function(){var t=tc(!1);return t=yo.bind(null,J,t.queue,!0,!1),$t().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,l,e){var a=J,u=$t();if(et){if(e===void 0)throw Error(s(407));e=e()}else{if(e=l(),yt===null)throw Error(s(349));(I&124)!==0||Xs(a,l,e)}u.memoizedState=e;var n={value:e,getSnapshot:l};return u.queue=n,ao(Zs.bind(null,a,n,t),[t]),a.flags|=2048,sa(9,nn(),Qs.bind(null,a,n,e,l),null),e},useId:function(){var t=$t(),l=yt.identifierPrefix;if(et){var e=wl,a=xl;e=(a&~(1<<32-el(a)-1)).toString(32)+e,l="«"+l+"R"+e,e=en++,0G?(Nt=w,w=null):Nt=w.sibling;var lt=_(m,w,v[G],A);if(lt===null){w===null&&(w=Nt);break}t&&w&<.alternate===null&&l(m,w),d=n(lt,d,G),k===null?x=lt:k.sibling=lt,k=lt,w=Nt}if(G===v.length)return e(m,w),et&&Oe(m,G),x;if(w===null){for(;GG?(Nt=w,w=null):Nt=w.sibling;var be=_(m,w,lt.value,A);if(be===null){w===null&&(w=Nt);break}t&&w&&be.alternate===null&&l(m,w),d=n(be,d,G),k===null?x=be:k.sibling=be,k=be,w=Nt}if(lt.done)return e(m,w),et&&Oe(m,G),x;if(w===null){for(;!lt.done;G++,lt=v.next())lt=M(m,lt.value,A),lt!==null&&(d=n(lt,d,G),k===null?x=lt:k.sibling=lt,k=lt);return et&&Oe(m,G),x}for(w=a(w);!lt.done;G++,lt=v.next())lt=g(w,m,G,lt.value,A),lt!==null&&(t&<.alternate!==null&&w.delete(lt.key===null?G:lt.key),d=n(lt,d,G),k===null?x=lt:k.sibling=lt,k=lt);return t&&w.forEach(function(i1){return l(m,i1)}),et&&Oe(m,G),x}function st(m,d,v,A){if(typeof v=="object"&&v!==null&&v.type===it&&v.key===null&&(v=v.props.children),typeof v=="object"&&v!==null){switch(v.$$typeof){case V:t:{for(var x=v.key;d!==null;){if(d.key===x){if(x=v.type,x===it){if(d.tag===7){e(m,d.sibling),A=u(d,v.props.children),A.return=m,m=A;break t}}else if(d.elementType===x||typeof x=="object"&&x!==null&&x.$$typeof===Pt&&Eo(x)===d.type){e(m,d.sibling),A=u(d,v.props),eu(A,v),A.return=m,m=A;break t}e(m,d);break}else l(m,d);d=d.sibling}v.type===it?(A=ze(v.props.children,m.mode,A,v.key),A.return=m,m=A):(A=Ku(v.type,v.key,v.props,null,m.mode,A),eu(A,v),A.return=m,m=A)}return i(m);case dt:t:{for(x=v.key;d!==null;){if(d.key===x)if(d.tag===4&&d.stateNode.containerInfo===v.containerInfo&&d.stateNode.implementation===v.implementation){e(m,d.sibling),A=u(d,v.children||[]),A.return=m,m=A;break t}else{e(m,d);break}else l(m,d);d=d.sibling}A=Oi(v,m.mode,A),A.return=m,m=A}return i(m);case Pt:return x=v._init,v=x(v._payload),st(m,d,v,A)}if(Xt(v))return X(m,d,v,A);if(Ct(v)){if(x=Ct(v),typeof x!="function")throw Error(s(150));return v=x.call(v),j(m,d,v,A)}if(typeof v.then=="function")return st(m,d,on(v),A);if(v.$$typeof===at)return st(m,d,$u(m,v),A);rn(m,v)}return typeof v=="string"&&v!==""||typeof v=="number"||typeof v=="bigint"?(v=""+v,d!==null&&d.tag===6?(e(m,d.sibling),A=u(d,v),A.return=m,m=A):(e(m,d),A=Di(v,m.mode,A),A.return=m,m=A),i(m)):e(m,d)}return function(m,d,v,A){try{lu=0;var x=st(m,d,v,A);return oa=null,x}catch(w){if(w===Ka||w===Iu)throw w;var k=ul(29,w,null,m.mode);return k.lanes=A,k.return=m,k}finally{}}}var ra=Ao(!0),Mo=Ao(!1),vl=z(null),zl=null;function ee(t){var l=t.alternate;R(zt,zt.current&1),R(vl,t),zl===null&&(l===null||ia.current!==null||l.memoizedState!==null)&&(zl=t)}function zo(t){if(t.tag===22){if(R(zt,zt.current),R(vl,t),zl===null){var l=t.alternate;l!==null&&l.memoizedState!==null&&(zl=t)}}else ae()}function ae(){R(zt,zt.current),R(vl,vl.current)}function Cl(t){B(vl),zl===t&&(zl=null),B(zt)}var zt=z(0);function dn(t){for(var l=t;l!==null;){if(l.tag===13){var e=l.memoizedState;if(e!==null&&(e=e.dehydrated,e===null||e.data==="$?"||$c(e)))return l}else if(l.tag===19&&l.memoizedProps.revealOrder!==void 0){if((l.flags&128)!==0)return l}else if(l.child!==null){l.child.return=l,l=l.child;continue}if(l===t)break;for(;l.sibling===null;){if(l.return===null||l.return===t)return null;l=l.return}l.sibling.return=l.return,l=l.sibling}return null}function cc(t,l,e,a){l=t.memoizedState,e=e(a,l),e=e==null?l:U({},l,e),t.memoizedState=e,t.lanes===0&&(t.updateQueue.baseState=e)}var fc={enqueueSetState:function(t,l,e){t=t._reactInternals;var a=fl(),u=Pl(a);u.payload=l,e!=null&&(u.callback=e),l=te(t,u,a),l!==null&&(sl(l,t,a),ka(l,t,a))},enqueueReplaceState:function(t,l,e){t=t._reactInternals;var a=fl(),u=Pl(a);u.tag=1,u.payload=l,e!=null&&(u.callback=e),l=te(t,u,a),l!==null&&(sl(l,t,a),ka(l,t,a))},enqueueForceUpdate:function(t,l){t=t._reactInternals;var e=fl(),a=Pl(e);a.tag=2,l!=null&&(a.callback=l),l=te(t,a,e),l!==null&&(sl(l,t,e),ka(l,t,e))}};function Do(t,l,e,a,u,n,i){return t=t.stateNode,typeof t.shouldComponentUpdate=="function"?t.shouldComponentUpdate(a,n,i):l.prototype&&l.prototype.isPureReactComponent?!ja(e,a)||!ja(u,n):!0}function Oo(t,l,e,a){t=l.state,typeof l.componentWillReceiveProps=="function"&&l.componentWillReceiveProps(e,a),typeof l.UNSAFE_componentWillReceiveProps=="function"&&l.UNSAFE_componentWillReceiveProps(e,a),l.state!==t&&fc.enqueueReplaceState(l,l.state,null)}function xe(t,l){var e=l;if("ref"in l){e={};for(var a in l)a!=="ref"&&(e[a]=l[a])}if(t=t.defaultProps){e===l&&(e=U({},e));for(var u in t)e[u]===void 0&&(e[u]=t[u])}return e}var yn=typeof reportError=="function"?reportError:function(t){if(typeof window=="object"&&typeof window.ErrorEvent=="function"){var l=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof t=="object"&&t!==null&&typeof t.message=="string"?String(t.message):String(t),error:t});if(!window.dispatchEvent(l))return}else if(typeof process=="object"&&typeof process.emit=="function"){process.emit("uncaughtException",t);return}console.error(t)};function Uo(t){yn(t)}function Ro(t){console.error(t)}function No(t){yn(t)}function mn(t,l){try{var e=t.onUncaughtError;e(l.value,{componentStack:l.stack})}catch(a){setTimeout(function(){throw a})}}function qo(t,l,e){try{var a=t.onCaughtError;a(e.value,{componentStack:e.stack,errorBoundary:l.tag===1?l.stateNode:null})}catch(u){setTimeout(function(){throw u})}}function sc(t,l,e){return e=Pl(e),e.tag=3,e.payload={element:null},e.callback=function(){mn(t,l)},e}function Ho(t){return t=Pl(t),t.tag=3,t}function Bo(t,l,e,a){var u=e.type.getDerivedStateFromError;if(typeof u=="function"){var n=a.value;t.payload=function(){return u(n)},t.callback=function(){qo(l,e,a)}}var i=e.stateNode;i!==null&&typeof i.componentDidCatch=="function"&&(t.callback=function(){qo(l,e,a),typeof u!="function"&&(se===null?se=new Set([this]):se.add(this));var c=a.stack;this.componentDidCatch(a.value,{componentStack:c!==null?c:""})})}function iy(t,l,e,a,u){if(e.flags|=32768,a!==null&&typeof a=="object"&&typeof a.then=="function"){if(l=e.alternate,l!==null&&Za(l,e,u,!0),e=vl.current,e!==null){switch(e.tag){case 13:return zl===null?Hc():e.alternate===null&>===0&&(gt=3),e.flags&=-257,e.flags|=65536,e.lanes=u,a===ji?e.flags|=16384:(l=e.updateQueue,l===null?e.updateQueue=new Set([a]):l.add(a),xc(t,a,u)),!1;case 22:return e.flags|=65536,a===ji?e.flags|=16384:(l=e.updateQueue,l===null?(l={transitions:null,markerInstances:null,retryQueue:new Set([a])},e.updateQueue=l):(e=l.retryQueue,e===null?l.retryQueue=new Set([a]):e.add(a)),xc(t,a,u)),!1}throw Error(s(435,e.tag))}return xc(t,a,u),Hc(),!1}if(et)return l=vl.current,l!==null?((l.flags&65536)===0&&(l.flags|=256),l.flags|=65536,l.lanes=u,a!==Ni&&(t=Error(s(422),{cause:a}),Qa(dl(t,e)))):(a!==Ni&&(l=Error(s(423),{cause:a}),Qa(dl(l,e))),t=t.current.alternate,t.flags|=65536,u&=-u,t.lanes|=u,a=dl(a,e),u=sc(t.stateNode,a,u),Xi(t,u),gt!==4&&(gt=2)),!1;var n=Error(s(520),{cause:a});if(n=dl(n,e),su===null?su=[n]:su.push(n),gt!==4&&(gt=2),l===null)return!0;a=dl(a,e),e=l;do{switch(e.tag){case 3:return e.flags|=65536,t=u&-u,e.lanes|=t,t=sc(e.stateNode,a,t),Xi(e,t),!1;case 1:if(l=e.type,n=e.stateNode,(e.flags&128)===0&&(typeof l.getDerivedStateFromError=="function"||n!==null&&typeof n.componentDidCatch=="function"&&(se===null||!se.has(n))))return e.flags|=65536,u&=-u,e.lanes|=u,u=Ho(u),Bo(u,t,e,a),Xi(e,u),!1}e=e.return}while(e!==null);return!1}var xo=Error(s(461)),Ut=!1;function Ht(t,l,e,a){l.child=t===null?Mo(l,null,e,a):ra(l,t.child,e,a)}function wo(t,l,e,a,u){e=e.render;var n=l.ref;if("ref"in a){var i={};for(var c in a)c!=="ref"&&(i[c]=a[c])}else i=a;return qe(l),a=Ki(t,l,e,i,n,u),c=Ji(),t!==null&&!Ut?(ki(t,l,u),Xl(t,l,u)):(et&&c&&Ui(l),l.flags|=1,Ht(t,l,a,u),l.child)}function Yo(t,l,e,a,u){if(t===null){var n=e.type;return typeof n=="function"&&!zi(n)&&n.defaultProps===void 0&&e.compare===null?(l.tag=15,l.type=n,jo(t,l,n,a,u)):(t=Ku(e.type,null,a,l,l.mode,u),t.ref=l.ref,t.return=l,l.child=t)}if(n=t.child,!bc(t,u)){var i=n.memoizedProps;if(e=e.compare,e=e!==null?e:ja,e(i,a)&&t.ref===l.ref)return Xl(t,l,u)}return l.flags|=1,t=Bl(n,a),t.ref=l.ref,t.return=l,l.child=t}function jo(t,l,e,a,u){if(t!==null){var n=t.memoizedProps;if(ja(n,a)&&t.ref===l.ref)if(Ut=!1,l.pendingProps=a=n,bc(t,u))(t.flags&131072)!==0&&(Ut=!0);else return l.lanes=t.lanes,Xl(t,l,u)}return oc(t,l,e,a,u)}function Go(t,l,e){var a=l.pendingProps,u=a.children,n=t!==null?t.memoizedState:null;if(a.mode==="hidden"){if((l.flags&128)!==0){if(a=n!==null?n.baseLanes|e:e,t!==null){for(u=l.child=t.child,n=0;u!==null;)n=n|u.lanes|u.childLanes,u=u.sibling;l.childLanes=n&~a}else l.childLanes=0,l.child=null;return Co(t,l,a,e)}if((e&536870912)!==0)l.memoizedState={baseLanes:0,cachePool:null},t!==null&&Fu(l,n!==null?n.cachePool:null),n!==null?Ys(l,n):Zi(),zo(l);else return l.lanes=l.childLanes=536870912,Co(t,l,n!==null?n.baseLanes|e:e,e)}else n!==null?(Fu(l,n.cachePool),Ys(l,n),ae(),l.memoizedState=null):(t!==null&&Fu(l,null),Zi(),ae());return Ht(t,l,u,e),l.child}function Co(t,l,e,a){var u=Yi();return u=u===null?null:{parent:Mt._currentValue,pool:u},l.memoizedState={baseLanes:e,cachePool:u},t!==null&&Fu(l,null),Zi(),zo(l),t!==null&&Za(t,l,a,!0),null}function hn(t,l){var e=l.ref;if(e===null)t!==null&&t.ref!==null&&(l.flags|=4194816);else{if(typeof e!="function"&&typeof e!="object")throw Error(s(284));(t===null||t.ref!==e)&&(l.flags|=4194816)}}function oc(t,l,e,a,u){return qe(l),e=Ki(t,l,e,a,void 0,u),a=Ji(),t!==null&&!Ut?(ki(t,l,u),Xl(t,l,u)):(et&&a&&Ui(l),l.flags|=1,Ht(t,l,e,u),l.child)}function Xo(t,l,e,a,u,n){return qe(l),l.updateQueue=null,e=Gs(l,a,e,u),js(t),a=Ji(),t!==null&&!Ut?(ki(t,l,n),Xl(t,l,n)):(et&&a&&Ui(l),l.flags|=1,Ht(t,l,e,n),l.child)}function Qo(t,l,e,a,u){if(qe(l),l.stateNode===null){var n=la,i=e.contextType;typeof i=="object"&&i!==null&&(n=Zt(i)),n=new e(a,n),l.memoizedState=n.state!==null&&n.state!==void 0?n.state:null,n.updater=fc,l.stateNode=n,n._reactInternals=l,n=l.stateNode,n.props=a,n.state=l.memoizedState,n.refs={},Gi(l),i=e.contextType,n.context=typeof i=="object"&&i!==null?Zt(i):la,n.state=l.memoizedState,i=e.getDerivedStateFromProps,typeof i=="function"&&(cc(l,e,i,a),n.state=l.memoizedState),typeof e.getDerivedStateFromProps=="function"||typeof n.getSnapshotBeforeUpdate=="function"||typeof n.UNSAFE_componentWillMount!="function"&&typeof n.componentWillMount!="function"||(i=n.state,typeof n.componentWillMount=="function"&&n.componentWillMount(),typeof n.UNSAFE_componentWillMount=="function"&&n.UNSAFE_componentWillMount(),i!==n.state&&fc.enqueueReplaceState(n,n.state,null),$a(l,a,n,u),Wa(),n.state=l.memoizedState),typeof n.componentDidMount=="function"&&(l.flags|=4194308),a=!0}else if(t===null){n=l.stateNode;var c=l.memoizedProps,o=xe(e,c);n.props=o;var b=n.context,p=e.contextType;i=la,typeof p=="object"&&p!==null&&(i=Zt(p));var M=e.getDerivedStateFromProps;p=typeof M=="function"||typeof n.getSnapshotBeforeUpdate=="function",c=l.pendingProps!==c,p||typeof n.UNSAFE_componentWillReceiveProps!="function"&&typeof n.componentWillReceiveProps!="function"||(c||b!==i)&&Oo(l,n,a,i),Il=!1;var _=l.memoizedState;n.state=_,$a(l,a,n,u),Wa(),b=l.memoizedState,c||_!==b||Il?(typeof M=="function"&&(cc(l,e,M,a),b=l.memoizedState),(o=Il||Do(l,e,o,a,_,b,i))?(p||typeof n.UNSAFE_componentWillMount!="function"&&typeof n.componentWillMount!="function"||(typeof n.componentWillMount=="function"&&n.componentWillMount(),typeof n.UNSAFE_componentWillMount=="function"&&n.UNSAFE_componentWillMount()),typeof n.componentDidMount=="function"&&(l.flags|=4194308)):(typeof n.componentDidMount=="function"&&(l.flags|=4194308),l.memoizedProps=a,l.memoizedState=b),n.props=a,n.state=b,n.context=i,a=o):(typeof n.componentDidMount=="function"&&(l.flags|=4194308),a=!1)}else{n=l.stateNode,Ci(t,l),i=l.memoizedProps,p=xe(e,i),n.props=p,M=l.pendingProps,_=n.context,b=e.contextType,o=la,typeof b=="object"&&b!==null&&(o=Zt(b)),c=e.getDerivedStateFromProps,(b=typeof c=="function"||typeof n.getSnapshotBeforeUpdate=="function")||typeof n.UNSAFE_componentWillReceiveProps!="function"&&typeof n.componentWillReceiveProps!="function"||(i!==M||_!==o)&&Oo(l,n,a,o),Il=!1,_=l.memoizedState,n.state=_,$a(l,a,n,u),Wa();var g=l.memoizedState;i!==M||_!==g||Il||t!==null&&t.dependencies!==null&&Wu(t.dependencies)?(typeof c=="function"&&(cc(l,e,c,a),g=l.memoizedState),(p=Il||Do(l,e,p,a,_,g,o)||t!==null&&t.dependencies!==null&&Wu(t.dependencies))?(b||typeof n.UNSAFE_componentWillUpdate!="function"&&typeof n.componentWillUpdate!="function"||(typeof n.componentWillUpdate=="function"&&n.componentWillUpdate(a,g,o),typeof n.UNSAFE_componentWillUpdate=="function"&&n.UNSAFE_componentWillUpdate(a,g,o)),typeof n.componentDidUpdate=="function"&&(l.flags|=4),typeof n.getSnapshotBeforeUpdate=="function"&&(l.flags|=1024)):(typeof n.componentDidUpdate!="function"||i===t.memoizedProps&&_===t.memoizedState||(l.flags|=4),typeof n.getSnapshotBeforeUpdate!="function"||i===t.memoizedProps&&_===t.memoizedState||(l.flags|=1024),l.memoizedProps=a,l.memoizedState=g),n.props=a,n.state=g,n.context=o,a=p):(typeof n.componentDidUpdate!="function"||i===t.memoizedProps&&_===t.memoizedState||(l.flags|=4),typeof n.getSnapshotBeforeUpdate!="function"||i===t.memoizedProps&&_===t.memoizedState||(l.flags|=1024),a=!1)}return n=a,hn(t,l),a=(l.flags&128)!==0,n||a?(n=l.stateNode,e=a&&typeof e.getDerivedStateFromError!="function"?null:n.render(),l.flags|=1,t!==null&&a?(l.child=ra(l,t.child,null,u),l.child=ra(l,null,e,u)):Ht(t,l,e,u),l.memoizedState=n.state,t=l.child):t=Xl(t,l,u),t}function Zo(t,l,e,a){return Xa(),l.flags|=256,Ht(t,l,e,a),l.child}var rc={dehydrated:null,treeContext:null,retryLane:0,hydrationErrors:null};function dc(t){return{baseLanes:t,cachePool:Us()}}function yc(t,l,e){return t=t!==null?t.childLanes&~e:0,l&&(t|=bl),t}function Lo(t,l,e){var a=l.pendingProps,u=!1,n=(l.flags&128)!==0,i;if((i=n)||(i=t!==null&&t.memoizedState===null?!1:(zt.current&2)!==0),i&&(u=!0,l.flags&=-129),i=(l.flags&32)!==0,l.flags&=-33,t===null){if(et){if(u?ee(l):ae(),et){var c=_t,o;if(o=c){t:{for(o=c,c=Ml;o.nodeType!==8;){if(!c){c=null;break t}if(o=pl(o.nextSibling),o===null){c=null;break t}}c=o}c!==null?(l.memoizedState={dehydrated:c,treeContext:De!==null?{id:xl,overflow:wl}:null,retryLane:536870912,hydrationErrors:null},o=ul(18,null,null,0),o.stateNode=c,o.return=l,l.child=o,Kt=l,_t=null,o=!0):o=!1}o||Re(l)}if(c=l.memoizedState,c!==null&&(c=c.dehydrated,c!==null))return $c(c)?l.lanes=32:l.lanes=536870912,null;Cl(l)}return c=a.children,a=a.fallback,u?(ae(),u=l.mode,c=vn({mode:"hidden",children:c},u),a=ze(a,u,e,null),c.return=l,a.return=l,c.sibling=a,l.child=c,u=l.child,u.memoizedState=dc(e),u.childLanes=yc(t,i,e),l.memoizedState=rc,a):(ee(l),mc(l,c))}if(o=t.memoizedState,o!==null&&(c=o.dehydrated,c!==null)){if(n)l.flags&256?(ee(l),l.flags&=-257,l=hc(t,l,e)):l.memoizedState!==null?(ae(),l.child=t.child,l.flags|=128,l=null):(ae(),u=a.fallback,c=l.mode,a=vn({mode:"visible",children:a.children},c),u=ze(u,c,e,null),u.flags|=2,a.return=l,u.return=l,a.sibling=u,l.child=a,ra(l,t.child,null,e),a=l.child,a.memoizedState=dc(e),a.childLanes=yc(t,i,e),l.memoizedState=rc,l=u);else if(ee(l),$c(c)){if(i=c.nextSibling&&c.nextSibling.dataset,i)var b=i.dgst;i=b,a=Error(s(419)),a.stack="",a.digest=i,Qa({value:a,source:null,stack:null}),l=hc(t,l,e)}else if(Ut||Za(t,l,e,!1),i=(e&t.childLanes)!==0,Ut||i){if(i=yt,i!==null&&(a=e&-e,a=(a&42)!==0?1:Fn(a),a=(a&(i.suspendedLanes|e))!==0?0:a,a!==0&&a!==o.retryLane))throw o.retryLane=a,ta(t,a),sl(i,t,a),xo;c.data==="$?"||Hc(),l=hc(t,l,e)}else c.data==="$?"?(l.flags|=192,l.child=t.child,l=null):(t=o.treeContext,_t=pl(c.nextSibling),Kt=l,et=!0,Ue=null,Ml=!1,t!==null&&(ml[hl++]=xl,ml[hl++]=wl,ml[hl++]=De,xl=t.id,wl=t.overflow,De=l),l=mc(l,a.children),l.flags|=4096);return l}return u?(ae(),u=a.fallback,c=l.mode,o=t.child,b=o.sibling,a=Bl(o,{mode:"hidden",children:a.children}),a.subtreeFlags=o.subtreeFlags&65011712,b!==null?u=Bl(b,u):(u=ze(u,c,e,null),u.flags|=2),u.return=l,a.return=l,a.sibling=u,l.child=a,a=u,u=l.child,c=t.child.memoizedState,c===null?c=dc(e):(o=c.cachePool,o!==null?(b=Mt._currentValue,o=o.parent!==b?{parent:b,pool:b}:o):o=Us(),c={baseLanes:c.baseLanes|e,cachePool:o}),u.memoizedState=c,u.childLanes=yc(t,i,e),l.memoizedState=rc,a):(ee(l),e=t.child,t=e.sibling,e=Bl(e,{mode:"visible",children:a.children}),e.return=l,e.sibling=null,t!==null&&(i=l.deletions,i===null?(l.deletions=[t],l.flags|=16):i.push(t)),l.child=e,l.memoizedState=null,e)}function mc(t,l){return l=vn({mode:"visible",children:l},t.mode),l.return=t,t.child=l}function vn(t,l){return t=ul(22,t,null,l),t.lanes=0,t.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null},t}function hc(t,l,e){return ra(l,t.child,null,e),t=mc(l,l.pendingProps.children),t.flags|=2,l.memoizedState=null,t}function Vo(t,l,e){t.lanes|=l;var a=t.alternate;a!==null&&(a.lanes|=l),Hi(t.return,l,e)}function vc(t,l,e,a,u){var n=t.memoizedState;n===null?t.memoizedState={isBackwards:l,rendering:null,renderingStartTime:0,last:a,tail:e,tailMode:u}:(n.isBackwards=l,n.rendering=null,n.renderingStartTime=0,n.last=a,n.tail=e,n.tailMode=u)}function Ko(t,l,e){var a=l.pendingProps,u=a.revealOrder,n=a.tail;if(Ht(t,l,a.children,e),a=zt.current,(a&2)!==0)a=a&1|2,l.flags|=128;else{if(t!==null&&(t.flags&128)!==0)t:for(t=l.child;t!==null;){if(t.tag===13)t.memoizedState!==null&&Vo(t,e,l);else if(t.tag===19)Vo(t,e,l);else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===l)break t;for(;t.sibling===null;){if(t.return===null||t.return===l)break t;t=t.return}t.sibling.return=t.return,t=t.sibling}a&=1}switch(R(zt,a),u){case"forwards":for(e=l.child,u=null;e!==null;)t=e.alternate,t!==null&&dn(t)===null&&(u=e),e=e.sibling;e=u,e===null?(u=l.child,l.child=null):(u=e.sibling,e.sibling=null),vc(l,!1,u,e,n);break;case"backwards":for(e=null,u=l.child,l.child=null;u!==null;){if(t=u.alternate,t!==null&&dn(t)===null){l.child=u;break}t=u.sibling,u.sibling=e,e=u,u=t}vc(l,!0,e,null,n);break;case"together":vc(l,!1,null,null,void 0);break;default:l.memoizedState=null}return l.child}function Xl(t,l,e){if(t!==null&&(l.dependencies=t.dependencies),fe|=l.lanes,(e&l.childLanes)===0)if(t!==null){if(Za(t,l,e,!1),(e&l.childLanes)===0)return null}else return null;if(t!==null&&l.child!==t.child)throw Error(s(153));if(l.child!==null){for(t=l.child,e=Bl(t,t.pendingProps),l.child=e,e.return=l;t.sibling!==null;)t=t.sibling,e=e.sibling=Bl(t,t.pendingProps),e.return=l;e.sibling=null}return l.child}function bc(t,l){return(t.lanes&l)!==0?!0:(t=t.dependencies,!!(t!==null&&Wu(t)))}function cy(t,l,e){switch(l.tag){case 3:ht(l,l.stateNode.containerInfo),Fl(l,Mt,t.memoizedState.cache),Xa();break;case 27:case 5:Kn(l);break;case 4:ht(l,l.stateNode.containerInfo);break;case 10:Fl(l,l.type,l.memoizedProps.value);break;case 13:var a=l.memoizedState;if(a!==null)return a.dehydrated!==null?(ee(l),l.flags|=128,null):(e&l.child.childLanes)!==0?Lo(t,l,e):(ee(l),t=Xl(t,l,e),t!==null?t.sibling:null);ee(l);break;case 19:var u=(t.flags&128)!==0;if(a=(e&l.childLanes)!==0,a||(Za(t,l,e,!1),a=(e&l.childLanes)!==0),u){if(a)return Ko(t,l,e);l.flags|=128}if(u=l.memoizedState,u!==null&&(u.rendering=null,u.tail=null,u.lastEffect=null),R(zt,zt.current),a)break;return null;case 22:case 23:return l.lanes=0,Go(t,l,e);case 24:Fl(l,Mt,t.memoizedState.cache)}return Xl(t,l,e)}function Jo(t,l,e){if(t!==null)if(t.memoizedProps!==l.pendingProps)Ut=!0;else{if(!bc(t,e)&&(l.flags&128)===0)return Ut=!1,cy(t,l,e);Ut=(t.flags&131072)!==0}else Ut=!1,et&&(l.flags&1048576)!==0&&Ts(l,ku,l.index);switch(l.lanes=0,l.tag){case 16:t:{t=l.pendingProps;var a=l.elementType,u=a._init;if(a=u(a._payload),l.type=a,typeof a=="function")zi(a)?(t=xe(a,t),l.tag=1,l=Qo(null,l,a,t,e)):(l.tag=0,l=oc(null,l,a,t,e));else{if(a!=null){if(u=a.$$typeof,u===jt){l.tag=11,l=wo(null,l,a,t,e);break t}else if(u===Gt){l.tag=14,l=Yo(null,l,a,t,e);break t}}throw l=Se(a)||a,Error(s(306,l,""))}}return l;case 0:return oc(t,l,l.type,l.pendingProps,e);case 1:return a=l.type,u=xe(a,l.pendingProps),Qo(t,l,a,u,e);case 3:t:{if(ht(l,l.stateNode.containerInfo),t===null)throw Error(s(387));a=l.pendingProps;var n=l.memoizedState;u=n.element,Ci(t,l),$a(l,a,null,e);var i=l.memoizedState;if(a=i.cache,Fl(l,Mt,a),a!==n.cache&&Bi(l,[Mt],e,!0),Wa(),a=i.element,n.isDehydrated)if(n={element:a,isDehydrated:!1,cache:i.cache},l.updateQueue.baseState=n,l.memoizedState=n,l.flags&256){l=Zo(t,l,a,e);break t}else if(a!==u){u=dl(Error(s(424)),l),Qa(u),l=Zo(t,l,a,e);break t}else{switch(t=l.stateNode.containerInfo,t.nodeType){case 9:t=t.body;break;default:t=t.nodeName==="HTML"?t.ownerDocument.body:t}for(_t=pl(t.firstChild),Kt=l,et=!0,Ue=null,Ml=!0,e=Mo(l,null,a,e),l.child=e;e;)e.flags=e.flags&-3|4096,e=e.sibling}else{if(Xa(),a===u){l=Xl(t,l,e);break t}Ht(t,l,a,e)}l=l.child}return l;case 26:return hn(t,l),t===null?(e=F0(l.type,null,l.pendingProps,null))?l.memoizedState=e:et||(e=l.type,t=l.pendingProps,a=Rn(Q.current).createElement(e),a[Qt]=l,a[kt]=t,xt(a,e,t),Ot(a),l.stateNode=a):l.memoizedState=F0(l.type,t.memoizedProps,l.pendingProps,t.memoizedState),null;case 27:return Kn(l),t===null&&et&&(a=l.stateNode=k0(l.type,l.pendingProps,Q.current),Kt=l,Ml=!0,u=_t,de(l.type)?(Fc=u,_t=pl(a.firstChild)):_t=u),Ht(t,l,l.pendingProps.children,e),hn(t,l),t===null&&(l.flags|=4194304),l.child;case 5:return t===null&&et&&((u=a=_t)&&(a=xy(a,l.type,l.pendingProps,Ml),a!==null?(l.stateNode=a,Kt=l,_t=pl(a.firstChild),Ml=!1,u=!0):u=!1),u||Re(l)),Kn(l),u=l.type,n=l.pendingProps,i=t!==null?t.memoizedProps:null,a=n.children,Jc(u,n)?a=null:i!==null&&Jc(u,i)&&(l.flags|=32),l.memoizedState!==null&&(u=Ki(t,l,Pd,null,null,e),_u._currentValue=u),hn(t,l),Ht(t,l,a,e),l.child;case 6:return t===null&&et&&((t=e=_t)&&(e=wy(e,l.pendingProps,Ml),e!==null?(l.stateNode=e,Kt=l,_t=null,t=!0):t=!1),t||Re(l)),null;case 13:return Lo(t,l,e);case 4:return ht(l,l.stateNode.containerInfo),a=l.pendingProps,t===null?l.child=ra(l,null,a,e):Ht(t,l,a,e),l.child;case 11:return wo(t,l,l.type,l.pendingProps,e);case 7:return Ht(t,l,l.pendingProps,e),l.child;case 8:return Ht(t,l,l.pendingProps.children,e),l.child;case 12:return Ht(t,l,l.pendingProps.children,e),l.child;case 10:return a=l.pendingProps,Fl(l,l.type,a.value),Ht(t,l,a.children,e),l.child;case 9:return u=l.type._context,a=l.pendingProps.children,qe(l),u=Zt(u),a=a(u),l.flags|=1,Ht(t,l,a,e),l.child;case 14:return Yo(t,l,l.type,l.pendingProps,e);case 15:return jo(t,l,l.type,l.pendingProps,e);case 19:return Ko(t,l,e);case 31:return a=l.pendingProps,e=l.mode,a={mode:a.mode,children:a.children},t===null?(e=vn(a,e),e.ref=l.ref,l.child=e,e.return=l,l=e):(e=Bl(t.child,a),e.ref=l.ref,l.child=e,e.return=l,l=e),l;case 22:return Go(t,l,e);case 24:return qe(l),a=Zt(Mt),t===null?(u=Yi(),u===null&&(u=yt,n=xi(),u.pooledCache=n,n.refCount++,n!==null&&(u.pooledCacheLanes|=e),u=n),l.memoizedState={parent:a,cache:u},Gi(l),Fl(l,Mt,u)):((t.lanes&e)!==0&&(Ci(t,l),$a(l,null,null,e),Wa()),u=t.memoizedState,n=l.memoizedState,u.parent!==a?(u={parent:a,cache:a},l.memoizedState=u,l.lanes===0&&(l.memoizedState=l.updateQueue.baseState=u),Fl(l,Mt,a)):(a=n.cache,Fl(l,Mt,a),a!==u.cache&&Bi(l,[Mt],e,!0))),Ht(t,l,l.pendingProps.children,e),l.child;case 29:throw l.pendingProps}throw Error(s(156,l.tag))}function Ql(t){t.flags|=4}function ko(t,l){if(l.type!=="stylesheet"||(l.state.loading&4)!==0)t.flags&=-16777217;else if(t.flags|=16777216,!er(l)){if(l=vl.current,l!==null&&((I&4194048)===I?zl!==null:(I&62914560)!==I&&(I&536870912)===0||l!==zl))throw Ja=ji,Rs;t.flags|=8192}}function bn(t,l){l!==null&&(t.flags|=4),t.flags&16384&&(l=t.tag!==22?Mf():536870912,t.lanes|=l,ha|=l)}function au(t,l){if(!et)switch(t.tailMode){case"hidden":l=t.tail;for(var e=null;l!==null;)l.alternate!==null&&(e=l),l=l.sibling;e===null?t.tail=null:e.sibling=null;break;case"collapsed":e=t.tail;for(var a=null;e!==null;)e.alternate!==null&&(a=e),e=e.sibling;a===null?l||t.tail===null?t.tail=null:t.tail.sibling=null:a.sibling=null}}function bt(t){var l=t.alternate!==null&&t.alternate.child===t.child,e=0,a=0;if(l)for(var u=t.child;u!==null;)e|=u.lanes|u.childLanes,a|=u.subtreeFlags&65011712,a|=u.flags&65011712,u.return=t,u=u.sibling;else for(u=t.child;u!==null;)e|=u.lanes|u.childLanes,a|=u.subtreeFlags,a|=u.flags,u.return=t,u=u.sibling;return t.subtreeFlags|=a,t.childLanes=e,l}function fy(t,l,e){var a=l.pendingProps;switch(Ri(l),l.tag){case 31:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return bt(l),null;case 1:return bt(l),null;case 3:return e=l.stateNode,a=null,t!==null&&(a=t.memoizedState.cache),l.memoizedState.cache!==a&&(l.flags|=2048),jl(Mt),Jl(),e.pendingContext&&(e.context=e.pendingContext,e.pendingContext=null),(t===null||t.child===null)&&(Ca(l)?Ql(l):t===null||t.memoizedState.isDehydrated&&(l.flags&256)===0||(l.flags|=1024,Ms())),bt(l),null;case 26:return e=l.memoizedState,t===null?(Ql(l),e!==null?(bt(l),ko(l,e)):(bt(l),l.flags&=-16777217)):e?e!==t.memoizedState?(Ql(l),bt(l),ko(l,e)):(bt(l),l.flags&=-16777217):(t.memoizedProps!==a&&Ql(l),bt(l),l.flags&=-16777217),null;case 27:Du(l),e=Q.current;var u=l.type;if(t!==null&&l.stateNode!=null)t.memoizedProps!==a&&Ql(l);else{if(!a){if(l.stateNode===null)throw Error(s(166));return bt(l),null}t=Y.current,Ca(l)?Es(l):(t=k0(u,a,e),l.stateNode=t,Ql(l))}return bt(l),null;case 5:if(Du(l),e=l.type,t!==null&&l.stateNode!=null)t.memoizedProps!==a&&Ql(l);else{if(!a){if(l.stateNode===null)throw Error(s(166));return bt(l),null}if(t=Y.current,Ca(l))Es(l);else{switch(u=Rn(Q.current),t){case 1:t=u.createElementNS("http://www.w3.org/2000/svg",e);break;case 2:t=u.createElementNS("http://www.w3.org/1998/Math/MathML",e);break;default:switch(e){case"svg":t=u.createElementNS("http://www.w3.org/2000/svg",e);break;case"math":t=u.createElementNS("http://www.w3.org/1998/Math/MathML",e);break;case"script":t=u.createElement("div"),t.innerHTML=" FlowLens - - + +
diff --git a/test/e2e/stage4-demo.spec.ts b/test/e2e/stage4-demo.spec.ts index 72fb754..394165f 100644 --- a/test/e2e/stage4-demo.spec.ts +++ b/test/e2e/stage4-demo.spec.ts @@ -14,7 +14,7 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ await page.setViewportSize({ width: 1440, height: 1000 }); await page.goto("./"); - await expect(page.locator("main.app")).toHaveAttribute( + await expect(page.locator(".app-shell")).toHaveAttribute( "data-source-mode", "demo", ); @@ -30,7 +30,38 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ const themeToggleBox = await page.locator(".theme-toggle").boundingBox(); expect(liveStatusBox).not.toBeNull(); expect(themeToggleBox).not.toBeNull(); - expect(themeToggleBox!.x - (liveStatusBox!.x + liveStatusBox!.width)).toBeGreaterThanOrEqual(18); + expect( + themeToggleBox!.x - (liveStatusBox!.x + liveStatusBox!.width), + ).toBeGreaterThanOrEqual(6); + const layers = await page.evaluate(() => ({ + header: Number.parseInt( + getComputedStyle(document.querySelector(".topbar")!).zIndex, + 10, + ), + range: Number.parseInt( + getComputedStyle(document.querySelector(".range-wrap")!).zIndex, + 10, + ), + })); + expect(layers.header).toBeGreaterThan(layers.range); + + const rangeBeforeScroll = await page.locator(".range-wrap").boundingBox(); + expect(rangeBeforeScroll).not.toBeNull(); + await page.evaluate( + (scrollTop) => window.scrollTo(0, scrollTop), + Math.max(0, rangeBeforeScroll!.y - 24), + ); + const overlapOwner = await page.evaluate(() => { + const header = document.querySelector(".topbar")!.getBoundingClientRect(); + const range = document + .querySelector(".range-wrap")! + .getBoundingClientRect(); + return document + .elementFromPoint(range.left + range.width / 2, header.bottom - 4) + ?.closest(".topbar")?.className; + }); + expect(overlapOwner).toContain("topbar"); + await page.evaluate(() => window.scrollTo(0, 0)); await expect(page.getByRole("button", { name: "跟随系统" })).toBeVisible(); await expect(page.getByRole("button", { name: "退出" })).toBeVisible(); await expect(page.getByRole("navigation")).toHaveCount(0); @@ -43,9 +74,7 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ await expect(page.getByRole("heading", { name: "流量总览" })).toHaveClass( /page-title/, ); - await expect( - page.getByRole("heading", { name: "实时吞吐" }), - ).toBeVisible(); + await expect(page.getByRole("heading", { name: "实时吞吐" })).toBeVisible(); await expect( page.getByRole("heading", { name: "实时目标分析" }), ).toBeVisible(); @@ -64,9 +93,7 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ ); expect(liveMetricBoxes).toHaveLength(6); expect( - liveMetricBoxes.every( - (box) => Math.abs(box.y - liveMetricBoxes[0]!.y) < 2, - ), + liveMetricBoxes.every((box) => Math.abs(box.y - liveMetricBoxes[0]!.y) < 2), ).toBe(true); await expect(page.getByText(/占全局 51\.6%/)).toBeVisible(); const topologyBox = await page.locator(".topology-panel").boundingBox(); @@ -87,7 +114,9 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ const number = (selector: string, property: string) => { const element = document.querySelector(selector); if (!(element instanceof HTMLElement)) return null; - return Number.parseFloat(getComputedStyle(element).getPropertyValue(property)); + return Number.parseFloat( + getComputedStyle(element).getPropertyValue(property), + ); }; return { dashboardGap: number(".dashboard", "gap"), @@ -95,13 +124,19 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ panelRadius: number(".hero-panel", "border-top-left-radius"), pageTitleSize: number(".page-title", "font-size"), panelTitleSize: number(".panel-head h2", "font-size"), - summaryValueSize: number(".chart-summary .chart-value strong", "font-size"), - chartHeight: document.querySelector(".chart-shell")?.getBoundingClientRect() - .height, - topologyHeight: document.querySelector(".topology")?.getBoundingClientRect() - .height, - targetHeight: document.querySelector(".target-item")?.getBoundingClientRect() - .height, + summaryValueSize: number( + ".chart-summary .chart-value strong", + "font-size", + ), + chartHeight: document + .querySelector(".chart-shell") + ?.getBoundingClientRect().height, + topologyHeight: document + .querySelector(".topology") + ?.getBoundingClientRect().height, + targetHeight: document + .querySelector(".target-item") + ?.getBoundingClientRect().height, }; }); expect(density.dashboardGap).toBeLessThanOrEqual(14); @@ -113,8 +148,14 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ expect(density.chartHeight).toBeLessThanOrEqual(260); expect(density.topologyHeight).toBeLessThanOrEqual(280); expect(density.targetHeight).toBeLessThanOrEqual(60); - const firstTarget = await page.locator(".targets-panel .target-item").nth(0).boundingBox(); - const secondTarget = await page.locator(".targets-panel .target-item").nth(1).boundingBox(); + const firstTarget = await page + .locator(".targets-panel .target-item") + .nth(0) + .boundingBox(); + const secondTarget = await page + .locator(".targets-panel .target-item") + .nth(1) + .boundingBox(); expect(firstTarget).not.toBeNull(); expect(secondTarget).not.toBeNull(); expect(Math.abs(firstTarget!.x - secondTarget!.x)).toBeLessThan(2); @@ -128,12 +169,8 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ await expect(page.locator("html")).toHaveAttribute("data-theme", "dark"); await page.getByRole("button", { name: "今天" }).click(); - await expect( - page.getByRole("heading", { name: "历史流量" }), - ).toBeVisible(); - await expect( - page.getByText("SQLite 聚合 · 自动选择分辨率"), - ).toHaveCount(0); + await expect(page.getByRole("heading", { name: "历史流量" })).toBeVisible(); + await expect(page.getByText("SQLite 聚合 · 自动选择分辨率")).toHaveCount(0); const historyDescription = page.getByRole("button", { name: "查看“历史流量”说明", }); @@ -153,9 +190,7 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ const historyConfidenceBox = await page .locator(".confidence-panel") .boundingBox(); - const historyTargetsBox = await page - .locator(".targets-panel") - .boundingBox(); + const historyTargetsBox = await page.locator(".targets-panel").boundingBox(); expect(historyDashboardBox).not.toBeNull(); expect(historyTopologyBox).not.toBeNull(); expect(historyConfidenceBox).not.toBeNull(); @@ -166,9 +201,9 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ expect(historyConfidenceBox!.y).toBeGreaterThan( historyTopologyBox!.y + historyTopologyBox!.height, ); - expect( - Math.abs(historyConfidenceBox!.y - historyTargetsBox!.y), - ).toBeLessThan(2); + expect(Math.abs(historyConfidenceBox!.y - historyTargetsBox!.y)).toBeLessThan( + 2, + ); expect( Math.abs(historyConfidenceBox!.height - historyTargetsBox!.height), ).toBeLessThan(2); @@ -207,9 +242,7 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ await page.getByRole("button", { name: "端口", exact: true }).click(); await expect(page.getByLabel("端口分布")).toBeVisible(); await expect(page.getByLabel(/流量拓扑/)).toHaveCount(0); - await page - .getByRole("button", { name: "Endpoint", exact: true }) - .click(); + await page.getByRole("button", { name: "Endpoint", exact: true }).click(); await expect(page.getByLabel(/流量拓扑/)).toBeVisible(); await page.getByRole("button", { name: "7 天" }).click(); @@ -282,7 +315,8 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ expect(desktopClose).not.toBeNull(); expect( Math.abs( - desktopAliasInput!.y + desktopAliasInput!.height / 2 - + desktopAliasInput!.y + + desktopAliasInput!.height / 2 - (desktopAliasActions!.y + desktopAliasActions!.height / 2), ), ).toBeLessThan(2); @@ -330,9 +364,7 @@ test("offline Demo exposes one rich responsive statistics dashboard", async ({ expect(sourceTwo!.x).toBeGreaterThan(sourceOne!.x + sourceOne!.width); expect(gateway!.y).toBeGreaterThan(sourceOne!.y + sourceOne!.height); expect(Math.abs(gateway!.width - topology!.width)).toBeLessThan(2); - expect(firstTopologyTarget!.y).toBeGreaterThan( - gateway!.y + gateway!.height, - ); + expect(firstTopologyTarget!.y).toBeGreaterThan(gateway!.y + gateway!.height); await expect(page.locator(".dashboard")).toHaveCSS( "grid-template-columns", /310px|300px|1fr/, diff --git a/test/e2e/stage4-production-csp.spec.ts b/test/e2e/stage4-production-csp.spec.ts index d5fe965..2c65c37 100644 --- a/test/e2e/stage4-production-csp.spec.ts +++ b/test/e2e/stage4-production-csp.spec.ts @@ -69,7 +69,7 @@ test("production bundle works with the shipped CSP and named SSE events", async }); await page.goto("http://127.0.0.1:4175/"); - await expect(page.locator("main.app")).toHaveAttribute( + await expect(page.locator(".app-shell")).toHaveAttribute( "data-source-mode", "app", ); diff --git a/web/src/app/Shell.tsx b/web/src/app/Shell.tsx index 3635031..c16fa77 100644 --- a/web/src/app/Shell.tsx +++ b/web/src/app/Shell.tsx @@ -23,7 +23,7 @@ export function Shell({ }) { const logoutLabel = logoutFailed ? "退出失败,请重试" : "退出"; return ( -
+
@@ -65,8 +65,8 @@ export function Shell({ ) : null}
- {children} +
{children}
-
+ ); } diff --git a/web/src/features/dashboard/test/DashboardPage.test.tsx b/web/src/features/dashboard/test/DashboardPage.test.tsx index 4999ef7..b3e2d67 100644 --- a/web/src/features/dashboard/test/DashboardPage.test.tsx +++ b/web/src/features/dashboard/test/DashboardPage.test.tsx @@ -61,6 +61,12 @@ describe("DashboardPage", () => { "href", "https://github.com/Willxup/flowlens", ); + const globalHeader = brand.closest("header"); + const main = screen.getByRole("main"); + expect(globalHeader).toHaveClass("topbar"); + expect(main).toHaveClass("app"); + expect(main).not.toContainElement(globalHeader); + expect(globalHeader?.parentElement).toBe(main.parentElement); expect(screen.getByText("采集正常")).toBeInTheDocument(); expect(await screen.findByText("© 2026")).toBeInTheDocument(); expect(screen.getByRole("link", { name: "License" })).toHaveAttribute( diff --git a/web/src/styles/components.css b/web/src/styles/components.css index 0306733..a67068b 100644 --- a/web/src/styles/components.css +++ b/web/src/styles/components.css @@ -26,7 +26,7 @@ select:focus-visible { width: max-content; max-width: min(320px, calc(100vw - 20px)); position: fixed; - z-index: 100; + z-index: var(--layer-tooltip); display: block; padding: 8px 11px; border: 1px solid var(--line-strong); @@ -629,7 +629,7 @@ select:focus-visible { .dialog-backdrop { position: fixed; inset: 0; - z-index: 50; + z-index: var(--layer-modal); display: grid; place-items: center; padding: 18px; diff --git a/web/src/styles/layout.css b/web/src/styles/layout.css index 4aa3dc0..8681a6b 100644 --- a/web/src/styles/layout.css +++ b/web/src/styles/layout.css @@ -1,7 +1,10 @@ -.app { +.app-shell { width: min(1360px, calc(100% - 48px)); margin: 20px auto 48px; } +.app { + min-width: 0; +} .app-footer { display: grid; gap: 6px; @@ -43,21 +46,22 @@ white-space: nowrap; } .topbar { - min-height: 64px; - padding: 10px 12px 10px 16px; + min-height: 54px; + padding: 8px 9px 8px 14px; display: grid; grid-template-columns: minmax(190px, 1fr) auto; align-items: center; - gap: 24px; + gap: 18px; border: 1px solid var(--line); - border-radius: var(--radius-lg); + border-radius: 14px; background: var(--surface); box-shadow: var(--shadow-soft); - backdrop-filter: blur(20px) saturate(150%); - -webkit-backdrop-filter: blur(20px) saturate(150%); + backdrop-filter: blur(14px) saturate(135%); + -webkit-backdrop-filter: blur(14px) saturate(135%); position: sticky; top: 12px; - z-index: 20; + z-index: var(--layer-header); + isolation: isolate; } .brand { width: fit-content; @@ -79,8 +83,8 @@ } .brand strong { color: var(--ink); - font-size: 0.98rem; - font-weight: 720; + font-size: 0.94rem; + font-weight: 700; letter-spacing: -0.025em; } .brand-mark { @@ -109,6 +113,26 @@ border-radius: 50%; background: var(--ink); } +.topbar .brand-mark { + width: 30px; + height: 30px; + border-radius: 9px; + background: linear-gradient( + 135deg, + var(--cyan) 0 54%, + var(--upload) 54% 100% + ); + box-shadow: + inset 0 0 0 5px var(--surface-strong), + 0 3px 9px var(--download-soft); +} +.topbar .brand-mark::after { + inset: 11px; +} +.topbar .brand .eyebrow { + font-size: 0.62rem; + letter-spacing: 0.08em; +} .segmented button { border: 0; border-radius: 9px; @@ -137,14 +161,39 @@ display: flex; align-items: center; justify-content: flex-end; - gap: 8px; + gap: 6px; +} +.topbar .top-actions .live-status { + margin-right: 2px; +} +.topbar .theme-toggle { + padding: 2px; + border-radius: 10px; + background: var(--surface-soft); +} +.topbar .theme-button { + width: 32px; + height: 32px; + border-radius: 7px; +} +.topbar .logout-button { + min-width: 36px; + min-height: 36px; + justify-content: center; + border: 1px solid var(--line); + border-radius: 9px; + background: var(--surface-soft); + padding: 0; +} +.topbar .logout-button span { + display: none; } .page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; - margin: 32px 4px 16px; + margin: 24px 4px 16px; } .page-title { width: fit-content; @@ -168,7 +217,7 @@ } .range-wrap { position: relative; - z-index: 30; + z-index: var(--layer-page-control); display: flex; flex-direction: column; align-items: flex-end; @@ -600,7 +649,7 @@ } @media (max-width: 980px) { - .app { + .app-shell { width: calc(100% - 32px); } .topbar { @@ -642,7 +691,7 @@ } @media (max-width: 620px) { - .app { + .app-shell { width: calc(100% - 20px); margin-top: 8px; margin-bottom: 28px; @@ -663,10 +712,17 @@ } .topbar { top: 6px; - min-height: 60px; - padding: 8px 9px 8px 12px; + min-height: 56px; + padding: 6px 7px 6px 10px; gap: 10px; } + .topbar .theme-button, + .topbar .logout-button { + width: 44px; + min-width: 44px; + height: 44px; + min-height: 44px; + } .brand .eyebrow, .top-actions .live-status, .top-actions .soft-button { @@ -676,7 +732,7 @@ gap: 4px; } .page-head { - margin: 26px 2px 14px; + margin: 22px 2px 14px; } .page-title { font-size: 1.72rem; diff --git a/web/src/styles/tokens.css b/web/src/styles/tokens.css index 58eeb01..792a6c0 100644 --- a/web/src/styles/tokens.css +++ b/web/src/styles/tokens.css @@ -60,6 +60,10 @@ --motion-fast: 160ms; --motion-base: 220ms; --ease-out: cubic-bezier(0.22, 1, 0.36, 1); + --layer-page-control: 30; + --layer-header: 40; + --layer-modal: 50; + --layer-tooltip: 100; } :root[data-theme="dark"] {