@usex/mikrotik-mcp 3.43.0 → 3.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +7 -2
- package/dist/index.js +2 -2
- package/dist/shared/{cli-j7xj0at0.js → cli-1e5sj65w.js} +1 -1
- package/dist/shared/{cli-vrm1c5fb.js → cli-k2ghtqd0.js} +24 -2
- package/dist/shared/{library-hjh5hy5d.js → library-98nh7hz6.js} +1 -1
- package/dist/shared/{library-hjde13aa.js → library-nb4wss02.js} +1 -1
- package/dist/ui/observability.html +7 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
resolveDeviceName,
|
|
75
75
|
restoreLocalBackup,
|
|
76
76
|
s3Target,
|
|
77
|
+
sampleAllTraffic,
|
|
77
78
|
sampleDeviceTraffic,
|
|
78
79
|
selectToolModules,
|
|
79
80
|
setConfig,
|
|
@@ -88,7 +89,7 @@ import {
|
|
|
88
89
|
toggleAaaEntity,
|
|
89
90
|
updateAaaEntity,
|
|
90
91
|
writeBackup
|
|
91
|
-
} from "./shared/cli-
|
|
92
|
+
} from "./shared/cli-k2ghtqd0.js";
|
|
92
93
|
|
|
93
94
|
// src/cli.ts
|
|
94
95
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -1561,6 +1562,10 @@ async function clientsRoutes(req, url) {
|
|
|
1561
1562
|
const ctx = createContext(undefined, deviceFromQuery());
|
|
1562
1563
|
return json(await sampleDeviceTraffic(ctx, ip));
|
|
1563
1564
|
}
|
|
1565
|
+
if (p === "/api/clients/traffic-bulk" && req.method === "GET") {
|
|
1566
|
+
const ctx = createContext(undefined, deviceFromQuery());
|
|
1567
|
+
return json(await sampleAllTraffic(ctx));
|
|
1568
|
+
}
|
|
1564
1569
|
if (req.method === "POST") {
|
|
1565
1570
|
const b = await readJson(req);
|
|
1566
1571
|
const ctx = createContext(undefined, b?.device);
|
|
@@ -2282,7 +2287,7 @@ function registerPrompts(server) {
|
|
|
2282
2287
|
// package.json
|
|
2283
2288
|
var package_default = {
|
|
2284
2289
|
name: "@usex/mikrotik-mcp",
|
|
2285
|
-
version: "3.
|
|
2290
|
+
version: "3.44.0",
|
|
2286
2291
|
description: "MCP server for MikroTik RouterOS \u2014 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
|
|
2287
2292
|
keywords: [
|
|
2288
2293
|
"ai",
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
resolveDeviceName,
|
|
22
22
|
selectToolModules,
|
|
23
23
|
setConfig
|
|
24
|
-
} from "./shared/library-
|
|
24
|
+
} from "./shared/library-nb4wss02.js";
|
|
25
25
|
// src/server.ts
|
|
26
26
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
27
27
|
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -131,7 +131,7 @@ function registerPrompts(server) {
|
|
|
131
131
|
// package.json
|
|
132
132
|
var package_default = {
|
|
133
133
|
name: "@usex/mikrotik-mcp",
|
|
134
|
-
version: "3.
|
|
134
|
+
version: "3.44.0",
|
|
135
135
|
description: "MCP server for MikroTik RouterOS \u2014 660+ tools over SSH for firewall, NAT, routing, DHCP, DNS, WireGuard, wireless, QoS and more.",
|
|
136
136
|
keywords: [
|
|
137
137
|
"ai",
|
|
@@ -2413,6 +2413,28 @@ async function sampleDeviceTraffic(ctx, ip) {
|
|
|
2413
2413
|
uploadLimit: limit(upLim)
|
|
2414
2414
|
};
|
|
2415
2415
|
}
|
|
2416
|
+
async function sampleAllTraffic(ctx) {
|
|
2417
|
+
const ts = Date.now();
|
|
2418
|
+
const out = await executeMikrotikCommand("/queue simple print stats detail", ctx);
|
|
2419
|
+
if (isEmpty(out) || looksLikeError(out))
|
|
2420
|
+
return { ts, queues: {} };
|
|
2421
|
+
const queues = {};
|
|
2422
|
+
const limit = (v) => v && v !== "0" ? v : "";
|
|
2423
|
+
for (const row of parseRecords(out).rows) {
|
|
2424
|
+
const ip = (row.target ?? "").split("/")[0]?.trim();
|
|
2425
|
+
if (!ip)
|
|
2426
|
+
continue;
|
|
2427
|
+
const [txB, rxB] = (row.bytes ?? "0/0").split("/");
|
|
2428
|
+
const [upLim, downLim] = (row["max-limit"] ?? "0/0").split("/");
|
|
2429
|
+
queues[ip] = {
|
|
2430
|
+
txBytes: parseLeadingNumber(txB) ?? 0,
|
|
2431
|
+
rxBytes: parseLeadingNumber(rxB) ?? 0,
|
|
2432
|
+
downloadLimit: limit(downLim),
|
|
2433
|
+
uploadLimit: limit(upLim)
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
return { ts, queues };
|
|
2437
|
+
}
|
|
2416
2438
|
async function setDeviceLimits(ctx, ip, opts) {
|
|
2417
2439
|
const rate = (v) => {
|
|
2418
2440
|
const t = (v ?? "").trim();
|
|
@@ -6288,7 +6310,7 @@ var cache = null;
|
|
|
6288
6310
|
async function gateway() {
|
|
6289
6311
|
if (cache)
|
|
6290
6312
|
return cache;
|
|
6291
|
-
const { moduleCatalog } = await import("./cli-
|
|
6313
|
+
const { moduleCatalog } = await import("./cli-1e5sj65w.js");
|
|
6292
6314
|
const forIndex = [];
|
|
6293
6315
|
const byName = new Map;
|
|
6294
6316
|
for (const mod of moduleCatalog) {
|
|
@@ -25885,4 +25907,4 @@ function selectToolModules(filter = {}, catalog = moduleCatalog) {
|
|
|
25885
25907
|
}).map((m) => m.tools);
|
|
25886
25908
|
}
|
|
25887
25909
|
|
|
25888
|
-
export { __require, DEFAULT_SNAPSHOT_DB, DEFAULT_CONFIG_HISTORY_DIR, DeviceConfigSchema, ToolFilterSchema, MikrotikConfigSchema, getConfigSource, loadConfig, logger, setConfig, getConfig, listDevices, deviceLabels, resolveDeviceName, deviceDirectory, isMacTelnetDevice, createDeviceClient, describeTransport, isPoolEnabled, closeAll, poolStatus, executeMikrotikCommand, createContext, isEmpty, looksLikeError, commandUnsupported, parseKeyValues, parseRouterosDate, parseSize, parseSystemResource, parseRecords, parseLeadingNumber, REDACTED, redact, configureRecorder, getEventStore, subscribe, subscriberCount, registerTools, fetchDevices, sampleDeviceTraffic, setDeviceLimits, blockDevice, allowDevice, makeDeviceStatic, setDeviceIp, setDeviceLabel, removeDeviceLease, devicesView, PROMPTS_DIR, UI_DIST_DIR, registerUiResources, backupDir, listBackups, readBackup, writeBackup, deleteBackup, renameBackup, createLocalBackup, restoreLocalBackup, isS3Configured, getS3Client, presignExpiresIn, s3Target, splitCommands, buildChangePlan, renderPlan, diffLines, normalizeExport, openSnapshotStore, DEFAULT_TZSP_PORT, capture2 as capture, AAA_ENTITIES, listAaaEntity, addAaaEntity, updateAaaEntity, removeAaaEntity, toggleAaaEntity, getRadiusIncoming, setRadiusIncoming, resetRadiusCounters, getUmSettings, setUmSettings, moduleCatalog, allToolModules, ALWAYS_ON_MODULES, selectToolModules };
|
|
25910
|
+
export { __require, DEFAULT_SNAPSHOT_DB, DEFAULT_CONFIG_HISTORY_DIR, DeviceConfigSchema, ToolFilterSchema, MikrotikConfigSchema, getConfigSource, loadConfig, logger, setConfig, getConfig, listDevices, deviceLabels, resolveDeviceName, deviceDirectory, isMacTelnetDevice, createDeviceClient, describeTransport, isPoolEnabled, closeAll, poolStatus, executeMikrotikCommand, createContext, isEmpty, looksLikeError, commandUnsupported, parseKeyValues, parseRouterosDate, parseSize, parseSystemResource, parseRecords, parseLeadingNumber, REDACTED, redact, configureRecorder, getEventStore, subscribe, subscriberCount, registerTools, fetchDevices, sampleDeviceTraffic, sampleAllTraffic, setDeviceLimits, blockDevice, allowDevice, makeDeviceStatic, setDeviceIp, setDeviceLabel, removeDeviceLease, devicesView, PROMPTS_DIR, UI_DIST_DIR, registerUiResources, backupDir, listBackups, readBackup, writeBackup, deleteBackup, renameBackup, createLocalBackup, restoreLocalBackup, isS3Configured, getS3Client, presignExpiresIn, s3Target, splitCommands, buildChangePlan, renderPlan, diffLines, normalizeExport, openSnapshotStore, DEFAULT_TZSP_PORT, capture2 as capture, AAA_ENTITIES, listAaaEntity, addAaaEntity, updateAaaEntity, removeAaaEntity, toggleAaaEntity, getRadiusIncoming, setRadiusIncoming, resetRadiusCounters, getUmSettings, setUmSettings, moduleCatalog, allToolModules, ALWAYS_ON_MODULES, selectToolModules };
|
|
@@ -6251,7 +6251,7 @@ var cache = null;
|
|
|
6251
6251
|
async function gateway() {
|
|
6252
6252
|
if (cache)
|
|
6253
6253
|
return cache;
|
|
6254
|
-
const { moduleCatalog } = await import("./library-
|
|
6254
|
+
const { moduleCatalog } = await import("./library-98nh7hz6.js");
|
|
6255
6255
|
const forIndex = [];
|
|
6256
6256
|
const byName = new Map;
|
|
6257
6257
|
for (const mod of moduleCatalog) {
|
|
@@ -71,17 +71,17 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
71
71
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function SH(e,t){if(e){if(typeof e==`string`)return CH(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?CH(e,t):void 0}}function CH(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function wH(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function TH(e){if(Array.isArray(e))return e}function EH(e,t){if(e==null)return{};var n,r,i=DH(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function DH(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function OH(){return OH=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},OH.apply(null,arguments)}function kH(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function AH(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?kH(Object(n),!0).forEach(function(t){jH(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):kH(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function jH(e,t,n){return(t=MH(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function MH(e){var t=NH(e,`string`);return typeof t==`symbol`?t:t+``}function NH(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var PH={x:0,y:0,width:0,height:0,viewBox:{x:0,y:0,width:0,height:0},orientation:`bottom`,ticks:[],stroke:`#666`,tickLine:!0,axisLine:!0,tick:!0,mirror:!1,minTickGap:5,tickSize:6,tickMargin:2,interval:`preserveEnd`,zIndex:$x.axis};function FH(e){var t=e.x,n=e.y,r=e.width,i=e.height,a=e.orientation,o=e.mirror,s=e.axisLine,c=e.otherSvgProps;if(!s)return null;var l=AH(AH(AH({},c),Nv(s)),{},{fill:`none`});if(a===`top`||a===`bottom`){var u=+(a===`top`&&!o||a===`bottom`&&o);l=AH(AH({},l),{},{x1:t,y1:n+u*i,x2:t+r,y2:n+u*i})}else{var d=+(a===`left`&&!o||a===`right`&&o);l=AH(AH({},l),{},{x1:t+d*r,y1:n,x2:t+d*r,y2:n+i})}return v.createElement(`line`,OH({},l,{className:Y(`recharts-cartesian-axis-line`,X(s,`className`))}))}function IH(e,t,n,r,i,a,o,s,c){var l,u,d,f,p,m,h=s?-1:1,g=e.tickSize||o,_=Z(e.tickCoord)?e.tickCoord:e.coordinate;switch(a){case`top`:l=u=e.coordinate,f=n+ +!s*i,d=f-h*g,m=d-h*c,p=_;break;case`left`:d=f=e.coordinate,u=t+ +!s*r,l=u-h*g,p=l-h*c,m=_;break;case`right`:d=f=e.coordinate,u=t+ +s*r,l=u+h*g,p=l+h*c,m=_;break;default:l=u=e.coordinate,f=n+ +s*i,d=f+h*g,m=d+h*c,p=_;break}return{line:{x1:l,y1:d,x2:u,y2:f},tick:{x:p,y:m}}}function LH(e,t){switch(e){case`left`:return t?`start`:`end`;case`right`:return t?`end`:`start`;default:return`middle`}}function RH(e,t){switch(e){case`left`:case`right`:return`middle`;case`top`:return t?`start`:`end`;default:return t?`end`:`start`}}function zH(e){var t=e.option,n=e.tickProps,r=e.value,i,a=Y(n.className,`recharts-cartesian-axis-tick-value`);if(v.isValidElement(t))i=v.cloneElement(t,AH(AH({},n),{},{className:a}));else if(typeof t==`function`)i=t(AH(AH({},n),{},{className:a}));else{var o=`recharts-cartesian-axis-tick-value`;typeof t!=`boolean`&&(o=Y(o,cL(t))),i=v.createElement(VI,OH({},n,{className:o}),r)}return i}function BH(e){var t=e.ticks,n=e.axisType,r=e.axisId,i=ef();return(0,v.useEffect)(()=>r==null||n==null?tu:(i(gH({ticks:t.map(e=>({value:e.value,coordinate:e.coordinate,offset:e.offset,index:e.index})),axisId:r,axisType:n})),()=>{i(_H({axisId:r,axisType:n}))}),[i,t,r,n]),null}var VH=(0,v.forwardRef)((e,t)=>{var n=e.ticks,r=n===void 0?[]:n,i=e.tick,a=e.tickLine,o=e.stroke,s=e.tickFormatter,c=e.unit,l=e.padding,u=e.tickTextProps,d=e.orientation,f=e.mirror,p=e.x,m=e.y,h=e.width,g=e.height,_=e.tickSize,y=e.tickMargin,b=e.fontSize,x=e.letterSpacing,S=e.getTicksConfig,C=e.events,w=e.axisType,T=e.axisId,E=fH(AH(AH({},S),{},{ticks:r}),b,x),D=Nv(S),O=Pv(i),k=AI(D.textAnchor)?D.textAnchor:LH(d,f),A=RH(d,f),j={};typeof a==`object`&&(j=a);var M=AH(AH({},D),{},{fill:`none`},j),N=E.map(e=>AH({entry:e},IH(e,p,m,h,g,d,_,f,y))),P=N.map(e=>{var t=e.entry,n=e.line;return v.createElement(hF,{className:`recharts-cartesian-axis-tick`,key:`tick-${t.value}-${t.coordinate}-${t.tickCoord}`},a&&v.createElement(`line`,OH({},M,n,{className:Y(`recharts-cartesian-axis-tick-line`,X(a,`className`))})))}),F=N.map((e,t)=>{var n=e.entry,r=e.tick,a=AH(AH({},AH(AH(AH(AH({verticalAnchor:A},D),{},{textAnchor:k,stroke:`none`,fill:o},r),{},{index:t,payload:n,visibleTicksCount:E.length,tickFormatter:s,padding:l},u),{},{angle:u?.angle??D.angle??0})),O);return v.createElement(hF,OH({className:`recharts-cartesian-axis-tick-label`,key:`tick-label-${n.value}-${n.coordinate}-${n.tickCoord}`},kv(C,n,t)),i&&v.createElement(zH,{option:i,tickProps:a,value:`${typeof s==`function`?s(n.value,t):n.value}${c||``}`}))});return v.createElement(`g`,{className:`recharts-cartesian-axis-ticks recharts-${w}-ticks`},v.createElement(BH,{ticks:E,axisId:T,axisType:w}),F.length>0&&v.createElement(uP,{zIndex:$x.label},v.createElement(`g`,{className:`recharts-cartesian-axis-tick-labels recharts-${w}-tick-labels`,ref:t},F)),P.length>0&&v.createElement(`g`,{className:`recharts-cartesian-axis-tick-lines recharts-${w}-tick-lines`},P))}),HH=(0,v.forwardRef)((e,t)=>{var n=e.axisLine,r=e.width,i=e.height,a=e.className,o=e.hide,s=e.ticks,c=e.axisType,l=e.axisId,u=EH(e,yH),d=bH((0,v.useState)(``),2),f=d[0],p=d[1],m=bH((0,v.useState)(``),2),h=m[0],g=m[1],_=(0,v.useRef)(null);(0,v.useImperativeHandle)(t,()=>({getCalculatedWidth:()=>pH({ticks:_.current,label:e.labelRef?.current,labelGapWithTick:5,tickSize:e.tickSize,tickMargin:e.tickMargin})}));var y=(0,v.useCallback)(e=>{if(e){var t=e.getElementsByClassName(`recharts-cartesian-axis-tick-value`);_.current=t;var n=t[0];if(n){var r=window.getComputedStyle(n),i=r.fontSize,a=r.letterSpacing;(i!==f||a!==h)&&(p(i),g(a))}}},[f,h]);return o||r!=null&&r<=0||i!=null&&i<=0?null:v.createElement(uP,{zIndex:e.zIndex},v.createElement(hF,{className:Y(`recharts-cartesian-axis`,a)},v.createElement(FH,{x:e.x,y:e.y,width:r,height:i,orientation:e.orientation,mirror:e.mirror,axisLine:n,otherSvgProps:Nv(e)}),v.createElement(VH,{ref:y,axisType:c,events:u,fontSize:f,getTicksConfig:e,height:e.height,letterSpacing:h,mirror:e.mirror,orientation:e.orientation,padding:e.padding,stroke:e.stroke,tick:e.tick,tickFormatter:e.tickFormatter,tickLine:e.tickLine,tickMargin:e.tickMargin,tickSize:e.tickSize,tickTextProps:e.tickTextProps,ticks:s,unit:e.unit,width:e.width,x:e.x,y:e.y,axisId:l}),v.createElement(Ez,{x:e.x,y:e.y,width:e.width,height:e.height,lowerWidth:e.width,upperWidth:e.width},v.createElement(Bz,{label:e.label,labelRef:e.labelRef}),e.children)))}),UH=v.forwardRef((e,t)=>{var n=hy(e,PH);return v.createElement(HH,OH({},n,{ref:t}))});UH.displayName=`CartesianAxis`;var WH=[`x1`,`y1`,`x2`,`y2`,`key`],GH=[`offset`],KH=[`xAxisId`,`yAxisId`],qH=[`xAxisId`,`yAxisId`];function JH(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function YH(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?JH(Object(n),!0).forEach(function(t){XH(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):JH(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function XH(e,t,n){return(t=ZH(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ZH(e){var t=QH(e,`string`);return typeof t==`symbol`?t:t+``}function QH(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function $H(){return $H=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},$H.apply(null,arguments)}function eU(e,t){if(e==null)return{};var n,r,i=tU(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function tU(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var nU=e=>{var t=e.fill;if(!t||t===`none`)return null;var n=e.fillOpacity,r=e.x,i=e.y,a=e.width,o=e.height,s=e.ry;return v.createElement(`rect`,{x:r,y:i,ry:s,width:a,height:o,stroke:`none`,fill:t,fillOpacity:n,className:`recharts-cartesian-grid-bg`})};function rU(e){var t=e.option,n=e.lineItemProps,r;if(v.isValidElement(t))r=v.cloneElement(t,n);else if(typeof t==`function`)r=t(n);else{var i=n.x1,a=n.y1,o=n.x2,s=n.y2,c=n.key,l=Nv(eU(n,WH))??{};l.offset;var u=eU(l,GH);r=v.createElement(`line`,$H({},u,{x1:i,y1:a,x2:o,y2:s,fill:`none`,key:c}))}return r}function iU(e){var t=e.x,n=e.width,r=e.horizontal,i=r===void 0?!0:r,a=e.horizontalPoints;if(!i||!a||!a.length)return null;e.xAxisId,e.yAxisId;var o=eU(e,KH),s=a.map((e,r)=>{var a=YH(YH({},o),{},{x1:t,y1:e,x2:t+n,y2:e,key:`line-${r}`,index:r});return v.createElement(rU,{key:`line-${r}`,option:i,lineItemProps:a})});return v.createElement(`g`,{className:`recharts-cartesian-grid-horizontal`},s)}function aU(e){var t=e.y,n=e.height,r=e.vertical,i=r===void 0?!0:r,a=e.verticalPoints;if(!i||!a||!a.length)return null;e.xAxisId,e.yAxisId;var o=eU(e,qH),s=a.map((e,r)=>{var a=YH(YH({},o),{},{x1:e,y1:t,x2:e,y2:t+n,key:`line-${r}`,index:r});return v.createElement(rU,{option:i,lineItemProps:a,key:`line-${r}`})});return v.createElement(`g`,{className:`recharts-cartesian-grid-vertical`},s)}function oU(e){var t=e.horizontalFill,n=e.fillOpacity,r=e.x,i=e.y,a=e.width,o=e.height,s=e.horizontalPoints,c=e.horizontal;if(!(c===void 0||c)||!t||!t.length||s==null)return null;var l=s.map(e=>Math.round(e+i-i)).sort((e,t)=>e-t);i!==l[0]&&l.unshift(0);var u=l.map((e,s)=>{var c=l[s+1],u=c==null?i+o-e:c-e;if(u<=0)return null;var d=s%t.length;return v.createElement(`rect`,{key:`react-${s}`,y:e,x:r,height:u,width:a,stroke:`none`,fill:t[d],fillOpacity:n,className:`recharts-cartesian-grid-bg`})});return v.createElement(`g`,{className:`recharts-cartesian-gridstripes-horizontal`},u)}function sU(e){var t=e.vertical,n=t===void 0?!0:t,r=e.verticalFill,i=e.fillOpacity,a=e.x,o=e.y,s=e.width,c=e.height,l=e.verticalPoints;if(!n||!r||!r.length)return null;var u=l.map(e=>Math.round(e+a-a)).sort((e,t)=>e-t);a!==u[0]&&u.unshift(0);var d=u.map((e,t)=>{var n=u[t+1],l=n==null?a+s-e:n-e;if(l<=0)return null;var d=t%r.length;return v.createElement(`rect`,{key:`react-${t}`,x:e,y:o,width:l,height:c,stroke:`none`,fill:r[d],fillOpacity:i,className:`recharts-cartesian-grid-bg`})});return v.createElement(`g`,{className:`recharts-cartesian-gridstripes-vertical`},d)}var cU=(e,t)=>{var n=e.xAxis,r=e.width,i=e.height,a=e.offset;return Ag(fH(YH(YH(YH({},PH),n),{},{ticks:jg(n,!0),viewBox:{x:0,y:0,width:r,height:i}})),a.left,a.left+a.width,t)},lU=(e,t)=>{var n=e.yAxis,r=e.width,i=e.height,a=e.offset;return Ag(fH(YH(YH(YH({},PH),n),{},{ticks:jg(n,!0),viewBox:{x:0,y:0,width:r,height:i}})),a.top,a.top+a.height,t)},uU={horizontal:!0,vertical:!0,horizontalPoints:[],verticalPoints:[],stroke:`#ccc`,fill:`none`,verticalFill:[],horizontalFill:[],xAxisId:0,yAxisId:0,syncWithTicks:!1,zIndex:$x.grid};function dU(e){var t=iv(),n=av(),r=rv(),i=YH(YH({},hy(e,uU)),{},{x:Z(e.x)?e.x:r.left,y:Z(e.y)?e.y:r.top,width:Z(e.width)?e.width:r.width,height:Z(e.height)?e.height:r.height}),a=i.xAxisId,o=i.yAxisId,s=i.x,c=i.y,l=i.width,u=i.height,d=i.syncWithTicks,f=i.horizontalValues,p=i.verticalValues,m=__(),h=Q(e=>FA(e,`xAxis`,a,m)),g=Q(e=>FA(e,`yAxis`,o,m));if(!xg(l)||!xg(u)||!Z(s)||!Z(c))return null;var _=i.verticalCoordinatesGenerator||cU,y=i.horizontalCoordinatesGenerator||lU,b=i.horizontalPoints,x=i.verticalPoints;if((!b||!b.length)&&typeof y==`function`){var S=f&&f.length,C=y({yAxis:g?YH(YH({},g),{},{ticks:S?f:g.ticks}):void 0,width:t??l,height:n??u,offset:r},S?!0:d);w_(Array.isArray(C),`horizontalCoordinatesGenerator should return Array but instead it returned [${typeof C}]`),Array.isArray(C)&&(b=C)}if((!x||!x.length)&&typeof _==`function`){var w=p&&p.length,T=_({xAxis:h?YH(YH({},h),{},{ticks:w?p:h.ticks}):void 0,width:t??l,height:n??u,offset:r},w?!0:d);w_(Array.isArray(T),`verticalCoordinatesGenerator should return Array but instead it returned [${typeof T}]`),Array.isArray(T)&&(x=T)}return v.createElement(uP,{zIndex:i.zIndex},v.createElement(`g`,{className:`recharts-cartesian-grid`},v.createElement(nU,{fill:i.fill,fillOpacity:i.fillOpacity,x:i.x,y:i.y,width:i.width,height:i.height,ry:i.ry}),v.createElement(oU,$H({},i,{horizontalPoints:b})),v.createElement(sU,$H({},i,{verticalPoints:x})),v.createElement(iU,$H({},i,{offset:r,horizontalPoints:b,xAxis:h,yAxis:g})),v.createElement(aU,$H({},i,{offset:r,verticalPoints:x,xAxis:h,yAxis:g}))))}dU.displayName=`CartesianGrid`;var fU=[`points`];function pU(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function mU(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?pU(Object(n),!0).forEach(function(t){hU(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):pU(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function hU(e,t,n){return(t=gU(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function gU(e){var t=_U(e,`string`);return typeof t==`symbol`?t:t+``}function _U(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function vU(){return vU=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},vU.apply(null,arguments)}function yU(e,t){if(e==null)return{};var n,r,i=bU(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function bU(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function xU(e){var t=e.option,n=e.dotProps,r=e.className;if((0,v.isValidElement)(t))return(0,v.cloneElement)(t,n);if(typeof t==`function`)return t(n);var i=Y(r,typeof t==`boolean`?``:t.className),a=n??{};a.points;var o=yU(a,fU);return v.createElement(_F,vU({},o,{className:i}))}function SU(e,t){return e==null?!1:t?!0:e.length===1}function CU(e){var t=e.points,n=e.dot,r=e.className,i=e.dotClassName,a=e.dataKey,o=e.baseProps,s=e.needClip,c=e.clipPathId,l=e.zIndex,u=l===void 0?$x.scatter:l;if(!SU(t,n))return null;var d=YL(n),f=Zv(n),p=t.map((e,r)=>{var s=mU(mU(mU({r:3},o),f),{},{index:r,cx:e.x??void 0,cy:e.y??void 0,dataKey:a,value:e.value,payload:e.payload,points:t});return v.createElement(xU,{key:`dot-${r}`,option:n,dotProps:s,className:i})}),m={};return s&&c!=null&&(m.clipPath=`url(#clipPath-${d?``:`dots-`}${c})`),v.createElement(uP,{zIndex:u},v.createElement(hF,vU({className:r},m),p))}function wU(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function TU(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?wU(Object(n),!0).forEach(function(t){EU(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):wU(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function EU(e,t,n){return(t=DU(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function DU(e){var t=OU(e,`string`);return typeof t==`symbol`?t:t+``}function OU(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var kU=Sm({name:`cartesianAxis`,initialState:{xAxis:{},yAxis:{},zAxis:{}},reducers:{addXAxis:{reducer(e,t){e.xAxis[t.payload.id]=Wj(t.payload)},prepare:sm()},replaceXAxis:{reducer(e,t){var n=t.payload,r=n.prev,i=n.next;e.xAxis[r.id]!==void 0&&(r.id!==i.id&&delete e.xAxis[r.id],e.xAxis[i.id]=Wj(i))},prepare:sm()},removeXAxis:{reducer(e,t){delete e.xAxis[t.payload.id]},prepare:sm()},addYAxis:{reducer(e,t){e.yAxis[t.payload.id]=Wj(t.payload)},prepare:sm()},replaceYAxis:{reducer(e,t){var n=t.payload,r=n.prev,i=n.next;e.yAxis[r.id]!==void 0&&(r.id!==i.id&&delete e.yAxis[r.id],e.yAxis[i.id]=Wj(i))},prepare:sm()},removeYAxis:{reducer(e,t){delete e.yAxis[t.payload.id]},prepare:sm()},addZAxis:{reducer(e,t){e.zAxis[t.payload.id]=Wj(t.payload)},prepare:sm()},replaceZAxis:{reducer(e,t){var n=t.payload,r=n.prev,i=n.next;e.zAxis[r.id]!==void 0&&(r.id!==i.id&&delete e.zAxis[r.id],e.zAxis[i.id]=Wj(i))},prepare:sm()},removeZAxis:{reducer(e,t){delete e.zAxis[t.payload.id]},prepare:sm()},updateYAxisWidth(e,t){var n=t.payload,r=n.id,i=n.width,a=e.yAxis[r];if(a){var o=a.widthHistory||[];if(o.length===3&&o[0]===o[2]&&i===o[1]&&i!==a.width&&Math.abs(i-(o[0]??0))<=1)return;var s=[...o,i].slice(-3);e.yAxis[r]=TU(TU({},a),{},{width:i,widthHistory:s})}}}}),AU=kU.actions,jU=AU.addXAxis,MU=AU.replaceXAxis,NU=AU.removeXAxis,PU=AU.addYAxis,FU=AU.replaceYAxis,IU=AU.removeYAxis;AU.addZAxis,AU.replaceZAxis,AU.removeZAxis;var LU=AU.updateYAxisWidth,RU=kU.reducer,zU=$([$([p_],e=>({top:e.top,bottom:e.bottom,left:e.left,right:e.right})),Yg,Xg],(e,t,n)=>{if(!(!e||t==null||n==null))return{x:e.left,y:e.top,width:Math.max(0,t-e.left-e.right),height:Math.max(0,n-e.top-e.bottom)}}),BU=()=>Q(zU),VU=()=>Q(fN);function HU(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function UU(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?HU(Object(n),!0).forEach(function(t){WU(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):HU(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function WU(e,t,n){return(t=GU(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function GU(e){var t=KU(e,`string`);return typeof t==`symbol`?t:t+``}function KU(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var qU=e=>{var t=e.point,n=e.childIndex,r=e.mainColor,i=e.activeDot,a=e.dataKey,o=e.clipPath;if(i===!1||t.x==null||t.y==null)return null;var s=UU(UU(UU({},{index:n,dataKey:a,cx:t.x,cy:t.y,r:4,fill:r??`none`,strokeWidth:2,stroke:`#fff`,payload:t.payload,value:t.value}),Pv(i)),Dv(i)),c=(0,v.isValidElement)(i)?(0,v.cloneElement)(i,s):typeof i==`function`?i(s):v.createElement(_F,s);return v.createElement(hF,{className:`recharts-active-dot`,clipPath:o},c)};function JU(e){var t=e.points,n=e.mainColor,r=e.activeDot,i=e.itemDataKey,a=e.clipPath,o=e.zIndex,s=o===void 0?$x.activeDot:o,c=Q(aN),l=VU();if(t==null||l==null)return null;var u=t.find(e=>l.includes(e.payload));return Ql(u)?null:v.createElement(uP,{zIndex:s},v.createElement(qU,{point:u,childIndex:Number(c),mainColor:n,dataKey:i,activeDot:r,clipPath:a}))}function YU(e,t){var n=Q(t=>LO(t,e)),r=Q(e=>BO(e,t)),i=n?.allowDataOverflow??FO.allowDataOverflow,a=r?.allowDataOverflow??RO.allowDataOverflow;return{needClip:i||a,needClipX:i,needClipY:a}}function XU(e){var t=e.xAxisId,n=e.yAxisId,r=e.clipPathId,i=BU(),a=YU(t,n),o=a.needClipX,s=a.needClipY,c=a.needClip,l=Q(e=>uA(e,t,!1)),u=Q(e=>dA(e,n,!1));if(!c||!i)return null;var d=i.x,f=i.y,p=i.width,m=i.height,h=o&&l?Math.min(l[0],l[1]):d-p/2,g=s&&u?Math.min(u[0],u[1]):f-m/2,_=o&&l?Math.abs(l[1]-l[0]):p*2,y=s&&u?Math.abs(u[1]-u[0]):m*2;return v.createElement(`clipPath`,{id:`clipPath-${r}`},v.createElement(`rect`,{x:h,y:g,width:_,height:y}))}function ZU(e,t){return e.graphicalItems.cartesianItems.find(e=>e.id===t)?.xAxisId??0}function QU(e,t){return e.graphicalItems.cartesianItems.find(e=>e.id===t)?.yAxisId??0}var $U=(e,t,n)=>BA(e,`xAxis`,ZU(e,t),n),eW=(e,t,n)=>zA(e,`xAxis`,ZU(e,t),n),tW=(e,t,n)=>BA(e,`yAxis`,QU(e,t),n),nW=(e,t,n)=>zA(e,`yAxis`,QU(e,t),n),rW=$([ov,$U,tW,eW,nW],(e,t,n,r,i)=>kg(e,`xAxis`)?Wg(t,r,!1):Wg(n,i,!1)),iW=$([JO,(e,t)=>t],(e,t)=>e.filter(e=>e.type===`area`).find(e=>e.id===t)),aW=e=>kg(ov(e),`xAxis`)?`yAxis`:`xAxis`,oW=(e,t)=>aW(e)===`yAxis`?QU(e,t):ZU(e,t),sW=$([ov,$U,tW,eW,nW,$([iW,(e,t,n)=>bk(e,aW(e),oW(e,t),n)],(e,t)=>{if(!(e==null||t==null)){var n=e.stackId,r=wS(e);if(!(n==null||r==null)){var i=(t[n]?.stackedData)?.find(e=>e.key===r);if(i!=null)return i.map(e=>[e[0],e[1]])}}}),fx,rW,iW,Qx],(e,t,n,r,i,a,o,s,c,l)=>{var u=o.chartData,d=o.dataStartIndex,f=o.dataEndIndex;if(!(c==null||e!==`horizontal`&&e!==`vertical`||t==null||n==null||r==null||i==null||r.length===0||i.length===0||s==null)){var p=c.data,m=p&&p.length>0?p:u?.slice(d,f+1);if(m!=null)return oG({layout:e,xAxis:t,yAxis:n,xAxisTicks:r,yAxisTicks:i,dataStartIndex:d,areaSettings:c,stackedData:a,displayedData:m,chartBaseValue:l,bandSize:s})}});function cW(e){var t=Pv(e),n=3,r=2;if(t!=null){var i=t.r,a=t.strokeWidth,o=Number(i),s=Number(a);return(Number.isNaN(o)||o<0)&&(o=n),(Number.isNaN(s)||s<0)&&(s=r),{r:o,strokeWidth:s}}return{r:n,strokeWidth:r}}var lW=o((e=>{var t=d();t.useSyncExternalStore,t.useRef,t.useEffect,t.useMemo,t.useDebugValue}));o(((e,t)=>{t.exports=lW()}))();function uW(e){e()}function dW(){let e=null,t=null;return{clear(){e=null,t=null},notify(){uW(()=>{let t=e;for(;t;)t.callback(),t=t.next})},get(){let t=[],n=e;for(;n;)t.push(n),n=n.next;return t},subscribe(n){let r=!0,i=t={callback:n,next:null,prev:t};return i.prev?i.prev.next=i:e=i,function(){!r||e===null||(r=!1,i.next?i.next.prev=i.prev:t=i.prev,i.prev?i.prev.next=i.next:e=i.next)}}}}var fW={notify(){},get:()=>[]};function pW(e,t){let n,r=fW,i=0,a=!1;function o(e){u();let t=r.subscribe(e),n=!1;return()=>{n||(n=!0,t(),d())}}function s(){r.notify()}function c(){m.onStateChange&&m.onStateChange()}function l(){return a}function u(){i++,n||(n=t?t.addNestedSub(c):e.subscribe(c),r=dW())}function d(){i--,n&&i===0&&(n(),n=void 0,r.clear(),r=fW)}function f(){a||(a=!0,u())}function p(){a&&(a=!1,d())}let m={addNestedSub:o,notifyNestedSubs:s,handleChangeWrapper:c,isSubscribed:l,trySubscribe:f,tryUnsubscribe:p,getListeners:()=>r};return m}var mW=typeof window<`u`&&window.document!==void 0&&window.document.createElement!==void 0,hW=typeof navigator<`u`&&navigator.product===`ReactNative`,gW=mW||hW?v.useLayoutEffect:v.useEffect;function _W(e,t){return e===t?e!==0||t!==0||1/e==1/t:e!==e&&t!==t}function vW(e,t){if(_W(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let r=0;r<n.length;r++)if(!Object.prototype.hasOwnProperty.call(t,n[r])||!_W(e[n[r]],t[n[r]]))return!1;return!0}var yW=Symbol.for(`react-redux-context`),bW=typeof globalThis<`u`?globalThis:{};function xW(){if(!v.createContext)return{};let e=bW[yW]??=new Map,t=e.get(v.createContext);return t||(t=v.createContext(null),e.set(v.createContext,t)),t}var SW=xW();function CW(e){let{children:t,context:n,serverState:r,store:i}=e,a=v.useMemo(()=>({store:i,subscription:pW(i),getServerState:r?()=>r:void 0}),[i,r]),o=v.useMemo(()=>i.getState(),[i]);gW(()=>{let{subscription:e}=a;return e.onStateChange=e.notifyNestedSubs,e.trySubscribe(),o!==i.getState()&&e.notifyNestedSubs(),()=>{e.tryUnsubscribe(),e.onStateChange=void 0}},[a,o]);let s=n||SW;return v.createElement(s.Provider,{value:a},t)}var wW=CW,TW=new Set([`axisLine`,`tickLine`,`activeBar`,`activeDot`,`activeLabel`,`activeShape`,`allowEscapeViewBox`,`background`,`cursor`,`dot`,`label`,`line`,`margin`,`padding`,`position`,`shape`,`style`,`tick`,`wrapperStyle`,`radius`,`throttledEvents`]);function EW(e,t){return e==null&&t==null?!0:typeof e==`number`&&typeof t==`number`?e===t||e!==e&&t!==t:e===t}function DW(e,t){for(var n of new Set([...Object.keys(e),...Object.keys(t)]))if(TW.has(n)){if(e[n]==null&&t[n]==null)continue;if(!vW(e[n],t[n]))return!1}else if(!EW(e[n],t[n]))return!1;return!0}var OW=[`animationElapsedTime`,`isAnimating`,`isEntrance`,`layout`,`isRange`,`stroke`,`connectNulls`],kW=[`id`,`baseLine`];function AW(){return AW=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},AW.apply(null,arguments)}function jW(e,t){if(e==null)return{};var n,r,i=MW(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function MW(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function NW(e){var t=e.alpha,n=e.baseLine,r=e.points,i=e.strokeWidth,a=r[0]?.x,o=r[r.length-1]?.x;if(!bg(a)||!bg(o))return null;var s=t*Math.abs(a-o),c=Math.max(...r.map(e=>e.y||0));return Z(n)?c=Math.max(n,c):n&&Array.isArray(n)&&n.length&&(c=Math.max(...n.map(e=>e.y||0),c)),Z(c)?v.createElement(`rect`,{x:a<o?a:a-s,y:0,width:s,height:Math.floor(c+(i?parseInt(`${i}`,10):1))}):null}function PW(e){var t=e.alpha,n=e.baseLine,r=e.points,i=e.strokeWidth,a=r[0]?.y,o=r[r.length-1]?.y;if(!bg(a)||!bg(o))return null;var s=t*Math.abs(a-o),c=Math.max(...r.map(e=>e.x||0));return Z(n)?c=Math.max(n,c):n&&Array.isArray(n)&&n.length&&(c=Math.max(...n.map(e=>e.x||0),c)),Z(c)?v.createElement(`rect`,{x:0,y:a<o?a:a-s,width:c+(i?parseInt(`${i}`,10):1),height:Math.floor(s)}):null}function FW(e){var t=e.alpha,n=e.layout,r=e.points,i=e.baseLine,a=e.strokeWidth;return n===`vertical`?v.createElement(PW,{alpha:t,points:r,baseLine:i,strokeWidth:a}):v.createElement(NW,{alpha:t,points:r,baseLine:i,strokeWidth:a})}function IW(e){var t=e.animationElapsedTime,n=t===void 0?1:t,r=e.isAnimating,i=r===void 0?!1:r,a=e.isEntrance,o=a===void 0?!1:a,s=e.layout,c=e.isRange,l=e.stroke,u=e.connectNulls,d=jW(e,OW),f=s===`vertical`?`vertical`:`horizontal`,p=u??!1,m=JR(),h=d.id,g=d.baseLine,_=Nv(jW(d,kW)),y=v.createElement(Yv,AW({},d,{id:h,baseLine:g,connectNulls:p,stroke:`none`,className:`recharts-area-area`,layout:f})),b=l!==`none`&&v.createElement(Yv,AW({},_,{className:`recharts-area-curve`,layout:f,type:d.type,connectNulls:p,fill:`none`,stroke:l,points:d.points})),x=l!==`none`&&c&&Array.isArray(g)&&v.createElement(Yv,AW({},_,{className:`recharts-area-curve`,layout:f,type:d.type,connectNulls:p,fill:`none`,stroke:l,points:g}));return o&&(i||n<1)?v.createElement(hF,null,v.createElement(`defs`,null,v.createElement(`clipPath`,{id:m},v.createElement(FW,{alpha:n,points:d.points??[],baseLine:g,layout:f,strokeWidth:d.strokeWidth}))),v.createElement(hF,{clipPath:`url(#${m})`},y,b,x)):v.createElement(v.Fragment,null,y,b,x)}var LW=[`id`],RW=[`activeDot`,`animationBegin`,`animationDuration`,`animationEasing`,`connectNulls`,`dot`,`fill`,`fillOpacity`,`hide`,`isAnimationActive`,`legendType`,`stroke`,`xAxisId`,`yAxisId`];function zW(){return zW=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},zW.apply(null,arguments)}function BW(e,t){if(e==null)return{};var n,r,i=VW(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function VW(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function HW(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function UW(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?HW(Object(n),!0).forEach(function(t){WW(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):HW(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function WW(e,t,n){return(t=GW(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function GW(e){var t=KW(e,`string`);return typeof t==`symbol`?t:t+``}function KW(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var qW={activeDot:!0,animationBegin:0,animationDuration:1500,animationEasing:`ease`,animationMatchBy:TR,animationInterpolateFn:(e,t)=>e==null?[]:t===1?e.flatMap(e=>e.status===`removed`?[]:[e.next]):e.flatMap(e=>e.status===`matched`?[UW(UW({},e.next),{},{x:Xl(e.prev.x,e.next.x,t),y:Xl(e.prev.y,e.next.y,t)})]:e.status===`added`?[e.next]:[]),connectNulls:!1,dot:!1,fill:`#3182bd`,fillOpacity:.6,hide:!1,isAnimationActive:`auto`,legendType:`line`,stroke:`#3182bd`,strokeWidth:1,type:`linear`,label:!1,shape:IW,xAxisId:0,yAxisId:0,zIndex:$x.area};function JW(e,t){return e&&e!==`none`?e:t}var YW=e=>{var t=e.dataKey,n=e.name,r=e.stroke,i=e.fill,a=e.legendType;return[{inactive:e.hide,dataKey:t,type:a,color:JW(r,i),value:Kg(n,t),payload:e}]},XW=v.memo(e=>{var t=e.dataKey,n=e.data,r=e.stroke,i=e.strokeWidth,a=e.fill,o=e.name,s=e.hide,c=e.unit,l=e.tooltipType,u=e.id,d={dataDefinedOnItem:n,getPosition:tu,settings:{stroke:r,strokeWidth:i,fill:a,dataKey:t,nameKey:void 0,name:Kg(o,t),hide:s,type:l,color:JW(r,a),unit:c,graphicalItemId:u}};return v.createElement(uR,{tooltipEntrySettings:d})});function ZW(e){var t=e.clipPathId,n=e.points,r=e.props,i=r.needClip,a=r.dot,o=r.dataKey,s=Nv(r);return v.createElement(CU,{points:n,dot:a,className:`recharts-area-dots`,dotClassName:`recharts-area-dot`,dataKey:o,baseProps:s,needClip:i,clipPathId:t})}function QW(e){var t=e.showLabels,n=e.children,r=e.points.map(e=>{var t={x:e.x??0,y:e.y??0,width:0,lowerWidth:0,upperWidth:0,height:0};return UW(UW({},t),{},{value:e.value,payload:e.payload,parentViewBox:void 0,viewBox:t,fill:void 0})});return v.createElement(Jz,{value:t?r:void 0},n)}function $W(e){var t=e.points,n=e.baseLine,r=e.needClip,i=e.clipPathId,a=e.props,o=e.animationElapsedTime,s=e.isAnimating,c=e.isEntrance,l=a.layout,u=a.type,d=a.stroke,f=a.connectNulls,p=a.isRange,m=a.shape,h=a.id,g=BW(a,LW),_=UW(UW({},Xv(g)),{},{id:h,points:t,connectNulls:f,type:u,baseLine:n,layout:l,stroke:d,isRange:p,animationElapsedTime:o,isAnimating:s,isEntrance:c});return v.createElement(v.Fragment,null,t?.length>1&&v.createElement(hF,{clipPath:r?`url(#clipPath-${i})`:void 0},v.createElement(oR,{option:m,DefaultShape:qW.shape,shapeProps:_})),v.createElement(ZW,{points:t,props:g,clipPathId:i}))}function eG(e,t,n){return Z(e)?Xl(Z(t)?t:void 0,e,n):Ql(e)||Ul(e)?Xl(Z(t)?t:void 0,0,n):e}function tG(e){var t=e.needClip,n=e.clipPathId,r=e.props,i=e.previousPointsRef,a=e.previousBaselineRef,o=r.points,s=r.baseLine,c=r.isAnimationActive,l=r.animationBegin,u=r.animationDuration,d=r.animationEasing,f=r.animationMatchBy,p=r.animationInterpolateFn,m=(0,v.useMemo)(()=>({points:o,baseLine:s}),[o,s]),h=NR(m,a),g=cv(),_=BR(r.onAnimationStart,r.onAnimationEnd),y=_.isAnimating,b=_.handleAnimationStart,x=_.handleAnimationEnd,S=h.startValue;if(g==null)return null;var C=Array.isArray(s)&&Array.isArray(S)?MR(S,s,f):Array.isArray(s)?MR(null,s,f):null;return v.createElement(VR,{animationInput:m,animationIdPrefix:`recharts-area-`,items:o,previousItemsRef:i,isAnimationActive:c,animationBegin:l,animationDuration:u,animationEasing:d,onAnimationStart:b,onAnimationEnd:x,animationInterpolateFn:p,animationMatchBy:f,layout:g},(e,i,a)=>{var c=i===1?s:Array.isArray(s)?p(C,i,g):a?s:eG(s,S,i);return h.syncStepValue(c,i),v.createElement(QW,{showLabels:!y,points:o},r.children,v.createElement($W,{points:e,baseLine:c,needClip:t,clipPathId:n,props:r,animationElapsedTime:i,isAnimating:y||i<1,isEntrance:a}),v.createElement(eB,{label:r.label}))})}function nG(e){var t=e.needClip,n=e.clipPathId,r=e.props,i=(0,v.useRef)(null),a=(0,v.useRef)();return v.createElement(tG,{needClip:t,clipPathId:n,props:r,previousPointsRef:i,previousBaselineRef:a})}var rG=class extends v.PureComponent{render(){var e=this.props,t=e.hide,n=e.dot,r=e.points,i=e.className,a=e.top,o=e.left,s=e.needClip,c=e.xAxisId,l=e.yAxisId,u=e.width,d=e.height,f=e.id,p=e.baseLine,m=e.zIndex;if(t)return null;var h=Y(`recharts-area`,i),g=f,_=cW(n),y=_.r,b=_.strokeWidth,x=YL(n),S=y*2+b,C=s?`url(#clipPath-${x?``:`dots-`}${g})`:void 0;return v.createElement(uP,{zIndex:m},v.createElement(hF,{className:h},s&&v.createElement(`defs`,null,v.createElement(XU,{clipPathId:g,xAxisId:c,yAxisId:l}),!x&&v.createElement(`clipPath`,{id:`clipPath-dots-${g}`},v.createElement(`rect`,{x:o-S/2,y:a-S/2,width:u+S,height:d+S}))),v.createElement(nG,{needClip:s,clipPathId:g,props:this.props})),v.createElement(JU,{points:r,mainColor:JW(this.props.stroke,this.props.fill),itemDataKey:this.props.dataKey,activeDot:this.props.activeDot,clipPath:C}),this.props.isRange&&Array.isArray(p)&&v.createElement(JU,{points:p,mainColor:JW(this.props.stroke,this.props.fill),itemDataKey:this.props.dataKey,activeDot:this.props.activeDot,clipPath:C}))}};function iG(e){var t=e.activeDot,n=e.animationBegin,r=e.animationDuration,i=e.animationEasing,a=e.connectNulls,o=e.dot,s=e.fill,c=e.fillOpacity,l=e.hide,u=e.isAnimationActive,d=e.legendType,f=e.stroke,p=e.xAxisId,m=e.yAxisId,h=BW(e,RW),g=sv(),_=kN(),y=YU(p,m).needClip,b=__(),x=Q(t=>sW(t,e.id,b))??{},S=x.points,C=x.isRange,w=x.baseLine,T=BU();if(g!==`horizontal`&&g!==`vertical`||T==null||_!==`AreaChart`&&_!==`ComposedChart`)return null;var E=T.height,D=T.width,O=T.x,k=T.y;return!S||!S.length?null:v.createElement(rG,zW({},h,{activeDot:t,animationBegin:n,animationDuration:r,animationEasing:i,baseLine:w,connectNulls:a,dot:o,fill:s,fillOpacity:c,height:E,hide:l,layout:g,isAnimationActive:u,isRange:C,legendType:d,needClip:y,points:S,stroke:f,width:D,left:O,top:k,xAxisId:p,yAxisId:m}))}var aG=(e,t,n,r,i)=>{var a=n??t;if(Z(a))return a;var o=e===`horizontal`?i:r,s=o.scale.domain();if(o.type===`number`){var c=Math.max(s[0],s[1]),l=Math.min(s[0],s[1]);return a===`dataMin`?l:a===`dataMax`||c<0?c:Math.max(Math.min(s[0],s[1]),0)}return a===`dataMin`?s[0]:a===`dataMax`?s[1]:s[0]};function oG(e){var t=e.areaSettings,n=t.connectNulls,r=t.baseValue,i=t.dataKey,a=e.stackedData,o=e.layout,s=e.chartBaseValue,c=e.xAxis,l=e.yAxis,u=e.displayedData,d=e.dataStartIndex,f=e.xAxisTicks,p=e.yAxisTicks,m=e.bandSize,h=a&&a.length,g=aG(o,s,r,c,l),_=o===`horizontal`,v=!1,y=u.map((e,t)=>{var r;if(h)r=a[d+t];else{var o=Dg(e,i);Array.isArray(o)?(r=o,v=!0):r=[g,o]}var s=r?.[1]??null,u=s==null||h&&!n&&Dg(e,i)==null;return _?{x:Ig({axis:c,ticks:f,bandSize:m,entry:e,index:t}),y:u?null:l.scale.map(s)??null,value:r,payload:e}:{x:u?null:c.scale.map(s)??null,y:Ig({axis:l,ticks:p,bandSize:m,entry:e,index:t}),value:r,payload:e}});return{points:y,baseLine:(h||v?y.map(e=>{var t=Array.isArray(e.value)?e.value[0]:null;return _?{x:e.x,y:t!=null&&e.y!=null?l.scale.map(t)??null:null,payload:e.payload}:{x:t==null?null:c.scale.map(t)??null,y:e.y,payload:e.payload}}):_?l.scale.map(g):c.scale.map(g))??0,isRange:v}}function sG(e){var t=hy(e,qW),n=__();return v.createElement(ZR,{id:t.id,type:`area`},e=>v.createElement(v.Fragment,null,v.createElement(_R,{legendPayload:YW(t)}),v.createElement(XW,{dataKey:t.dataKey,data:t.data,stroke:t.stroke,strokeWidth:t.strokeWidth,fill:t.fill,name:t.name,hide:t.hide,unit:t.unit,tooltipType:t.tooltipType,id:e}),v.createElement(sz,{type:`area`,id:e,data:t.data,dataKey:t.dataKey,xAxisId:t.xAxisId,yAxisId:t.yAxisId,zAxisId:0,stackId:Fg(t.stackId),hide:t.hide,barSize:void 0,baseValue:t.baseValue,isPanorama:n,connectNulls:t.connectNulls}),v.createElement(iG,zW({},t,{id:e}))))}var cG=v.memo(sG,DW);cG.displayName=`Area`;var lG=[`domain`,`range`],uG=[`domain`,`range`];function dG(e,t){if(e==null)return{};var n,r,i=fG(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function fG(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function pG(e,t){return e===t?!0:Array.isArray(e)&&e.length===2&&Array.isArray(t)&&t.length===2?e[0]===t[0]&&e[1]===t[1]:!1}function mG(e,t){if(e===t)return!0;var n=e.domain,r=e.range,i=dG(e,lG),a=t.domain,o=t.range,s=dG(t,uG);return!pG(n,a)||!pG(r,o)?!1:DW(i,s)}var hG=[`type`],gG=[`dangerouslySetInnerHTML`,`ticks`,`scale`],_G=[`id`,`scale`];function vG(){return vG=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},vG.apply(null,arguments)}function yG(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function bG(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?yG(Object(n),!0).forEach(function(t){xG(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):yG(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function xG(e,t,n){return(t=SG(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function SG(e){var t=CG(e,`string`);return typeof t==`symbol`?t:t+``}function CG(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function wG(e,t){if(e==null)return{};var n,r,i=TG(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function TG(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function EG(e){var t=ef(),n=(0,v.useRef)(null),r=cv(),i=e.type,a=wG(e,hG),o=rS(r,`xAxis`,i),s=(0,v.useMemo)(()=>{if(o!=null)return bG(bG({},a),{},{type:o})},[a,o]);return(0,v.useLayoutEffect)(()=>{s!=null&&(n.current===null?t(jU(s)):n.current!==s&&t(MU({prev:n.current,next:s})),n.current=s)},[s,t]),(0,v.useLayoutEffect)(()=>()=>{n.current&&=(t(NU(n.current)),null)},[t]),null}var DG=e=>{var t=e.xAxisId,n=e.className,r=Q(h_),i=__(),a=`xAxis`,o=Q(e=>LA(e,a,t,i)),s=Q(e=>TA(e,t)),c=Q(e=>AA(e,t)),l=Q(e=>IO(e,t));if(s==null||c==null||l==null)return null;e.dangerouslySetInnerHTML,e.ticks,e.scale;var u=wG(e,gG);l.id,l.scale;var d=wG(l,_G);return v.createElement(UH,vG({},u,d,{x:c.x,y:c.y,width:s.width,height:s.height,className:Y(`recharts-${a} ${a}`,n),viewBox:r,ticks:o,axisType:a,axisId:t}))},OG={allowDataOverflow:FO.allowDataOverflow,allowDecimals:FO.allowDecimals,allowDuplicatedCategory:FO.allowDuplicatedCategory,angle:FO.angle,axisLine:PH.axisLine,height:FO.height,hide:!1,includeHidden:FO.includeHidden,interval:FO.interval,label:!1,minTickGap:FO.minTickGap,mirror:FO.mirror,orientation:FO.orientation,padding:FO.padding,reversed:FO.reversed,scale:FO.scale,tick:FO.tick,tickCount:FO.tickCount,tickLine:PH.tickLine,tickSize:PH.tickSize,type:FO.type,niceTicks:FO.niceTicks,xAxisId:0},kG=v.memo(e=>{var t=hy(e,OG);return v.createElement(v.Fragment,null,v.createElement(EG,{allowDataOverflow:t.allowDataOverflow,allowDecimals:t.allowDecimals,allowDuplicatedCategory:t.allowDuplicatedCategory,angle:t.angle,dataKey:t.dataKey,domain:t.domain,height:t.height,hide:t.hide,id:t.xAxisId,includeHidden:t.includeHidden,interval:t.interval,minTickGap:t.minTickGap,mirror:t.mirror,name:t.name,orientation:t.orientation,padding:t.padding,reversed:t.reversed,scale:t.scale,tick:t.tick,tickCount:t.tickCount,tickFormatter:t.tickFormatter,ticks:t.ticks,type:t.type,unit:t.unit,niceTicks:t.niceTicks}),v.createElement(DG,t))},mG);kG.displayName=`XAxis`;var AG=[`type`],jG=[`dangerouslySetInnerHTML`,`ticks`,`scale`],MG=[`id`,`scale`];function NG(){return NG=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},NG.apply(null,arguments)}function PG(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function FG(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?PG(Object(n),!0).forEach(function(t){IG(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):PG(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function IG(e,t,n){return(t=LG(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function LG(e){var t=RG(e,`string`);return typeof t==`symbol`?t:t+``}function RG(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function zG(e,t){if(e==null)return{};var n,r,i=BG(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function BG(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function VG(e){var t=ef(),n=(0,v.useRef)(null),r=cv(),i=e.type,a=zG(e,AG),o=rS(r,`yAxis`,i),s=(0,v.useMemo)(()=>{if(o!=null)return FG(FG({},a),{},{type:o})},[o,a]);return(0,v.useLayoutEffect)(()=>{s!=null&&(n.current===null?t(PU(s)):n.current!==s&&t(FU({prev:n.current,next:s})),n.current=s)},[s,t]),(0,v.useLayoutEffect)(()=>()=>{n.current&&=(t(IU(n.current)),null)},[t]),null}function HG(e){var t=e.yAxisId,n=e.className,r=e.width,i=e.label,a=(0,v.useRef)(null),o=(0,v.useRef)(null),s=Q(h_),c=__(),l=ef(),u=`yAxis`,d=Q(e=>MA(e,t)),f=Q(e=>jA(e,t)),p=Q(e=>LA(e,u,t,c)),m=Q(e=>zO(e,t));if((0,v.useLayoutEffect)(()=>{if(!(r!==`auto`||!d||jz(i)||(0,v.isValidElement)(i)||m==null)){var e=a.current;if(e){var n=e.getCalculatedWidth();Math.round(d.width)!==Math.round(n)&&l(LU({id:t,width:n}))}}},[p,d,l,i,t,r,m]),d==null||f==null||m==null)return null;e.dangerouslySetInnerHTML,e.ticks,e.scale;var h=zG(e,jG);m.id,m.scale;var g=zG(m,MG);return v.createElement(UH,NG({},h,g,{ref:a,labelRef:o,x:f.x,y:f.y,tickTextProps:r===`auto`?{width:void 0}:{width:r},width:d.width,height:d.height,className:Y(`recharts-${u} ${u}`,n),viewBox:s,ticks:p,axisType:u,axisId:t}))}var UG={allowDataOverflow:RO.allowDataOverflow,allowDecimals:RO.allowDecimals,allowDuplicatedCategory:RO.allowDuplicatedCategory,angle:RO.angle,axisLine:PH.axisLine,hide:!1,includeHidden:RO.includeHidden,interval:RO.interval,label:!1,minTickGap:RO.minTickGap,mirror:RO.mirror,orientation:RO.orientation,padding:RO.padding,reversed:RO.reversed,scale:RO.scale,tick:RO.tick,tickCount:RO.tickCount,tickLine:PH.tickLine,tickSize:PH.tickSize,type:RO.type,niceTicks:RO.niceTicks,width:RO.width,yAxisId:0},WG=v.memo(e=>{var t=hy(e,UG);return v.createElement(v.Fragment,null,v.createElement(VG,{interval:t.interval,id:t.yAxisId,scale:t.scale,type:t.type,domain:t.domain,allowDataOverflow:t.allowDataOverflow,dataKey:t.dataKey,allowDuplicatedCategory:t.allowDuplicatedCategory,allowDecimals:t.allowDecimals,tickCount:t.tickCount,padding:t.padding,includeHidden:t.includeHidden,reversed:t.reversed,ticks:t.ticks,width:t.width,orientation:t.orientation,mirror:t.mirror,hide:t.hide,unit:t.unit,name:t.name,angle:t.angle,minTickGap:t.minTickGap,tick:t.tick,tickFormatter:t.tickFormatter,niceTicks:t.niceTicks}),v.createElement(HG,t))},mG);WG.displayName=`YAxis`;var GG=$([(e,t)=>t,ov,xS,AS,QM,eN,NN,p_],GN);function KG(e){return`getBBox`in e.currentTarget&&typeof e.currentTarget.getBBox==`function`}function qG(e){var t=e.currentTarget.getBoundingClientRect(),n,r;if(KG(e)){var i=e.currentTarget.getBBox();n=i.width>0?t.width/i.width:1,r=i.height>0?t.height/i.height:1}else{var a=e.currentTarget;n=a.offsetWidth>0?t.width/a.offsetWidth:1,r=a.offsetHeight>0?t.height/a.offsetHeight:1}var o=(e,i)=>({relativeX:Math.round((e-t.left)/n),relativeY:Math.round((i-t.top)/r)});return`touches`in e?Array.from(e.touches).map(e=>o(e.clientX,e.clientY)):o(e.clientX,e.clientY)}var JG=em(`mouseClick`),YG=ch();YG.startListening({actionCreator:JG,effect:(e,t)=>{var n=e.payload,r=GG(t.getState(),qG(n));r?.activeIndex!=null&&t.dispatch(rM({activeIndex:r.activeIndex,activeDataKey:void 0,activeCoordinate:r.activeCoordinate}))}});var XG=em(`mouseMove`),ZG=ch(),QG=null,$G=null,eK=null;ZG.startListening({actionCreator:XG,effect:(e,t)=>{var n=e.payload,r=t.getState().eventSettings,i=r.throttleDelay,a=r.throttledEvents,o=a===`all`||a?.includes(`mousemove`);QG!==null&&(cancelAnimationFrame(QG),QG=null),$G!==null&&(typeof i!=`number`||!o)&&(clearTimeout($G),$G=null),eK=qG(n);var s=()=>{var e=t.getState(),n=GA(e,e.tooltip.settings.shared);if(!eK){QG=null,$G=null;return}if(n===`axis`){var r=GG(e,eK);r?.activeIndex==null?t.dispatch(eM()):t.dispatch(nM({activeIndex:r.activeIndex,activeDataKey:void 0,activeCoordinate:r.activeCoordinate}))}QG=null,$G=null};if(!o){s();return}i===`raf`?QG=requestAnimationFrame(s):typeof i==`number`&&$G===null&&($G=setTimeout(s,i))}});function tK(e,t){return t instanceof HTMLElement?`HTMLElement <${t.tagName} class="${t.className}">`:t===window?`global.window`:e===`children`&&typeof t==`object`&&t?`<<CHILDREN>>`:t}var nK=Sm({name:`referenceElements`,initialState:{dots:[],areas:[],lines:[]},reducers:{addDot:(e,t)=>{e.dots.push(t.payload)},removeDot:(e,t)=>{var n=Pp(e).dots.findIndex(e=>e===t.payload);n!==-1&&e.dots.splice(n,1)},addArea:(e,t)=>{e.areas.push(t.payload)},removeArea:(e,t)=>{var n=Pp(e).areas.findIndex(e=>e===t.payload);n!==-1&&e.areas.splice(n,1)},addLine:(e,t)=>{e.lines.push(Wj(t.payload))},removeLine:(e,t)=>{var n=Pp(e).lines.findIndex(e=>e===t.payload);n!==-1&&e.lines.splice(n,1)}}}),rK=nK.actions;rK.addDot,rK.removeDot,rK.addArea,rK.removeArea,rK.addLine,rK.removeLine;var iK=nK.reducer,aK={x:0,y:0,width:0,height:0,padding:{top:0,right:0,bottom:0,left:0}},oK=Sm({name:`brush`,initialState:aK,reducers:{setBrushSettings(e,t){return t.payload==null?aK:t.payload}}});oK.actions.setBrushSettings;var sK=oK.reducer,cK={accessibilityLayer:!0,barCategoryGap:`10%`,barGap:4,barSize:void 0,className:void 0,maxBarSize:void 0,stackOffset:`none`,syncId:void 0,syncMethod:`index`,baseValue:void 0,reverseStackOrder:!1},lK=Sm({name:`rootProps`,initialState:cK,reducers:{updateOptions:(e,t)=>{e.accessibilityLayer=t.payload.accessibilityLayer,e.barCategoryGap=t.payload.barCategoryGap,e.barGap=t.payload.barGap??cK.barGap,e.barSize=t.payload.barSize,e.maxBarSize=t.payload.maxBarSize,e.stackOffset=t.payload.stackOffset,e.syncId=t.payload.syncId,e.syncMethod=t.payload.syncMethod,e.className=t.payload.className,e.baseValue=t.payload.baseValue,e.reverseStackOrder=t.payload.reverseStackOrder}}}),uK=lK.reducer,dK=lK.actions.updateOptions,fK=Sm({name:`polarOptions`,initialState:null,reducers:{updatePolarOptions:(e,t)=>e===null?t.payload:(e.startAngle=t.payload.startAngle,e.endAngle=t.payload.endAngle,e.cx=t.payload.cx,e.cy=t.payload.cy,e.innerRadius=t.payload.innerRadius,e.outerRadius=t.payload.outerRadius,e)}}),pK=fK.actions.updatePolarOptions,mK=fK.reducer,hK=em(`keyDown`),gK=em(`focus`),_K=em(`blur`),vK=ch(),yK=null,bK=null,xK=null;vK.startListening({actionCreator:hK,effect:(e,t)=>{xK=e.payload,yK!==null&&(cancelAnimationFrame(yK),yK=null);var n=t.getState().eventSettings,r=n.throttleDelay,i=n.throttledEvents,a=i===`all`||i.includes(`keydown`);bK!==null&&(typeof r!=`number`||!a)&&(clearTimeout(bK),bK=null);var o=()=>{try{var e=t.getState();if(e.rootProps.accessibilityLayer===!1)return;var n=e.tooltip.keyboardInteraction,r=xK;if(r!==`ArrowRight`&&r!==`ArrowLeft`&&r!==`Enter`)return;var i=vM(n,BM(e),_k(e),YM(e)),a=i==null?-1:Number(i),o=!Number.isFinite(a)||a<0,s=eN(e),c=BM(e),l=GA(e,e.tooltip.settings.shared);if(r===`Enter`){if(o)return;var u=RN(e,l,`hover`,String(n.index));t.dispatch(aM({active:!n.active,activeIndex:n.index,activeCoordinate:u}));return}var d=VA(e)===`left-to-right`?1:-1,f=r===`ArrowRight`?1:-1,p;if(o){var m=_k(e),h=YM(e),g=f*d,_=e=>({active:!1,index:String(e),dataKey:void 0,graphicalItemId:void 0,coordinate:void 0});if(p=-1,g>0){for(var v=0;v<c.length;v++)if(vM(_(v),c,m,h)!=null){p=v;break}}else for(var y=c.length-1;y>=0;y--)if(vM(_(y),c,m,h)!=null){p=y;break}if(p<0)return}else{p=a+f*d;var b=s?.length||c.length;if(b===0||p>=b||p<0)return}var x=RN(e,l,`hover`,String(p));t.dispatch(aM({active:!0,activeIndex:p.toString(),activeCoordinate:x}))}finally{yK=null,bK=null}};if(!a){o();return}r===`raf`?yK=requestAnimationFrame(o):typeof r==`number`&&bK===null&&(o(),xK=null,bK=setTimeout(()=>{xK?o():(bK=null,yK=null)},r))}}),vK.startListening({actionCreator:gK,effect:(e,t)=>{var n=t.getState();if(n.rootProps.accessibilityLayer!==!1){var r=n.tooltip.keyboardInteraction;if(!r.active&&r.index==null){var i=`0`,a=RN(n,GA(n,n.tooltip.settings.shared),`hover`,String(i));t.dispatch(aM({active:!0,activeIndex:i,activeCoordinate:a}))}}}}),vK.startListening({actionCreator:_K,effect:(e,t)=>{var n=t.getState();if(n.rootProps.accessibilityLayer!==!1){var r=n.tooltip.keyboardInteraction;r.active&&t.dispatch(aM({active:!1,activeIndex:r.index,activeCoordinate:r.coordinate}))}}});function SK(e){e.persist();var t=e.currentTarget;return new Proxy(e,{get:(e,n)=>{if(n===`currentTarget`)return t;var r=Reflect.get(e,n);return typeof r==`function`?r.bind(e):r}})}var CK=em(`externalEvent`),wK=ch(),TK=new Map,EK=new Map,DK=new Map;wK.startListening({actionCreator:CK,effect:(e,t)=>{var n=e.payload,r=n.handler,i=n.reactEvent;if(r!=null){var a=i.type,o=SK(i);DK.set(a,{handler:r,reactEvent:o});var s=TK.get(a);s!==void 0&&(cancelAnimationFrame(s),TK.delete(a));var c=t.getState().eventSettings,l=c.throttleDelay,u=c.throttledEvents,d=u===`all`||u?.includes(a),f=EK.get(a);f!==void 0&&(typeof l!=`number`||!d)&&(clearTimeout(f),EK.delete(a));var p=()=>{var e=DK.get(a);try{if(!e)return;var n=e.handler,r=e.reactEvent,i=t.getState(),o={activeCoordinate:uN(i),activeDataKey:sN(i),activeIndex:aN(i),activeLabel:oN(i),activeTooltipIndex:aN(i),isTooltipActive:dN(i)};n&&n(o,r)}finally{TK.delete(a),EK.delete(a),DK.delete(a)}};if(!d){p();return}if(l===`raf`){var m=requestAnimationFrame(p);TK.set(a,m)}else if(typeof l==`number`){if(!EK.has(a)){p();var h=setTimeout(p,l);EK.set(a,h)}}else p()}}});var OK=$([$([SM],e=>e.tooltipItemPayloads),(e,t)=>t,(e,t,n)=>n],(e,t,n)=>{if(t!=null){var r=e.find(e=>e.settings.graphicalItemId===n);if(r!=null){var i=r.getPosition;if(i!=null)return i(t)}}}),kK=em(`touchMove`),AK=ch(),jK=null,MK=null,NK=null,PK=null;AK.startListening({actionCreator:kK,effect:(e,t)=>{var n=e.payload;if(!(n.touches==null||n.touches.length===0)){PK=SK(n);var r=t.getState().eventSettings,i=r.throttleDelay,a=r.throttledEvents,o=a===`all`||a.includes(`touchmove`);jK!==null&&(cancelAnimationFrame(jK),jK=null),MK!==null&&(typeof i!=`number`||!o)&&(clearTimeout(MK),MK=null),NK=Array.from(n.touches).map(e=>qG({clientX:e.clientX,clientY:e.clientY,currentTarget:n.currentTarget}));var s=()=>{if(PK!=null){var e=t.getState(),n=GA(e,e.tooltip.settings.shared);if(n===`axis`){var r=NK?.[0];if(r==null){jK=null,MK=null;return}var i=GG(e,r);i?.activeIndex!=null&&t.dispatch(nM({activeIndex:i.activeIndex,activeDataKey:void 0,activeCoordinate:i.activeCoordinate}))}else if(n===`item`){var a=PK.touches[0];if(document.elementFromPoint==null||a==null)return;var o=document.elementFromPoint(a.clientX,a.clientY);if(!o||!o.getAttribute)return;var s=o.getAttribute(t_),c=o.getAttribute(`data-recharts-item-id`)??void 0,l=IM(e).find(e=>e.id===c);if(s==null||l==null||c==null)return;var u=l.dataKey,d=OK(e,s,c);t.dispatch(Qj({activeDataKey:u,activeIndex:s,activeCoordinate:d,activeGraphicalItemId:c}))}jK=null,MK=null}};if(!o){s();return}i===`raf`?jK=requestAnimationFrame(s):typeof i==`number`&&MK===null&&(s(),PK=null,MK=setTimeout(()=>{PK?s():(MK=null,jK=null)},i))}}});var FK=Sm({name:`errorBars`,initialState:{},reducers:{addErrorBar:(e,t)=>{var n=t.payload,r=n.itemId,i=n.errorBar;e[r]||(e[r]=[]),e[r].push(i)},replaceErrorBar:(e,t)=>{var n=t.payload,r=n.itemId,i=n.prev,a=n.next;e[r]&&(e[r]=e[r].map(e=>e.dataKey===i.dataKey&&e.direction===i.direction?a:e))},removeErrorBar:(e,t)=>{var n=t.payload,r=n.itemId,i=n.errorBar;e[r]&&(e[r]=e[r].filter(e=>e.dataKey!==i.dataKey||e.direction!==i.direction))}}}),IK=FK.actions;IK.addErrorBar,IK.replaceErrorBar,IK.removeErrorBar;var LK=FK.reducer,RK={throttleDelay:`raf`,throttledEvents:[`mousemove`,`touchmove`,`pointermove`,`scroll`,`wheel`]},zK=Sm({name:`eventSettings`,initialState:RK,reducers:{setEventSettings:(e,t)=>{t.payload.throttleDelay!=null&&(e.throttleDelay=t.payload.throttleDelay),t.payload.throttledEvents!=null&&(e.throttledEvents=Wj(t.payload.throttledEvents))}}}),BK=zK.actions.setEventSettings,VK=zK.reducer,HK=ff({brush:sK,cartesianAxis:RU,chartData:FP,errorBars:LK,eventSettings:VK,graphicalItems:oz,layout:gh,legend:gR,options:OP,polarAxis:KI,polarOptions:mK,referenceElements:iK,renderedTicks:vH,rootProps:uK,tooltip:oM,zIndex:cP}),UK=function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:`Chart`;return fm({reducer:HK,preloadedState:e,middleware:e=>e({serializableCheck:!1,immutableCheck:![`commonjs`,`es6`,`production`].includes(`es6`)}).concat([YG.middleware,ZG.middleware,vK.middleware,wK.middleware,AK.middleware]),enhancers:e=>{var t=e;return typeof e==`function`&&(t=e()),t.concat(um({type:`raf`}))},devTools:wu.devToolsEnabled&&{serialize:{replacer:tK},name:`recharts-${t}`}})};function WK(e){var t=e.preloadedState,n=e.children,r=e.reduxStoreName,i=__(),a=(0,v.useRef)(null);if(i)return n;a.current??=UK(t,r);var o=Zd;return v.createElement(wW,{context:o,store:a.current},n)}var GK=e=>{var t=e.chartData,n=ef(),r=__();return(0,v.useEffect)(()=>r?()=>{}:(n(NP(t)),()=>{n(NP(void 0))}),[t,n,r]),null};function KK(e){var t=e.layout,n=e.margin,r=ef(),i=__();return(0,v.useEffect)(()=>{i||(r(ph(t)),r(fh(n)))},[r,i,t,n]),null}var qK=(0,v.memo)(KK,DW);function JK(e){var t=ef();return(0,v.useEffect)(()=>{t(dK(e))},[t,e]),null}var YK=(0,v.memo)(e=>{var t=ef();return(0,v.useEffect)(()=>{t(BK(e))},[t,e]),null},DW);function XK(e){var t=ef();return(0,v.useEffect)(()=>{t(pK(e))},[t,e]),null}var ZK=[`children`,`width`,`height`,`viewBox`,`className`,`style`,`title`,`desc`];function QK(){return QK=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},QK.apply(null,arguments)}function $K(e,t){if(e==null)return{};var n,r,i=eq(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function eq(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var tq=(0,v.forwardRef)((e,t)=>{var n=e.children,r=e.width,i=e.height,a=e.viewBox,o=e.className,s=e.style,c=e.title,l=e.desc,u=$K(e,ZK),d=a||{width:r,height:i,x:0,y:0},f=Y(`recharts-surface`,o);return v.createElement(`svg`,QK({},Xv(u),{className:f,width:r,height:i,style:s,viewBox:`${d.x} ${d.y} ${d.width} ${d.height}`,ref:t}),v.createElement(`title`,null,c),v.createElement(`desc`,null,l),n)});function nq(e){var t=e.zIndex,n=e.isPanorama,r=(0,v.useRef)(null),i=ef();return(0,v.useLayoutEffect)(()=>(r.current&&i(oP({zIndex:t,element:r.current,isPanorama:n})),()=>{i(sP({zIndex:t,isPanorama:n}))}),[i,t,n]),v.createElement(`g`,{tabIndex:-1,ref:r,className:`recharts-zIndex-layer_${t}`})}function rq(e){var t=e.children,n=e.isPanorama,r=Q(qN);if(!r||r.length===0)return t;var i=r.filter(e=>e<0),a=r.filter(e=>e>0);return v.createElement(v.Fragment,null,i.map(e=>v.createElement(nq,{key:e,zIndex:e,isPanorama:n})),t,a.map(e=>v.createElement(nq,{key:e,zIndex:e,isPanorama:n})))}var iq=[`children`];function aq(e,t){if(e==null)return{};var n,r,i=oq(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function oq(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function sq(){return sq=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},sq.apply(null,arguments)}var cq={width:`100%`,height:`100%`,display:`block`},lq=(0,v.forwardRef)((e,t)=>{var n=iv(),r=av(),i=pv();if(!xg(n)||!xg(r))return null;var a=e.children,o=e.otherAttributes,s=e.title,c=e.desc,l,u;return o!=null&&(l=typeof o.tabIndex==`number`?o.tabIndex:i?0:void 0,u=typeof o.role==`string`?o.role:i?`application`:void 0),v.createElement(tq,sq({},o,{title:s,desc:c,role:u,tabIndex:l,width:n,height:r,style:cq,ref:t}),a)}),uq=e=>{var t=e.children,n=Q(y_);if(!n)return null;var r=n.width,i=n.height,a=n.y,o=n.x;return v.createElement(tq,{width:r,height:i,x:o,y:a},t)},dq=(0,v.forwardRef)((e,t)=>{var n=e.children,r=aq(e,iq);return __()?v.createElement(uq,null,v.createElement(rq,{isPanorama:!0},n)):v.createElement(lq,sq({ref:t},r),v.createElement(rq,{isPanorama:!1},n))});function fq(e,t){return _q(e)||gq(e,t)||mq(e,t)||pq()}function pq(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
72
72
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function mq(e,t){if(e){if(typeof e==`string`)return hq(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?hq(e,t):void 0}}function hq(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function gq(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function _q(e){if(Array.isArray(e))return e}function vq(){var e=ef(),t=fq((0,v.useState)(null),2),n=t[0],r=t[1],i=Q(Zg);return(0,v.useEffect)(()=>{if(n!=null){var t=n.getBoundingClientRect().width/n.offsetWidth;bg(t)&&t!==i&&e(hh(t))}},[n,e,i]),r}var yq=(0,v.createContext)(null);function bq(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function xq(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?bq(Object(n),!0).forEach(function(t){Sq(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):bq(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function Sq(e,t,n){return(t=Cq(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Cq(e){var t=wq(e,`string`);return typeof t==`symbol`?t:t+``}function wq(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function Tq(){return Tq=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Tq.apply(null,arguments)}function Eq(e,t){return jq(e)||Aq(e,t)||Oq(e,t)||Dq()}function Dq(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
73
73
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Oq(e,t){if(e){if(typeof e==`string`)return kq(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?kq(e,t):void 0}}function kq(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function Aq(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function jq(e){if(Array.isArray(e))return e}var Mq=()=>(KP(),null);function Nq(e){if(typeof e==`number`)return e;if(typeof e==`string`){var t=parseFloat(e);if(!Number.isNaN(t))return t}return 0}var Pq=(0,v.forwardRef)((e,t)=>{var n=(0,v.useRef)(null),r=Eq((0,v.useState)({containerWidth:Nq(e.style?.width),containerHeight:Nq(e.style?.height)}),2),i=r[0],a=r[1],o=(0,v.useCallback)((e,t)=>{a(n=>{var r=Math.round(e),i=Math.round(t);return n.containerWidth===r&&n.containerHeight===i?n:{containerWidth:r,containerHeight:i}})},[]),s=(0,v.useCallback)(e=>{if(typeof t==`function`&&t(e),n.current!=null&&(n.current.disconnect(),n.current=null),e!=null&&typeof ResizeObserver<`u`){var r=e.getBoundingClientRect(),i=r.width,a=r.height;o(i,a);var s=new ResizeObserver(e=>{var t=e[0];if(t!=null){var n=t.contentRect,r=n.width,i=n.height;o(r,i)}});s.observe(e),n.current=s}},[t,o]);return(0,v.useEffect)(()=>()=>{n.current?.disconnect()},[o]),v.createElement(v.Fragment,null,v.createElement(fv,{width:i.containerWidth,height:i.containerHeight}),v.createElement(`div`,Tq({ref:s},e)))}),Fq=(0,v.forwardRef)((e,t)=>{var n=e.width,r=e.height,i=Eq((0,v.useState)({containerWidth:Nq(n),containerHeight:Nq(r)}),2),a=i[0],o=i[1],s=(0,v.useCallback)((e,t)=>{o(n=>{var r=Math.round(e),i=Math.round(t);return n.containerWidth===r&&n.containerHeight===i?n:{containerWidth:r,containerHeight:i}})},[]),c=(0,v.useCallback)(e=>{if(typeof t==`function`&&t(e),e!=null){var n=e.getBoundingClientRect(),r=n.width,i=n.height;s(r,i)}},[t,s]);return v.createElement(v.Fragment,null,v.createElement(fv,{width:a.containerWidth,height:a.containerHeight}),v.createElement(`div`,Tq({ref:c},e)))}),Iq=(0,v.forwardRef)((e,t)=>{var n=e.width,r=e.height;return v.createElement(v.Fragment,null,v.createElement(fv,{width:n,height:r}),v.createElement(`div`,Tq({ref:t},e)))}),Lq=(0,v.forwardRef)((e,t)=>{var n=e.width,r=e.height;return typeof n==`string`||typeof r==`string`?v.createElement(Fq,Tq({},e,{ref:t})):typeof n==`number`&&typeof r==`number`?v.createElement(Iq,Tq({},e,{width:n,height:r,ref:t})):v.createElement(v.Fragment,null,v.createElement(fv,{width:n,height:r}),v.createElement(`div`,Tq({ref:t},e)))});function Rq(e){return e?Pq:Lq}var zq=(0,v.forwardRef)((e,t)=>{var n=e.children,r=e.className,i=e.height,a=e.onClick,o=e.onContextMenu,s=e.onDoubleClick,c=e.onMouseDown,l=e.onMouseEnter,u=e.onMouseLeave,d=e.onMouseMove,f=e.onMouseUp,p=e.onTouchEnd,m=e.onTouchMove,h=e.onTouchStart,g=e.style,_=e.width,y=e.responsive,b=e.dispatchTouchEvents,x=b===void 0?!0:b,S=(0,v.useRef)(null),C=ef(),w=Eq((0,v.useState)(null),2),T=w[0],E=w[1],D=Eq((0,v.useState)(null),2),O=D[0],k=D[1],A=vq(),j=Z_(),M=j?.width>0?j.width:_,N=j?.height>0?j.height:i,P=(0,v.useCallback)(e=>{A(e),typeof t==`function`&&t(e),E(e),k(e),e!=null&&(S.current=e)},[A,t,E,k]),F=(0,v.useCallback)(e=>{C(JG(e)),C(CK({handler:a,reactEvent:e}))},[C,a]),I=(0,v.useCallback)(e=>{C(XG(e)),C(CK({handler:l,reactEvent:e}))},[C,l]),L=(0,v.useCallback)(e=>{C(eM()),C(CK({handler:u,reactEvent:e}))},[C,u]),ee=(0,v.useCallback)(e=>{C(XG(e)),C(CK({handler:d,reactEvent:e}))},[C,d]),te=(0,v.useCallback)(()=>{C(gK())},[C]),R=(0,v.useCallback)(()=>{C(_K())},[C]),z=(0,v.useCallback)(e=>{C(hK(e.key))},[C]),ne=(0,v.useCallback)(e=>{C(CK({handler:o,reactEvent:e}))},[C,o]),B=(0,v.useCallback)(e=>{C(CK({handler:s,reactEvent:e}))},[C,s]),re=(0,v.useCallback)(e=>{C(CK({handler:c,reactEvent:e}))},[C,c]),ie=(0,v.useCallback)(e=>{C(CK({handler:f,reactEvent:e}))},[C,f]),ae=(0,v.useCallback)(e=>{C(CK({handler:h,reactEvent:e}))},[C,h]),oe=(0,v.useCallback)(e=>{x&&C(kK(e)),C(CK({handler:m,reactEvent:e}))},[C,x,m]),se=(0,v.useCallback)(e=>{C(CK({handler:p,reactEvent:e}))},[C,p]),ce=Rq(y);return v.createElement(bP.Provider,{value:T},v.createElement(yq.Provider,{value:O},v.createElement(ce,{width:M??g?.width,height:N??g?.height,className:Y(`recharts-wrapper`,r),style:xq({position:`relative`,cursor:`default`,width:M,height:N},g),onClick:F,onContextMenu:ne,onDoubleClick:B,onFocus:te,onBlur:R,onKeyDown:z,onMouseDown:re,onMouseEnter:I,onMouseLeave:L,onMouseMove:ee,onMouseUp:ie,onTouchEnd:se,onTouchMove:oe,onTouchStart:ae,ref:P},v.createElement(Mq,null),n)))});function Bq(e,t){return Gq(e)||Wq(e,t)||Hq(e,t)||Vq()}function Vq(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
74
|
-
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Hq(e,t){if(e){if(typeof e==`string`)return Uq(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Uq(e,t):void 0}}function Uq(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function Wq(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function Gq(e){if(Array.isArray(e))return e}var Kq=(0,v.createContext)(void 0),qq=e=>{var t=e.children,n=Bq((0,v.useState)(`${ql(`recharts`)}-clip`),1)[0],r=BU();if(r==null)return null;var i=r.x,a=r.y,o=r.width,s=r.height;return v.createElement(Kq.Provider,{value:n},v.createElement(`defs`,null,v.createElement(`clipPath`,{id:n},v.createElement(`rect`,{x:i,y:a,height:s,width:o}))),t)},Jq=[`width`,`height`,`responsive`,`children`,`className`,`style`,`compact`,`title`,`desc`];function Yq(e,t){if(e==null)return{};var n,r,i=Xq(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Xq(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var Zq=(0,v.forwardRef)((e,t)=>{var n=e.width,r=e.height,i=e.responsive,a=e.children,o=e.className,s=e.style,c=e.compact,l=e.title,u=e.desc,d=Nv(Yq(e,Jq));return c?v.createElement(v.Fragment,null,v.createElement(fv,{width:n,height:r}),v.createElement(dq,{otherAttributes:d,title:l,desc:u},a)):v.createElement(zq,{className:o,style:s,width:n,height:r,responsive:i??!1,onClick:e.onClick,onMouseLeave:e.onMouseLeave,onMouseEnter:e.onMouseEnter,onMouseMove:e.onMouseMove,onMouseDown:e.onMouseDown,onMouseUp:e.onMouseUp,onContextMenu:e.onContextMenu,onDoubleClick:e.onDoubleClick,onTouchStart:e.onTouchStart,onTouchMove:e.onTouchMove,onTouchEnd:e.onTouchEnd},v.createElement(dq,{otherAttributes:d,title:l,desc:u,ref:t},v.createElement(qq,null,a)))}),Qq=[`layout`];function $q(){return $q=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},$q.apply(null,arguments)}function eJ(e,t){if(e==null)return{};var n,r,i=tJ(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function tJ(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function nJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function rJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?nJ(Object(n),!0).forEach(function(t){iJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):nJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function iJ(e,t,n){return(t=aJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aJ(e){var t=oJ(e,`string`);return typeof t==`symbol`?t:t+``}function oJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var sJ=rJ({accessibilityLayer:!0,stackOffset:`none`,barCategoryGap:`10%`,barGap:4,margin:{top:5,right:5,bottom:5,left:5},reverseStackOrder:!1,syncMethod:`index`,layout:`radial`,responsive:!1,cx:`50%`,cy:`50%`,innerRadius:0,outerRadius:`80%`},RK),cJ=(0,v.forwardRef)(function(e,t){var n=hy(e.categoricalChartProps,sJ),r=n.layout,i=eJ(n,Qq),a=e.chartName,o={chartName:a,defaultTooltipEventType:e.defaultTooltipEventType,validateTooltipEventTypes:e.validateTooltipEventTypes,tooltipPayloadSearcher:e.tooltipPayloadSearcher,eventEmitter:void 0};return v.createElement(WK,{preloadedState:{options:o},reduxStoreName:n.id??a},v.createElement(GK,{chartData:n.data}),v.createElement(qK,{layout:r,margin:n.margin}),v.createElement(YK,{throttleDelay:n.throttleDelay,throttledEvents:n.throttledEvents}),v.createElement(JK,{baseValue:void 0,accessibilityLayer:n.accessibilityLayer,barCategoryGap:n.barCategoryGap,maxBarSize:n.maxBarSize,stackOffset:n.stackOffset,barGap:n.barGap,barSize:n.barSize,syncId:n.syncId,syncMethod:n.syncMethod,className:n.className,reverseStackOrder:n.reverseStackOrder}),v.createElement(XK,{cx:n.cx,cy:n.cy,startAngle:n.startAngle,endAngle:n.endAngle,innerRadius:n.innerRadius,outerRadius:n.outerRadius}),v.createElement(Zq,$q({},i,{ref:t})))});function lJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function uJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?lJ(Object(n),!0).forEach(function(t){dJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):lJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function dJ(e,t,n){return(t=fJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function fJ(e){var t=pJ(e,`string`);return typeof t==`symbol`?t:t+``}function pJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var mJ=[`item`],hJ=uJ(uJ({},sJ),{},{layout:`centric`,startAngle:0,endAngle:360}),gJ=(0,v.forwardRef)((e,t)=>{var n=hy(e,hJ);return v.createElement(cJ,{chartName:`PieChart`,defaultTooltipEventType:`item`,validateTooltipEventTypes:mJ,tooltipPayloadSearcher:EP,categoricalChartProps:n,ref:t})});function _J(){return _J=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_J.apply(null,arguments)}function vJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function yJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?vJ(Object(n),!0).forEach(function(t){bJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):vJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function bJ(e,t,n){return(t=xJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function xJ(e){var t=SJ(e,`string`);return typeof t==`symbol`?t:t+``}function SJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var CJ=yJ({accessibilityLayer:!0,barCategoryGap:`10%`,barGap:4,layout:`horizontal`,margin:{top:5,right:5,bottom:5,left:5},responsive:!1,reverseStackOrder:!1,stackOffset:`none`,syncMethod:`index`},RK),wJ=(0,v.forwardRef)(function(e,t){var n=hy(e.categoricalChartProps,CJ),r=e.chartName,i=e.defaultTooltipEventType,a=e.validateTooltipEventTypes,o=e.tooltipPayloadSearcher,s=e.categoricalChartProps,c={chartName:r,defaultTooltipEventType:i,validateTooltipEventTypes:a,tooltipPayloadSearcher:o,eventEmitter:void 0};return v.createElement(WK,{preloadedState:{options:c},reduxStoreName:s.id??r},v.createElement(GK,{chartData:s.data}),v.createElement(qK,{layout:n.layout,margin:n.margin}),v.createElement(YK,{throttleDelay:n.throttleDelay,throttledEvents:n.throttledEvents}),v.createElement(JK,{baseValue:n.baseValue,accessibilityLayer:n.accessibilityLayer,barCategoryGap:n.barCategoryGap,maxBarSize:n.maxBarSize,stackOffset:n.stackOffset,barGap:n.barGap,barSize:n.barSize,syncId:n.syncId,syncMethod:n.syncMethod,className:n.className,reverseStackOrder:n.reverseStackOrder}),v.createElement(Zq,_J({},n,{ref:t})))}),TJ=[`axis`],EJ=(0,v.forwardRef)((e,t)=>v.createElement(wJ,{chartName:`AreaChart`,defaultTooltipEventType:`axis`,validateTooltipEventTypes:TJ,tooltipPayloadSearcher:EP,categoricalChartProps:e,ref:t}));function DJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function OJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?DJ(Object(n),!0).forEach(function(t){kJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):DJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function kJ(e,t,n){return(t=AJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function AJ(e){var t=jJ(e,`string`);return typeof t==`symbol`?t:t+``}function jJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var MJ=[`axis`,`item`],NJ=OJ(OJ({},sJ),{},{layout:`radial`,startAngle:0,endAngle:360}),PJ=(0,v.forwardRef)((e,t)=>{var n=hy(e,NJ);return v.createElement(cJ,{chartName:`RadialBarChart`,defaultTooltipEventType:`axis`,validateTooltipEventTypes:MJ,tooltipPayloadSearcher:EP,categoricalChartProps:n,ref:t})}),FJ=e=>new Date(e).toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,hour12:!1});function IJ({active:e,payload:t,label:n,unit:r}){return!e||!t?.length?null:(0,J.jsxs)(`div`,{className:`chart-tip`,children:[n!=null&&(0,J.jsx)(`div`,{className:`chart-tip__label`,children:n}),t.map((e,t)=>(0,J.jsxs)(`div`,{className:`chart-tip__row`,children:[(0,J.jsx)(`span`,{className:`chart-tip__dot`,style:{background:e.color}}),(0,J.jsx)(`span`,{className:`chart-tip__name`,children:e.name??e.dataKey}),(0,J.jsxs)(`span`,{className:`chart-tip__val`,children:[typeof e.value==`number`?e.value.toLocaleString():e.value,r??``]})]},t))]})}var LJ=`color-mix(in srgb, var(--mt-border) 80%, transparent)`,RJ={fill:`var(--mt-text-faint)`,fontSize:10,fontFamily:`var(--mt-mono)`};function zJ({series:e}){return(0,J.jsx)(`div`,{className:`chart`,style:{height:200},children:(0,J.jsx)($_,{width:`100%`,height:`100%`,children:(0,J.jsxs)(EJ,{data:e,margin:{top:8,right:8,left:-18,bottom:0},children:[(0,J.jsxs)(`defs`,{children:[(0,J.jsxs)(`linearGradient`,{id:`fillOk`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,J.jsx)(`stop`,{offset:`0%`,stopColor:`var(--page-accent)`,stopOpacity:.5}),(0,J.jsx)(`stop`,{offset:`100%`,stopColor:`var(--page-accent)`,stopOpacity:.04})]}),(0,J.jsxs)(`linearGradient`,{id:`fillErr`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,J.jsx)(`stop`,{offset:`0%`,stopColor:`var(--mt-bad)`,stopOpacity:.55}),(0,J.jsx)(`stop`,{offset:`100%`,stopColor:`var(--mt-bad)`,stopOpacity:.05})]})]}),(0,J.jsx)(dU,{vertical:!1,stroke:LJ,strokeDasharray:`3 3`}),(0,J.jsx)(kG,{dataKey:`t`,tickFormatter:FJ,tick:RJ,tickLine:!1,axisLine:!1,minTickGap:48}),(0,J.jsx)(WG,{tick:RJ,tickLine:!1,axisLine:!1,width:34,allowDecimals:!1}),(0,J.jsx)(lF,{cursor:{stroke:LJ},content:({active:e,payload:t,label:n})=>(0,J.jsx)(IJ,{active:e,payload:t,label:typeof n==`number`?FJ(n):n})}),(0,J.jsx)(cG,{type:`monotone`,dataKey:`ok`,name:`ok`,stackId:`1`,stroke:`var(--page-accent)`,fill:`url(#fillOk)`,strokeWidth:2,isAnimationActive:!1}),(0,J.jsx)(cG,{type:`monotone`,dataKey:`error`,name:`error`,stackId:`1`,stroke:`var(--mt-bad)`,fill:`url(#fillErr)`,strokeWidth:2,isAnimationActive:!1})]})})})}function BJ({segments:e,centerLabel:t=`calls`}){let n=e.filter(e=>e.value>0),r=e.reduce((e,t)=>e+t.value,0);return(0,J.jsxs)(`div`,{className:`chart chart--donut`,children:[(0,J.jsx)(`div`,{className:`chart-donut__svg`,children:(0,J.jsx)($_,{width:`100%`,height:180,children:(0,J.jsxs)(gJ,{children:[(0,J.jsx)(lF,{content:({active:e,payload:t})=>(0,J.jsx)(IJ,{active:e,payload:t})}),(0,J.jsx)(NB,{data:n,dataKey:`value`,nameKey:`label`,innerRadius:58,outerRadius:80,paddingAngle:2,strokeWidth:0,isAnimationActive:!1,children:n.map(e=>(0,J.jsx)(uF,{fill:e.color},e.label))}),(0,J.jsx)(`text`,{x:`50%`,y:`47%`,textAnchor:`middle`,fill:`var(--mt-text)`,fontSize:22,fontWeight:600,children:r.toLocaleString()}),(0,J.jsx)(`text`,{x:`50%`,y:`59%`,textAnchor:`middle`,fill:`var(--mt-text-dim)`,fontSize:10,children:t})]})})}),(0,J.jsx)(`div`,{className:`chart-legend`,children:n.map(e=>(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:e.color}}),e.label,` `,(0,J.jsx)(`b`,{children:e.value})]},e.label))})]})}function VJ({values:e,color:t,unit:n,maxValue:r,id:i}){let a=e.filter(e=>e!=null);if(a.length===0)return(0,J.jsx)(`div`,{className:`spark spark--empty`,children:`no samples yet`});let o=e.map((e,t)=>({i:t,v:e})),s=a[a.length-1],c=`ma-${(i??t).replace(/[^a-z0-9]/gi,``)}`,l=Math.min(...a),u=Math.max(...a),d=Math.max(0,(n===`%`?10:0)-(u-l))/2,f=l-d,p=u+d,m=(p-f)*.15||1;return f=Math.max(0,f-m),p+=m,r!=null&&(p=Math.min(r,p)),p<=f&&(p=f+1),(0,J.jsxs)(`div`,{className:`chart chart--spark`,children:[(0,J.jsxs)(`span`,{className:`chart-spark__last`,style:{color:t},children:[s.toFixed(n===`%`?0:1),n??``]}),(0,J.jsx)($_,{width:`100%`,height:46,children:(0,J.jsxs)(EJ,{data:o,margin:{top:4,right:2,left:2,bottom:0},children:[(0,J.jsx)(`defs`,{children:(0,J.jsxs)(`linearGradient`,{id:c,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,J.jsx)(`stop`,{offset:`0%`,stopColor:t,stopOpacity:.35}),(0,J.jsx)(`stop`,{offset:`100%`,stopColor:t,stopOpacity:0})]})}),(0,J.jsx)(WG,{hide:!0,domain:[f,p]}),(0,J.jsx)(lF,{cursor:{stroke:LJ},content:({active:e,payload:r})=>(0,J.jsx)(IJ,{active:e,payload:r?.map(e=>({...e,name:`value`,color:t})),unit:n})}),(0,J.jsx)(cG,{type:`monotone`,dataKey:`v`,stroke:t,fill:`url(#${c})`,strokeWidth:1.7,connectNulls:!1,isAnimationActive:!1,dot:!1})]})})]})}function HJ({value:e,label:t,color:n}){let r=e!=null,i=r?Math.max(0,Math.min(100,e)):0;return(0,J.jsxs)(`div`,{className:`gauge`,children:[(0,J.jsxs)(`div`,{className:`gauge__radial`,children:[(0,J.jsx)($_,{width:72,height:72,children:(0,J.jsxs)(PJ,{data:[{name:t,value:i,fill:n}],innerRadius:`72%`,outerRadius:`100%`,startAngle:90,endAngle:-270,barSize:7,children:[(0,J.jsx)(AL,{type:`number`,domain:[0,100],tick:!1,axisLine:!1}),(0,J.jsx)(YV,{dataKey:`value`,cornerRadius:4,background:{fill:`var(--mt-surface-2)`},isAnimationActive:!1})]})}),(0,J.jsx)(`span`,{className:`gauge__pct`,style:{color:r?`var(--mt-text)`:`var(--mt-text-faint)`},children:r?`${Math.round(i)}%`:`n/a`})]}),(0,J.jsx)(`span`,{className:`gauge__label`,children:t})]})}var UJ=40,WJ=2e3,GJ=`http://www.w3.org/2000/svg`,KJ=e=>`${(e/1e6).toFixed(2)} Mbps`;function qJ({history:e}){let t=Math.max(1,...e.flatMap(e=>[e.rx,e.tx])),n=e=>8+e*504/Math.max(1,UJ-1),r=e=>142-e/t*134,i=t=>e.map((e,i)=>`${n(i).toFixed(1)},${r(t(e)).toFixed(1)}`).join(` `),a=t=>{if(e.length<2)return``;let r=n(0).toFixed(1),a=n(e.length-1).toFixed(1);return`${r},${142 .toFixed(1)} ${i(t)} ${a},${142 .toFixed(1)}`};return(0,J.jsx)(`svg`,{className:`clients-chart`,viewBox:`0 0 520 150`,xmlns:GJ,role:`img`,children:e.length>=2&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`polygon`,{className:`rx area`,points:a(e=>e.rx)}),(0,J.jsx)(`polygon`,{className:`tx area`,points:a(e=>e.tx)}),(0,J.jsx)(`polyline`,{className:`rx line`,points:i(e=>e.rx)}),(0,J.jsx)(`polyline`,{className:`tx line`,points:i(e=>e.tx)})]})})}function JJ({ip:e,deviceName:t,current:n,onSaved:r}){let[i,a]=(0,v.useState)(n.download),[o,s]=(0,v.useState)(n.upload),[c,l]=(0,v.useState)(!1),[u,d]=(0,v.useState)(!1),[f,p]=(0,v.useState)(null);(0,v.useEffect)(()=>{c||(a(n.download),s(n.upload))},[n.download,n.upload,c]);let m=(0,v.useCallback)(async(n,i)=>{d(!0),p(null);try{let a=await pc(`/api/clients/limits`,{ip:e,device:t,download:n,upload:i});p(a.message),a.ok&&(l(!1),r())}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[e,t,r]),h=!!(n.download||n.upload);return(0,J.jsxs)(`div`,{className:`clients-limits`,children:[(0,J.jsxs)(`div`,{className:`clients-limits__hd`,children:[(0,J.jsx)(`span`,{className:`clients-limits__label`,children:`Rate limits`}),(0,J.jsxs)(`span`,{className:`muted`,children:[`current: ↓ `,n.download||`unlimited`,` · ↑ `,n.upload||`unlimited`]})]}),(0,J.jsxs)(`div`,{className:`clients-limits__row`,children:[(0,J.jsxs)(`label`,{className:`clients-limits__field`,children:[(0,J.jsx)(`span`,{className:`muted`,children:`↓ Download`}),(0,J.jsx)(Fc,{placeholder:`10M · blank = unlimited`,value:i,onChange:e=>{l(!0),a(e.target.value)}})]}),(0,J.jsxs)(`label`,{className:`clients-limits__field`,children:[(0,J.jsx)(`span`,{className:`muted`,children:`↑ Upload`}),(0,J.jsx)(Fc,{placeholder:`2M · blank = unlimited`,value:o,onChange:e=>{l(!0),s(e.target.value)}})]}),(0,J.jsx)(Ac,{size:`sm`,type:`accent`,loading:u,onClick:()=>void m(i,o),children:`Apply`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,disabled:u||!h,onClick:()=>{a(``),s(``),m(``,``)},children:`Remove`})]}),f&&(0,J.jsx)(`div`,{className:`muted clients-limits__msg`,children:f})]})}function YJ({device:e,deviceName:t}){let[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)([]),o=(0,v.useRef)(e.ip);o.current=e.ip;let s=(0,v.useCallback)(async()=>{if(e.ip)try{let n=t?`&device=${encodeURIComponent(t)}`:``,i=await fc(`/api/clients/traffic?ip=${encodeURIComponent(e.ip)}${n}`);if(i.ip!==o.current)return;r(i),a(e=>[...e,{rx:i.rxBitsPerSec,tx:i.txBitsPerSec}].slice(-40))}catch{}},[e.ip,t]);return(0,v.useEffect)(()=>{if(r(null),a([]),!e.ip)return;s();let t=setInterval(()=>void s(),WJ);return()=>clearInterval(t)},[s,e.ip]),(0,J.jsxs)(`div`,{className:`clients-detail`,children:[(0,J.jsxs)(`div`,{className:`clients-detail__hd`,children:[(0,J.jsx)(`span`,{className:`clients-detail__title`,children:e.host||e.comment||e.ip}),(0,J.jsxs)(`span`,{className:`muted`,children:[e.ip||`no IP`,` · `,e.mac,` · `,e.iface||`?`,` · `,e.status]})]}),n&&n.source===`none`?(0,J.jsxs)(jc,{type:`secondary`,label:`No per-device counter`,children:[`Set a rate limit below to start tracking this device's Download/Upload (it creates a simple queue targeting `,(0,J.jsx)(`code`,{children:e.ip}),`), or leave it unlimited.`]}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`div`,{className:`clients-rates`,children:[(0,J.jsxs)(`span`,{className:`rate rx`,children:[`↓ `,n?KJ(n.rxBitsPerSec):`…`]}),(0,J.jsxs)(`span`,{className:`rate tx`,children:[`↑ `,n?KJ(n.txBitsPerSec):`…`]})]}),(0,J.jsx)(qJ,{history:i}),n&&(0,J.jsxs)(`div`,{className:`muted clients-totals`,children:[`total ↓ `,Sc(n.rxBytes),` · ↑ `,Sc(n.txBytes)]})]}),e.ip&&(0,J.jsx)(JJ,{ip:e.ip,deviceName:t,current:{download:n?.downloadLimit??``,upload:n?.uploadLimit??``},onSaved:()=>void s()}),e.ip&&(0,J.jsxs)(`div`,{className:`clients-history`,children:[(0,J.jsx)(`div`,{className:`clients-history__hd`,children:`Usage history · last 3 months`}),(0,J.jsx)(Uc,{endpoint:`/api/usage/client?ip=${encodeURIComponent(e.ip)}${t?`&device=${encodeURIComponent(t)}`:``}&days=90`,days:90})]})]})}function XJ(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),[m,h]=(0,v.useState)(null);(0,v.useEffect)(()=>{fc(`/api/devices`).then(e=>{t(e),r(t=>t||e.defaultDevice||e.devices[0]?.name||``)}).catch(()=>t({server:``,defaultDevice:``,devices:[]}))},[]);let g=(0,v.useCallback)(async()=>{try{a(await fc(`/api/clients${n?`?device=${encodeURIComponent(n)}`:``}`)),d(null)}catch(e){d(e instanceof Error?e.message:String(e))}},[n]);(0,v.useEffect)(()=>{a(null),s(null),g();let e=setInterval(()=>void g(),15e3);return()=>clearInterval(e)},[g]);let _=(0,v.useCallback)(async(e,t,r)=>{l(t),d(null);try{let i=await pc(`/api/clients/${e}`,{mac:t,device:n,...r});i.view?a(i.view):await g(),i.ok||d(i.message)}catch(e){d(e instanceof Error?e.message:String(e))}finally{l(null)}},[n,g]),y=(0,v.useCallback)((e,t)=>{s(e.mac),h({mac:e.mac,field:t,value:t===`ip`?e.ip:e.comment||e.host})},[]),b=(0,v.useCallback)(async()=>{if(!m)return;let e=m.value.trim();m.field===`ip`?e&&await _(`set-ip`,m.mac,{ip:e}):await _(`label`,m.mac,{label:e}),h(null)},[m,_]),x=(0,v.useMemo)(()=>{let e=i?.devices??[],t=f.trim().toLowerCase();return t?e.filter(e=>e.ip.toLowerCase().includes(t)||e.mac.toLowerCase().includes(t)||e.host.toLowerCase().includes(t)||e.comment.toLowerCase().includes(t)):e},[i,f]),S=(0,v.useMemo)(()=>i?.devices.find(e=>e.mac===o)??null,[i,o]),C=e?.devices??[],w=i?.counts;return(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsxs)(gc,{title:`Connected clients`,className:`reveal`,extra:(0,J.jsxs)(`div`,{className:`clients-toolbar`,children:[C.length>1&&(0,J.jsx)(Ic,{value:n,onChange:e=>r(e.target.value),"aria-label":`Router`,children:C.map(e=>(0,J.jsxs)(`option`,{value:e.name,children:[e.name,e.isDefault?` (default)`:``]},e.name))}),(0,J.jsx)(`input`,{className:`geist-input`,placeholder:`Filter IP / MAC / name…`,value:f,onChange:e=>p(e.target.value)}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,onClick:()=>void g(),children:`↻ Refresh`})]}),children:[w&&(0,J.jsxs)(`div`,{className:`clients-counts muted`,children:[w.total,` total · `,w.static,` static · `,w.blocked,` blocked`]}),u&&(0,J.jsx)(jc,{type:`error`,className:`clients-error`,children:u}),i?x.length===0?(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`📡`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No connected devices`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[`Nothing in this router's DHCP-lease or ARP table`,f?` matches the filter`:``,`.`]})]}):(0,J.jsxs)(`div`,{className:`clients-table`,children:[(0,J.jsxs)(`div`,{className:`clients-row clients-row--head`,children:[(0,J.jsx)(`span`,{children:`IP`}),(0,J.jsx)(`span`,{children:`Name`}),(0,J.jsx)(`span`,{children:`MAC`}),(0,J.jsx)(`span`,{children:`Iface`}),(0,J.jsx)(`span`,{children:`Status`}),(0,J.jsx)(`span`,{className:`clients-actions-h`,children:`Actions`})]}),x.map(e=>{let t=e.mac===o,n=c===e.mac;return(0,J.jsxs)(`div`,{className:[`clients-row`,t?`is-selected`:``,e.blocked?`is-blocked`:``].filter(Boolean).join(` `),onClick:()=>s(t?null:e.mac),children:[(0,J.jsx)(`span`,{className:`clients-ip`,children:e.ip||`—`}),(0,J.jsx)(`span`,{className:`clients-name`,children:e.host||e.comment||`(unknown)`}),(0,J.jsx)(`span`,{className:`clients-mac`,children:e.mac}),(0,J.jsx)(`span`,{className:`muted`,children:e.iface||``}),(0,J.jsxs)(`span`,{className:`clients-badges`,children:[e.static&&(0,J.jsx)(Mc,{type:`secondary`,children:`static`}),e.blocked?(0,J.jsx)(Mc,{type:`error`,children:`blocked`}):(0,J.jsx)(`span`,{className:`muted`,children:e.status})]}),(0,J.jsxs)(`span`,{className:`clients-actions`,onClick:e=>e.stopPropagation(),role:`presentation`,children:[e.blocked?(0,J.jsx)(Ac,{size:`sm`,type:`success`,ghost:!0,loading:n,onClick:()=>void _(`allow`,e.mac),children:`Allow`}):(0,J.jsx)(Ac,{size:`sm`,type:`error`,ghost:!0,loading:n,onClick:()=>void _(`block`,e.mac),children:`Block`}),!e.static&&(0,J.jsx)(Ac,{size:`sm`,ghost:!0,loading:n,onClick:()=>void _(`pin`,e.mac),children:`Pin IP`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,disabled:n,onClick:()=>y(e,`ip`),children:`Set IP`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,disabled:n,onClick:()=>y(e,`label`),children:`Label`})]})]},e.mac)})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading connected devices…`}),m&&S?.mac===m.mac&&(0,J.jsxs)(`div`,{className:`clients-edit`,children:[(0,J.jsxs)(`span`,{className:`clients-edit__label`,children:[m.field===`ip`?`Reserve IP for`:`Label for`,` `,(0,J.jsx)(`b`,{children:S.host||S.mac}),`:`]}),(0,J.jsx)(Fc,{autoFocus:!0,value:m.value,placeholder:m.field===`ip`?`e.g. 192.168.88.50`:`e.g. Ali phone`,onChange:e=>h({...m,value:e.target.value}),onKeyDown:e=>{e.key===`Enter`&&b(),e.key===`Escape`&&h(null)}}),(0,J.jsx)(Ac,{size:`sm`,type:`accent`,loading:c===m.mac,onClick:()=>void b(),children:`Save`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,onClick:()=>h(null),children:`Cancel`})]}),S&&(0,J.jsx)(YJ,{device:S,deviceName:n})]})})}function ZJ(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function QJ(e){return new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`,hour12:!1})}function $J({onRestored:e}){let[t,n]=(0,v.useState)(null),[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(!1),[s,c]=(0,v.useState)(null),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)(null),h=(0,v.useCallback)(()=>{fc(`/api/config/history`).then(n).catch(()=>n({versions:[],bytes:0,retention:50}))},[]);(0,v.useEffect)(()=>h(),[h]);let g=(e,t)=>pc(e,t).catch(()=>({error:`request failed`})),_=async()=>{let e=(p??``).trim();m(null);let t=await g(`/api/config/history/checkpoint`,{label:e||void 0});i(t.ok?`Checkpoint saved${e?` · “${e}”`:``}`:`Failed: ${t.error}`),t.ok&&h()},y=async e=>{if(s===e){c(null),u(null);return}c(e),u(null),u(await fc(`/api/config/history/diff?id=${encodeURIComponent(e)}`).catch(()=>null))},b=async t=>{f(null),o(!0);let n=await g(`/api/config/history/restore`,{id:t});o(!1),i(n.ok?`Restored ${t}${n.persisted===!1?` (applied live, not persisted)`:``}`:`Restore failed: ${n.error}`),n.ok&&(h(),e())},x=async e=>{let t=await g(`/api/config/history/delete`,{id:e});i(t.ok?`Version deleted`:`Failed: ${t.error}`),t.ok&&h()};return t?(0,J.jsxs)(J.Fragment,{children:[r&&(0,J.jsx)(`div`,{className:`cfg-msg`,children:r}),(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:14},children:[p===null?(0,J.jsx)(`button`,{className:`btn is-active`,onClick:()=>m(``),children:`★ Save checkpoint`}):(0,J.jsxs)(`span`,{className:`cfgver-cp`,children:[(0,J.jsx)(`input`,{className:`backup-path-input`,autoFocus:!0,placeholder:`checkpoint name (e.g. pre-upgrade)`,value:p,onChange:e=>m(e.target.value),onKeyDown:e=>{e.key===`Enter`&&_(),e.key===`Escape`&&m(null)}}),(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,onClick:()=>void _(),children:`Save`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>m(null),children:`Cancel`})]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsxs)(`span`,{className:`muted`,children:[t.versions.length,` versions · `,ZJ(t.bytes),` · auto-keep `,t.retention]})]}),t.versions.length===0?(0,J.jsx)(`div`,{className:`muted`,children:`No versions yet — they appear here after each config change.`}):(0,J.jsx)(`ol`,{className:`cfgver`,children:t.versions.map((e,t)=>{let n=e.drift.added+e.drift.removed;return(0,J.jsxs)(`li`,{className:`cfgver__row${t===0?` is-head`:``}`,children:[(0,J.jsx)(`span`,{className:`cfgver__dot`,"aria-hidden":`true`}),(0,J.jsxs)(`div`,{className:`cfgver__main`,children:[(0,J.jsxs)(`div`,{className:`cfgver__line`,children:[(0,J.jsx)(`span`,{className:`cfgver__kind cfgver__kind--${e.kind}`,children:e.kind===`checkpoint`?`★ checkpoint`:`auto`}),e.label&&(0,J.jsx)(`span`,{className:`cfgver__label`,children:e.label}),(0,J.jsx)(`span`,{className:`cfgver__time`,children:QJ(e.ts)}),t===0?(0,J.jsx)(`span`,{className:`cfgver__cur`,children:`latest`}):n===0?(0,J.jsx)(`span`,{className:`cfgver__same`,children:`identical to current`}):(0,J.jsxs)(`span`,{className:`cfgver__drift`,children:[(0,J.jsxs)(`span`,{className:`add`,children:[`+`,e.drift.added]}),(0,J.jsxs)(`span`,{className:`rem`,children:[`−`,e.drift.removed]}),(0,J.jsx)(`span`,{className:`muted`,children:` vs current`})]})]}),s===e.id&&(0,J.jsx)(`div`,{className:`cfgver__diff`,children:l?l.unified.trim()?(0,J.jsx)(`pre`,{className:`body diff`,children:l.unified}):(0,J.jsx)(`span`,{className:`muted`,children:`No differences from the current config.`}):(0,J.jsx)(`span`,{className:`muted`,children:`computing diff…`})})]}),(0,J.jsxs)(`div`,{className:`cfgver__actions`,children:[(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void y(e.id),children:s===e.id?`Hide`:`Diff`}),d===e.id?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,disabled:a,onClick:()=>void b(e.id),children:`Confirm restore`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>f(null),children:`Cancel`})]}):(0,J.jsx)(`button`,{className:`topo-btn`,disabled:t===0,title:t===0?`This is the current config`:`Restore this version`,onClick:()=>f(e.id),children:`Restore`}),e.kind===`checkpoint`&&(0,J.jsx)(`button`,{className:`topo-btn cfgver__del`,title:`Delete`,onClick:()=>void x(e.id),children:`✕`})]})]},e.id)})})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading history…`})}function eY(e){if(!e)return[];let t=[],n=e=>e?Array.isArray(e.enum)?`enum`:e.type===`array`?`array<${n(e.items)}>`:Array.isArray(e.type)?e.type.join(` | `):e.type??(e.properties?`object`:`any`):`any`,r=(e,i,a,o)=>{let s=e.properties??{};for(let[e,c]of Object.entries(s)){let s=i?`${i}.${e}`:e,l=a||e;t.push({path:s,section:l,type:n(c),def:c.default===void 0?void 0:JSON.stringify(c.default),desc:c.description,enumv:Array.isArray(c.enum)?c.enum:void 0,required:o.has(e)}),c.properties&&r(c,s,l,new Set(c.required??[]));let u=c.additionalProperties;u?.properties&&r(u,`${s}.<name>`,l,new Set(u.required??[]));let d=c.items;d?.properties&&r(d,`${s}[]`,l,new Set(d.required??[]))}};return r(e,``,``,new Set(e.required??[])),t}function tY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``);(0,v.useEffect)(()=>{fc(`/api/config-schema`).then(t).catch(()=>{})},[]);let i=(0,v.useMemo)(()=>eY(e),[e]),a=n.trim().toLowerCase(),o=a?i.filter(e=>e.path.toLowerCase().includes(a)||(e.desc??``).toLowerCase().includes(a)):i,s=(0,v.useMemo)(()=>{let e=new Map;for(let t of o){let n=e.get(t.section)??[];n.push(t),e.set(t.section,n)}return[...e.entries()]},[o]);return e?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:12},children:[(0,J.jsx)(`input`,{className:`backup-path-input`,style:{width:`min(360px, 60vw)`},placeholder:`Search fields & descriptions…`,value:n,onChange:e=>r(e.target.value)}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsxs)(`span`,{className:`muted`,children:[o.length,` options`]})]}),s.length===0?(0,J.jsxs)(`div`,{className:`muted`,children:[`No fields match “`,n,`”.`]}):(0,J.jsx)(`div`,{className:`fguide`,children:s.map(([e,t])=>(0,J.jsxs)(`div`,{className:`fguide__sec`,children:[(0,J.jsx)(`h4`,{className:`fguide__sechd`,children:e}),(0,J.jsx)(`div`,{className:`fguide__list`,children:t.map(e=>(0,J.jsxs)(`div`,{className:`fguide__item`,children:[(0,J.jsxs)(`div`,{className:`fguide__top`,children:[(0,J.jsx)(`code`,{className:`fguide__path`,children:e.path}),(0,J.jsx)(`span`,{className:`fguide__type`,children:e.type}),e.required&&(0,J.jsx)(`span`,{className:`fguide__req`,children:`required`}),e.def!==void 0&&(0,J.jsxs)(`span`,{className:`fguide__def`,children:[`default `,(0,J.jsx)(`code`,{children:e.def})]})]}),e.desc&&(0,J.jsx)(`p`,{className:`fguide__desc`,children:e.desc}),e.enumv&&(0,J.jsx)(`div`,{className:`fguide__enum`,children:e.enumv.map(e=>(0,J.jsx)(`code`,{children:e},e))})]},e.path))})]},e))})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading schema…`})}var nY=/("(?:\\.|[^"\\])*"(?:\s*:)?)|\b(true|false|null)\b|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g;function rY(e){let t=[],n=0,r=0;for(let i of e.matchAll(nY)){let a=i.index??0;a>n&&t.push(e.slice(n,a));let o=i[0],s;s=i[1]===void 0?i[2]===void 0?`j-num`:o===`null`?`j-null`:`j-bool`:/:\s*$/.test(o)?`j-key`:`j-str`,t.push((0,J.jsx)(`span`,{className:s,children:o},r++)),n=a+o.length}return n<e.length&&t.push(e.slice(n)),t}var iY=new RegExp([/(;;;[^\n]*)/,/("(?:\\.|[^"\\])*")/,/([0-9A-Fa-f]{2}(?::[0-9A-Fa-f]{2}){5})/,/(\d{1,3}(?:\.\d{1,3}){3}(?:\/\d{1,2})?)/,/([A-Za-z.][\w.-]*)(?==)/,/\b(running|enabled|active|connected|established|reachable|bound|authorized|ok|up)\b/,/\b(disabled|invalid|inactive|stopped|unreachable|timeout|failure|failed|error|rejected|expired|down)\b/,/\b(yes|no|true|false)\b/,/\b(dynamic|slave|builtin|default|passthrough|complete)\b/,/(-?\d+(?:\.\d+)?)/].map(e=>e.source).join(`|`),`gi`);function aY(e){let t=[],n=0,r=0;for(let i of e.matchAll(iY)){let a=i.index??0;a>n&&t.push(e.slice(n,a));let o=i[0],s=`ros-num`;i[1]===void 0?i[2]===void 0?i[3]===void 0?i[4]===void 0?i[5]===void 0?i[6]===void 0?i[7]===void 0?i[8]===void 0?i[9]!==void 0&&(s=`ros-dim`):s=`ros-bool`:s=`ros-bad`:s=`ros-good`:s=`ros-key`:s=`ros-ip`:s=`ros-mac`:s=`ros-str`:s=`ros-comment`,t.push((0,J.jsx)(`span`,{className:s,children:o},r++)),n=a+o.length}return n<e.length&&t.push(e.slice(n)),t}var oY=`mt-pretty-input`;function sY(){try{return localStorage.getItem(oY)!==`0`}catch{return!0}}function cY(e){try{localStorage.setItem(oY,e?`1`:`0`)}catch{}}function lY(e,t){if(!t)return e;try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function uY({value:e,maxHeight:t}){let n=typeof e==`string`?e:JSON.stringify(e,null,2);return(0,J.jsx)(`pre`,{className:`body json`,style:t?{maxHeight:t}:void 0,children:rY(n)})}function dY(e){let t=new Set,n=new Set,r=e=>{if(!e||typeof e!=`object`)return;let i=e;if(i.properties&&typeof i.properties==`object`)for(let e of Object.keys(i.properties))t.add(e),r(i.properties[e]);if(Array.isArray(i.enum))for(let e of i.enum)typeof e==`string`&&n.add(e);for(let e of[`items`,`additionalProperties`,`anyOf`,`oneOf`,`allOf`]){let t=i[e];Array.isArray(t)?t.forEach(r):t&&typeof t==`object`&&r(t)}for(let e of[`$defs`,`definitions`,`patternProperties`]){let t=i[e];if(t&&typeof t==`object`)for(let e of Object.values(t))r(e)}};return r(e),{keys:[...t].sort(),enums:[...n.add(`true`).add(`false`)].sort()}}function fY(e,t){let n=t;for(;n>0&&/[A-Za-z0-9_.-]/.test(e[n-1]);)n--;let r=e.slice(n,t),i=n-1;for(;i>=0&&/\s/.test(e[i]);)i--;return{word:r,start:n,isValue:e[i]===`:`}}var pY=[[`revert in 30s`,3e4],[`revert in 60s`,6e4],[`revert in 2m`,12e4],[`no auto-revert`,0]];function mY({initial:e,onClose:t,onReload:n}){let[r,i]=(0,v.useState)(()=>JSON.stringify(e,null,2)),[a,o]=(0,v.useState)({keys:[],enums:[]}),[s,c]=(0,v.useState)([]),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)({}),[h,g]=(0,v.useState)(null),[_,y]=(0,v.useState)(null),[b,x]=(0,v.useState)(0),[S,C]=(0,v.useState)(6e4),[w,T]=(0,v.useState)(null),E=(0,v.useRef)(null),D=(0,v.useRef)(null),O=(0,v.useRef)(null),k=(0,v.useRef)(null);(0,v.useEffect)(()=>{fc(`/api/config-schema`).then(e=>o(dY(e))).catch(()=>{})},[]),(0,v.useEffect)(()=>{D.current!=null&&E.current&&(E.current.selectionStart=E.current.selectionEnd=D.current,D.current=null)}),(0,v.useEffect)(()=>{let e=setTimeout(()=>{let e;try{e=JSON.parse(r)}catch(e){u(e instanceof Error?e.message:String(e)),c([]);return}u(null),pc(`/api/config/validate`,e).then(e=>c(e.errors??[])).catch(()=>{})},350);return()=>clearTimeout(e)},[r]),(0,v.useEffect)(()=>{if(!_||b<=0)return;let e=setInterval(()=>x(e=>Math.max(0,e-1)),1e3);return()=>clearInterval(e)},[_,b]),(0,v.useEffect)(()=>{_&&b===0&&(_.rollbackMs??0)>0&&(T(`Auto-reverted — changes were not confirmed in time.`),y(null),n())},[_,b,n]);let A=!l&&s.length===0,j=e=>{let{word:t,start:n,isValue:r}=fY(e.value,e.selectionStart);if(t.length<1){f(null);return}let i=(r?a.enums:a.keys).filter(e=>e.startsWith(t)&&e!==t).slice(0,8);if(!i.length){f(null);return}let o=e.value.slice(0,e.selectionStart).split(`
|
|
74
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Hq(e,t){if(e){if(typeof e==`string`)return Uq(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?Uq(e,t):void 0}}function Uq(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function Wq(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}}function Gq(e){if(Array.isArray(e))return e}var Kq=(0,v.createContext)(void 0),qq=e=>{var t=e.children,n=Bq((0,v.useState)(`${ql(`recharts`)}-clip`),1)[0],r=BU();if(r==null)return null;var i=r.x,a=r.y,o=r.width,s=r.height;return v.createElement(Kq.Provider,{value:n},v.createElement(`defs`,null,v.createElement(`clipPath`,{id:n},v.createElement(`rect`,{x:i,y:a,height:s,width:o}))),t)},Jq=[`width`,`height`,`responsive`,`children`,`className`,`style`,`compact`,`title`,`desc`];function Yq(e,t){if(e==null)return{};var n,r,i=Xq(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function Xq(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}var Zq=(0,v.forwardRef)((e,t)=>{var n=e.width,r=e.height,i=e.responsive,a=e.children,o=e.className,s=e.style,c=e.compact,l=e.title,u=e.desc,d=Nv(Yq(e,Jq));return c?v.createElement(v.Fragment,null,v.createElement(fv,{width:n,height:r}),v.createElement(dq,{otherAttributes:d,title:l,desc:u},a)):v.createElement(zq,{className:o,style:s,width:n,height:r,responsive:i??!1,onClick:e.onClick,onMouseLeave:e.onMouseLeave,onMouseEnter:e.onMouseEnter,onMouseMove:e.onMouseMove,onMouseDown:e.onMouseDown,onMouseUp:e.onMouseUp,onContextMenu:e.onContextMenu,onDoubleClick:e.onDoubleClick,onTouchStart:e.onTouchStart,onTouchMove:e.onTouchMove,onTouchEnd:e.onTouchEnd},v.createElement(dq,{otherAttributes:d,title:l,desc:u,ref:t},v.createElement(qq,null,a)))}),Qq=[`layout`];function $q(){return $q=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},$q.apply(null,arguments)}function eJ(e,t){if(e==null)return{};var n,r,i=tJ(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)===-1&&{}.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}function tJ(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function nJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function rJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?nJ(Object(n),!0).forEach(function(t){iJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):nJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function iJ(e,t,n){return(t=aJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function aJ(e){var t=oJ(e,`string`);return typeof t==`symbol`?t:t+``}function oJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var sJ=rJ({accessibilityLayer:!0,stackOffset:`none`,barCategoryGap:`10%`,barGap:4,margin:{top:5,right:5,bottom:5,left:5},reverseStackOrder:!1,syncMethod:`index`,layout:`radial`,responsive:!1,cx:`50%`,cy:`50%`,innerRadius:0,outerRadius:`80%`},RK),cJ=(0,v.forwardRef)(function(e,t){var n=hy(e.categoricalChartProps,sJ),r=n.layout,i=eJ(n,Qq),a=e.chartName,o={chartName:a,defaultTooltipEventType:e.defaultTooltipEventType,validateTooltipEventTypes:e.validateTooltipEventTypes,tooltipPayloadSearcher:e.tooltipPayloadSearcher,eventEmitter:void 0};return v.createElement(WK,{preloadedState:{options:o},reduxStoreName:n.id??a},v.createElement(GK,{chartData:n.data}),v.createElement(qK,{layout:r,margin:n.margin}),v.createElement(YK,{throttleDelay:n.throttleDelay,throttledEvents:n.throttledEvents}),v.createElement(JK,{baseValue:void 0,accessibilityLayer:n.accessibilityLayer,barCategoryGap:n.barCategoryGap,maxBarSize:n.maxBarSize,stackOffset:n.stackOffset,barGap:n.barGap,barSize:n.barSize,syncId:n.syncId,syncMethod:n.syncMethod,className:n.className,reverseStackOrder:n.reverseStackOrder}),v.createElement(XK,{cx:n.cx,cy:n.cy,startAngle:n.startAngle,endAngle:n.endAngle,innerRadius:n.innerRadius,outerRadius:n.outerRadius}),v.createElement(Zq,$q({},i,{ref:t})))});function lJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function uJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?lJ(Object(n),!0).forEach(function(t){dJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):lJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function dJ(e,t,n){return(t=fJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function fJ(e){var t=pJ(e,`string`);return typeof t==`symbol`?t:t+``}function pJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var mJ=[`item`],hJ=uJ(uJ({},sJ),{},{layout:`centric`,startAngle:0,endAngle:360}),gJ=(0,v.forwardRef)((e,t)=>{var n=hy(e,hJ);return v.createElement(cJ,{chartName:`PieChart`,defaultTooltipEventType:`item`,validateTooltipEventTypes:mJ,tooltipPayloadSearcher:EP,categoricalChartProps:n,ref:t})});function _J(){return _J=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_J.apply(null,arguments)}function vJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function yJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?vJ(Object(n),!0).forEach(function(t){bJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):vJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function bJ(e,t,n){return(t=xJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function xJ(e){var t=SJ(e,`string`);return typeof t==`symbol`?t:t+``}function SJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var CJ=yJ({accessibilityLayer:!0,barCategoryGap:`10%`,barGap:4,layout:`horizontal`,margin:{top:5,right:5,bottom:5,left:5},responsive:!1,reverseStackOrder:!1,stackOffset:`none`,syncMethod:`index`},RK),wJ=(0,v.forwardRef)(function(e,t){var n=hy(e.categoricalChartProps,CJ),r=e.chartName,i=e.defaultTooltipEventType,a=e.validateTooltipEventTypes,o=e.tooltipPayloadSearcher,s=e.categoricalChartProps,c={chartName:r,defaultTooltipEventType:i,validateTooltipEventTypes:a,tooltipPayloadSearcher:o,eventEmitter:void 0};return v.createElement(WK,{preloadedState:{options:c},reduxStoreName:s.id??r},v.createElement(GK,{chartData:s.data}),v.createElement(qK,{layout:n.layout,margin:n.margin}),v.createElement(YK,{throttleDelay:n.throttleDelay,throttledEvents:n.throttledEvents}),v.createElement(JK,{baseValue:n.baseValue,accessibilityLayer:n.accessibilityLayer,barCategoryGap:n.barCategoryGap,maxBarSize:n.maxBarSize,stackOffset:n.stackOffset,barGap:n.barGap,barSize:n.barSize,syncId:n.syncId,syncMethod:n.syncMethod,className:n.className,reverseStackOrder:n.reverseStackOrder}),v.createElement(Zq,_J({},n,{ref:t})))}),TJ=[`axis`],EJ=(0,v.forwardRef)((e,t)=>v.createElement(wJ,{chartName:`AreaChart`,defaultTooltipEventType:`axis`,validateTooltipEventTypes:TJ,tooltipPayloadSearcher:EP,categoricalChartProps:e,ref:t}));function DJ(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function OJ(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?DJ(Object(n),!0).forEach(function(t){kJ(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):DJ(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function kJ(e,t,n){return(t=AJ(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function AJ(e){var t=jJ(e,`string`);return typeof t==`symbol`?t:t+``}function jJ(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}var MJ=[`axis`,`item`],NJ=OJ(OJ({},sJ),{},{layout:`radial`,startAngle:0,endAngle:360}),PJ=(0,v.forwardRef)((e,t)=>{var n=hy(e,NJ);return v.createElement(cJ,{chartName:`RadialBarChart`,defaultTooltipEventType:`axis`,validateTooltipEventTypes:MJ,tooltipPayloadSearcher:EP,categoricalChartProps:n,ref:t})}),FJ=e=>new Date(e).toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,hour12:!1});function IJ({active:e,payload:t,label:n,unit:r}){return!e||!t?.length?null:(0,J.jsxs)(`div`,{className:`chart-tip`,children:[n!=null&&(0,J.jsx)(`div`,{className:`chart-tip__label`,children:n}),t.map((e,t)=>(0,J.jsxs)(`div`,{className:`chart-tip__row`,children:[(0,J.jsx)(`span`,{className:`chart-tip__dot`,style:{background:e.color}}),(0,J.jsx)(`span`,{className:`chart-tip__name`,children:e.name??e.dataKey}),(0,J.jsxs)(`span`,{className:`chart-tip__val`,children:[typeof e.value==`number`?e.value.toLocaleString():e.value,r??``]})]},t))]})}var LJ=`color-mix(in srgb, var(--mt-border) 80%, transparent)`,RJ={fill:`var(--mt-text-faint)`,fontSize:10,fontFamily:`var(--mt-mono)`};function zJ({series:e}){return(0,J.jsx)(`div`,{className:`chart`,style:{height:200},children:(0,J.jsx)($_,{width:`100%`,height:`100%`,children:(0,J.jsxs)(EJ,{data:e,margin:{top:8,right:8,left:-18,bottom:0},children:[(0,J.jsxs)(`defs`,{children:[(0,J.jsxs)(`linearGradient`,{id:`fillOk`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,J.jsx)(`stop`,{offset:`0%`,stopColor:`var(--page-accent)`,stopOpacity:.5}),(0,J.jsx)(`stop`,{offset:`100%`,stopColor:`var(--page-accent)`,stopOpacity:.04})]}),(0,J.jsxs)(`linearGradient`,{id:`fillErr`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,J.jsx)(`stop`,{offset:`0%`,stopColor:`var(--mt-bad)`,stopOpacity:.55}),(0,J.jsx)(`stop`,{offset:`100%`,stopColor:`var(--mt-bad)`,stopOpacity:.05})]})]}),(0,J.jsx)(dU,{vertical:!1,stroke:LJ,strokeDasharray:`3 3`}),(0,J.jsx)(kG,{dataKey:`t`,tickFormatter:FJ,tick:RJ,tickLine:!1,axisLine:!1,minTickGap:48}),(0,J.jsx)(WG,{tick:RJ,tickLine:!1,axisLine:!1,width:34,allowDecimals:!1}),(0,J.jsx)(lF,{cursor:{stroke:LJ},content:({active:e,payload:t,label:n})=>(0,J.jsx)(IJ,{active:e,payload:t,label:typeof n==`number`?FJ(n):n})}),(0,J.jsx)(cG,{type:`monotone`,dataKey:`ok`,name:`ok`,stackId:`1`,stroke:`var(--page-accent)`,fill:`url(#fillOk)`,strokeWidth:2,isAnimationActive:!1}),(0,J.jsx)(cG,{type:`monotone`,dataKey:`error`,name:`error`,stackId:`1`,stroke:`var(--mt-bad)`,fill:`url(#fillErr)`,strokeWidth:2,isAnimationActive:!1})]})})})}function BJ({segments:e,centerLabel:t=`calls`}){let n=e.filter(e=>e.value>0),r=e.reduce((e,t)=>e+t.value,0);return(0,J.jsxs)(`div`,{className:`chart chart--donut`,children:[(0,J.jsx)(`div`,{className:`chart-donut__svg`,children:(0,J.jsx)($_,{width:`100%`,height:180,children:(0,J.jsxs)(gJ,{children:[(0,J.jsx)(lF,{content:({active:e,payload:t})=>(0,J.jsx)(IJ,{active:e,payload:t})}),(0,J.jsx)(NB,{data:n,dataKey:`value`,nameKey:`label`,innerRadius:58,outerRadius:80,paddingAngle:2,strokeWidth:0,isAnimationActive:!1,children:n.map(e=>(0,J.jsx)(uF,{fill:e.color},e.label))}),(0,J.jsx)(`text`,{x:`50%`,y:`47%`,textAnchor:`middle`,fill:`var(--mt-text)`,fontSize:22,fontWeight:600,children:r.toLocaleString()}),(0,J.jsx)(`text`,{x:`50%`,y:`59%`,textAnchor:`middle`,fill:`var(--mt-text-dim)`,fontSize:10,children:t})]})})}),(0,J.jsx)(`div`,{className:`chart-legend`,children:n.map(e=>(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:e.color}}),e.label,` `,(0,J.jsx)(`b`,{children:e.value})]},e.label))})]})}function VJ({values:e,color:t,unit:n,maxValue:r,id:i}){let a=e.filter(e=>e!=null);if(a.length===0)return(0,J.jsx)(`div`,{className:`spark spark--empty`,children:`no samples yet`});let o=e.map((e,t)=>({i:t,v:e})),s=a[a.length-1],c=`ma-${(i??t).replace(/[^a-z0-9]/gi,``)}`,l=Math.min(...a),u=Math.max(...a),d=Math.max(0,(n===`%`?10:0)-(u-l))/2,f=l-d,p=u+d,m=(p-f)*.15||1;return f=Math.max(0,f-m),p+=m,r!=null&&(p=Math.min(r,p)),p<=f&&(p=f+1),(0,J.jsxs)(`div`,{className:`chart chart--spark`,children:[(0,J.jsxs)(`span`,{className:`chart-spark__last`,style:{color:t},children:[s.toFixed(n===`%`?0:1),n??``]}),(0,J.jsx)($_,{width:`100%`,height:46,children:(0,J.jsxs)(EJ,{data:o,margin:{top:4,right:2,left:2,bottom:0},children:[(0,J.jsx)(`defs`,{children:(0,J.jsxs)(`linearGradient`,{id:c,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,J.jsx)(`stop`,{offset:`0%`,stopColor:t,stopOpacity:.35}),(0,J.jsx)(`stop`,{offset:`100%`,stopColor:t,stopOpacity:0})]})}),(0,J.jsx)(WG,{hide:!0,domain:[f,p]}),(0,J.jsx)(lF,{cursor:{stroke:LJ},content:({active:e,payload:r})=>(0,J.jsx)(IJ,{active:e,payload:r?.map(e=>({...e,name:`value`,color:t})),unit:n})}),(0,J.jsx)(cG,{type:`monotone`,dataKey:`v`,stroke:t,fill:`url(#${c})`,strokeWidth:1.7,connectNulls:!1,isAnimationActive:!1,dot:!1})]})})]})}function HJ({value:e,label:t,color:n}){let r=e!=null,i=r?Math.max(0,Math.min(100,e)):0;return(0,J.jsxs)(`div`,{className:`gauge`,children:[(0,J.jsxs)(`div`,{className:`gauge__radial`,children:[(0,J.jsx)($_,{width:72,height:72,children:(0,J.jsxs)(PJ,{data:[{name:t,value:i,fill:n}],innerRadius:`72%`,outerRadius:`100%`,startAngle:90,endAngle:-270,barSize:7,children:[(0,J.jsx)(AL,{type:`number`,domain:[0,100],tick:!1,axisLine:!1}),(0,J.jsx)(YV,{dataKey:`value`,cornerRadius:4,background:{fill:`var(--mt-surface-2)`},isAnimationActive:!1})]})}),(0,J.jsx)(`span`,{className:`gauge__pct`,style:{color:r?`var(--mt-text)`:`var(--mt-text-faint)`},children:r?`${Math.round(i)}%`:`n/a`})]}),(0,J.jsx)(`span`,{className:`gauge__label`,children:t})]})}var UJ=40,WJ=30,GJ=1e3,KJ=`http://www.w3.org/2000/svg`,qJ=e=>`${(e/1e6).toFixed(2)} Mbps`,JJ=e=>e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(0)}k`:e>0?`${Math.round(e)}`:`0`;function YJ({history:e}){let t=Math.max(1,...e.flatMap(e=>[e.rx,e.tx])),n=e=>8+e*504/Math.max(1,UJ-1),r=e=>142-e/t*134,i=t=>e.map((e,i)=>`${n(i).toFixed(1)},${r(t(e)).toFixed(1)}`).join(` `),a=t=>{if(e.length<2)return``;let r=n(0).toFixed(1),a=n(e.length-1).toFixed(1);return`${r},${142 .toFixed(1)} ${i(t)} ${a},${142 .toFixed(1)}`};return(0,J.jsx)(`svg`,{className:`clients-chart`,viewBox:`0 0 520 150`,xmlns:KJ,role:`img`,children:e.length>=2&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`polygon`,{className:`rx area`,points:a(e=>e.rx)}),(0,J.jsx)(`polygon`,{className:`tx area`,points:a(e=>e.tx)}),(0,J.jsx)(`polyline`,{className:`rx line`,points:i(e=>e.rx)}),(0,J.jsx)(`polyline`,{className:`tx line`,points:i(e=>e.tx)})]})})}function XJ({history:e}){if(e.length<2)return(0,J.jsx)(`svg`,{className:`mini-spark`,viewBox:`0 0 80 18`});let t=Math.max(1,...e.flatMap(e=>[e.rx,e.tx])),n=e=>1+e*78/Math.max(1,WJ-1),r=e=>17-e/t*16,i=t=>e.map((e,i)=>`${n(i).toFixed(1)},${r(t(e)).toFixed(1)}`).join(` `),a=t=>{let r=n(0).toFixed(1),a=n(e.length-1).toFixed(1),o=17 .toFixed(1);return`${r},${o} ${i(t)} ${a},${o}`};return(0,J.jsxs)(`svg`,{className:`mini-spark`,viewBox:`0 0 80 18`,xmlns:KJ,children:[(0,J.jsx)(`polygon`,{className:`rx area`,points:a(e=>e.rx)}),(0,J.jsx)(`polygon`,{className:`tx area`,points:a(e=>e.tx)}),(0,J.jsx)(`polyline`,{className:`rx line`,points:i(e=>e.rx)}),(0,J.jsx)(`polyline`,{className:`tx line`,points:i(e=>e.tx)})]})}function ZJ({ip:e,deviceName:t,current:n,onSaved:r}){let[i,a]=(0,v.useState)(n.download),[o,s]=(0,v.useState)(n.upload),[c,l]=(0,v.useState)(!1),[u,d]=(0,v.useState)(!1),[f,p]=(0,v.useState)(null);(0,v.useEffect)(()=>{c||(a(n.download),s(n.upload))},[n.download,n.upload,c]);let m=(0,v.useCallback)(async(n,i)=>{d(!0),p(null);try{let a=await pc(`/api/clients/limits`,{ip:e,device:t,download:n,upload:i});p(a.message),a.ok&&(l(!1),r())}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[e,t,r]),h=!!(n.download||n.upload);return(0,J.jsxs)(`div`,{className:`clients-limits`,children:[(0,J.jsxs)(`div`,{className:`clients-limits__hd`,children:[(0,J.jsx)(`span`,{className:`clients-limits__label`,children:`Rate limits`}),(0,J.jsxs)(`span`,{className:`muted`,children:[`current: ↓ `,n.download||`unlimited`,` · ↑ `,n.upload||`unlimited`]})]}),(0,J.jsxs)(`div`,{className:`clients-limits__row`,children:[(0,J.jsxs)(`label`,{className:`clients-limits__field`,children:[(0,J.jsx)(`span`,{className:`muted`,children:`↓ Download`}),(0,J.jsx)(Fc,{placeholder:`10M · blank = unlimited`,value:i,onChange:e=>{l(!0),a(e.target.value)}})]}),(0,J.jsxs)(`label`,{className:`clients-limits__field`,children:[(0,J.jsx)(`span`,{className:`muted`,children:`↑ Upload`}),(0,J.jsx)(Fc,{placeholder:`2M · blank = unlimited`,value:o,onChange:e=>{l(!0),s(e.target.value)}})]}),(0,J.jsx)(Ac,{size:`sm`,type:`accent`,loading:u,onClick:()=>void m(i,o),children:`Apply`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,disabled:u||!h,onClick:()=>{a(``),s(``),m(``,``)},children:`Remove`})]}),f&&(0,J.jsx)(`div`,{className:`muted clients-limits__msg`,children:f})]})}function QJ({device:e,deviceName:t,traffic:n}){let r=n!==void 0;return(0,J.jsxs)(`div`,{className:`clients-detail`,children:[(0,J.jsxs)(`div`,{className:`clients-detail__hd`,children:[(0,J.jsx)(`span`,{className:`clients-detail__title`,children:e.host||e.comment||e.ip}),(0,J.jsxs)(`span`,{className:`muted`,children:[e.ip||`no IP`,` · `,e.mac,` · `,e.iface||`?`,` · `,e.status]})]}),r?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`div`,{className:`clients-rates`,children:[(0,J.jsxs)(`span`,{className:`rate rx`,children:[`↓ `,qJ(n.rxRate)]}),(0,J.jsxs)(`span`,{className:`rate tx`,children:[`↑ `,qJ(n.txRate)]})]}),(0,J.jsx)(YJ,{history:n.history}),(0,J.jsxs)(`div`,{className:`muted clients-totals`,children:[`total ↓ `,Sc(n.rxBytes),` · ↑ `,Sc(n.txBytes)]})]}):(0,J.jsxs)(jc,{type:`secondary`,label:`No per-device counter`,children:[`Set a rate limit below to start tracking this device's Download/Upload (it creates a simple queue targeting `,(0,J.jsx)(`code`,{children:e.ip}),`), or leave it unlimited.`]}),e.ip&&(0,J.jsx)(ZJ,{ip:e.ip,deviceName:t,current:{download:n?.downloadLimit??``,upload:n?.uploadLimit??``},onSaved:()=>{}}),e.ip&&(0,J.jsxs)(`div`,{className:`clients-history`,children:[(0,J.jsx)(`div`,{className:`clients-history__hd`,children:`Usage history · last 3 months`}),(0,J.jsx)(Uc,{endpoint:`/api/usage/client?ip=${encodeURIComponent(e.ip)}${t?`&device=${encodeURIComponent(t)}`:``}&days=90`,days:90})]})]})}function $J(e){let[t,n]=(0,v.useState)(new Map),r=(0,v.useRef)(null);return(0,v.useEffect)(()=>{r.current=null,n(new Map)},[e]),(0,v.useEffect)(()=>{if(!e)return;let t=!1,i=async()=>{try{let i=await fc(`/api/clients/traffic-bulk${e?`?device=${encodeURIComponent(e)}`:``}`);if(t)return;let a=r.current;if(r.current={ts:i.ts,queues:i.queues},!a)return;let o=Math.max(.1,(i.ts-a.ts)/1e3);n(e=>{let t=new Map;for(let[n,r]of Object.entries(i.queues)){let i=a.queues[n],s=e.get(n),c=i?Math.max(0,r.rxBytes-i.rxBytes):0,l=i?Math.max(0,r.txBytes-i.txBytes):0,u=c/o*8,d=l/o*8,f=[...s?.history??[],{rx:u,tx:d}].slice(-30);t.set(n,{rxRate:u,txRate:d,rxBytes:r.rxBytes,txBytes:r.txBytes,downloadLimit:r.downloadLimit,uploadLimit:r.uploadLimit,history:f})}return t})}catch{}};i();let a=setInterval(()=>void i(),GJ);return()=>{t=!0,clearInterval(a)}},[e]),t}function eY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),[m,h]=(0,v.useState)(null),g=$J(n);(0,v.useEffect)(()=>{fc(`/api/devices`).then(e=>{t(e),r(t=>t||e.defaultDevice||e.devices[0]?.name||``)}).catch(()=>t({server:``,defaultDevice:``,devices:[]}))},[]);let _=(0,v.useCallback)(async()=>{try{a(await fc(`/api/clients${n?`?device=${encodeURIComponent(n)}`:``}`)),d(null)}catch(e){d(e instanceof Error?e.message:String(e))}},[n]);(0,v.useEffect)(()=>{a(null),s(null),_();let e=setInterval(()=>void _(),15e3);return()=>clearInterval(e)},[_]);let y=(0,v.useCallback)(async(e,t,r)=>{l(t),d(null);try{let i=await pc(`/api/clients/${e}`,{mac:t,device:n,...r});i.view?a(i.view):await _(),i.ok||d(i.message)}catch(e){d(e instanceof Error?e.message:String(e))}finally{l(null)}},[n,_]),b=(0,v.useCallback)((e,t)=>{s(e.mac),h({mac:e.mac,field:t,value:t===`ip`?e.ip:e.comment||e.host})},[]),x=(0,v.useCallback)(async()=>{if(!m)return;let e=m.value.trim();m.field===`ip`?e&&await y(`set-ip`,m.mac,{ip:e}):await y(`label`,m.mac,{label:e}),h(null)},[m,y]),S=(0,v.useMemo)(()=>{let e=i?.devices??[],t=f.trim().toLowerCase();return t?e.filter(e=>e.ip.toLowerCase().includes(t)||e.mac.toLowerCase().includes(t)||e.host.toLowerCase().includes(t)||e.comment.toLowerCase().includes(t)):e},[i,f]),C=(0,v.useMemo)(()=>i?.devices.find(e=>e.mac===o)??null,[i,o]),w=e?.devices??[],T=i?.counts;return(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsxs)(gc,{title:`Connected clients`,className:`reveal`,extra:(0,J.jsxs)(`div`,{className:`clients-toolbar`,children:[w.length>1&&(0,J.jsx)(Ic,{value:n,onChange:e=>r(e.target.value),"aria-label":`Router`,children:w.map(e=>(0,J.jsxs)(`option`,{value:e.name,children:[e.name,e.isDefault?` (default)`:``]},e.name))}),(0,J.jsx)(`input`,{className:`geist-input`,placeholder:`Filter IP / MAC / name…`,value:f,onChange:e=>p(e.target.value)}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,onClick:()=>void _(),children:`↻ Refresh`})]}),children:[T&&(0,J.jsxs)(`div`,{className:`clients-counts muted`,children:[T.total,` total · `,T.static,` static · `,T.blocked,` blocked`]}),u&&(0,J.jsx)(jc,{type:`error`,className:`clients-error`,children:u}),i?S.length===0?(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`📡`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No connected devices`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[`Nothing in this router's DHCP-lease or ARP table`,f?` matches the filter`:``,`.`]})]}):(0,J.jsxs)(`div`,{className:`clients-table`,children:[(0,J.jsxs)(`div`,{className:`clients-row clients-row--head`,children:[(0,J.jsx)(`span`,{children:`IP`}),(0,J.jsx)(`span`,{children:`Name`}),(0,J.jsx)(`span`,{children:`MAC`}),(0,J.jsx)(`span`,{children:`Iface`}),(0,J.jsx)(`span`,{children:`Status`}),(0,J.jsx)(`span`,{children:`Traffic`}),(0,J.jsx)(`span`,{className:`clients-actions-h`,children:`Actions`})]}),S.map(e=>{let t=e.mac===o,n=c===e.mac,r=e.ip?g.get(e.ip):void 0;return(0,J.jsxs)(`div`,{className:[`clients-row`,t?`is-selected`:``,e.blocked?`is-blocked`:``].filter(Boolean).join(` `),onClick:()=>s(t?null:e.mac),children:[(0,J.jsx)(`span`,{className:`clients-ip`,children:e.ip||`—`}),(0,J.jsx)(`span`,{className:`clients-name`,children:e.host||e.comment||`(unknown)`}),(0,J.jsx)(`span`,{className:`clients-mac`,children:e.mac}),(0,J.jsx)(`span`,{className:`muted`,children:e.iface||``}),(0,J.jsxs)(`span`,{className:`clients-badges`,children:[e.static&&(0,J.jsx)(Mc,{type:`secondary`,children:`static`}),e.blocked?(0,J.jsx)(Mc,{type:`error`,children:`blocked`}):(0,J.jsx)(`span`,{className:`muted`,children:e.status})]}),(0,J.jsx)(`span`,{className:`clients-traffic`,children:r?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`span`,{className:`clients-traffic__rates`,children:[(0,J.jsxs)(`span`,{className:`rx`,children:[`↓`,JJ(r.rxRate)]}),(0,J.jsxs)(`span`,{className:`tx`,children:[`↑`,JJ(r.txRate)]})]}),(0,J.jsx)(XJ,{history:r.history})]}):(0,J.jsx)(`span`,{className:`muted`,children:e.ip?`—`:``})}),(0,J.jsxs)(`span`,{className:`clients-actions`,onClick:e=>e.stopPropagation(),role:`presentation`,children:[e.blocked?(0,J.jsx)(Ac,{size:`sm`,type:`success`,ghost:!0,loading:n,onClick:()=>void y(`allow`,e.mac),children:`Allow`}):(0,J.jsx)(Ac,{size:`sm`,type:`error`,ghost:!0,loading:n,onClick:()=>void y(`block`,e.mac),children:`Block`}),!e.static&&(0,J.jsx)(Ac,{size:`sm`,ghost:!0,loading:n,onClick:()=>void y(`pin`,e.mac),children:`Pin IP`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,disabled:n,onClick:()=>b(e,`ip`),children:`Set IP`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,disabled:n,onClick:()=>b(e,`label`),children:`Label`})]})]},e.mac)})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading connected devices…`}),m&&C?.mac===m.mac&&(0,J.jsxs)(`div`,{className:`clients-edit`,children:[(0,J.jsxs)(`span`,{className:`clients-edit__label`,children:[m.field===`ip`?`Reserve IP for`:`Label for`,` `,(0,J.jsx)(`b`,{children:C.host||C.mac}),`:`]}),(0,J.jsx)(Fc,{autoFocus:!0,value:m.value,placeholder:m.field===`ip`?`e.g. 192.168.88.50`:`e.g. Ali phone`,onChange:e=>h({...m,value:e.target.value}),onKeyDown:e=>{e.key===`Enter`&&x(),e.key===`Escape`&&h(null)}}),(0,J.jsx)(Ac,{size:`sm`,type:`accent`,loading:c===m.mac,onClick:()=>void x(),children:`Save`}),(0,J.jsx)(Ac,{size:`sm`,ghost:!0,onClick:()=>h(null),children:`Cancel`})]}),C&&(0,J.jsx)(QJ,{device:C,deviceName:n,traffic:C.ip?g.get(C.ip):void 0})]})})}function tY(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function nY(e){return new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`,hour12:!1})}function rY({onRestored:e}){let[t,n]=(0,v.useState)(null),[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(!1),[s,c]=(0,v.useState)(null),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)(null),h=(0,v.useCallback)(()=>{fc(`/api/config/history`).then(n).catch(()=>n({versions:[],bytes:0,retention:50}))},[]);(0,v.useEffect)(()=>h(),[h]);let g=(e,t)=>pc(e,t).catch(()=>({error:`request failed`})),_=async()=>{let e=(p??``).trim();m(null);let t=await g(`/api/config/history/checkpoint`,{label:e||void 0});i(t.ok?`Checkpoint saved${e?` · “${e}”`:``}`:`Failed: ${t.error}`),t.ok&&h()},y=async e=>{if(s===e){c(null),u(null);return}c(e),u(null),u(await fc(`/api/config/history/diff?id=${encodeURIComponent(e)}`).catch(()=>null))},b=async t=>{f(null),o(!0);let n=await g(`/api/config/history/restore`,{id:t});o(!1),i(n.ok?`Restored ${t}${n.persisted===!1?` (applied live, not persisted)`:``}`:`Restore failed: ${n.error}`),n.ok&&(h(),e())},x=async e=>{let t=await g(`/api/config/history/delete`,{id:e});i(t.ok?`Version deleted`:`Failed: ${t.error}`),t.ok&&h()};return t?(0,J.jsxs)(J.Fragment,{children:[r&&(0,J.jsx)(`div`,{className:`cfg-msg`,children:r}),(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:14},children:[p===null?(0,J.jsx)(`button`,{className:`btn is-active`,onClick:()=>m(``),children:`★ Save checkpoint`}):(0,J.jsxs)(`span`,{className:`cfgver-cp`,children:[(0,J.jsx)(`input`,{className:`backup-path-input`,autoFocus:!0,placeholder:`checkpoint name (e.g. pre-upgrade)`,value:p,onChange:e=>m(e.target.value),onKeyDown:e=>{e.key===`Enter`&&_(),e.key===`Escape`&&m(null)}}),(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,onClick:()=>void _(),children:`Save`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>m(null),children:`Cancel`})]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsxs)(`span`,{className:`muted`,children:[t.versions.length,` versions · `,tY(t.bytes),` · auto-keep `,t.retention]})]}),t.versions.length===0?(0,J.jsx)(`div`,{className:`muted`,children:`No versions yet — they appear here after each config change.`}):(0,J.jsx)(`ol`,{className:`cfgver`,children:t.versions.map((e,t)=>{let n=e.drift.added+e.drift.removed;return(0,J.jsxs)(`li`,{className:`cfgver__row${t===0?` is-head`:``}`,children:[(0,J.jsx)(`span`,{className:`cfgver__dot`,"aria-hidden":`true`}),(0,J.jsxs)(`div`,{className:`cfgver__main`,children:[(0,J.jsxs)(`div`,{className:`cfgver__line`,children:[(0,J.jsx)(`span`,{className:`cfgver__kind cfgver__kind--${e.kind}`,children:e.kind===`checkpoint`?`★ checkpoint`:`auto`}),e.label&&(0,J.jsx)(`span`,{className:`cfgver__label`,children:e.label}),(0,J.jsx)(`span`,{className:`cfgver__time`,children:nY(e.ts)}),t===0?(0,J.jsx)(`span`,{className:`cfgver__cur`,children:`latest`}):n===0?(0,J.jsx)(`span`,{className:`cfgver__same`,children:`identical to current`}):(0,J.jsxs)(`span`,{className:`cfgver__drift`,children:[(0,J.jsxs)(`span`,{className:`add`,children:[`+`,e.drift.added]}),(0,J.jsxs)(`span`,{className:`rem`,children:[`−`,e.drift.removed]}),(0,J.jsx)(`span`,{className:`muted`,children:` vs current`})]})]}),s===e.id&&(0,J.jsx)(`div`,{className:`cfgver__diff`,children:l?l.unified.trim()?(0,J.jsx)(`pre`,{className:`body diff`,children:l.unified}):(0,J.jsx)(`span`,{className:`muted`,children:`No differences from the current config.`}):(0,J.jsx)(`span`,{className:`muted`,children:`computing diff…`})})]}),(0,J.jsxs)(`div`,{className:`cfgver__actions`,children:[(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void y(e.id),children:s===e.id?`Hide`:`Diff`}),d===e.id?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,disabled:a,onClick:()=>void b(e.id),children:`Confirm restore`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>f(null),children:`Cancel`})]}):(0,J.jsx)(`button`,{className:`topo-btn`,disabled:t===0,title:t===0?`This is the current config`:`Restore this version`,onClick:()=>f(e.id),children:`Restore`}),e.kind===`checkpoint`&&(0,J.jsx)(`button`,{className:`topo-btn cfgver__del`,title:`Delete`,onClick:()=>void x(e.id),children:`✕`})]})]},e.id)})})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading history…`})}function iY(e){if(!e)return[];let t=[],n=e=>e?Array.isArray(e.enum)?`enum`:e.type===`array`?`array<${n(e.items)}>`:Array.isArray(e.type)?e.type.join(` | `):e.type??(e.properties?`object`:`any`):`any`,r=(e,i,a,o)=>{let s=e.properties??{};for(let[e,c]of Object.entries(s)){let s=i?`${i}.${e}`:e,l=a||e;t.push({path:s,section:l,type:n(c),def:c.default===void 0?void 0:JSON.stringify(c.default),desc:c.description,enumv:Array.isArray(c.enum)?c.enum:void 0,required:o.has(e)}),c.properties&&r(c,s,l,new Set(c.required??[]));let u=c.additionalProperties;u?.properties&&r(u,`${s}.<name>`,l,new Set(u.required??[]));let d=c.items;d?.properties&&r(d,`${s}[]`,l,new Set(d.required??[]))}};return r(e,``,``,new Set(e.required??[])),t}function aY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``);(0,v.useEffect)(()=>{fc(`/api/config-schema`).then(t).catch(()=>{})},[]);let i=(0,v.useMemo)(()=>iY(e),[e]),a=n.trim().toLowerCase(),o=a?i.filter(e=>e.path.toLowerCase().includes(a)||(e.desc??``).toLowerCase().includes(a)):i,s=(0,v.useMemo)(()=>{let e=new Map;for(let t of o){let n=e.get(t.section)??[];n.push(t),e.set(t.section,n)}return[...e.entries()]},[o]);return e?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:12},children:[(0,J.jsx)(`input`,{className:`backup-path-input`,style:{width:`min(360px, 60vw)`},placeholder:`Search fields & descriptions…`,value:n,onChange:e=>r(e.target.value)}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsxs)(`span`,{className:`muted`,children:[o.length,` options`]})]}),s.length===0?(0,J.jsxs)(`div`,{className:`muted`,children:[`No fields match “`,n,`”.`]}):(0,J.jsx)(`div`,{className:`fguide`,children:s.map(([e,t])=>(0,J.jsxs)(`div`,{className:`fguide__sec`,children:[(0,J.jsx)(`h4`,{className:`fguide__sechd`,children:e}),(0,J.jsx)(`div`,{className:`fguide__list`,children:t.map(e=>(0,J.jsxs)(`div`,{className:`fguide__item`,children:[(0,J.jsxs)(`div`,{className:`fguide__top`,children:[(0,J.jsx)(`code`,{className:`fguide__path`,children:e.path}),(0,J.jsx)(`span`,{className:`fguide__type`,children:e.type}),e.required&&(0,J.jsx)(`span`,{className:`fguide__req`,children:`required`}),e.def!==void 0&&(0,J.jsxs)(`span`,{className:`fguide__def`,children:[`default `,(0,J.jsx)(`code`,{children:e.def})]})]}),e.desc&&(0,J.jsx)(`p`,{className:`fguide__desc`,children:e.desc}),e.enumv&&(0,J.jsx)(`div`,{className:`fguide__enum`,children:e.enumv.map(e=>(0,J.jsx)(`code`,{children:e},e))})]},e.path))})]},e))})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading schema…`})}var oY=/("(?:\\.|[^"\\])*"(?:\s*:)?)|\b(true|false|null)\b|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)/g;function sY(e){let t=[],n=0,r=0;for(let i of e.matchAll(oY)){let a=i.index??0;a>n&&t.push(e.slice(n,a));let o=i[0],s;s=i[1]===void 0?i[2]===void 0?`j-num`:o===`null`?`j-null`:`j-bool`:/:\s*$/.test(o)?`j-key`:`j-str`,t.push((0,J.jsx)(`span`,{className:s,children:o},r++)),n=a+o.length}return n<e.length&&t.push(e.slice(n)),t}var cY=new RegExp([/(;;;[^\n]*)/,/("(?:\\.|[^"\\])*")/,/([0-9A-Fa-f]{2}(?::[0-9A-Fa-f]{2}){5})/,/(\d{1,3}(?:\.\d{1,3}){3}(?:\/\d{1,2})?)/,/([A-Za-z.][\w.-]*)(?==)/,/\b(running|enabled|active|connected|established|reachable|bound|authorized|ok|up)\b/,/\b(disabled|invalid|inactive|stopped|unreachable|timeout|failure|failed|error|rejected|expired|down)\b/,/\b(yes|no|true|false)\b/,/\b(dynamic|slave|builtin|default|passthrough|complete)\b/,/(-?\d+(?:\.\d+)?)/].map(e=>e.source).join(`|`),`gi`);function lY(e){let t=[],n=0,r=0;for(let i of e.matchAll(cY)){let a=i.index??0;a>n&&t.push(e.slice(n,a));let o=i[0],s=`ros-num`;i[1]===void 0?i[2]===void 0?i[3]===void 0?i[4]===void 0?i[5]===void 0?i[6]===void 0?i[7]===void 0?i[8]===void 0?i[9]!==void 0&&(s=`ros-dim`):s=`ros-bool`:s=`ros-bad`:s=`ros-good`:s=`ros-key`:s=`ros-ip`:s=`ros-mac`:s=`ros-str`:s=`ros-comment`,t.push((0,J.jsx)(`span`,{className:s,children:o},r++)),n=a+o.length}return n<e.length&&t.push(e.slice(n)),t}var uY=`mt-pretty-input`;function dY(){try{return localStorage.getItem(uY)!==`0`}catch{return!0}}function fY(e){try{localStorage.setItem(uY,e?`1`:`0`)}catch{}}function pY(e,t){if(!t)return e;try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function mY({value:e,maxHeight:t}){let n=typeof e==`string`?e:JSON.stringify(e,null,2);return(0,J.jsx)(`pre`,{className:`body json`,style:t?{maxHeight:t}:void 0,children:sY(n)})}function hY(e){let t=new Set,n=new Set,r=e=>{if(!e||typeof e!=`object`)return;let i=e;if(i.properties&&typeof i.properties==`object`)for(let e of Object.keys(i.properties))t.add(e),r(i.properties[e]);if(Array.isArray(i.enum))for(let e of i.enum)typeof e==`string`&&n.add(e);for(let e of[`items`,`additionalProperties`,`anyOf`,`oneOf`,`allOf`]){let t=i[e];Array.isArray(t)?t.forEach(r):t&&typeof t==`object`&&r(t)}for(let e of[`$defs`,`definitions`,`patternProperties`]){let t=i[e];if(t&&typeof t==`object`)for(let e of Object.values(t))r(e)}};return r(e),{keys:[...t].sort(),enums:[...n.add(`true`).add(`false`)].sort()}}function gY(e,t){let n=t;for(;n>0&&/[A-Za-z0-9_.-]/.test(e[n-1]);)n--;let r=e.slice(n,t),i=n-1;for(;i>=0&&/\s/.test(e[i]);)i--;return{word:r,start:n,isValue:e[i]===`:`}}var _Y=[[`revert in 30s`,3e4],[`revert in 60s`,6e4],[`revert in 2m`,12e4],[`no auto-revert`,0]];function vY({initial:e,onClose:t,onReload:n}){let[r,i]=(0,v.useState)(()=>JSON.stringify(e,null,2)),[a,o]=(0,v.useState)({keys:[],enums:[]}),[s,c]=(0,v.useState)([]),[l,u]=(0,v.useState)(null),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)({}),[h,g]=(0,v.useState)(null),[_,y]=(0,v.useState)(null),[b,x]=(0,v.useState)(0),[S,C]=(0,v.useState)(6e4),[w,T]=(0,v.useState)(null),E=(0,v.useRef)(null),D=(0,v.useRef)(null),O=(0,v.useRef)(null),k=(0,v.useRef)(null);(0,v.useEffect)(()=>{fc(`/api/config-schema`).then(e=>o(hY(e))).catch(()=>{})},[]),(0,v.useEffect)(()=>{D.current!=null&&E.current&&(E.current.selectionStart=E.current.selectionEnd=D.current,D.current=null)}),(0,v.useEffect)(()=>{let e=setTimeout(()=>{let e;try{e=JSON.parse(r)}catch(e){u(e instanceof Error?e.message:String(e)),c([]);return}u(null),pc(`/api/config/validate`,e).then(e=>c(e.errors??[])).catch(()=>{})},350);return()=>clearTimeout(e)},[r]),(0,v.useEffect)(()=>{if(!_||b<=0)return;let e=setInterval(()=>x(e=>Math.max(0,e-1)),1e3);return()=>clearInterval(e)},[_,b]),(0,v.useEffect)(()=>{_&&b===0&&(_.rollbackMs??0)>0&&(T(`Auto-reverted — changes were not confirmed in time.`),y(null),n())},[_,b,n]);let A=!l&&s.length===0,j=e=>{let{word:t,start:n,isValue:r}=gY(e.value,e.selectionStart);if(t.length<1){f(null);return}let i=(r?a.enums:a.keys).filter(e=>e.startsWith(t)&&e!==t).slice(0,8);if(!i.length){f(null);return}let o=e.value.slice(0,e.selectionStart).split(`
|
|
75
75
|
`),s=o[o.length-1].length,c=Math.min(12+s*7.22-e.scrollLeft,e.clientWidth-160),l=10+o.length*18-e.scrollTop+4;f({items:i,index:0,start:n,x:Math.max(4,c),y:l})},M=e=>{let t=E.current;if(!t||!d)return;let n=r.slice(0,d.start)+e+r.slice(t.selectionStart);D.current=d.start+e.length,i(n),f(null)},N=e=>{if(!d){e.key===` `&&e.ctrlKey&&(e.preventDefault(),j(e.currentTarget));return}e.key===`ArrowDown`?(e.preventDefault(),f({...d,index:(d.index+1)%d.items.length})):e.key===`ArrowUp`?(e.preventDefault(),f({...d,index:(d.index-1+d.items.length)%d.items.length})):e.key===`Enter`||e.key===`Tab`?(e.preventDefault(),M(d.items[d.index])):e.key===`Escape`&&f(null)},P=()=>{try{return JSON.parse(r)}catch{return null}},F=async()=>{let e=P();if(!e?.devices)return;T(`Testing devices…`);let t={};for(let[n,r]of Object.entries(e.devices)){let e=await pc(`/api/config/test-device`,{name:n,config:r}).catch(()=>({ok:!1}));t[n]=e.ok&&e.status?.reachable===!0?{ok:!0,label:`${Math.round(e.status.latencyMs??0)}ms · ${e.status.identity??`ok`}`}:{ok:!1,label:e.status?.error??e.errors?.[0]?.message??`unreachable`},m({...t})}T(null)},I=async()=>{let e=P();e!=null&&g(await pc(`/api/config/preview`,e))},L=async()=>{let e=P();if(e==null)return;T(`Saving…`);let t=await pc(`/api/config`,{config:e,rollbackMs:S});if(T(null),g(null),!t.ok){c(t.errors??[{path:`(root)`,message:`save rejected`}]);return}y(t),x(Math.round((t.rollbackMs??0)/1e3))},ee=async()=>{_?.pendingId&&(await pc(`/api/config/keep`,{pendingId:_.pendingId}),y(null),T(`Changes kept.`),n())},te=async()=>{_?.pendingId&&(await pc(`/api/config/rollback`,{pendingId:_.pendingId}),y(null),T(`Reverted to the previous config.`),n())},R=r.split(`
|
|
76
|
-
`).length;return(0,J.jsxs)(`div`,{className:`cfgstudio`,children:[(0,J.jsxs)(`div`,{className:`cfg-toolbar`,children:[(0,J.jsx)(`span`,{className:`cfg-status ${A?`is-ok`:`is-bad`}`,children:l?`invalid JSON`:s.length?`${s.length} schema issue(s)`:`valid ✓`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void F(),children:`Test devices`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void I(),disabled:!A,children:`Preview diff`}),(0,J.jsx)(`select`,{className:`cfg-select`,value:S,onChange:e=>C(Number(e.target.value)),title:`Auto-revert window`,children:
|
|
77
|
-
`)}),(0,J.jsxs)(`div`,{className:`cfg-ta-wrap`,children:[(0,J.jsxs)(`pre`,{className:`cfg-hl`,"aria-hidden":`true`,ref:O,children:[
|
|
76
|
+
`).length;return(0,J.jsxs)(`div`,{className:`cfgstudio`,children:[(0,J.jsxs)(`div`,{className:`cfg-toolbar`,children:[(0,J.jsx)(`span`,{className:`cfg-status ${A?`is-ok`:`is-bad`}`,children:l?`invalid JSON`:s.length?`${s.length} schema issue(s)`:`valid ✓`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void F(),children:`Test devices`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void I(),disabled:!A,children:`Preview diff`}),(0,J.jsx)(`select`,{className:`cfg-select`,value:S,onChange:e=>C(Number(e.target.value)),title:`Auto-revert window`,children:_Y.map(([e,t])=>(0,J.jsx)(`option`,{value:t,children:e},t))}),(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,onClick:()=>void L(),disabled:!A||!!_,children:`Save`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:t,children:`Close`})]}),w&&(0,J.jsx)(`div`,{className:`cfg-msg`,children:w}),_&&(0,J.jsxs)(`div`,{className:`cfg-banner`,children:[(0,J.jsx)(`strong`,{children:`Applied.`}),` `,(_.rollbackMs??0)>0?(0,J.jsxs)(J.Fragment,{children:[`Reverting in `,(0,J.jsxs)(`span`,{className:`cfg-count`,children:[b,`s`]}),` unless you keep it.`]}):(0,J.jsx)(J.Fragment,{children:`Saved without an auto-revert window.`}),_.devicesChanged&&(0,J.jsxs)(`span`,{className:`cfg-warn`,children:[` `,`· device list changed — reconnect the MCP client to expose it to the model`]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,onClick:()=>void ee(),children:`Keep changes`}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>void te(),children:`Revert now`})]}),(0,J.jsxs)(`div`,{className:`cfg-editor`,children:[(0,J.jsx)(`pre`,{className:`cfg-gutter`,"aria-hidden":`true`,ref:k,children:Array.from({length:R},(e,t)=>t+1).join(`
|
|
77
|
+
`)}),(0,J.jsxs)(`div`,{className:`cfg-ta-wrap`,children:[(0,J.jsxs)(`pre`,{className:`cfg-hl`,"aria-hidden":`true`,ref:O,children:[sY(r),`
|
|
78
78
|
`]}),(0,J.jsx)(`textarea`,{ref:E,className:`cfg-ta`,spellCheck:!1,wrap:`off`,value:r,onChange:e=>{i(e.target.value),j(e.currentTarget)},onKeyDown:N,onClick:()=>f(null),onScroll:e=>{let t=e.currentTarget;O.current&&(O.current.scrollTop=t.scrollTop,O.current.scrollLeft=t.scrollLeft),k.current&&(k.current.scrollTop=t.scrollTop)}}),d&&(0,J.jsx)(`div`,{className:`cfg-ac`,style:{left:d.x,top:d.y},children:d.items.map((e,t)=>(0,J.jsx)(`div`,{className:`cfg-ac-item${t===d.index?` is-sel`:``}`,onMouseDown:t=>{t.preventDefault(),M(e)},children:e},e))})]})]}),Object.keys(p).length>0&&(0,J.jsx)(`div`,{className:`cfg-chips`,children:Object.entries(p).map(([e,t])=>(0,J.jsxs)(`span`,{className:`cfg-chip ${t.ok?`is-ok`:`is-bad`}`,children:[t.ok?`●`:`○`,` `,e,`: `,t.label]},e))}),(l||s.length>0)&&(0,J.jsx)(`div`,{className:`cfg-errors`,children:l?(0,J.jsxs)(`div`,{className:`cfg-err`,children:[`JSON: `,l]}):s.slice(0,12).map((e,t)=>(0,J.jsxs)(`div`,{className:`cfg-err`,children:[(0,J.jsx)(`code`,{children:e.path}),` — `,e.message]},t))}),h&&(0,J.jsxs)(`div`,{className:`cfg-preview`,children:[(0,J.jsxs)(`div`,{className:`cfg-preview__hd`,children:[(0,J.jsx)(`strong`,{children:`Diff vs current`}),(0,J.jsx)(`span`,{className:`muted`,children:h.summary?.changed?`+${h.summary.added} / -${h.summary.removed}`:`no changes`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>g(null),children:`✕`})]}),(0,J.jsx)(`pre`,{className:`cfg-diff`,children:(h.unified||`(identical)`).split(`
|
|
79
|
-
`).map((e,t)=>(0,J.jsx)(`div`,{className:e.startsWith(`+`)?`d-add`:e.startsWith(`-`)?`d-del`:e.startsWith(`@@`)?`d-hunk`:``,children:e||` `},t))})]})]})}function hY({x:e,y:t,text:n,className:r,textClassName:i,padX:a=9,fontSize:o=9}){let s=(0,v.useRef)(null),[c,l]=(0,v.useState)(()=>n.length*o*.62);(0,v.useLayoutEffect)(()=>{let e=s.current?.getComputedTextLength();e&&e>0&&l(e)},[n,o]);let u=Math.round(c+a*2);return(0,J.jsxs)(`g`,{transform:`translate(${e.toFixed(1)},${t.toFixed(1)})`,children:[(0,J.jsx)(`rect`,{className:r,x:-u/2,y:-9,rx:9,width:u,height:18}),(0,J.jsx)(`text`,{ref:s,className:i,x:0,y:3.5,textAnchor:`middle`,fontSize:o,children:n})]})}function gY(e){return e.reachable===!0?{label:`online`,color:`#d4d4d8`}:e.reachable===!1?{label:`offline`,color:`#f87171`}:{label:`checking…`,color:`#71717a`}}function _Y(e){let t=0;for(let n=0;n<e.length;n++)t=Math.imul(t,31)+e.charCodeAt(n)>>>0;return`hsl(${t%360} 70% 62%)`}function vY(e,t,n,r){let i=1-r;return{x:i*i*e.x+2*i*r*t.x+r*r*n.x,y:i*i*e.y+2*i*r*t.y+r*r*n.y}}function yY(e,t,n,r){let i=1-r,a=2*i*(t.x-e.x)+2*r*(n.x-t.x),o=2*i*(t.y-e.y)+2*r*(n.y-t.y);return Math.atan2(o,a)*180/Math.PI}var bY=`#e4e4e7`,xY=`#d4d4d8`,SY=`#f59e0b`;function CY(e){return e.jumpVia?e.jumpVia:e.jumpHost?`${e.jumpHost.host}:${e.jumpHost.port}`:null}var wY=18,TY=e=>e.length>wY?`${e.slice(0,wY-1)}…`:e,EY=e=>Math.max(23,Math.min(70,e.length*3.1+12));function DY({payload:e,pulses:t}){let n=e.devices,r=Math.max(1,n.length),i=n.map(e=>{let t=TY(e.name);return{d:e,label:t,r:EY(t)}}),a=Math.max(23,...i.map(e=>e.r)),o=r>1?(a+18)/Math.sin(Math.PI/r):0,s=Math.max(110+a,o,120),c=a+60,l=Math.max(700,Math.round((s+a+40)*2)),u=Math.round((s+c)*2),d=l/2,f=u/2,p={x:d,y:f},m=i.map((e,t)=>{let n=t/r*Math.PI*2-Math.PI/2+(r%2==0?Math.PI/r:0);return{...e,i:t,x:d+s*Math.cos(n),y:f+s*Math.sin(n)}});return(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`svg`,{className:`conn`,viewBox:`0 0 ${l} ${u}`,width:`100%`,height:u,preserveAspectRatio:`xMidYMid meet`,children:[(0,J.jsxs)(`defs`,{children:[(0,J.jsxs)(`radialGradient`,{id:`conn-hub`,cx:`0.5`,cy:`0.34`,r:`0.75`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:`#fafafa`}),(0,J.jsx)(`stop`,{offset:`0.6`,stopColor:`#d4d4d8`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:`#a1a1aa`})]}),(0,J.jsxs)(`radialGradient`,{id:`conn-orb`,cx:`0.5`,cy:`0.32`,r:`0.85`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:`#27272a`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:`#18181b`})]}),(0,J.jsxs)(`radialGradient`,{id:`conn-burst`,cx:`0.5`,cy:`0.5`,r:`0.5`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:`#fafafa`}),(0,J.jsx)(`stop`,{offset:`0.5`,stopColor:`#e4e4e7`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:`#a1a1aa`,stopOpacity:`0`})]}),(0,J.jsxs)(`linearGradient`,{id:`conn-tunnel-grad`,x1:`0`,y1:`0`,x2:`1`,y2:`0`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:SY,stopOpacity:`0.15`}),(0,J.jsx)(`stop`,{offset:`0.5`,stopColor:SY,stopOpacity:`0.95`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:SY,stopOpacity:`0.15`})]}),(0,J.jsxs)(`filter`,{id:`conn-tunnel-glow`,x:`-40%`,y:`-40%`,width:`180%`,height:`180%`,children:[(0,J.jsx)(`feGaussianBlur`,{stdDeviation:`3`,result:`b`}),(0,J.jsxs)(`feMerge`,{children:[(0,J.jsx)(`feMergeNode`,{in:`b`}),(0,J.jsx)(`feMergeNode`,{in:`SourceGraphic`})]})]})]}),[.5,.78,1].map((e,t)=>(0,J.jsx)(`circle`,{className:`conn-grid`,cx:d,cy:f,r:s*e},`g-${t}`)),[0,1,2].map(e=>(0,J.jsx)(`circle`,{className:`conn-sonar`,cx:d,cy:f,style:{animationDelay:`${e*1.1}s`}},`s-${e}`)),m.map(({d:e,i:n,x:r,y:i})=>{let a=gY(e.status),o=e.status.reachable===!0,s=e.status.reachable==null,c={x:r,y:i},l=(d+r)/2,u=(f+i)/2,m=r-d,h=i-f,g=Math.hypot(m,h)||1,_=-h/g,v=m/g,y={x:l+_*16,y:u+v*16},b={x:l-_*16,y:u-v*16},x=`M${d},${f} Q${y.x.toFixed(1)},${y.y.toFixed(1)} ${r.toFixed(1)},${i.toFixed(1)}`,S=`M${d},${f} Q${b.x.toFixed(1)},${b.y.toFixed(1)} ${r.toFixed(1)},${i.toFixed(1)}`,C=`M${d},${f} Q${l.toFixed(1)},${u.toFixed(1)} ${r.toFixed(1)},${i.toFixed(1)}`,w=vY(p,y,c,.52),T=yY(p,y,c,.52),E=vY(p,b,c,.48),D=yY(p,b,c,.48)+180,O=t[e.name]??0;return(0,J.jsxs)(`g`,{children:[(0,J.jsx)(`path`,{id:`conn-cmd-${n}`,className:`conn-link`,d:x,stroke:o?bY:a.color,strokeOpacity:o?.5:.32,strokeDasharray:s?`2 8`:o?void 0:`6 7`}),(0,J.jsx)(`path`,{id:`conn-res-${n}`,className:`conn-link`,d:S,stroke:o?xY:a.color,strokeOpacity:o?.5:.18,strokeDasharray:o?void 0:`6 7`}),o&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{className:`conn-flow`,d:x,stroke:`#e4e4e7`}),(0,J.jsx)(`circle`,{className:`conn-packet`,r:3.2,fill:`#e4e4e7`,children:(0,J.jsx)(`animateMotion`,{dur:`2.6s`,repeatCount:`indefinite`,calcMode:`linear`,children:(0,J.jsx)(`mpath`,{href:`#conn-cmd-${n}`})})}),(0,J.jsx)(`rect`,{className:`conn-packet`,x:-2.6,y:-2.6,width:5.2,height:5.2,fill:`#d4d4d8`,transform:`rotate(45)`,children:(0,J.jsx)(`animateMotion`,{dur:`2.6s`,begin:`0.9s`,repeatCount:`indefinite`,calcMode:`linear`,keyPoints:`1;0`,keyTimes:`0;1`,children:(0,J.jsx)(`mpath`,{href:`#conn-res-${n}`})})}),(0,J.jsx)(`path`,{className:`conn-chevron`,d:`M-4,-3 L4,0 L-4,3`,stroke:`#e4e4e7`,transform:`translate(${w.x.toFixed(1)},${w.y.toFixed(1)}) rotate(${T.toFixed(1)})`}),(0,J.jsx)(`path`,{className:`conn-chevron`,d:`M-4,-3 L4,0 L-4,3`,stroke:`#d4d4d8`,transform:`translate(${E.x.toFixed(1)},${E.y.toFixed(1)}) rotate(${D.toFixed(1)})`})]}),O>0&&(0,J.jsx)(`g`,{children:(0,J.jsxs)(`circle`,{r:6,fill:`url(#conn-burst)`,children:[(0,J.jsx)(`animateMotion`,{dur:`1.1s`,repeatCount:`1`,calcMode:`linear`,keyPoints:`0;1;0`,keyTimes:`0;0.5;1`,path:C}),(0,J.jsx)(`animate`,{attributeName:`opacity`,values:`0;1;1;0`,keyTimes:`0;0.1;0.85;1`,dur:`1.1s`,repeatCount:`1`,fill:`freeze`})]})},`burst-${e.name}-${O}`)]},`l-${e.name}`)}),m.map(e=>{let t=e.d.jumpVia,n=t?m.find(e=>e.d.name===t):void 0,r=!n&&e.d.jumpHost?e.d.jumpHost:void 0;if(!n&&!r)return null;let i={x:e.x,y:e.y},a=Math.hypot(e.x-d,e.y-f)||1,o=(e.x-d)/a,s=(e.y-f)/a,c=n?{x:n.x,y:n.y}:{x:e.x+o*(e.r+46),y:e.y+s*(e.r+46)},l=(c.x+i.x)/2,u=(c.y+i.y)/2,p=Math.hypot(l-d,u-f)||1,h=n?50:16,g={x:l+(l-d)/p*h,y:u+(u-f)/p*h},_=`M${c.x.toFixed(1)},${c.y.toFixed(1)} Q${g.x.toFixed(1)},${g.y.toFixed(1)} ${i.x.toFixed(1)},${i.y.toFixed(1)}`,v=CY(e.d)??``,y=vY(c,g,i,.5),b=`conn-tunnel-${e.i}`;return(0,J.jsxs)(`g`,{className:`conn-tunnel-g`,children:[(0,J.jsx)(`path`,{className:`conn-tunnel-halo`,d:_,stroke:SY}),(0,J.jsx)(`path`,{id:b,className:`conn-tunnel`,d:_,stroke:`url(#conn-tunnel-grad)`,filter:`url(#conn-tunnel-glow)`}),r&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{className:`conn-tunnel-sat`,cx:c.x,cy:c.y,r:11,fill:`#1c1917`,stroke:`#f59e0b`}),(0,J.jsx)(`text`,{x:c.x,y:c.y+3.5,textAnchor:`middle`,fontSize:11,children:`🛡️`})]}),(0,J.jsxs)(`text`,{className:`conn-tunnel-lock`,fontSize:13,textAnchor:`middle`,children:[`🔒`,(0,J.jsx)(`animateMotion`,{dur:`2.4s`,repeatCount:`indefinite`,calcMode:`linear`,rotate:`auto`,children:(0,J.jsx)(`mpath`,{href:`#${b}`})})]}),(0,J.jsx)(hY,{x:y.x,y:y.y,text:`⤳ via ${v}`,className:`conn-tunnel-badge`,textClassName:`conn-tunnel-badge-tx`})]},`jump-${e.d.name}`)}),(0,J.jsx)(`circle`,{className:`conn-hub-glow`,cx:d,cy:f,r:42}),(0,J.jsx)(`circle`,{className:`conn-hub-ring`,cx:d,cy:f,r:37}),(0,J.jsx)(`circle`,{cx:d,cy:f,r:29,fill:`url(#conn-hub)`,stroke:`#71717a`,strokeWidth:1.5}),(0,J.jsx)(`text`,{x:d,y:f-4,textAnchor:`middle`,fill:`#09090b`,fontSize:12,fontWeight:700,children:`LLM`}),(0,J.jsx)(`text`,{x:d,y:f+8,textAnchor:`middle`,fill:`#3f3f46`,fontSize:8,fontWeight:600,children:`⇄ MCP`}),(0,J.jsx)(`text`,{x:d,y:f+18,textAnchor:`middle`,fill:`#3f3f46`,fontSize:7.5,fontWeight:600,children:`server`}),m.map(({d:e,x:t,y:n,r,label:i})=>{let a=gY(e.status),o=e.status.reachable===!0,s=o?`${e.status.latencyMs??`?`} ms`:a.label,c=_Y(e.name);return(0,J.jsxs)(`g`,{className:`conn-node`,children:[o&&(0,J.jsx)(`circle`,{className:`conn-node-halo`,cx:t,cy:n,r:r+1,stroke:c}),e.pool?.pooled&&(0,J.jsx)(`circle`,{cx:t,cy:n,r:r+5,fill:`none`,stroke:e.pool.inflight>0?`#3b82f6`:`#22c55e`,strokeWidth:1.5,strokeDasharray:e.pool.inflight>0?void 0:`4 4`,opacity:.5,className:e.pool.inflight>0?`conn-blink`:void 0}),(0,J.jsx)(`circle`,{cx:t,cy:n,r,fill:`url(#conn-orb)`}),(0,J.jsx)(`circle`,{cx:t,cy:n,r,fill:c,opacity:.16}),(0,J.jsx)(`circle`,{cx:t,cy:n,r,fill:`none`,stroke:c,strokeWidth:2.5}),(0,J.jsx)(`circle`,{className:o?`conn-blink`:void 0,cx:t+r*.7,cy:n-r*.7,r:4.5,fill:a.color,stroke:`#0a121b`,strokeWidth:1.5}),(0,J.jsx)(`text`,{x:t,y:n+3.5,textAnchor:`middle`,fill:`#fafafa`,fontSize:10,fontWeight:600,children:i}),(0,J.jsx)(`text`,{x:t,y:n+r+14,textAnchor:`middle`,fill:`#a1a1aa`,fontSize:9,children:e.address??e.host}),(0,J.jsx)(`text`,{x:t,y:n+r+26,textAnchor:`middle`,fill:a.color,fontSize:9,fontWeight:600,children:s})]},`n-${e.name}`)})]}),(0,J.jsxs)(`div`,{className:`conn-legend`,children:[(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:bY}}),` command · LLM → device`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:xY}}),` response · device → LLM`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:`#e4e4e7`}}),` live call (round-trip)`]}),e.devices.some(e=>CY(e))&&(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:`#f59e0b`}}),` 🔒 SSH jump tunnel (ProxyJump)`]}),e.devices.some(e=>e.pool?.pooled)&&(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:`#22c55e`}}),` pooled SSH connection`]})]})]})}function OY({d:e}){let t=gY(e.status),n=e.status.reachable===!0?`${t.label} · ${e.status.latencyMs??`?`}ms${e.status.version?` · v${e.status.version}`:``}`:e.status.reachable===!1?`${t.label}${e.status.error?` · ${e.status.error}`:``}`:t.label,r=_Y(e.name);return(0,J.jsxs)(`div`,{className:`card dev-card`,style:{borderLeft:`3px solid ${r}`},children:[(0,J.jsxs)(`div`,{className:`dev-card__top`,children:[(0,J.jsx)(`span`,{className:`dot`,style:{background:r},title:`device colour`}),(0,J.jsx)(`span`,{className:`dev-card__name`,children:e.name}),e.isDefault&&(0,J.jsx)(Mc,{type:`accent`,children:`default`}),(0,J.jsx)(`span`,{className:`dot dot--status`,style:{background:t.color},title:t.label}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`span`,{className:`chip`,children:e.authMode})]}),(0,J.jsxs)(`div`,{className:`dev-card__meta`,children:[(0,J.jsx)(`span`,{children:e.mac?`mac`:`host`}),(0,J.jsx)(`b`,{children:e.address??`${e.host}:${e.port}`}),(0,J.jsx)(`span`,{children:`user`}),(0,J.jsx)(`b`,{children:e.username}),(0,J.jsx)(`span`,{children:`status`}),(0,J.jsx)(`b`,{style:{color:t.color},children:n}),(0,J.jsx)(`span`,{children:`activity`}),(0,J.jsxs)(`b`,{children:[e.activity.calls,` calls · `,e.activity.errors,` err`,e.activity.avgMs?` · ${xc(e.activity.avgMs)} avg`:``]}),e.pool&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`span`,{children:`pool`}),(0,J.jsx)(`b`,{style:{color:e.pool.dead?`#ef4444`:e.pool.inflight>0?`#3b82f6`:e.pool.pooled?`#22c55e`:`#52525b`},children:e.pool.pooled?e.pool.inflight>0?`${e.pool.inflight} inflight`:`connected`:`—`})]}),e.description&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`span`,{children:`note`}),(0,J.jsx)(`b`,{children:e.description})]})]}),CY(e)&&(0,J.jsxs)(`div`,{className:`jump-route`,title:`Reached over SSH through the bastion ${CY(e)} (ProxyJump) — no port exposed on ${e.name}.`,children:[(0,J.jsxs)(`span`,{className:`jump-route__hop jump-route__hop--bastion`,children:[`🛡️ `,CY(e),e.jumpVia?(0,J.jsx)(`i`,{className:`jump-route__tag`,children:`jump`}):null]}),(0,J.jsx)(`span`,{className:`jump-route__wire jump-route__wire--enc`,children:(0,J.jsx)(`span`,{className:`jump-route__lock`,"aria-hidden":!0,children:`🔒`})}),(0,J.jsxs)(`span`,{className:`jump-route__hop jump-route__hop--dest`,style:{borderColor:r},title:e.name,children:[`📡 `,e.name]})]})]})}function kY({event:e,onClose:t}){let[n,r]=(0,v.useState)(sY);return(0,J.jsx)(`div`,{className:`overlay`,onClick:e=>e.target===e.currentTarget&&t(),children:(0,J.jsxs)(`div`,{className:`sheet`,children:[(0,J.jsxs)(`div`,{className:`sheet__hd`,children:[(0,J.jsx)(`span`,{className:`risk risk-${e.risk}`,children:e.risk}),(0,J.jsxs)(`h3`,{className:`sheet__tool`,children:[e.tool,(0,J.jsx)(bc,{text:e.tool,className:`iconbtn`,icon:!0,title:`Copy tool name`})]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(Ac,{type:`secondary`,size:`sm`,onClick:t,children:`✕ Close`})]}),(0,J.jsxs)(`div`,{className:`kv__body`,children:[(0,J.jsx)(`div`,{className:`kv__k`,children:`title`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.title}),(0,J.jsx)(`div`,{className:`kv__k`,children:`time`}),(0,J.jsx)(`div`,{className:`kv__v`,children:new Date(e.ts).toLocaleString(void 0,{hour12:!1})}),(0,J.jsx)(`div`,{className:`kv__k`,children:`device`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.device??`—`}),(0,J.jsx)(`div`,{className:`kv__k`,children:`transport`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.transport??`—`}),(0,J.jsx)(`div`,{className:`kv__k`,children:`duration`}),(0,J.jsx)(`div`,{className:`kv__v`,children:xc(e.durationMs)}),(0,J.jsx)(`div`,{className:`kv__k`,children:`status`}),(0,J.jsx)(`div`,{className:`kv__v`,children:(0,J.jsx)(`span`,{className:e.isError?`status-err`:`status-ok`,children:e.isError?`error`:`ok`})}),(0,J.jsx)(`div`,{className:`kv__k`,children:`output size`}),(0,J.jsxs)(`div`,{className:`kv__v`,children:[Sc(e.outputBytes),e.truncated?` (truncated)`:``]}),(0,J.jsx)(`div`,{className:`kv__k`,children:`structured`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.hasStructured?`yes (renders an MCP App view)`:`no`})]}),e.error&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`h2`,{className:`muted`,children:`ERROR`}),(0,J.jsx)(`pre`,{className:`body`,style:{color:`var(--mt-bad)`},children:e.error})]}),(0,J.jsxs)(`div`,{className:`sheet__hd`,children:[(0,J.jsx)(`h2`,{className:`muted`,style:{margin:0},children:`INPUT`}),(0,J.jsx)(`span`,{style:{flex:1}}),e.input&&(0,J.jsx)(Ac,{type:`secondary`,size:`sm`,ghost:!0,onClick:()=>r(e=>{let t=!e;return cY(t),t}),title:n?`Showing pretty-printed JSON — click for raw`:`Showing raw JSON — click to pretty-print`,children:n?`✦ Pretty`:`{ } Raw`}),(0,J.jsx)(bc,{text:e.input,title:`Copy input JSON`})]}),e.input?(0,J.jsx)(uY,{value:lY(e.input,n)}):(0,J.jsx)(`pre`,{className:`body`,children:`—`}),(0,J.jsxs)(`div`,{className:`sheet__hd`,children:[(0,J.jsx)(`h2`,{className:`muted`,style:{margin:0},children:`OUTPUT`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(bc,{text:e.output,title:`Copy output`})]}),(0,J.jsx)(`pre`,{className:`body ros`,children:e.output?aY(e.output):`—`})]})})}var AY=e=>e==null?`?`:Sc(e);function jY({d:e}){let t=e.status,n=e.history??[];return t.reachable===!0||n.length>0?(0,J.jsxs)(`div`,{className:`card health-card`,children:[(0,J.jsxs)(`div`,{className:`health-card__hd`,children:[(0,J.jsx)(Nc,{color:gY(t).color}),(0,J.jsx)(`span`,{className:`dev-card__name`,children:e.name}),e.isDefault&&(0,J.jsx)(Mc,{type:`accent`,children:`default`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(Mc,{type:t.version?`success`:`default`,children:t.version?`v${t.version}`:`—`})]}),(0,J.jsxs)(`div`,{className:`health-card__sub muted`,children:[t.boardName??`router`,t.architecture?` · ${t.architecture}`:``,t.cpuCount?` · ${t.cpuCount} cpu`:``,t.uptime?` · up ${t.uptime}`:``]}),(0,J.jsxs)(`div`,{className:`health-card__gauges`,children:[(0,J.jsx)(HJ,{value:t.cpuLoad,label:`CPU`,color:Ec.cpu}),(0,J.jsx)(HJ,{value:t.memUsedPct,label:`MEM`,color:Ec.mem}),(0,J.jsx)(HJ,{value:t.hddUsedPct,label:`DISK`,color:Ec.disk})]}),(0,J.jsxs)(`div`,{className:`health-card__charts`,children:[(0,J.jsxs)(`div`,{className:`health-chart`,children:[(0,J.jsx)(`span`,{className:`health-chart__k`,children:`CPU load`}),(0,J.jsx)(VJ,{id:`${e.name}-cpu`,values:n.map(e=>e.cpuLoad),color:Ec.cpu,maxValue:100,unit:`%`})]}),(0,J.jsxs)(`div`,{className:`health-chart`,children:[(0,J.jsx)(`span`,{className:`health-chart__k`,children:`Memory used`}),(0,J.jsx)(VJ,{id:`${e.name}-mem`,values:n.map(e=>e.memUsedPct),color:Ec.mem,maxValue:100,unit:`%`})]}),(0,J.jsxs)(`div`,{className:`health-chart`,children:[(0,J.jsx)(`span`,{className:`health-chart__k`,children:`Probe latency`}),(0,J.jsx)(VJ,{id:`${e.name}-lat`,values:n.map(e=>e.latencyMs),color:Ec.latency,unit:`ms`})]})]}),(0,J.jsxs)(`div`,{className:`health-card__foot muted`,children:[`RAM `,AY(t.totalMemory&&t.freeMemory?t.totalMemory-t.freeMemory:void 0),` /`,` `,AY(t.totalMemory),` · free disk `,AY(t.freeHdd)]})]}):(0,J.jsxs)(`div`,{className:`card health-card health-card--na`,children:[(0,J.jsxs)(`div`,{className:`health-card__hd`,children:[(0,J.jsx)(Nc,{color:gY(t).color}),(0,J.jsx)(`span`,{className:`dev-card__name`,children:e.name}),e.isDefault&&(0,J.jsx)(Mc,{type:`accent`,children:`default`})]}),(0,J.jsx)(`p`,{className:`muted`,style:{margin:0},children:t.reachable===!1?`Offline — ${t.error??`unreachable`}`:e.mac?`Waiting for the first MAC-Telnet probe (these run every few minutes to avoid contending with tool calls)…`:`Waiting for the first health probe…`})]})}function MY(e,t){let n=(0,v.useRef)(e),r=(0,v.useRef)(t);n.current=e,r.current=t,(0,v.useEffect)(()=>{let e=!1,t=null,i=null,a=()=>{e||(i=new EventSource(dc(`/api/sse`)),i.addEventListener(`hello`,()=>r.current(`sse`)),i.addEventListener(`tool`,e=>{try{n.current(JSON.parse(e.data))}catch{}}),i.onerror=()=>{i&&i.readyState===EventSource.CONNECTING&&r.current(`off`)})},o=()=>{if(e)return;let i=location.protocol===`https:`?`wss`:`ws`;t=new WebSocket(dc(`${i}://${location.host}/api/stream`));let s=!1;t.onopen=()=>{s=!0,r.current(`ws`)},t.onerror=()=>t?.close(),t.onmessage=e=>{try{let t=JSON.parse(e.data);t.type===`event`&&t.event&&n.current(t.event)}catch{}},t.onclose=()=>{e||(r.current(`off`),s?setTimeout(o,2e3):a())}};return o(),()=>{e=!0,t?.close(),i?.close()}},[])}function NY(e){(0,v.useLayoutEffect)(()=>{let t=e.current;if(!t||window.matchMedia(`(prefers-reduced-motion: reduce)`).matches)return;document.documentElement.classList.add(`js-motion`);let n=new WeakSet,r=e=>{n.has(e)||(n.add(e),Ri.set(e,{opacity:0,y:26}),q.create({trigger:e,start:`top 90%`,once:!0,onEnter:()=>Ri.to(e,{opacity:1,y:0,duration:.7,ease:`power3.out`})}))},i=e=>{for(let t of e.querySelectorAll(`.reveal`))r(t)};i(t);let a=new MutationObserver(e=>{for(let t of e)for(let e of t.addedNodes)e instanceof Element&&(e.matches(`.reveal`)&&r(e),i(e))});a.observe(t,{childList:!0,subtree:!0});let o=setInterval(()=>q.refresh(),1200),s=setTimeout(()=>clearInterval(o),7e3);return()=>{a.disconnect(),clearInterval(o),clearTimeout(s);for(let e of q.getAll())e.kill();document.documentElement.classList.remove(`js-motion`)}},[e])}function PY({m:e,busy:t,onToggle:n}){return(0,J.jsxs)(`label`,{className:`mod-row`,"data-on":e.enabled?`1`:void 0,title:e.description,children:[(0,J.jsx)(`input`,{type:`checkbox`,checked:e.enabled,disabled:t,onChange:()=>n(e.slug,!e.enabled)}),(0,J.jsxs)(`span`,{className:`mod-row__main`,children:[(0,J.jsxs)(`span`,{className:`mod-row__name`,children:[e.label,(0,J.jsx)(`code`,{className:`mod-row__slug`,children:e.slug})]}),(0,J.jsx)(`span`,{className:`mod-row__desc muted`,children:e.description})]}),(0,J.jsxs)(`span`,{className:`mod-row__count muted`,children:[e.toolCount,` tool`,e.toolCount===1?``:`s`]})]})}function FY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(new Set),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(``),c=(0,v.useCallback)(()=>{fc(`/api/modules`).then(t).catch(()=>a(`could not load modules`))},[]);(0,v.useEffect)(()=>c(),[c]);let l=e=>t(t=>t?{...t,...e}:e),u=(0,v.useCallback)(async(e,n)=>{r(t=>new Set(t).add(e)),t(t=>t&&{...t,modules:t.modules.map(t=>t.slug===e?{...t,enabled:n}:t)});let i=await pc(`/api/modules/toggle`,{slug:e,enabled:n}).catch(()=>({error:`request failed`}));if(r(t=>{let n=new Set(t);return n.delete(e),n}),i.error||i.ok===!1){a(i.error??`toggle failed`),c();return}l(i);let o=i.persisted?`saved to config`:`applied live (not saved)`,s=i.warning?` ⚠ ${i.warning}`:``;a(`${e} ${n?`enabled`:`disabled`} — ${o}. Reconnect the MCP client (or restart the server) for the tool list to update.${s}`)},[c]),d=(0,v.useCallback)(async(e,t)=>{for(let n of e)await u(n,t)},[u]),f=(0,v.useMemo)(()=>{if(!e)return[];let t=o.trim().toLowerCase(),n=e=>!t||e.slug.toLowerCase().includes(t)||e.label.toLowerCase().includes(t)||e.group.toLowerCase().includes(t)||e.description.toLowerCase().includes(t),r=new Map;for(let t of e.modules){if(!n(t))continue;let e=r.get(t.group)??[];e.push(t),r.set(t.group,e)}return[...r.entries()].map(([e,t])=>({group:e,modules:t}))},[e,o]);if(!e)return(0,J.jsx)(`div`,{className:`muted`,children:`loading modules…`});let p=f.reduce((e,t)=>e+t.modules.length,0);return(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsxs)(gc,{title:`Tool modules`,className:`reveal`,extra:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`span`,{className:`muted`,children:[e.enabledModules,`/`,e.total,` modules · `,e.enabledTools,`/`,e.totalTools,` `,`tools exposed`]}),(0,J.jsx)(`button`,{className:`btn`,onClick:c,style:{marginLeft:10},children:`↻ Refresh`})]}),children:[(0,J.jsxs)(`div`,{className:`legend`,style:{margin:`0 0 10px`},children:[(0,J.jsxs)(`span`,{children:[`writes to: `,(0,J.jsx)(`code`,{children:e.source?.path??`config file`})]}),(0,J.jsx)(`span`,{children:e.hasAllowList?`allow-list active`:`all modules on by default`})]}),(0,J.jsxs)(`p`,{className:`muted`,style:{margin:`0 0 12px`,fontSize:12},children:[`Toggle a module to expose or hide all of its tools. Disabling adds it to`,` `,(0,J.jsx)(`code`,{children:`tools.disabledModules`}),` in your config file; enabling removes it (or adds it to`,` `,(0,J.jsx)(`code`,{children:`tools.enabledModules`}),` when an allow-list is in force). Trimming the surface below ~150–200 tools makes every remaining tool reliably findable by the MCP client. The client must reconnect for changes to take effect.`]}),(0,J.jsxs)(`div`,{className:`mod-toolbar`,children:[(0,J.jsx)(`input`,{className:`input`,placeholder:`Filter modules by name, slug, group or description…`,value:o,onChange:e=>s(e.target.value)}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>void d(e.modules.filter(e=>!e.enabled).map(e=>e.slug),!0),children:`Enable all`}),` `,(0,J.jsx)(`button`,{className:`btn`,onClick:()=>void d(e.modules.filter(e=>e.enabled).map(e=>e.slug),!1),children:`Disable all`})]}),i&&(0,J.jsx)(`div`,{className:`cfg-msg`,style:{marginTop:12},children:i}),p===0?(0,J.jsxs)(`div`,{className:`muted`,style:{padding:12},children:[`No modules match “`,o,`”.`]}):(0,J.jsx)(`div`,{className:`mod-groups`,children:f.map(({group:e,modules:t})=>{let r=t.filter(e=>e.enabled).length,i=t.map(e=>e.slug);return(0,J.jsxs)(`div`,{className:`mod-group`,children:[(0,J.jsxs)(`div`,{className:`mod-group__hd`,children:[(0,J.jsx)(`h3`,{className:`mod-group__title`,children:e}),(0,J.jsxs)(`span`,{className:`muted`,children:[r,`/`,t.length,` on`]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`btn btn-sm`,onClick:()=>void d(i.filter(e=>{let n=t.find(t=>t.slug===e);return n?!n.enabled:!1}),!0),children:`Enable group`}),` `,(0,J.jsx)(`button`,{className:`btn btn-sm`,onClick:()=>void d(i.filter(e=>{let n=t.find(t=>t.slug===e);return n?n.enabled:!1}),!1),children:`Disable group`})]}),(0,J.jsx)(`div`,{className:`mod-list`,children:t.map(e=>(0,J.jsx)(PY,{m:e,busy:n.has(e.slug),onToggle:(e,t)=>void u(e,t)},e.slug))})]},e)})})]})})}var IY={TCP:`#e4e4e7`,UDP:`#d4d4d8`,ICMP:`#a1a1aa`,ICMPv6:`#a1a1aa`,ARP:`#e4e4e7`,IPv6:`#a1a1aa`},LY=e=>e&&IY[e]||`#71717a`;function RY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(!1);(0,v.useEffect)(()=>{let e=()=>void fc(`/api/capture/packets?limit=150`).then(t).catch(()=>{});e();let n=setInterval(e,1500);return()=>clearInterval(n)},[]);let i=e?.stats,a=e?.packets??[],o=async()=>{r(!0),await pc(`/api/capture/stop`,{}).catch(()=>{}),r(!1)};if(!i||!i.running&&i.packets===0)return(0,J.jsxs)(`div`,{className:`cap-idle muted`,children:[`No capture running. Start one with the `,(0,J.jsx)(`code`,{children:`start_packet_capture`}),` tool — point the device's TZSP stream at this host — and decoded packets stream in here live.`]});let s=Math.max(1,...Object.values(i.protocols));return(0,J.jsxs)(`div`,{className:`cap`,children:[(0,J.jsxs)(`div`,{className:`cap-bar`,children:[(0,J.jsx)(`span`,{className:`cap-dot${i.running?` is-on`:``}`}),(0,J.jsx)(`b`,{children:i.running?`capturing`:`stopped`}),(0,J.jsxs)(`span`,{className:`muted`,children:[`UDP `,i.port]}),(0,J.jsxs)(`span`,{className:`muted`,children:[wc(i.packets),` pkts · `,Sc(i.bytes)]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`a`,{className:`btn`,href:dc(`/api/capture/pcap`),download:`capture.pcap`,children:`⤓ pcap`}),(0,J.jsx)(`button`,{className:`btn btn-danger`,onClick:()=>void o(),disabled:n||!i.running,children:`■ Stop`})]}),(0,J.jsxs)(`div`,{className:`cap-cols`,children:[(0,J.jsxs)(`div`,{className:`cap-side`,children:[(0,J.jsx)(`div`,{className:`cap-h`,children:`Protocols`}),Object.entries(i.protocols).map(([e,t])=>(0,J.jsxs)(`div`,{className:`cap-pbar`,children:[(0,J.jsx)(`span`,{className:`cap-plabel`,style:{color:LY(e)},children:e}),(0,J.jsx)(`span`,{className:`cap-ptrack`,children:(0,J.jsx)(`i`,{style:{width:`${t/s*100}%`,background:LY(e)}})}),(0,J.jsx)(`span`,{className:`cap-pn`,children:t})]},e)),(0,J.jsx)(`div`,{className:`cap-h`,style:{marginTop:12},children:`Top talkers`}),i.topTalkers.length===0&&(0,J.jsx)(`div`,{className:`muted`,children:`—`}),i.topTalkers.map(e=>(0,J.jsxs)(`div`,{className:`cap-talker`,children:[(0,J.jsx)(`span`,{children:e.addr}),(0,J.jsx)(`b`,{children:e.count})]},e.addr))]}),(0,J.jsx)(`div`,{className:`cap-list`,children:a.length===0?(0,J.jsx)(`div`,{className:`muted`,style:{padding:10},children:`waiting for packets…`}):a.map((e,t)=>(0,J.jsxs)(`div`,{className:`cap-row`,children:[(0,J.jsx)(`span`,{className:`cap-tt`,children:Cc(e.ts)}),(0,J.jsx)(`span`,{className:`cap-proto`,style:{color:LY(e.protocol)},children:e.protocol??e.ethType}),(0,J.jsx)(`span`,{className:`cap-len`,children:e.len}),(0,J.jsx)(`span`,{className:`cap-info`,children:e.info})]},t))})]})]})}function zY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(null),c=(0,v.useCallback)(()=>{fc(`/api/s3/list`).then(t).catch(()=>t({configured:!1,objects:[]}))},[]);(0,v.useEffect)(()=>c(),[c]);let l=e=>{fc(`/api/s3/presign?key=${encodeURIComponent(e)}`).then(e=>{e.url?window.open(e.url,`_blank`,`noopener`):s(`could not generate download link`)}).catch(()=>s(`could not generate download link`))},u=async e=>{a(e);let t=await pc(`/api/s3/delete`,{key:e}).catch(()=>({error:`request failed`}));a(null),r(null),t.ok?(s(`Deleted ${e}`),c()):s(t.error??`delete failed`)};return e?e.configured?(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsxs)(gc,{title:`S3 backups`,className:`reveal`,extra:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`span`,{className:`muted`,children:[e.target,` · `,e.objects.length,` object`,e.objects.length===1?``:`s`,e.truncated?` (truncated)`:``]}),(0,J.jsx)(`button`,{className:`btn`,onClick:c,style:{marginLeft:10},children:`↻ Refresh`})]}),children:[o&&(0,J.jsx)(`div`,{className:`cfg-msg`,children:o}),e.objects.length===0?(0,J.jsxs)(`div`,{className:`muted`,style:{padding:12},children:[`No objects in the bucket. Upload one with the `,(0,J.jsx)(`code`,{children:`upload_backup_to_s3`}),` tool.`]}):(0,J.jsx)(`div`,{className:`feedwrap`,children:(0,J.jsxs)(`table`,{className:`feed`,children:[(0,J.jsx)(`thead`,{children:(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`th`,{children:`key`}),(0,J.jsx)(`th`,{className:`num`,children:`size`}),(0,J.jsx)(`th`,{children:`modified`}),(0,J.jsx)(`th`,{style:{width:200},children:`actions`})]})}),(0,J.jsx)(`tbody`,{children:e.objects.map(e=>(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`td`,{children:e.key}),(0,J.jsx)(`td`,{className:`num`,children:Sc(e.size)}),(0,J.jsx)(`td`,{children:e.lastModified?new Date(e.lastModified).toLocaleString(void 0,{hour12:!1}):`—`}),(0,J.jsxs)(`td`,{onClick:e=>e.stopPropagation(),children:[(0,J.jsx)(`button`,{className:`btn`,onClick:()=>l(e.key),children:`⤓ Download`}),` `,n===e.key?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`button`,{className:`btn btn-danger`,disabled:i===e.key,onClick:()=>void u(e.key),children:`✓ Confirm`}),` `,(0,J.jsx)(`button`,{className:`btn`,onClick:()=>r(null),children:`Cancel`})]}):(0,J.jsx)(`button`,{className:`btn`,onClick:()=>r(e.key),children:`🗑 Delete`})]})]},e.key))})]})})]})}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`☁️`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`S3 is not configured`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[`Add an `,(0,J.jsx)(`code`,{children:`s3`}),` block (bucket + credentials) to your config to manage backup objects here.`]})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading S3 objects…`})}function BY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),u=(0,v.useCallback)(()=>{fc(`/api/snapshots`).then(e=>t(e.snapshots)).catch(()=>t([]))},[]);(0,v.useEffect)(()=>u(),[u]);let d=e=>{fc(`/api/snapshot/${encodeURIComponent(e)}`).then(s).catch(()=>{})},f=()=>{!n||!i||pc(`/api/snapshots/diff`,{from:n,to:i}).then(l).catch(()=>{})};if(!e)return(0,J.jsx)(`div`,{className:`muted`,children:`loading snapshots…`});if(e.length===0)return(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🕰️`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No config snapshots yet`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[`Capture one with the `,(0,J.jsx)(`code`,{children:`capture_config_snapshot`}),` tool — then time-travel diff any two here.`]})]});let p=e.map(e=>(0,J.jsxs)(`option`,{value:e.id,children:[e.device,` · `,e.label??e.id,` · `,Cc(e.ts)]},e.id));return(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsxs)(gc,{title:`Config snapshots`,className:`reveal`,extra:(0,J.jsx)(`button`,{className:`btn`,onClick:u,children:`↻ Refresh`}),children:[(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:12},children:[(0,J.jsxs)(`select`,{className:`btn`,value:n,onChange:e=>r(e.target.value),children:[(0,J.jsx)(`option`,{value:``,children:`diff from…`}),p]}),(0,J.jsxs)(`select`,{className:`btn`,value:i,onChange:e=>a(e.target.value),children:[(0,J.jsx)(`option`,{value:``,children:`to…`}),p]}),(0,J.jsx)(`button`,{className:`btn is-active`,onClick:f,disabled:!n||!i,children:`Diff →`}),(0,J.jsxs)(`span`,{className:`muted`,children:[e.length,` snapshots`]})]}),(0,J.jsx)(`div`,{className:`feedwrap`,children:(0,J.jsxs)(`table`,{className:`feed`,children:[(0,J.jsx)(`thead`,{children:(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`th`,{children:`captured`}),(0,J.jsx)(`th`,{children:`device`}),(0,J.jsx)(`th`,{children:`label`}),(0,J.jsx)(`th`,{children:`version`}),(0,J.jsx)(`th`,{className:`num`,children:`lines`}),(0,J.jsx)(`th`,{className:`num`,children:`size`}),(0,J.jsx)(`th`,{children:`output`})]})}),(0,J.jsx)(`tbody`,{children:e.map(e=>(0,J.jsxs)(`tr`,{className:o?.id===e.id?`is-selected`:void 0,onClick:()=>d(e.id),children:[(0,J.jsx)(`td`,{children:Cc(e.ts)}),(0,J.jsx)(`td`,{children:e.device}),(0,J.jsx)(`td`,{children:e.label??`—`}),(0,J.jsx)(`td`,{children:e.rosVersion??`—`}),(0,J.jsx)(`td`,{className:`num`,children:e.lines}),(0,J.jsx)(`td`,{className:`num`,children:Sc(e.bytes)}),(0,J.jsx)(`td`,{className:`preview`,children:`view export →`})]},e.id))})]})})]}),c&&(0,J.jsx)(gc,{title:`Time-travel diff`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:c.summary.changed?`+${c.summary.added} / -${c.summary.removed}`:`identical`}),children:(0,J.jsx)(`pre`,{className:`cfg-diff`,children:(c.unified||`(identical)`).split(`
|
|
80
|
-
`).map((e,t)=>(0,J.jsx)(`div`,{className:e.startsWith(`+`)?`d-add`:e.startsWith(`-`)?`d-del`:e.startsWith(`@@`)?`d-hunk`:``,children:e||` `},t))})}),o&&(0,J.jsx)(gc,{title:`Snapshot · ${o.label??o.id}`,className:`reveal`,extra:(0,J.jsx)(Ac,{type:`secondary`,size:`sm`,onClick:()=>s(null),children:`✕ Close`}),children:(0,J.jsx)(`pre`,{className:`body`,style:{maxHeight:460},children:o.body||`(empty)`})})]})}function VY(e){return e==null?`#3f3f46`:e>=85?`#f87171`:e>=60?`#a1a1aa`:`#d4d4d8`}function HY({topo:e,onOnboard:t}){let[n,r]=(0,v.useState)(null),i=e.nodes.filter(e=>e.kind===`device`),a=e.nodes.filter(e=>e.kind===`neighbor`),o=Math.max(1,i.length),s=i.length<=1?0:Math.min(150,76+o*8),c=s+(i.length<=1?180:140),l=Math.max(360,Math.round((c+78)*2)),u=l/2,d=new Map,f=new Map;i.forEach((e,t)=>{if(i.length===1){d.set(e.id,{x:380,y:u}),f.set(e.id,-Math.PI/2);return}let n=t/o*Math.PI*2-Math.PI/2;f.set(e.id,n),d.set(e.id,{x:380+s*Math.cos(n),y:u+s*Math.sin(n)})});let p=new Map,m=new Set(a.map(e=>e.id));for(let t of e.edges)m.has(t.to)&&!p.has(t.to)&&p.set(t.to,t.from);let h=new Map;for(let e of a){let t=p.get(e.id)??i[0]?.id??``;h.set(t,[...h.get(t)??[],e.id])}if(i.length<=1)a.forEach((e,t)=>{let n=t/Math.max(1,a.length)*Math.PI*2-Math.PI/2;d.set(e.id,{x:380+c*Math.cos(n),y:u+c*Math.sin(n)})});else for(let[e,t]of h){let n=f.get(e)??-Math.PI/2,r=Math.min(Math.PI/2.2,.32*t.length);t.forEach((e,i)=>{let a=t.length===1?n:n-r/2+r*i/(t.length-1);d.set(e,{x:380+c*Math.cos(a),y:u+c*Math.sin(a)})})}let g=new Map(e.nodes.map(e=>[e.id,e])),_=n?g.get(n):null;return(0,J.jsxs)(`div`,{className:`topo`,children:[(0,J.jsxs)(`svg`,{viewBox:`0 0 760 ${l}`,width:`100%`,height:Math.min(l,540),preserveAspectRatio:`xMidYMid meet`,children:[e.edges.map((e,t)=>{let n=d.get(e.from),r=d.get(e.to);return!n||!r?null:(0,J.jsx)(`line`,{className:`topo-edge${m.has(e.to)?` is-dashed`:``}`,x1:n.x,y1:n.y,x2:r.x,y2:r.y,children:(0,J.jsxs)(`title`,{children:[e.from,` → `,e.to,e.interface?` (${e.interface})`:``]})},`e-${t}`)}),e.nodes.map(e=>{let t=d.get(e.id);if(!t)return null;let i=e.kind===`device`,a=i?132:108,o=i?50:38,s=t.x-a/2,c=t.y-o/2,l=e.reachable===!0?`#d4d4d8`:e.reachable===!1?`#f87171`:i?`#71717a`:`#e4e4e7`,u=n===e.id;return(0,J.jsxs)(`g`,{className:`topo-node${i?` is-device`:` is-neighbor`}${e.onboardable?` is-onboard`:``}${u?` is-picked`:``}`,transform:`translate(${s},${c})`,onClick:()=>r(t=>t===e.id?null:e.id),children:[(0,J.jsx)(`rect`,{width:a,height:o,rx:9,style:{stroke:l}}),(0,J.jsx)(`text`,{className:`topo-label`,x:9,y:16,children:(e.label||e.id).slice(0,16)}),i?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`text`,{className:`topo-sub`,x:9,y:30,children:(e.board||e.ip||``).slice(0,18)}),(0,J.jsx)(`rect`,{className:`topo-bar-bg`,x:9,y:37,width:a-18,height:4,rx:2}),(0,J.jsx)(`rect`,{x:9,y:37,width:(a-18)*Math.min(100,e.cpuLoad??0)/100,height:4,rx:2,style:{fill:VY(e.cpuLoad)}}),(0,J.jsx)(`rect`,{className:`topo-bar-bg`,x:9,y:43,width:a-18,height:4,rx:2}),(0,J.jsx)(`rect`,{x:9,y:43,width:(a-18)*Math.min(100,e.memUsedPct??0)/100,height:4,rx:2,style:{fill:VY(e.memUsedPct)}})]}):(0,J.jsx)(`text`,{className:`topo-sub`,x:9,y:29,children:e.onboardable?`+ onboard`:e.ip||e.mac||``})]},e.id)})]}),(0,J.jsxs)(`div`,{className:`topo-foot`,children:[(0,J.jsxs)(`span`,{className:`legend`,children:[(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{className:`dot`,style:{background:`#d4d4d8`}}),` online`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{className:`dot`,style:{background:`#f87171`}}),` offline`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{className:`dot`,style:{background:`#e4e4e7`}}),` neighbour`]}),(0,J.jsxs)(`span`,{className:`muted`,children:[e.stats.devices,` devices · `,e.stats.neighbors,` discovered ·`,` `,e.stats.onboardable,` onboardable`]})]}),_&&(0,J.jsxs)(`div`,{className:`topo-pop`,children:[(0,J.jsxs)(`div`,{className:`topo-pop__hd`,children:[(0,J.jsx)(`strong`,{children:_.label}),(0,J.jsx)(`span`,{className:`muted`,children:[_.board,_.version,_.mac].filter(Boolean).join(` · `)||`no details advertised`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>r(null),children:`✕`})]}),_.suggestedConfig?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`div`,{className:`muted`,style:{margin:`2px 0 6px`},children:`Not managed yet — add this to your device config to onboard it:`}),(0,J.jsx)(`pre`,{className:`topo-stub`,children:JSON.stringify({[_.suggestedConfig.name]:UY(_.suggestedConfig)},null,2)}),(0,J.jsx)(bc,{className:`topo-btn`,title:`Copy config stub`,label:`Copy config stub`,text:JSON.stringify({[_.suggestedConfig.name]:UY(_.suggestedConfig)},null,2)}),t&&(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,onClick:()=>t(_.suggestedConfig.name,UY(_.suggestedConfig)),children:`Add to config →`})]}):(0,J.jsxs)(`div`,{className:`muted`,children:[`Managed device`,_.ip?` · ${_.ip}`:``,_.uptime?` · up ${_.uptime}`:``]})]})]})]})}function UY(e){let t={port:e.port,username:e.username};return e.host&&(t.host=e.host),e.mac&&(t.mac=e.mac),t}function WY(e){return e>=1e3?`${(e/1e3).toFixed(1)}s`:`${Math.round(e)}ms`}function GY(e){return!e||!e.pooled?`#52525b`:e.dead?`#ef4444`:e.inflight>0?`#3b82f6`:`#22c55e`}function KY(e){return!e||!e.pooled?`no connection`:e.dead?`reconnecting`:e.inflight>0?`${e.inflight} inflight`:`ready`}function qY({device:e}){let t=e.pool,n=!t||!t.pooled?`disconnected`:t.dead?`dead`:t.inflight>0?`busy`:`idle`,r=GY(t),i=!t||!t.pooled?0:t.inflight>0?Math.min(8+t.inflight*15,100):100;return(0,J.jsxs)(`div`,{className:`pool-card pool-card--${n}`,children:[(0,J.jsxs)(`div`,{className:`pool-card__hd`,children:[(0,J.jsx)(`span`,{className:`pool-card__dot`,style:{background:r}}),(0,J.jsx)(`span`,{className:`pool-card__name`,children:e.name}),(0,J.jsx)(`span`,{className:`pool-card__badge`,style:{color:r},children:KY(t)})]}),(0,J.jsxs)(`div`,{className:`pool-pipe`,children:[(0,J.jsx)(`div`,{className:`pool-pipe__fill${n===`busy`?` pool-pipe__fill--pulse`:``}`,style:{width:`${i}%`,background:r}}),t&&t.pooled&&t.inflight>0&&(0,J.jsxs)(`span`,{className:`pool-pipe__label`,children:[t.inflight,` ch`]})]})]})}function JY({k:e,v:t,sub:n}){return(0,J.jsxs)(`div`,{className:`stat`,style:{minWidth:100},children:[(0,J.jsx)(`p`,{className:`k`,children:e}),(0,J.jsxs)(`div`,{className:`v`,children:[t,n!=null&&(0,J.jsxs)(`small`,{children:[` `,n]})]})]})}function YY({devices:e,poolPayload:t}){let n=e.filter(e=>e.pool!==null&&e.pool!==void 0);if(!(t?.enabled??n.length>0)&&n.length===0)return(0,J.jsxs)(`details`,{className:`pool-panel`,open:!0,children:[(0,J.jsx)(`summary`,{style:{cursor:`pointer`,fontWeight:600,marginBottom:8},children:`SSH Connection Pool`}),(0,J.jsxs)(`p`,{className:`pool-disabled`,children:[`Connection pooling is disabled. Enable it with `,(0,J.jsx)(`code`,{children:`--ssh-keep-alive true`}),` or`,` `,(0,J.jsx)(`code`,{children:`MIKROTIK_SSH__KEEP_ALIVE=true`}),` to keep persistent SSH connections across tool calls.`]})]});let r=t?.aggregate,i=t?.config;return(0,J.jsxs)(`details`,{className:`pool-panel`,open:!0,children:[(0,J.jsx)(`summary`,{style:{cursor:`pointer`,fontWeight:600,marginBottom:8},children:`SSH Connection Pool`}),r&&(0,J.jsxs)(`div`,{className:`pool-stats`,children:[(0,J.jsx)(JY,{k:`Connections`,v:String(r.totalConnections)}),(0,J.jsx)(JY,{k:`Inflight`,v:String(r.totalInflight),sub:`channels`}),(0,J.jsx)(JY,{k:`Idle`,v:String(r.totalIdle)}),(0,J.jsx)(JY,{k:`Busy`,v:String(r.totalBusy)}),i&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(JY,{k:`Keepalive`,v:WY(i.keepAliveInterval)}),(0,J.jsx)(JY,{k:`Idle timeout`,v:WY(i.idleTimeout)})]})]}),n.length>0&&(0,J.jsx)(`div`,{className:`pool-grid`,children:n.map(e=>(0,J.jsx)(qY,{device:e},e.name))})]})}Ri.registerPlugin(q);function XY(e,t,n){let r=URL.createObjectURL(new Blob([t],{type:`${n};charset=utf-8`})),i=document.createElement(`a`);i.href=r,i.download=e,document.body.append(i),i.click(),i.remove(),URL.revokeObjectURL(r)}var ZY=[{id:`overview`,label:`Overview`,sub:`Calls, latency & risk at a glance`},{id:`devices`,label:`Devices`,sub:`Connectivity radar & system health`},{id:`clients`,label:`Clients`,sub:`Connected LAN devices — usage, block/allow, pin IP`},{id:`aaa`,label:`RADIUS & UM`,sub:`RADIUS client & User Manager RADIUS server`},{id:`topology`,label:`Topology`,sub:`Layer-2 neighbours via MNDP / CDP / LLDP`},{id:`packets`,label:`Packets`,sub:`Live TZSP capture & decode`},{id:`snapshots`,label:`Snapshots`,sub:`Config history & time-travel diff`},{id:`plan`,label:`Change Plan`,sub:`Dry-run intended RouterOS commands`},{id:`s3`,label:`S3 Backups`,sub:`List, download & delete S3 backup objects`},{id:`backups`,label:`Backups`,sub:`Local config vault — create, restore, manage`},{id:`modules`,label:`Modules`,sub:`Enable/disable tool modules — curate the surface`},{id:`config`,label:`Config`,sub:`Effective configuration & safe editor`},{id:`feed`,label:`Live Feed`,sub:`Every tool call, in real time`}],QY=new Set(ZY.map(e=>e.id)),$Y=`mt-view`;function eX(){try{let e=location.hash.replace(/^#\/?/,``);return QY.has(e)?e:null}catch{return null}}function tX(){let e=eX();if(e)return e;try{let e=localStorage.getItem($Y);if(e&&QY.has(e))return e}catch{}return`overview`}var nX=[`#ededed`,`#a1a1a1`],rX={overview:nX,devices:nX,clients:nX,aaa:nX,topology:nX,packets:nX,snapshots:nX,plan:nX,s3:nX,backups:nX,modules:nX,config:nX,feed:nX},iX={overview:{what:`A live pulse of all MCP tool activity: total calls, error rate, p50/p95 latency, the busiest tools, and a risk breakdown — over a time window you choose.`,tips:[`Change the time window (top-right) to zoom from the last 5 minutes out to 24 hours.`,`The risk donut splits calls by annotation: read · write · destructive · dangerous.`,`A rising error line usually points at one device or one tool — jump to Live Feed to see which.`]},devices:{what:`Every configured router with its live reachability (SSH or MAC-Telnet), latency, identity, and system health — CPU, memory and disk — refreshed continuously.`,tips:[`Each device gets a stable colour so you can track it across the connectivity radar.`,`Health (CPU/Mem/Disk) is probed periodically; MAC-Telnet devices are probed on a slower cadence.`,`Latency tiers are colour-coded green → amber → red; a grey node is currently unreachable.`,`The SSH Connection Pool panel shows persistent connections: green = idle/ready, blue = busy with inflight channels, red = reconnecting.`]},clients:{what:`The LAN devices connected to a router — merged from its DHCP leases and ARP table — with live Download/Upload charts, and one-click controls to block/allow a device, pin (reserve) its IP, change that IP, or relabel it.`,tips:[`Pick the router (top-right) to inspect its connected devices; filter by IP, MAC or name.`,`Click a device to open its live ↓/↑ traffic chart — needs a simple queue targeting its IP.`,`Block/allow is enforced by MAC, so it survives the device changing IP; “Pin IP” makes its lease static.`]},aaa:{what:"Full management of the router's RADIUS client (`/radius`) and the built-in User Manager RADIUS server (`/user-manager`): RADIUS servers + incoming CoA, and User Manager users, service profiles, rate/quota limitations, NAS clients, profile assignments, accounting sessions, and global settings.",tips:[`Pick the router (top-right), then switch tabs across RADIUS, Users, Profiles, Limitations, NAS, Assignments, Sessions and Settings.`,`Every tab is full CRUD: add, edit, enable/disable and remove — secrets are write-only and shown redacted.`,`The Usage & Heatmap tab shows each user's 3-month download/upload and a GitHub-style connection heatmap, persisted locally.`,`If a device lacks the user-manager package, the User Manager tabs explain how to install it; RADIUS-client tabs still work.`]},topology:{what:`A Layer-2 map of neighbours each router discovers via MNDP / CDP / LLDP — the physical adjacency of your network, drawn live.`,tips:[`Solid nodes are configured devices; faint nodes are discovered-but-unmanaged neighbours.`,`Use “Add to config →” on an unmanaged neighbour to pre-fill it in the Config editor.`,`Drag to pan; the layout settles automatically as new neighbours arrive.`]},packets:{what:`Live packet capture streamed from a router over TZSP — decode headers in real time without leaving the dashboard.`,tips:[`Pick a device and start the capture; packets decode as they arrive.`,`Stop the capture when done — it frees the router-side sniffer.`,`Great for debugging a protocol issue alongside the Live Feed of tool calls.`]},snapshots:{what:`Point-in-time captures of a device’s full configuration (/export), stored locally so you can diff any two and see exactly what changed.`,tips:[`Capture a snapshot before a risky change, then diff after to audit the delta.`,`The diff is line-level: green added, red removed.`,`Snapshots are device config exports — for the dashboard’s OWN config history see the Config page.`]},plan:{what:`Dry-run the exact RouterOS commands a change would run before it touches a device — a change plan you can review and trust.`,tips:[`Paste or build intended commands to see them validated and ordered.`,`Nothing is sent to the device from here — it’s a preview.`,`Pair with Safe Mode (auto-revert) when you do apply for real.`]},s3:{what:`Browse, download, and delete backup objects in your configured S3-compatible bucket — your off-box archive of device backups and exports.`,tips:[`Filter by key prefix to find a device’s backups quickly.`,`Download fetches the object through a presigned URL; delete is permanent.`,`For host-side .rsc backups instead, use the Backups page.`]},backups:{what:`A local config vault on the MCP server: capture a device’s /export as a timestamped .rsc file, then download, upload, rename, restore (via Safe Mode), or delete it.`,tips:[`Restore offers a dry-run (applies then rolls back) before you commit for real.`,`Edit the vault path inline in the header — it’s saved to your config.`,`Filenames are stamped in the device’s local 24-hour clock.`]},modules:{what:"Every tool module in the catalog with a live on/off switch. Toggling one writes your config file's `tools` block (disabledModules / enabledModules) and applies it immediately, so you can curate exactly which scopes the MCP server exposes.",tips:[`MCP clients search-rank tools and degrade past ~100; trim the surface below ~150–200 tools so every remaining tool is reliably findable.`,`Disable adds the module to tools.disabledModules; enable removes it (or adds it to an active allow-list) — your config file is updated live on each toggle.`,`Changes need an MCP client reconnect (or a server restart) to actually shrink/grow the visible tool list.`]},config:{what:`View the effective configuration, edit it safely with schema-aware validation and auto-rollback, browse a full field guide, and travel through config version history.`,tips:[`Every successful apply is auto-saved to the version timeline — restore any point in time.`,`Save a named checkpoint before a big change for an easy, labelled rollback.`,`The Field Guide documents every config option, its type, and default — straight from the schema.`]},feed:{what:`Every tool call as it happens — tool, device, risk, duration, and success/error — with full request/response detail on click.`,tips:[`Filter by status to isolate failures, or by tool/device to follow one thread.`,`Click any row to open the full (secret-redacted) request and response.`,`Pause the stream when you want to inspect without rows shifting under you.`]}};function aX({view:e}){let t=iX[e];return(0,J.jsxs)(`div`,{className:`pagehelp reveal`,role:`region`,"aria-label":`Page help`,children:[(0,J.jsx)(`div`,{className:`pagehelp__icon`,"aria-hidden":`true`,children:`?`}),(0,J.jsxs)(`div`,{className:`pagehelp__body`,children:[(0,J.jsx)(`p`,{className:`pagehelp__what`,children:t.what}),(0,J.jsx)(`ul`,{className:`pagehelp__tips`,children:t.tips.map((e,t)=>(0,J.jsx)(`li`,{children:e},t))})]})]})}function oX({name:e}){return(0,J.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.7`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:{overview:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`rect`,{x:`3`,y:`3`,width:`8`,height:`8`,rx:`1.6`}),(0,J.jsx)(`rect`,{x:`13`,y:`3`,width:`8`,height:`5`,rx:`1.6`}),(0,J.jsx)(`rect`,{x:`13`,y:`10`,width:`8`,height:`11`,rx:`1.6`}),(0,J.jsx)(`rect`,{x:`3`,y:`13`,width:`8`,height:`8`,rx:`1.6`})]}),devices:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`7`,rx:`2`}),(0,J.jsx)(`rect`,{x:`3`,y:`13`,width:`18`,height:`7`,rx:`2`}),(0,J.jsx)(`path`,{d:`M7 7.5h.01M7 16.5h.01`})]}),clients:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{cx:`9`,cy:`8`,r:`3`}),(0,J.jsx)(`path`,{d:`M3.5 19a5.5 5.5 0 0 1 11 0`}),(0,J.jsx)(`path`,{d:`M16 7.5a2.5 2.5 0 0 1 0 5M17.5 19a4.5 4.5 0 0 0-2-3.6`})]}),aaa:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M12 3 4 6v5c0 4.4 3.2 7.6 8 9 4.8-1.4 8-4.6 8-9V6l-8-3Z`}),(0,J.jsx)(`path`,{d:`M9.5 11.5 11 13l3.5-3.5`})]}),topology:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{cx:`12`,cy:`5`,r:`2.4`}),(0,J.jsx)(`circle`,{cx:`5`,cy:`19`,r:`2.4`}),(0,J.jsx)(`circle`,{cx:`19`,cy:`19`,r:`2.4`}),(0,J.jsx)(`path`,{d:`M12 7.4 6.4 16.6M12 7.4 17.6 16.6`})]}),packets:(0,J.jsx)(`path`,{d:`M3 12h4l2-7 4 14 2-7h6`}),snapshots:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M12 3 3 7.5 12 12 21 7.5 12 3Z`}),(0,J.jsx)(`path`,{d:`M3 12 12 16.5 21 12`}),(0,J.jsx)(`path`,{d:`M3 16.5 12 21 21 16.5`})]}),plan:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{cx:`6`,cy:`6`,r:`2.3`}),(0,J.jsx)(`circle`,{cx:`6`,cy:`18`,r:`2.3`}),(0,J.jsx)(`circle`,{cx:`18`,cy:`8`,r:`2.3`}),(0,J.jsx)(`path`,{d:`M6 8.3v7.4M8.3 6H13a3 3 0 0 1 3 3v0`})]}),s3:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`ellipse`,{cx:`12`,cy:`6`,rx:`7`,ry:`2.6`}),(0,J.jsx)(`path`,{d:`M5 6v12c0 1.5 3.1 2.6 7 2.6s7-1.1 7-2.6V6`}),(0,J.jsx)(`path`,{d:`M5 12c0 1.5 3.1 2.6 7 2.6s7-1.1 7-2.6`})]}),backups:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M3 6.5 5 3.5h14l2 3`}),(0,J.jsx)(`rect`,{x:`3`,y:`6.5`,width:`18`,height:`14`,rx:`2`}),(0,J.jsx)(`path`,{d:`M9.5 12h5`})]}),modules:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`rect`,{x:`3`,y:`5`,width:`18`,height:`6`,rx:`3`}),(0,J.jsx)(`circle`,{cx:`8`,cy:`8`,r:`1.5`}),(0,J.jsx)(`rect`,{x:`3`,y:`13`,width:`18`,height:`6`,rx:`3`}),(0,J.jsx)(`circle`,{cx:`16`,cy:`16`,r:`1.5`})]}),config:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M4 7h8M16 7h4M4 17h4M12 17h8`}),(0,J.jsx)(`circle`,{cx:`14`,cy:`7`,r:`2.2`}),(0,J.jsx)(`circle`,{cx:`10`,cy:`17`,r:`2.2`})]}),feed:(0,J.jsx)(`path`,{d:`M4 6h16M4 12h16M4 18h10`})}[e]})}function sX(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(!1),[m,h]=(0,v.useState)(null),[g,_]=(0,v.useState)([]),[y,b]=(0,v.useState)(36e5),[x,S]=(0,v.useState)(!1),[C,w]=(0,v.useState)(`off`),[T,E]=(0,v.useState)(null),[D,O]=(0,v.useState)(()=>new Set),[k,A]=(0,v.useState)({}),[j,M]=(0,v.useState)({tool:``,risk:``,device:``,status:``,q:``}),N=(0,v.useRef)(x);N.current=x;let P=(0,v.useRef)(null);NY(P);let[F,I]=(0,v.useState)(tX),L=(0,v.useCallback)(e=>{I(e);try{eX()!==e&&(location.hash=e),localStorage.setItem($Y,e)}catch{}},[]);(0,v.useEffect)(()=>{if(eX()!==F)try{location.hash=F}catch{}let e=()=>{let e=eX();e&&L(e)};return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]);let[ee,te]=(0,v.useState)(()=>{try{let e=localStorage.getItem(`mt-help-open`);return new Set(e?JSON.parse(e):[])}catch{return new Set}}),R=e=>te(t=>{let n=new Set(t);n.has(e)?n.delete(e):n.add(e);try{localStorage.setItem(`mt-help-open`,JSON.stringify([...n]))}catch{}return n}),[z,ne]=(0,v.useState)(``),[B,re]=(0,v.useState)(`all`),ie=(0,v.useMemo)(()=>{let e=i?.devices??[];return{online:e.filter(e=>e.status.reachable===!0).length,offline:e.filter(e=>e.status.reachable===!1).length,total:e.length}},[i]),ae=(0,v.useMemo)(()=>{let e=i?.devices??[],t=z.trim().toLowerCase();return e.filter(e=>!(B===`online`&&e.status.reachable!==!0||B===`offline`&&e.status.reachable!==!1||t&&!e.name.toLowerCase().includes(t)&&!(e.address??e.host??``).toLowerCase().includes(t)))},[i,z,B]);MY((0,v.useCallback)(e=>{if(N.current)return;_(t=>[e,...t].slice(0,kc));let t=e.device;t&&A(e=>({...e,[t]:(e[t]??0)+1}))},[]),(0,v.useCallback)(e=>w(e),[])),(0,v.useEffect)(()=>{fc(`/api/events?limit=${kc}`).then(e=>_(e.events)).catch(()=>{})},[]);let oe=(0,v.useCallback)(()=>{fc(`/api/stats?window=${y}&buckets=60`).then(t).catch(()=>{})},[y]);(0,v.useEffect)(()=>{oe();let e=()=>{oe(),fc(`/api/meta`).then(r).catch(()=>{}),fc(`/api/devices`).then(a).catch(()=>{}),fc(`/api/ssh-pool`).then(s).catch(()=>{}),fc(`/api/topology`).then(l).catch(()=>{})};e();let t=setInterval(()=>{N.current||e()},4e3);return()=>clearInterval(t)},[oe]),(0,v.useEffect)(()=>{let e=()=>void fc(`/api/config`).then(d).catch(()=>{});e();let t=setInterval(e,3e4);return()=>clearInterval(t)},[]),(0,v.useEffect)(()=>{let e=e=>{e.key===`Escape`&&E(null)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let se=(0,v.useMemo)(()=>{let e=j.q.trim().toLowerCase();return g.filter(t=>!(j.tool&&t.tool!==j.tool||j.risk&&t.risk!==j.risk||j.device&&t.device!==j.device||j.status===`ok`&&t.isError||j.status===`error`&&!t.isError||e&&!t.tool.toLowerCase().includes(e)&&!t.input.toLowerCase().includes(e)&&!t.output.toLowerCase().includes(e)&&!(t.error??``).toLowerCase().includes(e))).sort((e,t)=>t.ts-e.ts)},[g,j]),ce=!!(j.tool||j.risk||j.device||j.status||j.q),V=(0,v.useMemo)(()=>g.filter(e=>e.isError),[g]),le=(0,v.useMemo)(()=>({ok:g.length-V.length,error:V.length}),[g,V]),ue=(0,v.useCallback)(async e=>{try{E(await fc(`/api/event/${encodeURIComponent(e.id)}`))}catch{E(e)}},[]),de=(0,v.useMemo)(()=>se.slice(0,200),[se]),H=(0,v.useMemo)(()=>de.map(e=>e.id),[de]),fe=H.length>0&&H.every(e=>D.has(e)),pe=!fe&&H.some(e=>D.has(e)),me=(0,v.useCallback)(e=>{O(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),he=(0,v.useCallback)(()=>{O(e=>{let t=new Set(e);if(H.length>0&&H.every(e=>t.has(e)))for(let e of H)t.delete(e);else for(let e of H)t.add(e);return t})},[H]),[ge,_e]=(0,v.useState)(!1),ve=(0,v.useCallback)(async()=>{let e=[...D];if(e.length!==0)try{await mc({ids:e});let t=new Set(e);_(e=>e.filter(e=>!t.has(e.id))),O(new Set)}catch{}finally{_e(!1)}},[D]),ye=e=>{if(e===`json`){XY(`mcp-events.json`,JSON.stringify(se,null,2),`application/json`);return}let t=[`ts`,`tool`,`risk`,`device`,`durationMs`,`isError`,`error`],n=e=>/[",\n]/.test(e)?`"${e.replace(/"/g,`""`)}"`:e,r=se.map(e=>[new Date(e.ts).toISOString(),e.tool,e.risk,e.device??``,String(e.durationMs),String(e.isError),e.error??``].map(n).join(`,`)).join(`
|
|
81
|
-
`);XY(`mcp-events.csv`,`${t.join(`,`)}\n${r}\n`,`text/csv`)},be=e?e.errorRate>=.2?`is-bad`:e.errorRate>=.05?`is-warn`:`is-good`:``,xe=u?.mcp??{},Se=u?.dashboard??{},Ce=u?.ssh??{},we=(e,t,n)=>(0,J.jsxs)(`select`,{className:`btn`,value:j[e],onChange:t=>M(n=>({...n,[e]:t.target.value})),children:[(0,J.jsx)(`option`,{value:``,children:t}),n.map(e=>(0,J.jsx)(`option`,{value:e,children:e},e))]}),Te=ZY.find(e=>e.id===F)??ZY[0];return(0,J.jsxs)(`div`,{className:`shell`,ref:P,"data-view":F,style:{"--page-accent":rX[F][0],"--page-accent-2":rX[F][1]},children:[(0,J.jsxs)(`aside`,{className:`nav`,children:[(0,J.jsxs)(`div`,{className:`nav__brand`,children:[(0,J.jsx)(`div`,{className:`nav__mark`,children:(0,J.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,"aria-hidden":`true`,children:(0,J.jsxs)(`g`,{stroke:`#18181b`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,J.jsx)(`path`,{d:`M12 12 L4 5 M12 12 L20 5 M12 12 L12 20`}),(0,J.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`,fill:`#18181b`,stroke:`none`}),(0,J.jsx)(`circle`,{cx:`4`,cy:`5`,r:`1.9`,fill:`#18181b`,stroke:`none`}),(0,J.jsx)(`circle`,{cx:`20`,cy:`5`,r:`1.9`,fill:`#18181b`,stroke:`none`}),(0,J.jsx)(`circle`,{cx:`12`,cy:`20`,r:`1.9`,fill:`#18181b`,stroke:`none`})]})})}),(0,J.jsxs)(`div`,{className:`nav__brandtext`,children:[(0,J.jsx)(`b`,{children:`MikroTik MCP`}),(0,J.jsx)(`small`,{children:`Observability`})]})]}),(0,J.jsx)(`nav`,{className:`nav__items`,children:ZY.map(e=>(0,J.jsxs)(`button`,{className:`nav__item${F===e.id?` is-active`:``}`,onClick:()=>L(e.id),children:[(0,J.jsx)(oX,{name:e.id}),(0,J.jsx)(`span`,{children:e.label}),e.id===`feed`&&g.length>0&&(0,J.jsx)(`span`,{className:`nav__badge`,children:g.length>999?`999+`:g.length},g.length)]},e.id))}),(0,J.jsxs)(`div`,{className:`nav__foot`,children:[(0,J.jsxs)(`span`,{className:`hero__live${C===`off`?``:` is-on`}${C===`ws`?` is-ws`:C===`sse`?` is-sse`:``}`,title:`Live transport: WebSocket (preferred) or SSE fallback`,children:[(0,J.jsx)(`span`,{className:`dot`}),C===`off`?`offline`:`live · ${C}`]}),(0,J.jsx)(`small`,{className:`muted`,children:n?`${wc(n.total)} events · ${n.transport}`:`connecting…`})]})]}),(0,J.jsxs)(`main`,{className:`main`,"data-view":F,children:[(0,J.jsxs)(`header`,{className:`topline reveal`,children:[(0,J.jsxs)(`div`,{className:`topline__txt`,children:[(0,J.jsx)(`h1`,{children:Te.label}),(0,J.jsx)(`small`,{children:Te.sub})]}),(0,J.jsx)(`span`,{className:`topline__spacer`}),F===`overview`&&(0,J.jsx)(`select`,{className:`btn`,value:y,onChange:e=>b(Number(e.target.value)),title:`Stats time window`,children:Oc.map(([e,t])=>(0,J.jsxs)(`option`,{value:t,children:[`window: `,e]},t))}),(0,J.jsxs)(`button`,{className:`help-toggle${ee.has(F)?` is-on`:``}`,onClick:()=>R(F),"aria-expanded":ee.has(F),title:`About this page`,children:[(0,J.jsx)(`span`,{className:`help-toggle__q`,"aria-hidden":`true`,children:`?`}),`Help`]})]}),ee.has(F)&&(0,J.jsx)(aX,{view:F}),F===`overview`&&(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsx)(`div`,{className:`cards reveal`,children:e?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(_c,{k:`Calls (window)`,v:wc(e.total)}),(0,J.jsx)(_c,{k:`Calls / min`,v:e.callsPerMin.toFixed(1)}),(0,J.jsx)(_c,{k:`Error rate`,v:`${(e.errorRate*100).toFixed(1)}%`,sub:`${e.errors} err`,cls:be}),(0,J.jsx)(_c,{k:`Avg latency`,v:xc(e.latency.avg)}),(0,J.jsx)(_c,{k:`p95 latency`,v:xc(e.latency.p95)}),(0,J.jsx)(_c,{k:`p99 latency`,v:xc(e.latency.p99)}),(0,J.jsx)(_c,{k:`Distinct tools`,v:wc(e.distinctTools)}),(0,J.jsx)(_c,{k:`Output volume`,v:Sc(e.outputBytes)})]}):(0,J.jsxs)(`div`,{className:`stat`,children:[(0,J.jsx)(`p`,{className:`k`,children:`Loading…`}),(0,J.jsx)(`div`,{className:`v`,children:`—`})]})}),(0,J.jsxs)(`div`,{className:`bento reveal`,children:[(0,J.jsx)(gc,{title:`Calls over time`,className:`b-series`,children:e?(0,J.jsx)(zJ,{series:e.series}):(0,J.jsx)(`div`,{className:`muted`,children:`no data`})}),e&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(gc,{title:`By risk`,className:`b-risk`,children:(0,J.jsx)(BJ,{segments:Object.keys(e.byRisk).map(t=>({label:t,value:e.byRisk[t],color:Dc[t]}))})}),(0,J.jsx)(gc,{title:`Top tools`,className:`b-tools`,children:(0,J.jsx)(vc,{rows:e.byTool.map(e=>({label:e.tool,value:e.count,sub:`${e.count}× · ${xc(e.p95Ms)} p95${e.errors?` · ${e.errors} err`:``}`,color:e.errors?`var(--mt-bad)`:void 0}))})}),(0,J.jsx)(gc,{title:`Status`,className:`b-status`,children:(0,J.jsx)(BJ,{centerLabel:`calls`,segments:[{label:`ok`,value:le.ok,color:`#a1a1a1`},{label:`error`,value:le.error,color:`#ff5c5c`}]})}),(0,J.jsx)(gc,{title:`By device`,className:`b-device`,children:e.byDevice.length?(0,J.jsx)(vc,{rows:e.byDevice.map(e=>({label:e.device,value:e.count}))}):(0,J.jsx)(`div`,{className:`muted`,children:`single device`})}),(0,J.jsx)(gc,{title:`Recent errors`,className:`b-errors`,children:V.length?(0,J.jsx)(`div`,{className:`hbar`,children:V.slice(0,8).map(e=>(0,J.jsxs)(`div`,{className:`hbar__row conn-errrow`,style:{gridTemplateColumns:`auto 1fr`},onClick:()=>void ue(e),children:[(0,J.jsx)(`span`,{className:`muted`,children:Cc(e.ts)}),(0,J.jsxs)(`span`,{style:{color:`var(--mt-bad)`,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`,minWidth:0},title:e.error??e.output,children:[e.tool,`: `,e.error??e.output??`error`]})]},e.id))}):(0,J.jsx)(`div`,{className:`muted`,children:`no errors 🎉`})})]})]})]}),F===`devices`&&(i&&i.devices.length>0?(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsxs)(`div`,{className:`dev-toolbar reveal`,children:[(0,J.jsx)(`input`,{className:`search`,type:`search`,placeholder:`Search devices by name or address…`,value:z,onChange:e=>ne(e.target.value),style:{flex:1,minWidth:180}}),(0,J.jsx)(`div`,{className:`dev-filters`,children:[`all`,`online`,`offline`].map(e=>(0,J.jsx)(`button`,{className:`dev-fbtn${B===e?` is-active`:``}`,onClick:()=>re(e),children:e===`all`?`All ${ie.total}`:e===`online`?`Online ${ie.online}`:`Offline ${ie.offline}`},e))}),(0,J.jsxs)(`span`,{className:`muted`,children:[ae.length,`/`,ie.total,` shown`]})]}),(0,J.jsxs)(`details`,{className:`dev-collapse reveal`,open:ie.total<=8,children:[(0,J.jsxs)(`summary`,{children:[`Connectivity radar`,(0,J.jsxs)(`span`,{className:`muted`,children:[` `,`· `,ie.online,` online · `,ie.offline,` offline ·`,` `,ie.total,` total`]})]}),(0,J.jsx)(DY,{payload:i,pulses:k})]}),(0,J.jsx)(YY,{devices:ae,poolPayload:o}),ae.length===0?(0,J.jsxs)(`div`,{className:`feed-empty reveal`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🔍`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No devices match`}),(0,J.jsx)(`p`,{className:`feed-empty__sub`,children:`Try a different search or status filter.`})]}):(0,J.jsx)(`div`,{className:`dev-grid-wide reveal`,children:ae.map(e=>(0,J.jsx)(OY,{d:e},e.name))}),ae.length>0&&(0,J.jsx)(gc,{title:`Device system health`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`CPU · memory · disk · latency · live probe`}),children:(0,J.jsx)(`div`,{className:`health-grid`,children:ae.map(e=>(0,J.jsx)(jY,{d:e},e.name))})})]}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🖧`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No devices configured`}),(0,J.jsx)(jc,{type:`secondary`,label:`Tip`,children:`Add a device to your config to see connectivity and system health here.`})]})),F===`clients`&&(0,J.jsx)(XJ,{}),F===`aaa`&&(0,J.jsx)(pl,{}),F===`topology`&&(c&&c.nodes.length>0?(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsx)(gc,{title:`Network topology`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`Layer-2 neighbours via MNDP/CDP/LLDP · click a neighbour to onboard it`}),children:(0,J.jsx)(HY,{topo:c,onOnboard:(e,t)=>{h({name:e,body:t}),p(!0),L(`config`)}})})}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🛰️`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No neighbours discovered yet`}),(0,J.jsx)(`p`,{className:`feed-empty__sub`,children:`Layer-2 neighbours (MNDP / CDP / LLDP) appear here as the device reports them.`})]})),F===`packets`&&(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsx)(gc,{title:`Packet capture`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`live TZSP decode · /tool sniffer streaming`}),children:(0,J.jsx)(RY,{})})}),F===`snapshots`&&(0,J.jsx)(BY,{}),F===`plan`&&(0,J.jsx)(hl,{}),F===`s3`&&(0,J.jsx)(zY,{}),F===`backups`&&(0,J.jsx)(Lc,{}),F===`modules`&&(0,J.jsx)(FY,{}),F===`config`&&(u?(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsx)(gc,{title:`Configuration`,className:`reveal`,extra:(0,J.jsx)(`button`,{className:`btn`,onClick:()=>p(e=>!e),title:`Edit the config JSON with autocomplete, validation and safe-apply`,children:f?`View`:`✎ Edit config`}),children:f?(0,J.jsx)(mY,{initial:m?{...u,devices:{...u.devices,[m.name]:m.body}}:u,onClose:()=>{p(!1),h(null)},onReload:()=>{h(null),fc(`/api/config`).then(d).catch(()=>{})}},m?`seed-${m.name}`:`config`):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`div`,{className:`legend`,style:{margin:`0 0 10px`},children:[(0,J.jsxs)(`span`,{children:[`transport: `,Tc(xe.transport)]}),(0,J.jsxs)(`span`,{children:[`read-only: `,u.readOnly?`yes`:`no`]}),(0,J.jsxs)(`span`,{children:[`dashboard: `,Tc(Se.host),`:`,Tc(Se.port)]}),(0,J.jsxs)(`span`,{children:[`capture: `,Se.captureBody?`on`:`off`]}),(0,J.jsxs)(`span`,{children:[`s3: `,u.s3?`configured`:`off`]}),(0,J.jsxs)(`span`,{children:[`ssh pool: `,Ce.keepAlive===!1?`off`:`on`]})]}),(0,J.jsxs)(`details`,{className:`cfg`,children:[(0,J.jsx)(`summary`,{children:`Full effective configuration (secrets redacted)`}),(0,J.jsx)(uY,{value:u,maxHeight:340})]})]})}),(0,J.jsx)(gc,{title:`Version history`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`point-in-time snapshots · diff & restore`}),children:(0,J.jsx)($J,{onRestored:()=>void fc(`/api/config`).then(d).catch(()=>{})})}),(0,J.jsx)(gc,{title:`Field guide`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`every config option, documented from the schema`}),children:(0,J.jsx)(tY,{})})]}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(Pc,{}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`Loading configuration…`})]})),F===`feed`&&(0,J.jsxs)(`div`,{className:`panel reveal`,children:[(0,J.jsxs)(`div`,{className:`sheet__hd`,style:{marginBottom:12},children:[(0,J.jsx)(`h2`,{style:{margin:0},children:`Live tool calls`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsxs)(`span`,{className:`muted`,children:[se.length,` shown · `,g.length,` buffered`]})]}),(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:12},children:[(0,J.jsx)(`div`,{className:`grow`,style:{flex:1,minWidth:180},children:(0,J.jsx)(`input`,{className:`search`,type:`search`,placeholder:`Search tool / input / output / error…`,value:j.q,onChange:e=>M(t=>({...t,q:e.target.value}))})}),we(`tool`,`all tools`,n?.tools??[]),we(`risk`,`all risk`,[`READ`,`WRITE`,`WRITE_IDEMPOTENT`,`DESTRUCTIVE`,`DANGEROUS`]),we(`device`,`all devices`,n?.devices??[]),we(`status`,`all status`,[`ok`,`error`]),(0,J.jsx)(`button`,{className:`btn${x?` is-active`:``}`,onClick:()=>S(e=>!e),children:x?`▶ Resume`:`⏸ Pause`}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>ye(`csv`),children:`CSV`}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>ye(`json`),children:`JSON`}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>M({tool:``,risk:``,device:``,status:``,q:``}),children:`Clear`}),ge&&D.size>0?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`button`,{className:`btn btn-danger`,onClick:()=>void ve(),children:[`✓ Confirm delete (`,D.size,`)`]}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>_e(!1),children:`Cancel`})]}):(0,J.jsxs)(`button`,{className:`btn`,disabled:D.size===0,onClick:()=>_e(!0),title:`Delete the selected rows`,children:[`🗑 Delete`,D.size>0?` (${D.size})`:``]})]}),se.length===0?ce?(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🔍`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No calls match your filters`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[g.length,` call`,g.length===1?``:`s`,` buffered — try widening the search or the risk / device / status filters.`]}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>M({tool:``,risk:``,device:``,status:``,q:``}),children:`Clear filters`})]}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__pulse${C===`off`?``:` is-on`}`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:C===`off`?`Not connected`:`Listening for tool calls…`}),(0,J.jsx)(`p`,{className:`feed-empty__sub`,children:C===`off`?`The live stream is offline — it will reconnect automatically.`:`Tool calls the LLM makes against this server stream in here in real time.`})]}):(0,J.jsx)(`div`,{className:`feedwrap`,children:(0,J.jsxs)(`table`,{className:`feed`,children:[(0,J.jsx)(`thead`,{children:(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`th`,{style:{width:28},children:(0,J.jsx)(`input`,{type:`checkbox`,"aria-label":`Select all shown rows`,checked:fe,ref:e=>{e&&(e.indeterminate=pe)},onChange:he})}),(0,J.jsx)(`th`,{children:`time`}),(0,J.jsx)(`th`,{children:`tool`}),(0,J.jsx)(`th`,{children:`risk`}),(0,J.jsx)(`th`,{children:`device`}),(0,J.jsx)(`th`,{className:`num`,children:`dur`}),(0,J.jsx)(`th`,{children:`status`}),(0,J.jsx)(`th`,{children:`output`})]})}),(0,J.jsx)(`tbody`,{children:de.map(e=>(0,J.jsxs)(`tr`,{className:`${e.isError?`is-err`:``}${D.has(e.id)?` is-selected`:``}`.trim()||void 0,onClick:()=>void ue(e),children:[(0,J.jsx)(`td`,{onClick:e=>e.stopPropagation(),children:(0,J.jsx)(`input`,{type:`checkbox`,"aria-label":`Select row`,checked:D.has(e.id),onChange:()=>me(e.id)})}),(0,J.jsx)(`td`,{children:Cc(e.ts)}),(0,J.jsx)(`td`,{children:e.tool}),(0,J.jsx)(`td`,{children:(0,J.jsx)(`span`,{className:`risk risk-${e.risk}`,children:e.risk.replace(`WRITE_IDEMPOTENT`,`WRITE·I`)})}),(0,J.jsx)(`td`,{children:e.device??`—`}),(0,J.jsx)(`td`,{className:`num`,children:xc(e.durationMs)}),(0,J.jsx)(`td`,{children:(0,J.jsx)(`span`,{className:e.isError?`status-err`:`status-ok`,children:e.isError?`error`:`ok`})}),(0,J.jsx)(`td`,{className:`preview`,children:e.isError?e.error??`error`:e.output||`—`})]},e.id))})]})})]})]}),T&&(0,J.jsx)(kY,{event:T,onClose:()=>E(null)})]})}var cX=document.getElementById(`root`);cX&&(0,y.createRoot)(cX).render((0,J.jsx)(sX,{}));
|
|
79
|
+
`).map((e,t)=>(0,J.jsx)(`div`,{className:e.startsWith(`+`)?`d-add`:e.startsWith(`-`)?`d-del`:e.startsWith(`@@`)?`d-hunk`:``,children:e||` `},t))})]})]})}function yY({x:e,y:t,text:n,className:r,textClassName:i,padX:a=9,fontSize:o=9}){let s=(0,v.useRef)(null),[c,l]=(0,v.useState)(()=>n.length*o*.62);(0,v.useLayoutEffect)(()=>{let e=s.current?.getComputedTextLength();e&&e>0&&l(e)},[n,o]);let u=Math.round(c+a*2);return(0,J.jsxs)(`g`,{transform:`translate(${e.toFixed(1)},${t.toFixed(1)})`,children:[(0,J.jsx)(`rect`,{className:r,x:-u/2,y:-9,rx:9,width:u,height:18}),(0,J.jsx)(`text`,{ref:s,className:i,x:0,y:3.5,textAnchor:`middle`,fontSize:o,children:n})]})}function bY(e){return e.reachable===!0?{label:`online`,color:`#d4d4d8`}:e.reachable===!1?{label:`offline`,color:`#f87171`}:{label:`checking…`,color:`#71717a`}}function xY(e){let t=0;for(let n=0;n<e.length;n++)t=Math.imul(t,31)+e.charCodeAt(n)>>>0;return`hsl(${t%360} 70% 62%)`}function SY(e,t,n,r){let i=1-r;return{x:i*i*e.x+2*i*r*t.x+r*r*n.x,y:i*i*e.y+2*i*r*t.y+r*r*n.y}}function CY(e,t,n,r){let i=1-r,a=2*i*(t.x-e.x)+2*r*(n.x-t.x),o=2*i*(t.y-e.y)+2*r*(n.y-t.y);return Math.atan2(o,a)*180/Math.PI}var wY=`#e4e4e7`,TY=`#d4d4d8`,EY=`#f59e0b`;function DY(e){return e.jumpVia?e.jumpVia:e.jumpHost?`${e.jumpHost.host}:${e.jumpHost.port}`:null}var OY=18,kY=e=>e.length>OY?`${e.slice(0,OY-1)}…`:e,AY=e=>Math.max(23,Math.min(70,e.length*3.1+12));function jY({payload:e,pulses:t}){let n=e.devices,r=Math.max(1,n.length),i=n.map(e=>{let t=kY(e.name);return{d:e,label:t,r:AY(t)}}),a=Math.max(23,...i.map(e=>e.r)),o=r>1?(a+18)/Math.sin(Math.PI/r):0,s=Math.max(110+a,o,120),c=a+60,l=Math.max(700,Math.round((s+a+40)*2)),u=Math.round((s+c)*2),d=l/2,f=u/2,p={x:d,y:f},m=i.map((e,t)=>{let n=t/r*Math.PI*2-Math.PI/2+(r%2==0?Math.PI/r:0);return{...e,i:t,x:d+s*Math.cos(n),y:f+s*Math.sin(n)}});return(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`svg`,{className:`conn`,viewBox:`0 0 ${l} ${u}`,width:`100%`,height:u,preserveAspectRatio:`xMidYMid meet`,children:[(0,J.jsxs)(`defs`,{children:[(0,J.jsxs)(`radialGradient`,{id:`conn-hub`,cx:`0.5`,cy:`0.34`,r:`0.75`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:`#fafafa`}),(0,J.jsx)(`stop`,{offset:`0.6`,stopColor:`#d4d4d8`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:`#a1a1aa`})]}),(0,J.jsxs)(`radialGradient`,{id:`conn-orb`,cx:`0.5`,cy:`0.32`,r:`0.85`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:`#27272a`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:`#18181b`})]}),(0,J.jsxs)(`radialGradient`,{id:`conn-burst`,cx:`0.5`,cy:`0.5`,r:`0.5`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:`#fafafa`}),(0,J.jsx)(`stop`,{offset:`0.5`,stopColor:`#e4e4e7`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:`#a1a1aa`,stopOpacity:`0`})]}),(0,J.jsxs)(`linearGradient`,{id:`conn-tunnel-grad`,x1:`0`,y1:`0`,x2:`1`,y2:`0`,children:[(0,J.jsx)(`stop`,{offset:`0`,stopColor:EY,stopOpacity:`0.15`}),(0,J.jsx)(`stop`,{offset:`0.5`,stopColor:EY,stopOpacity:`0.95`}),(0,J.jsx)(`stop`,{offset:`1`,stopColor:EY,stopOpacity:`0.15`})]}),(0,J.jsxs)(`filter`,{id:`conn-tunnel-glow`,x:`-40%`,y:`-40%`,width:`180%`,height:`180%`,children:[(0,J.jsx)(`feGaussianBlur`,{stdDeviation:`3`,result:`b`}),(0,J.jsxs)(`feMerge`,{children:[(0,J.jsx)(`feMergeNode`,{in:`b`}),(0,J.jsx)(`feMergeNode`,{in:`SourceGraphic`})]})]})]}),[.5,.78,1].map((e,t)=>(0,J.jsx)(`circle`,{className:`conn-grid`,cx:d,cy:f,r:s*e},`g-${t}`)),[0,1,2].map(e=>(0,J.jsx)(`circle`,{className:`conn-sonar`,cx:d,cy:f,style:{animationDelay:`${e*1.1}s`}},`s-${e}`)),m.map(({d:e,i:n,x:r,y:i})=>{let a=bY(e.status),o=e.status.reachable===!0,s=e.status.reachable==null,c={x:r,y:i},l=(d+r)/2,u=(f+i)/2,m=r-d,h=i-f,g=Math.hypot(m,h)||1,_=-h/g,v=m/g,y={x:l+_*16,y:u+v*16},b={x:l-_*16,y:u-v*16},x=`M${d},${f} Q${y.x.toFixed(1)},${y.y.toFixed(1)} ${r.toFixed(1)},${i.toFixed(1)}`,S=`M${d},${f} Q${b.x.toFixed(1)},${b.y.toFixed(1)} ${r.toFixed(1)},${i.toFixed(1)}`,C=`M${d},${f} Q${l.toFixed(1)},${u.toFixed(1)} ${r.toFixed(1)},${i.toFixed(1)}`,w=SY(p,y,c,.52),T=CY(p,y,c,.52),E=SY(p,b,c,.48),D=CY(p,b,c,.48)+180,O=t[e.name]??0;return(0,J.jsxs)(`g`,{children:[(0,J.jsx)(`path`,{id:`conn-cmd-${n}`,className:`conn-link`,d:x,stroke:o?wY:a.color,strokeOpacity:o?.5:.32,strokeDasharray:s?`2 8`:o?void 0:`6 7`}),(0,J.jsx)(`path`,{id:`conn-res-${n}`,className:`conn-link`,d:S,stroke:o?TY:a.color,strokeOpacity:o?.5:.18,strokeDasharray:o?void 0:`6 7`}),o&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{className:`conn-flow`,d:x,stroke:`#e4e4e7`}),(0,J.jsx)(`circle`,{className:`conn-packet`,r:3.2,fill:`#e4e4e7`,children:(0,J.jsx)(`animateMotion`,{dur:`2.6s`,repeatCount:`indefinite`,calcMode:`linear`,children:(0,J.jsx)(`mpath`,{href:`#conn-cmd-${n}`})})}),(0,J.jsx)(`rect`,{className:`conn-packet`,x:-2.6,y:-2.6,width:5.2,height:5.2,fill:`#d4d4d8`,transform:`rotate(45)`,children:(0,J.jsx)(`animateMotion`,{dur:`2.6s`,begin:`0.9s`,repeatCount:`indefinite`,calcMode:`linear`,keyPoints:`1;0`,keyTimes:`0;1`,children:(0,J.jsx)(`mpath`,{href:`#conn-res-${n}`})})}),(0,J.jsx)(`path`,{className:`conn-chevron`,d:`M-4,-3 L4,0 L-4,3`,stroke:`#e4e4e7`,transform:`translate(${w.x.toFixed(1)},${w.y.toFixed(1)}) rotate(${T.toFixed(1)})`}),(0,J.jsx)(`path`,{className:`conn-chevron`,d:`M-4,-3 L4,0 L-4,3`,stroke:`#d4d4d8`,transform:`translate(${E.x.toFixed(1)},${E.y.toFixed(1)}) rotate(${D.toFixed(1)})`})]}),O>0&&(0,J.jsx)(`g`,{children:(0,J.jsxs)(`circle`,{r:6,fill:`url(#conn-burst)`,children:[(0,J.jsx)(`animateMotion`,{dur:`1.1s`,repeatCount:`1`,calcMode:`linear`,keyPoints:`0;1;0`,keyTimes:`0;0.5;1`,path:C}),(0,J.jsx)(`animate`,{attributeName:`opacity`,values:`0;1;1;0`,keyTimes:`0;0.1;0.85;1`,dur:`1.1s`,repeatCount:`1`,fill:`freeze`})]})},`burst-${e.name}-${O}`)]},`l-${e.name}`)}),m.map(e=>{let t=e.d.jumpVia,n=t?m.find(e=>e.d.name===t):void 0,r=!n&&e.d.jumpHost?e.d.jumpHost:void 0;if(!n&&!r)return null;let i={x:e.x,y:e.y},a=Math.hypot(e.x-d,e.y-f)||1,o=(e.x-d)/a,s=(e.y-f)/a,c=n?{x:n.x,y:n.y}:{x:e.x+o*(e.r+46),y:e.y+s*(e.r+46)},l=(c.x+i.x)/2,u=(c.y+i.y)/2,p=Math.hypot(l-d,u-f)||1,h=n?50:16,g={x:l+(l-d)/p*h,y:u+(u-f)/p*h},_=`M${c.x.toFixed(1)},${c.y.toFixed(1)} Q${g.x.toFixed(1)},${g.y.toFixed(1)} ${i.x.toFixed(1)},${i.y.toFixed(1)}`,v=DY(e.d)??``,y=SY(c,g,i,.5),b=`conn-tunnel-${e.i}`;return(0,J.jsxs)(`g`,{className:`conn-tunnel-g`,children:[(0,J.jsx)(`path`,{className:`conn-tunnel-halo`,d:_,stroke:EY}),(0,J.jsx)(`path`,{id:b,className:`conn-tunnel`,d:_,stroke:`url(#conn-tunnel-grad)`,filter:`url(#conn-tunnel-glow)`}),r&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{className:`conn-tunnel-sat`,cx:c.x,cy:c.y,r:11,fill:`#1c1917`,stroke:`#f59e0b`}),(0,J.jsx)(`text`,{x:c.x,y:c.y+3.5,textAnchor:`middle`,fontSize:11,children:`🛡️`})]}),(0,J.jsxs)(`text`,{className:`conn-tunnel-lock`,fontSize:13,textAnchor:`middle`,children:[`🔒`,(0,J.jsx)(`animateMotion`,{dur:`2.4s`,repeatCount:`indefinite`,calcMode:`linear`,rotate:`auto`,children:(0,J.jsx)(`mpath`,{href:`#${b}`})})]}),(0,J.jsx)(yY,{x:y.x,y:y.y,text:`⤳ via ${v}`,className:`conn-tunnel-badge`,textClassName:`conn-tunnel-badge-tx`})]},`jump-${e.d.name}`)}),(0,J.jsx)(`circle`,{className:`conn-hub-glow`,cx:d,cy:f,r:42}),(0,J.jsx)(`circle`,{className:`conn-hub-ring`,cx:d,cy:f,r:37}),(0,J.jsx)(`circle`,{cx:d,cy:f,r:29,fill:`url(#conn-hub)`,stroke:`#71717a`,strokeWidth:1.5}),(0,J.jsx)(`text`,{x:d,y:f-4,textAnchor:`middle`,fill:`#09090b`,fontSize:12,fontWeight:700,children:`LLM`}),(0,J.jsx)(`text`,{x:d,y:f+8,textAnchor:`middle`,fill:`#3f3f46`,fontSize:8,fontWeight:600,children:`⇄ MCP`}),(0,J.jsx)(`text`,{x:d,y:f+18,textAnchor:`middle`,fill:`#3f3f46`,fontSize:7.5,fontWeight:600,children:`server`}),m.map(({d:e,x:t,y:n,r,label:i})=>{let a=bY(e.status),o=e.status.reachable===!0,s=o?`${e.status.latencyMs??`?`} ms`:a.label,c=xY(e.name);return(0,J.jsxs)(`g`,{className:`conn-node`,children:[o&&(0,J.jsx)(`circle`,{className:`conn-node-halo`,cx:t,cy:n,r:r+1,stroke:c}),e.pool?.pooled&&(0,J.jsx)(`circle`,{cx:t,cy:n,r:r+5,fill:`none`,stroke:e.pool.inflight>0?`#3b82f6`:`#22c55e`,strokeWidth:1.5,strokeDasharray:e.pool.inflight>0?void 0:`4 4`,opacity:.5,className:e.pool.inflight>0?`conn-blink`:void 0}),(0,J.jsx)(`circle`,{cx:t,cy:n,r,fill:`url(#conn-orb)`}),(0,J.jsx)(`circle`,{cx:t,cy:n,r,fill:c,opacity:.16}),(0,J.jsx)(`circle`,{cx:t,cy:n,r,fill:`none`,stroke:c,strokeWidth:2.5}),(0,J.jsx)(`circle`,{className:o?`conn-blink`:void 0,cx:t+r*.7,cy:n-r*.7,r:4.5,fill:a.color,stroke:`#0a121b`,strokeWidth:1.5}),(0,J.jsx)(`text`,{x:t,y:n+3.5,textAnchor:`middle`,fill:`#fafafa`,fontSize:10,fontWeight:600,children:i}),(0,J.jsx)(`text`,{x:t,y:n+r+14,textAnchor:`middle`,fill:`#a1a1aa`,fontSize:9,children:e.address??e.host}),(0,J.jsx)(`text`,{x:t,y:n+r+26,textAnchor:`middle`,fill:a.color,fontSize:9,fontWeight:600,children:s})]},`n-${e.name}`)})]}),(0,J.jsxs)(`div`,{className:`conn-legend`,children:[(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:wY}}),` command · LLM → device`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:TY}}),` response · device → LLM`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:`#e4e4e7`}}),` live call (round-trip)`]}),e.devices.some(e=>DY(e))&&(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:`#f59e0b`}}),` 🔒 SSH jump tunnel (ProxyJump)`]}),e.devices.some(e=>e.pool?.pooled)&&(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{style:{background:`#22c55e`}}),` pooled SSH connection`]})]})]})}function MY({d:e}){let t=bY(e.status),n=e.status.reachable===!0?`${t.label} · ${e.status.latencyMs??`?`}ms${e.status.version?` · v${e.status.version}`:``}`:e.status.reachable===!1?`${t.label}${e.status.error?` · ${e.status.error}`:``}`:t.label,r=xY(e.name);return(0,J.jsxs)(`div`,{className:`card dev-card`,style:{borderLeft:`3px solid ${r}`},children:[(0,J.jsxs)(`div`,{className:`dev-card__top`,children:[(0,J.jsx)(`span`,{className:`dot`,style:{background:r},title:`device colour`}),(0,J.jsx)(`span`,{className:`dev-card__name`,children:e.name}),e.isDefault&&(0,J.jsx)(Mc,{type:`accent`,children:`default`}),(0,J.jsx)(`span`,{className:`dot dot--status`,style:{background:t.color},title:t.label}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`span`,{className:`chip`,children:e.authMode})]}),(0,J.jsxs)(`div`,{className:`dev-card__meta`,children:[(0,J.jsx)(`span`,{children:e.mac?`mac`:`host`}),(0,J.jsx)(`b`,{children:e.address??`${e.host}:${e.port}`}),(0,J.jsx)(`span`,{children:`user`}),(0,J.jsx)(`b`,{children:e.username}),(0,J.jsx)(`span`,{children:`status`}),(0,J.jsx)(`b`,{style:{color:t.color},children:n}),(0,J.jsx)(`span`,{children:`activity`}),(0,J.jsxs)(`b`,{children:[e.activity.calls,` calls · `,e.activity.errors,` err`,e.activity.avgMs?` · ${xc(e.activity.avgMs)} avg`:``]}),e.pool&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`span`,{children:`pool`}),(0,J.jsx)(`b`,{style:{color:e.pool.dead?`#ef4444`:e.pool.inflight>0?`#3b82f6`:e.pool.pooled?`#22c55e`:`#52525b`},children:e.pool.pooled?e.pool.inflight>0?`${e.pool.inflight} inflight`:`connected`:`—`})]}),e.description&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`span`,{children:`note`}),(0,J.jsx)(`b`,{children:e.description})]})]}),DY(e)&&(0,J.jsxs)(`div`,{className:`jump-route`,title:`Reached over SSH through the bastion ${DY(e)} (ProxyJump) — no port exposed on ${e.name}.`,children:[(0,J.jsxs)(`span`,{className:`jump-route__hop jump-route__hop--bastion`,children:[`🛡️ `,DY(e),e.jumpVia?(0,J.jsx)(`i`,{className:`jump-route__tag`,children:`jump`}):null]}),(0,J.jsx)(`span`,{className:`jump-route__wire jump-route__wire--enc`,children:(0,J.jsx)(`span`,{className:`jump-route__lock`,"aria-hidden":!0,children:`🔒`})}),(0,J.jsxs)(`span`,{className:`jump-route__hop jump-route__hop--dest`,style:{borderColor:r},title:e.name,children:[`📡 `,e.name]})]})]})}function NY({event:e,onClose:t}){let[n,r]=(0,v.useState)(dY);return(0,J.jsx)(`div`,{className:`overlay`,onClick:e=>e.target===e.currentTarget&&t(),children:(0,J.jsxs)(`div`,{className:`sheet`,children:[(0,J.jsxs)(`div`,{className:`sheet__hd`,children:[(0,J.jsx)(`span`,{className:`risk risk-${e.risk}`,children:e.risk}),(0,J.jsxs)(`h3`,{className:`sheet__tool`,children:[e.tool,(0,J.jsx)(bc,{text:e.tool,className:`iconbtn`,icon:!0,title:`Copy tool name`})]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(Ac,{type:`secondary`,size:`sm`,onClick:t,children:`✕ Close`})]}),(0,J.jsxs)(`div`,{className:`kv__body`,children:[(0,J.jsx)(`div`,{className:`kv__k`,children:`title`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.title}),(0,J.jsx)(`div`,{className:`kv__k`,children:`time`}),(0,J.jsx)(`div`,{className:`kv__v`,children:new Date(e.ts).toLocaleString(void 0,{hour12:!1})}),(0,J.jsx)(`div`,{className:`kv__k`,children:`device`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.device??`—`}),(0,J.jsx)(`div`,{className:`kv__k`,children:`transport`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.transport??`—`}),(0,J.jsx)(`div`,{className:`kv__k`,children:`duration`}),(0,J.jsx)(`div`,{className:`kv__v`,children:xc(e.durationMs)}),(0,J.jsx)(`div`,{className:`kv__k`,children:`status`}),(0,J.jsx)(`div`,{className:`kv__v`,children:(0,J.jsx)(`span`,{className:e.isError?`status-err`:`status-ok`,children:e.isError?`error`:`ok`})}),(0,J.jsx)(`div`,{className:`kv__k`,children:`output size`}),(0,J.jsxs)(`div`,{className:`kv__v`,children:[Sc(e.outputBytes),e.truncated?` (truncated)`:``]}),(0,J.jsx)(`div`,{className:`kv__k`,children:`structured`}),(0,J.jsx)(`div`,{className:`kv__v`,children:e.hasStructured?`yes (renders an MCP App view)`:`no`})]}),e.error&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`h2`,{className:`muted`,children:`ERROR`}),(0,J.jsx)(`pre`,{className:`body`,style:{color:`var(--mt-bad)`},children:e.error})]}),(0,J.jsxs)(`div`,{className:`sheet__hd`,children:[(0,J.jsx)(`h2`,{className:`muted`,style:{margin:0},children:`INPUT`}),(0,J.jsx)(`span`,{style:{flex:1}}),e.input&&(0,J.jsx)(Ac,{type:`secondary`,size:`sm`,ghost:!0,onClick:()=>r(e=>{let t=!e;return fY(t),t}),title:n?`Showing pretty-printed JSON — click for raw`:`Showing raw JSON — click to pretty-print`,children:n?`✦ Pretty`:`{ } Raw`}),(0,J.jsx)(bc,{text:e.input,title:`Copy input JSON`})]}),e.input?(0,J.jsx)(mY,{value:pY(e.input,n)}):(0,J.jsx)(`pre`,{className:`body`,children:`—`}),(0,J.jsxs)(`div`,{className:`sheet__hd`,children:[(0,J.jsx)(`h2`,{className:`muted`,style:{margin:0},children:`OUTPUT`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(bc,{text:e.output,title:`Copy output`})]}),(0,J.jsx)(`pre`,{className:`body ros`,children:e.output?lY(e.output):`—`})]})})}var PY=e=>e==null?`?`:Sc(e);function FY({d:e}){let t=e.status,n=e.history??[];return t.reachable===!0||n.length>0?(0,J.jsxs)(`div`,{className:`card health-card`,children:[(0,J.jsxs)(`div`,{className:`health-card__hd`,children:[(0,J.jsx)(Nc,{color:bY(t).color}),(0,J.jsx)(`span`,{className:`dev-card__name`,children:e.name}),e.isDefault&&(0,J.jsx)(Mc,{type:`accent`,children:`default`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(Mc,{type:t.version?`success`:`default`,children:t.version?`v${t.version}`:`—`})]}),(0,J.jsxs)(`div`,{className:`health-card__sub muted`,children:[t.boardName??`router`,t.architecture?` · ${t.architecture}`:``,t.cpuCount?` · ${t.cpuCount} cpu`:``,t.uptime?` · up ${t.uptime}`:``]}),(0,J.jsxs)(`div`,{className:`health-card__gauges`,children:[(0,J.jsx)(HJ,{value:t.cpuLoad,label:`CPU`,color:Ec.cpu}),(0,J.jsx)(HJ,{value:t.memUsedPct,label:`MEM`,color:Ec.mem}),(0,J.jsx)(HJ,{value:t.hddUsedPct,label:`DISK`,color:Ec.disk})]}),(0,J.jsxs)(`div`,{className:`health-card__charts`,children:[(0,J.jsxs)(`div`,{className:`health-chart`,children:[(0,J.jsx)(`span`,{className:`health-chart__k`,children:`CPU load`}),(0,J.jsx)(VJ,{id:`${e.name}-cpu`,values:n.map(e=>e.cpuLoad),color:Ec.cpu,maxValue:100,unit:`%`})]}),(0,J.jsxs)(`div`,{className:`health-chart`,children:[(0,J.jsx)(`span`,{className:`health-chart__k`,children:`Memory used`}),(0,J.jsx)(VJ,{id:`${e.name}-mem`,values:n.map(e=>e.memUsedPct),color:Ec.mem,maxValue:100,unit:`%`})]}),(0,J.jsxs)(`div`,{className:`health-chart`,children:[(0,J.jsx)(`span`,{className:`health-chart__k`,children:`Probe latency`}),(0,J.jsx)(VJ,{id:`${e.name}-lat`,values:n.map(e=>e.latencyMs),color:Ec.latency,unit:`ms`})]})]}),(0,J.jsxs)(`div`,{className:`health-card__foot muted`,children:[`RAM `,PY(t.totalMemory&&t.freeMemory?t.totalMemory-t.freeMemory:void 0),` /`,` `,PY(t.totalMemory),` · free disk `,PY(t.freeHdd)]})]}):(0,J.jsxs)(`div`,{className:`card health-card health-card--na`,children:[(0,J.jsxs)(`div`,{className:`health-card__hd`,children:[(0,J.jsx)(Nc,{color:bY(t).color}),(0,J.jsx)(`span`,{className:`dev-card__name`,children:e.name}),e.isDefault&&(0,J.jsx)(Mc,{type:`accent`,children:`default`})]}),(0,J.jsx)(`p`,{className:`muted`,style:{margin:0},children:t.reachable===!1?`Offline — ${t.error??`unreachable`}`:e.mac?`Waiting for the first MAC-Telnet probe (these run every few minutes to avoid contending with tool calls)…`:`Waiting for the first health probe…`})]})}function IY(e,t){let n=(0,v.useRef)(e),r=(0,v.useRef)(t);n.current=e,r.current=t,(0,v.useEffect)(()=>{let e=!1,t=null,i=null,a=()=>{e||(i=new EventSource(dc(`/api/sse`)),i.addEventListener(`hello`,()=>r.current(`sse`)),i.addEventListener(`tool`,e=>{try{n.current(JSON.parse(e.data))}catch{}}),i.onerror=()=>{i&&i.readyState===EventSource.CONNECTING&&r.current(`off`)})},o=()=>{if(e)return;let i=location.protocol===`https:`?`wss`:`ws`;t=new WebSocket(dc(`${i}://${location.host}/api/stream`));let s=!1;t.onopen=()=>{s=!0,r.current(`ws`)},t.onerror=()=>t?.close(),t.onmessage=e=>{try{let t=JSON.parse(e.data);t.type===`event`&&t.event&&n.current(t.event)}catch{}},t.onclose=()=>{e||(r.current(`off`),s?setTimeout(o,2e3):a())}};return o(),()=>{e=!0,t?.close(),i?.close()}},[])}function LY(e){(0,v.useLayoutEffect)(()=>{let t=e.current;if(!t||window.matchMedia(`(prefers-reduced-motion: reduce)`).matches)return;document.documentElement.classList.add(`js-motion`);let n=new WeakSet,r=e=>{n.has(e)||(n.add(e),Ri.set(e,{opacity:0,y:26}),q.create({trigger:e,start:`top 90%`,once:!0,onEnter:()=>Ri.to(e,{opacity:1,y:0,duration:.7,ease:`power3.out`})}))},i=e=>{for(let t of e.querySelectorAll(`.reveal`))r(t)};i(t);let a=new MutationObserver(e=>{for(let t of e)for(let e of t.addedNodes)e instanceof Element&&(e.matches(`.reveal`)&&r(e),i(e))});a.observe(t,{childList:!0,subtree:!0});let o=setInterval(()=>q.refresh(),1200),s=setTimeout(()=>clearInterval(o),7e3);return()=>{a.disconnect(),clearInterval(o),clearTimeout(s);for(let e of q.getAll())e.kill();document.documentElement.classList.remove(`js-motion`)}},[e])}function RY({m:e,busy:t,onToggle:n}){return(0,J.jsxs)(`label`,{className:`mod-row`,"data-on":e.enabled?`1`:void 0,title:e.description,children:[(0,J.jsx)(`input`,{type:`checkbox`,checked:e.enabled,disabled:t,onChange:()=>n(e.slug,!e.enabled)}),(0,J.jsxs)(`span`,{className:`mod-row__main`,children:[(0,J.jsxs)(`span`,{className:`mod-row__name`,children:[e.label,(0,J.jsx)(`code`,{className:`mod-row__slug`,children:e.slug})]}),(0,J.jsx)(`span`,{className:`mod-row__desc muted`,children:e.description})]}),(0,J.jsxs)(`span`,{className:`mod-row__count muted`,children:[e.toolCount,` tool`,e.toolCount===1?``:`s`]})]})}function zY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(new Set),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(``),c=(0,v.useCallback)(()=>{fc(`/api/modules`).then(t).catch(()=>a(`could not load modules`))},[]);(0,v.useEffect)(()=>c(),[c]);let l=e=>t(t=>t?{...t,...e}:e),u=(0,v.useCallback)(async(e,n)=>{r(t=>new Set(t).add(e)),t(t=>t&&{...t,modules:t.modules.map(t=>t.slug===e?{...t,enabled:n}:t)});let i=await pc(`/api/modules/toggle`,{slug:e,enabled:n}).catch(()=>({error:`request failed`}));if(r(t=>{let n=new Set(t);return n.delete(e),n}),i.error||i.ok===!1){a(i.error??`toggle failed`),c();return}l(i);let o=i.persisted?`saved to config`:`applied live (not saved)`,s=i.warning?` ⚠ ${i.warning}`:``;a(`${e} ${n?`enabled`:`disabled`} — ${o}. Reconnect the MCP client (or restart the server) for the tool list to update.${s}`)},[c]),d=(0,v.useCallback)(async(e,t)=>{for(let n of e)await u(n,t)},[u]),f=(0,v.useMemo)(()=>{if(!e)return[];let t=o.trim().toLowerCase(),n=e=>!t||e.slug.toLowerCase().includes(t)||e.label.toLowerCase().includes(t)||e.group.toLowerCase().includes(t)||e.description.toLowerCase().includes(t),r=new Map;for(let t of e.modules){if(!n(t))continue;let e=r.get(t.group)??[];e.push(t),r.set(t.group,e)}return[...r.entries()].map(([e,t])=>({group:e,modules:t}))},[e,o]);if(!e)return(0,J.jsx)(`div`,{className:`muted`,children:`loading modules…`});let p=f.reduce((e,t)=>e+t.modules.length,0);return(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsxs)(gc,{title:`Tool modules`,className:`reveal`,extra:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`span`,{className:`muted`,children:[e.enabledModules,`/`,e.total,` modules · `,e.enabledTools,`/`,e.totalTools,` `,`tools exposed`]}),(0,J.jsx)(`button`,{className:`btn`,onClick:c,style:{marginLeft:10},children:`↻ Refresh`})]}),children:[(0,J.jsxs)(`div`,{className:`legend`,style:{margin:`0 0 10px`},children:[(0,J.jsxs)(`span`,{children:[`writes to: `,(0,J.jsx)(`code`,{children:e.source?.path??`config file`})]}),(0,J.jsx)(`span`,{children:e.hasAllowList?`allow-list active`:`all modules on by default`})]}),(0,J.jsxs)(`p`,{className:`muted`,style:{margin:`0 0 12px`,fontSize:12},children:[`Toggle a module to expose or hide all of its tools. Disabling adds it to`,` `,(0,J.jsx)(`code`,{children:`tools.disabledModules`}),` in your config file; enabling removes it (or adds it to`,` `,(0,J.jsx)(`code`,{children:`tools.enabledModules`}),` when an allow-list is in force). Trimming the surface below ~150–200 tools makes every remaining tool reliably findable by the MCP client. The client must reconnect for changes to take effect.`]}),(0,J.jsxs)(`div`,{className:`mod-toolbar`,children:[(0,J.jsx)(`input`,{className:`input`,placeholder:`Filter modules by name, slug, group or description…`,value:o,onChange:e=>s(e.target.value)}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>void d(e.modules.filter(e=>!e.enabled).map(e=>e.slug),!0),children:`Enable all`}),` `,(0,J.jsx)(`button`,{className:`btn`,onClick:()=>void d(e.modules.filter(e=>e.enabled).map(e=>e.slug),!1),children:`Disable all`})]}),i&&(0,J.jsx)(`div`,{className:`cfg-msg`,style:{marginTop:12},children:i}),p===0?(0,J.jsxs)(`div`,{className:`muted`,style:{padding:12},children:[`No modules match “`,o,`”.`]}):(0,J.jsx)(`div`,{className:`mod-groups`,children:f.map(({group:e,modules:t})=>{let r=t.filter(e=>e.enabled).length,i=t.map(e=>e.slug);return(0,J.jsxs)(`div`,{className:`mod-group`,children:[(0,J.jsxs)(`div`,{className:`mod-group__hd`,children:[(0,J.jsx)(`h3`,{className:`mod-group__title`,children:e}),(0,J.jsxs)(`span`,{className:`muted`,children:[r,`/`,t.length,` on`]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`btn btn-sm`,onClick:()=>void d(i.filter(e=>{let n=t.find(t=>t.slug===e);return n?!n.enabled:!1}),!0),children:`Enable group`}),` `,(0,J.jsx)(`button`,{className:`btn btn-sm`,onClick:()=>void d(i.filter(e=>{let n=t.find(t=>t.slug===e);return n?n.enabled:!1}),!1),children:`Disable group`})]}),(0,J.jsx)(`div`,{className:`mod-list`,children:t.map(e=>(0,J.jsx)(RY,{m:e,busy:n.has(e.slug),onToggle:(e,t)=>void u(e,t)},e.slug))})]},e)})})]})})}var BY={TCP:`#e4e4e7`,UDP:`#d4d4d8`,ICMP:`#a1a1aa`,ICMPv6:`#a1a1aa`,ARP:`#e4e4e7`,IPv6:`#a1a1aa`},VY=e=>e&&BY[e]||`#71717a`;function HY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(!1);(0,v.useEffect)(()=>{let e=()=>void fc(`/api/capture/packets?limit=150`).then(t).catch(()=>{});e();let n=setInterval(e,1500);return()=>clearInterval(n)},[]);let i=e?.stats,a=e?.packets??[],o=async()=>{r(!0),await pc(`/api/capture/stop`,{}).catch(()=>{}),r(!1)};if(!i||!i.running&&i.packets===0)return(0,J.jsxs)(`div`,{className:`cap-idle muted`,children:[`No capture running. Start one with the `,(0,J.jsx)(`code`,{children:`start_packet_capture`}),` tool — point the device's TZSP stream at this host — and decoded packets stream in here live.`]});let s=Math.max(1,...Object.values(i.protocols));return(0,J.jsxs)(`div`,{className:`cap`,children:[(0,J.jsxs)(`div`,{className:`cap-bar`,children:[(0,J.jsx)(`span`,{className:`cap-dot${i.running?` is-on`:``}`}),(0,J.jsx)(`b`,{children:i.running?`capturing`:`stopped`}),(0,J.jsxs)(`span`,{className:`muted`,children:[`UDP `,i.port]}),(0,J.jsxs)(`span`,{className:`muted`,children:[wc(i.packets),` pkts · `,Sc(i.bytes)]}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`a`,{className:`btn`,href:dc(`/api/capture/pcap`),download:`capture.pcap`,children:`⤓ pcap`}),(0,J.jsx)(`button`,{className:`btn btn-danger`,onClick:()=>void o(),disabled:n||!i.running,children:`■ Stop`})]}),(0,J.jsxs)(`div`,{className:`cap-cols`,children:[(0,J.jsxs)(`div`,{className:`cap-side`,children:[(0,J.jsx)(`div`,{className:`cap-h`,children:`Protocols`}),Object.entries(i.protocols).map(([e,t])=>(0,J.jsxs)(`div`,{className:`cap-pbar`,children:[(0,J.jsx)(`span`,{className:`cap-plabel`,style:{color:VY(e)},children:e}),(0,J.jsx)(`span`,{className:`cap-ptrack`,children:(0,J.jsx)(`i`,{style:{width:`${t/s*100}%`,background:VY(e)}})}),(0,J.jsx)(`span`,{className:`cap-pn`,children:t})]},e)),(0,J.jsx)(`div`,{className:`cap-h`,style:{marginTop:12},children:`Top talkers`}),i.topTalkers.length===0&&(0,J.jsx)(`div`,{className:`muted`,children:`—`}),i.topTalkers.map(e=>(0,J.jsxs)(`div`,{className:`cap-talker`,children:[(0,J.jsx)(`span`,{children:e.addr}),(0,J.jsx)(`b`,{children:e.count})]},e.addr))]}),(0,J.jsx)(`div`,{className:`cap-list`,children:a.length===0?(0,J.jsx)(`div`,{className:`muted`,style:{padding:10},children:`waiting for packets…`}):a.map((e,t)=>(0,J.jsxs)(`div`,{className:`cap-row`,children:[(0,J.jsx)(`span`,{className:`cap-tt`,children:Cc(e.ts)}),(0,J.jsx)(`span`,{className:`cap-proto`,style:{color:VY(e.protocol)},children:e.protocol??e.ethType}),(0,J.jsx)(`span`,{className:`cap-len`,children:e.len}),(0,J.jsx)(`span`,{className:`cap-info`,children:e.info})]},t))})]})]})}function UY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(null),c=(0,v.useCallback)(()=>{fc(`/api/s3/list`).then(t).catch(()=>t({configured:!1,objects:[]}))},[]);(0,v.useEffect)(()=>c(),[c]);let l=e=>{fc(`/api/s3/presign?key=${encodeURIComponent(e)}`).then(e=>{e.url?window.open(e.url,`_blank`,`noopener`):s(`could not generate download link`)}).catch(()=>s(`could not generate download link`))},u=async e=>{a(e);let t=await pc(`/api/s3/delete`,{key:e}).catch(()=>({error:`request failed`}));a(null),r(null),t.ok?(s(`Deleted ${e}`),c()):s(t.error??`delete failed`)};return e?e.configured?(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsxs)(gc,{title:`S3 backups`,className:`reveal`,extra:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`span`,{className:`muted`,children:[e.target,` · `,e.objects.length,` object`,e.objects.length===1?``:`s`,e.truncated?` (truncated)`:``]}),(0,J.jsx)(`button`,{className:`btn`,onClick:c,style:{marginLeft:10},children:`↻ Refresh`})]}),children:[o&&(0,J.jsx)(`div`,{className:`cfg-msg`,children:o}),e.objects.length===0?(0,J.jsxs)(`div`,{className:`muted`,style:{padding:12},children:[`No objects in the bucket. Upload one with the `,(0,J.jsx)(`code`,{children:`upload_backup_to_s3`}),` tool.`]}):(0,J.jsx)(`div`,{className:`feedwrap`,children:(0,J.jsxs)(`table`,{className:`feed`,children:[(0,J.jsx)(`thead`,{children:(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`th`,{children:`key`}),(0,J.jsx)(`th`,{className:`num`,children:`size`}),(0,J.jsx)(`th`,{children:`modified`}),(0,J.jsx)(`th`,{style:{width:200},children:`actions`})]})}),(0,J.jsx)(`tbody`,{children:e.objects.map(e=>(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`td`,{children:e.key}),(0,J.jsx)(`td`,{className:`num`,children:Sc(e.size)}),(0,J.jsx)(`td`,{children:e.lastModified?new Date(e.lastModified).toLocaleString(void 0,{hour12:!1}):`—`}),(0,J.jsxs)(`td`,{onClick:e=>e.stopPropagation(),children:[(0,J.jsx)(`button`,{className:`btn`,onClick:()=>l(e.key),children:`⤓ Download`}),` `,n===e.key?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`button`,{className:`btn btn-danger`,disabled:i===e.key,onClick:()=>void u(e.key),children:`✓ Confirm`}),` `,(0,J.jsx)(`button`,{className:`btn`,onClick:()=>r(null),children:`Cancel`})]}):(0,J.jsx)(`button`,{className:`btn`,onClick:()=>r(e.key),children:`🗑 Delete`})]})]},e.key))})]})})]})}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`☁️`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`S3 is not configured`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[`Add an `,(0,J.jsx)(`code`,{children:`s3`}),` block (bucket + credentials) to your config to manage backup objects here.`]})]}):(0,J.jsx)(`div`,{className:`muted`,children:`loading S3 objects…`})}function WY(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),u=(0,v.useCallback)(()=>{fc(`/api/snapshots`).then(e=>t(e.snapshots)).catch(()=>t([]))},[]);(0,v.useEffect)(()=>u(),[u]);let d=e=>{fc(`/api/snapshot/${encodeURIComponent(e)}`).then(s).catch(()=>{})},f=()=>{!n||!i||pc(`/api/snapshots/diff`,{from:n,to:i}).then(l).catch(()=>{})};if(!e)return(0,J.jsx)(`div`,{className:`muted`,children:`loading snapshots…`});if(e.length===0)return(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🕰️`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No config snapshots yet`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[`Capture one with the `,(0,J.jsx)(`code`,{children:`capture_config_snapshot`}),` tool — then time-travel diff any two here.`]})]});let p=e.map(e=>(0,J.jsxs)(`option`,{value:e.id,children:[e.device,` · `,e.label??e.id,` · `,Cc(e.ts)]},e.id));return(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsxs)(gc,{title:`Config snapshots`,className:`reveal`,extra:(0,J.jsx)(`button`,{className:`btn`,onClick:u,children:`↻ Refresh`}),children:[(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:12},children:[(0,J.jsxs)(`select`,{className:`btn`,value:n,onChange:e=>r(e.target.value),children:[(0,J.jsx)(`option`,{value:``,children:`diff from…`}),p]}),(0,J.jsxs)(`select`,{className:`btn`,value:i,onChange:e=>a(e.target.value),children:[(0,J.jsx)(`option`,{value:``,children:`to…`}),p]}),(0,J.jsx)(`button`,{className:`btn is-active`,onClick:f,disabled:!n||!i,children:`Diff →`}),(0,J.jsxs)(`span`,{className:`muted`,children:[e.length,` snapshots`]})]}),(0,J.jsx)(`div`,{className:`feedwrap`,children:(0,J.jsxs)(`table`,{className:`feed`,children:[(0,J.jsx)(`thead`,{children:(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`th`,{children:`captured`}),(0,J.jsx)(`th`,{children:`device`}),(0,J.jsx)(`th`,{children:`label`}),(0,J.jsx)(`th`,{children:`version`}),(0,J.jsx)(`th`,{className:`num`,children:`lines`}),(0,J.jsx)(`th`,{className:`num`,children:`size`}),(0,J.jsx)(`th`,{children:`output`})]})}),(0,J.jsx)(`tbody`,{children:e.map(e=>(0,J.jsxs)(`tr`,{className:o?.id===e.id?`is-selected`:void 0,onClick:()=>d(e.id),children:[(0,J.jsx)(`td`,{children:Cc(e.ts)}),(0,J.jsx)(`td`,{children:e.device}),(0,J.jsx)(`td`,{children:e.label??`—`}),(0,J.jsx)(`td`,{children:e.rosVersion??`—`}),(0,J.jsx)(`td`,{className:`num`,children:e.lines}),(0,J.jsx)(`td`,{className:`num`,children:Sc(e.bytes)}),(0,J.jsx)(`td`,{className:`preview`,children:`view export →`})]},e.id))})]})})]}),c&&(0,J.jsx)(gc,{title:`Time-travel diff`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:c.summary.changed?`+${c.summary.added} / -${c.summary.removed}`:`identical`}),children:(0,J.jsx)(`pre`,{className:`cfg-diff`,children:(c.unified||`(identical)`).split(`
|
|
80
|
+
`).map((e,t)=>(0,J.jsx)(`div`,{className:e.startsWith(`+`)?`d-add`:e.startsWith(`-`)?`d-del`:e.startsWith(`@@`)?`d-hunk`:``,children:e||` `},t))})}),o&&(0,J.jsx)(gc,{title:`Snapshot · ${o.label??o.id}`,className:`reveal`,extra:(0,J.jsx)(Ac,{type:`secondary`,size:`sm`,onClick:()=>s(null),children:`✕ Close`}),children:(0,J.jsx)(`pre`,{className:`body`,style:{maxHeight:460},children:o.body||`(empty)`})})]})}function GY(e){return e==null?`#3f3f46`:e>=85?`#f87171`:e>=60?`#a1a1aa`:`#d4d4d8`}function KY({topo:e,onOnboard:t}){let[n,r]=(0,v.useState)(null),i=e.nodes.filter(e=>e.kind===`device`),a=e.nodes.filter(e=>e.kind===`neighbor`),o=Math.max(1,i.length),s=i.length<=1?0:Math.min(150,76+o*8),c=s+(i.length<=1?180:140),l=Math.max(360,Math.round((c+78)*2)),u=l/2,d=new Map,f=new Map;i.forEach((e,t)=>{if(i.length===1){d.set(e.id,{x:380,y:u}),f.set(e.id,-Math.PI/2);return}let n=t/o*Math.PI*2-Math.PI/2;f.set(e.id,n),d.set(e.id,{x:380+s*Math.cos(n),y:u+s*Math.sin(n)})});let p=new Map,m=new Set(a.map(e=>e.id));for(let t of e.edges)m.has(t.to)&&!p.has(t.to)&&p.set(t.to,t.from);let h=new Map;for(let e of a){let t=p.get(e.id)??i[0]?.id??``;h.set(t,[...h.get(t)??[],e.id])}if(i.length<=1)a.forEach((e,t)=>{let n=t/Math.max(1,a.length)*Math.PI*2-Math.PI/2;d.set(e.id,{x:380+c*Math.cos(n),y:u+c*Math.sin(n)})});else for(let[e,t]of h){let n=f.get(e)??-Math.PI/2,r=Math.min(Math.PI/2.2,.32*t.length);t.forEach((e,i)=>{let a=t.length===1?n:n-r/2+r*i/(t.length-1);d.set(e,{x:380+c*Math.cos(a),y:u+c*Math.sin(a)})})}let g=new Map(e.nodes.map(e=>[e.id,e])),_=n?g.get(n):null;return(0,J.jsxs)(`div`,{className:`topo`,children:[(0,J.jsxs)(`svg`,{viewBox:`0 0 760 ${l}`,width:`100%`,height:Math.min(l,540),preserveAspectRatio:`xMidYMid meet`,children:[e.edges.map((e,t)=>{let n=d.get(e.from),r=d.get(e.to);return!n||!r?null:(0,J.jsx)(`line`,{className:`topo-edge${m.has(e.to)?` is-dashed`:``}`,x1:n.x,y1:n.y,x2:r.x,y2:r.y,children:(0,J.jsxs)(`title`,{children:[e.from,` → `,e.to,e.interface?` (${e.interface})`:``]})},`e-${t}`)}),e.nodes.map(e=>{let t=d.get(e.id);if(!t)return null;let i=e.kind===`device`,a=i?132:108,o=i?50:38,s=t.x-a/2,c=t.y-o/2,l=e.reachable===!0?`#d4d4d8`:e.reachable===!1?`#f87171`:i?`#71717a`:`#e4e4e7`,u=n===e.id;return(0,J.jsxs)(`g`,{className:`topo-node${i?` is-device`:` is-neighbor`}${e.onboardable?` is-onboard`:``}${u?` is-picked`:``}`,transform:`translate(${s},${c})`,onClick:()=>r(t=>t===e.id?null:e.id),children:[(0,J.jsx)(`rect`,{width:a,height:o,rx:9,style:{stroke:l}}),(0,J.jsx)(`text`,{className:`topo-label`,x:9,y:16,children:(e.label||e.id).slice(0,16)}),i?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`text`,{className:`topo-sub`,x:9,y:30,children:(e.board||e.ip||``).slice(0,18)}),(0,J.jsx)(`rect`,{className:`topo-bar-bg`,x:9,y:37,width:a-18,height:4,rx:2}),(0,J.jsx)(`rect`,{x:9,y:37,width:(a-18)*Math.min(100,e.cpuLoad??0)/100,height:4,rx:2,style:{fill:GY(e.cpuLoad)}}),(0,J.jsx)(`rect`,{className:`topo-bar-bg`,x:9,y:43,width:a-18,height:4,rx:2}),(0,J.jsx)(`rect`,{x:9,y:43,width:(a-18)*Math.min(100,e.memUsedPct??0)/100,height:4,rx:2,style:{fill:GY(e.memUsedPct)}})]}):(0,J.jsx)(`text`,{className:`topo-sub`,x:9,y:29,children:e.onboardable?`+ onboard`:e.ip||e.mac||``})]},e.id)})]}),(0,J.jsxs)(`div`,{className:`topo-foot`,children:[(0,J.jsxs)(`span`,{className:`legend`,children:[(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{className:`dot`,style:{background:`#d4d4d8`}}),` online`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{className:`dot`,style:{background:`#f87171`}}),` offline`]}),(0,J.jsxs)(`span`,{children:[(0,J.jsx)(`i`,{className:`dot`,style:{background:`#e4e4e7`}}),` neighbour`]}),(0,J.jsxs)(`span`,{className:`muted`,children:[e.stats.devices,` devices · `,e.stats.neighbors,` discovered ·`,` `,e.stats.onboardable,` onboardable`]})]}),_&&(0,J.jsxs)(`div`,{className:`topo-pop`,children:[(0,J.jsxs)(`div`,{className:`topo-pop__hd`,children:[(0,J.jsx)(`strong`,{children:_.label}),(0,J.jsx)(`span`,{className:`muted`,children:[_.board,_.version,_.mac].filter(Boolean).join(` · `)||`no details advertised`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsx)(`button`,{className:`topo-btn`,onClick:()=>r(null),children:`✕`})]}),_.suggestedConfig?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`div`,{className:`muted`,style:{margin:`2px 0 6px`},children:`Not managed yet — add this to your device config to onboard it:`}),(0,J.jsx)(`pre`,{className:`topo-stub`,children:JSON.stringify({[_.suggestedConfig.name]:qY(_.suggestedConfig)},null,2)}),(0,J.jsx)(bc,{className:`topo-btn`,title:`Copy config stub`,label:`Copy config stub`,text:JSON.stringify({[_.suggestedConfig.name]:qY(_.suggestedConfig)},null,2)}),t&&(0,J.jsx)(`button`,{className:`topo-btn cfg-save`,onClick:()=>t(_.suggestedConfig.name,qY(_.suggestedConfig)),children:`Add to config →`})]}):(0,J.jsxs)(`div`,{className:`muted`,children:[`Managed device`,_.ip?` · ${_.ip}`:``,_.uptime?` · up ${_.uptime}`:``]})]})]})]})}function qY(e){let t={port:e.port,username:e.username};return e.host&&(t.host=e.host),e.mac&&(t.mac=e.mac),t}function JY(e){return e>=1e3?`${(e/1e3).toFixed(1)}s`:`${Math.round(e)}ms`}function YY(e){return!e||!e.pooled?`#52525b`:e.dead?`#ef4444`:e.inflight>0?`#3b82f6`:`#22c55e`}function XY(e){return!e||!e.pooled?`no connection`:e.dead?`reconnecting`:e.inflight>0?`${e.inflight} inflight`:`ready`}function ZY({device:e}){let t=e.pool,n=!t||!t.pooled?`disconnected`:t.dead?`dead`:t.inflight>0?`busy`:`idle`,r=YY(t),i=!t||!t.pooled?0:t.inflight>0?Math.min(8+t.inflight*15,100):100;return(0,J.jsxs)(`div`,{className:`pool-card pool-card--${n}`,children:[(0,J.jsxs)(`div`,{className:`pool-card__hd`,children:[(0,J.jsx)(`span`,{className:`pool-card__dot`,style:{background:r}}),(0,J.jsx)(`span`,{className:`pool-card__name`,children:e.name}),(0,J.jsx)(`span`,{className:`pool-card__badge`,style:{color:r},children:XY(t)})]}),(0,J.jsxs)(`div`,{className:`pool-pipe`,children:[(0,J.jsx)(`div`,{className:`pool-pipe__fill${n===`busy`?` pool-pipe__fill--pulse`:``}`,style:{width:`${i}%`,background:r}}),t&&t.pooled&&t.inflight>0&&(0,J.jsxs)(`span`,{className:`pool-pipe__label`,children:[t.inflight,` ch`]})]})]})}function QY({k:e,v:t,sub:n}){return(0,J.jsxs)(`div`,{className:`stat`,style:{minWidth:100},children:[(0,J.jsx)(`p`,{className:`k`,children:e}),(0,J.jsxs)(`div`,{className:`v`,children:[t,n!=null&&(0,J.jsxs)(`small`,{children:[` `,n]})]})]})}function $Y({devices:e,poolPayload:t}){let n=e.filter(e=>e.pool!==null&&e.pool!==void 0);if(!(t?.enabled??n.length>0)&&n.length===0)return(0,J.jsxs)(`details`,{className:`pool-panel`,open:!0,children:[(0,J.jsx)(`summary`,{style:{cursor:`pointer`,fontWeight:600,marginBottom:8},children:`SSH Connection Pool`}),(0,J.jsxs)(`p`,{className:`pool-disabled`,children:[`Connection pooling is disabled. Enable it with `,(0,J.jsx)(`code`,{children:`--ssh-keep-alive true`}),` or`,` `,(0,J.jsx)(`code`,{children:`MIKROTIK_SSH__KEEP_ALIVE=true`}),` to keep persistent SSH connections across tool calls.`]})]});let r=t?.aggregate,i=t?.config;return(0,J.jsxs)(`details`,{className:`pool-panel`,open:!0,children:[(0,J.jsx)(`summary`,{style:{cursor:`pointer`,fontWeight:600,marginBottom:8},children:`SSH Connection Pool`}),r&&(0,J.jsxs)(`div`,{className:`pool-stats`,children:[(0,J.jsx)(QY,{k:`Connections`,v:String(r.totalConnections)}),(0,J.jsx)(QY,{k:`Inflight`,v:String(r.totalInflight),sub:`channels`}),(0,J.jsx)(QY,{k:`Idle`,v:String(r.totalIdle)}),(0,J.jsx)(QY,{k:`Busy`,v:String(r.totalBusy)}),i&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(QY,{k:`Keepalive`,v:JY(i.keepAliveInterval)}),(0,J.jsx)(QY,{k:`Idle timeout`,v:JY(i.idleTimeout)})]})]}),n.length>0&&(0,J.jsx)(`div`,{className:`pool-grid`,children:n.map(e=>(0,J.jsx)(ZY,{device:e},e.name))})]})}Ri.registerPlugin(q);function eX(e,t,n){let r=URL.createObjectURL(new Blob([t],{type:`${n};charset=utf-8`})),i=document.createElement(`a`);i.href=r,i.download=e,document.body.append(i),i.click(),i.remove(),URL.revokeObjectURL(r)}var tX=[{id:`overview`,label:`Overview`,sub:`Calls, latency & risk at a glance`},{id:`devices`,label:`Devices`,sub:`Connectivity radar & system health`},{id:`clients`,label:`Clients`,sub:`Connected LAN devices — usage, block/allow, pin IP`},{id:`aaa`,label:`RADIUS & UM`,sub:`RADIUS client & User Manager RADIUS server`},{id:`topology`,label:`Topology`,sub:`Layer-2 neighbours via MNDP / CDP / LLDP`},{id:`packets`,label:`Packets`,sub:`Live TZSP capture & decode`},{id:`snapshots`,label:`Snapshots`,sub:`Config history & time-travel diff`},{id:`plan`,label:`Change Plan`,sub:`Dry-run intended RouterOS commands`},{id:`s3`,label:`S3 Backups`,sub:`List, download & delete S3 backup objects`},{id:`backups`,label:`Backups`,sub:`Local config vault — create, restore, manage`},{id:`modules`,label:`Modules`,sub:`Enable/disable tool modules — curate the surface`},{id:`config`,label:`Config`,sub:`Effective configuration & safe editor`},{id:`feed`,label:`Live Feed`,sub:`Every tool call, in real time`}],nX=new Set(tX.map(e=>e.id)),rX=`mt-view`;function iX(){try{let e=location.hash.replace(/^#\/?/,``);return nX.has(e)?e:null}catch{return null}}function aX(){let e=iX();if(e)return e;try{let e=localStorage.getItem(rX);if(e&&nX.has(e))return e}catch{}return`overview`}var oX=[`#ededed`,`#a1a1a1`],sX={overview:oX,devices:oX,clients:oX,aaa:oX,topology:oX,packets:oX,snapshots:oX,plan:oX,s3:oX,backups:oX,modules:oX,config:oX,feed:oX},cX={overview:{what:`A live pulse of all MCP tool activity: total calls, error rate, p50/p95 latency, the busiest tools, and a risk breakdown — over a time window you choose.`,tips:[`Change the time window (top-right) to zoom from the last 5 minutes out to 24 hours.`,`The risk donut splits calls by annotation: read · write · destructive · dangerous.`,`A rising error line usually points at one device or one tool — jump to Live Feed to see which.`]},devices:{what:`Every configured router with its live reachability (SSH or MAC-Telnet), latency, identity, and system health — CPU, memory and disk — refreshed continuously.`,tips:[`Each device gets a stable colour so you can track it across the connectivity radar.`,`Health (CPU/Mem/Disk) is probed periodically; MAC-Telnet devices are probed on a slower cadence.`,`Latency tiers are colour-coded green → amber → red; a grey node is currently unreachable.`,`The SSH Connection Pool panel shows persistent connections: green = idle/ready, blue = busy with inflight channels, red = reconnecting.`]},clients:{what:`The LAN devices connected to a router — merged from its DHCP leases and ARP table — with live Download/Upload charts, and one-click controls to block/allow a device, pin (reserve) its IP, change that IP, or relabel it.`,tips:[`Pick the router (top-right) to inspect its connected devices; filter by IP, MAC or name.`,`Click a device to open its live ↓/↑ traffic chart — needs a simple queue targeting its IP.`,`Block/allow is enforced by MAC, so it survives the device changing IP; “Pin IP” makes its lease static.`]},aaa:{what:"Full management of the router's RADIUS client (`/radius`) and the built-in User Manager RADIUS server (`/user-manager`): RADIUS servers + incoming CoA, and User Manager users, service profiles, rate/quota limitations, NAS clients, profile assignments, accounting sessions, and global settings.",tips:[`Pick the router (top-right), then switch tabs across RADIUS, Users, Profiles, Limitations, NAS, Assignments, Sessions and Settings.`,`Every tab is full CRUD: add, edit, enable/disable and remove — secrets are write-only and shown redacted.`,`The Usage & Heatmap tab shows each user's 3-month download/upload and a GitHub-style connection heatmap, persisted locally.`,`If a device lacks the user-manager package, the User Manager tabs explain how to install it; RADIUS-client tabs still work.`]},topology:{what:`A Layer-2 map of neighbours each router discovers via MNDP / CDP / LLDP — the physical adjacency of your network, drawn live.`,tips:[`Solid nodes are configured devices; faint nodes are discovered-but-unmanaged neighbours.`,`Use “Add to config →” on an unmanaged neighbour to pre-fill it in the Config editor.`,`Drag to pan; the layout settles automatically as new neighbours arrive.`]},packets:{what:`Live packet capture streamed from a router over TZSP — decode headers in real time without leaving the dashboard.`,tips:[`Pick a device and start the capture; packets decode as they arrive.`,`Stop the capture when done — it frees the router-side sniffer.`,`Great for debugging a protocol issue alongside the Live Feed of tool calls.`]},snapshots:{what:`Point-in-time captures of a device’s full configuration (/export), stored locally so you can diff any two and see exactly what changed.`,tips:[`Capture a snapshot before a risky change, then diff after to audit the delta.`,`The diff is line-level: green added, red removed.`,`Snapshots are device config exports — for the dashboard’s OWN config history see the Config page.`]},plan:{what:`Dry-run the exact RouterOS commands a change would run before it touches a device — a change plan you can review and trust.`,tips:[`Paste or build intended commands to see them validated and ordered.`,`Nothing is sent to the device from here — it’s a preview.`,`Pair with Safe Mode (auto-revert) when you do apply for real.`]},s3:{what:`Browse, download, and delete backup objects in your configured S3-compatible bucket — your off-box archive of device backups and exports.`,tips:[`Filter by key prefix to find a device’s backups quickly.`,`Download fetches the object through a presigned URL; delete is permanent.`,`For host-side .rsc backups instead, use the Backups page.`]},backups:{what:`A local config vault on the MCP server: capture a device’s /export as a timestamped .rsc file, then download, upload, rename, restore (via Safe Mode), or delete it.`,tips:[`Restore offers a dry-run (applies then rolls back) before you commit for real.`,`Edit the vault path inline in the header — it’s saved to your config.`,`Filenames are stamped in the device’s local 24-hour clock.`]},modules:{what:"Every tool module in the catalog with a live on/off switch. Toggling one writes your config file's `tools` block (disabledModules / enabledModules) and applies it immediately, so you can curate exactly which scopes the MCP server exposes.",tips:[`MCP clients search-rank tools and degrade past ~100; trim the surface below ~150–200 tools so every remaining tool is reliably findable.`,`Disable adds the module to tools.disabledModules; enable removes it (or adds it to an active allow-list) — your config file is updated live on each toggle.`,`Changes need an MCP client reconnect (or a server restart) to actually shrink/grow the visible tool list.`]},config:{what:`View the effective configuration, edit it safely with schema-aware validation and auto-rollback, browse a full field guide, and travel through config version history.`,tips:[`Every successful apply is auto-saved to the version timeline — restore any point in time.`,`Save a named checkpoint before a big change for an easy, labelled rollback.`,`The Field Guide documents every config option, its type, and default — straight from the schema.`]},feed:{what:`Every tool call as it happens — tool, device, risk, duration, and success/error — with full request/response detail on click.`,tips:[`Filter by status to isolate failures, or by tool/device to follow one thread.`,`Click any row to open the full (secret-redacted) request and response.`,`Pause the stream when you want to inspect without rows shifting under you.`]}};function lX({view:e}){let t=cX[e];return(0,J.jsxs)(`div`,{className:`pagehelp reveal`,role:`region`,"aria-label":`Page help`,children:[(0,J.jsx)(`div`,{className:`pagehelp__icon`,"aria-hidden":`true`,children:`?`}),(0,J.jsxs)(`div`,{className:`pagehelp__body`,children:[(0,J.jsx)(`p`,{className:`pagehelp__what`,children:t.what}),(0,J.jsx)(`ul`,{className:`pagehelp__tips`,children:t.tips.map((e,t)=>(0,J.jsx)(`li`,{children:e},t))})]})]})}function uX({name:e}){return(0,J.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.7`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:{overview:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`rect`,{x:`3`,y:`3`,width:`8`,height:`8`,rx:`1.6`}),(0,J.jsx)(`rect`,{x:`13`,y:`3`,width:`8`,height:`5`,rx:`1.6`}),(0,J.jsx)(`rect`,{x:`13`,y:`10`,width:`8`,height:`11`,rx:`1.6`}),(0,J.jsx)(`rect`,{x:`3`,y:`13`,width:`8`,height:`8`,rx:`1.6`})]}),devices:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`7`,rx:`2`}),(0,J.jsx)(`rect`,{x:`3`,y:`13`,width:`18`,height:`7`,rx:`2`}),(0,J.jsx)(`path`,{d:`M7 7.5h.01M7 16.5h.01`})]}),clients:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{cx:`9`,cy:`8`,r:`3`}),(0,J.jsx)(`path`,{d:`M3.5 19a5.5 5.5 0 0 1 11 0`}),(0,J.jsx)(`path`,{d:`M16 7.5a2.5 2.5 0 0 1 0 5M17.5 19a4.5 4.5 0 0 0-2-3.6`})]}),aaa:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M12 3 4 6v5c0 4.4 3.2 7.6 8 9 4.8-1.4 8-4.6 8-9V6l-8-3Z`}),(0,J.jsx)(`path`,{d:`M9.5 11.5 11 13l3.5-3.5`})]}),topology:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{cx:`12`,cy:`5`,r:`2.4`}),(0,J.jsx)(`circle`,{cx:`5`,cy:`19`,r:`2.4`}),(0,J.jsx)(`circle`,{cx:`19`,cy:`19`,r:`2.4`}),(0,J.jsx)(`path`,{d:`M12 7.4 6.4 16.6M12 7.4 17.6 16.6`})]}),packets:(0,J.jsx)(`path`,{d:`M3 12h4l2-7 4 14 2-7h6`}),snapshots:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M12 3 3 7.5 12 12 21 7.5 12 3Z`}),(0,J.jsx)(`path`,{d:`M3 12 12 16.5 21 12`}),(0,J.jsx)(`path`,{d:`M3 16.5 12 21 21 16.5`})]}),plan:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`circle`,{cx:`6`,cy:`6`,r:`2.3`}),(0,J.jsx)(`circle`,{cx:`6`,cy:`18`,r:`2.3`}),(0,J.jsx)(`circle`,{cx:`18`,cy:`8`,r:`2.3`}),(0,J.jsx)(`path`,{d:`M6 8.3v7.4M8.3 6H13a3 3 0 0 1 3 3v0`})]}),s3:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`ellipse`,{cx:`12`,cy:`6`,rx:`7`,ry:`2.6`}),(0,J.jsx)(`path`,{d:`M5 6v12c0 1.5 3.1 2.6 7 2.6s7-1.1 7-2.6V6`}),(0,J.jsx)(`path`,{d:`M5 12c0 1.5 3.1 2.6 7 2.6s7-1.1 7-2.6`})]}),backups:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M3 6.5 5 3.5h14l2 3`}),(0,J.jsx)(`rect`,{x:`3`,y:`6.5`,width:`18`,height:`14`,rx:`2`}),(0,J.jsx)(`path`,{d:`M9.5 12h5`})]}),modules:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`rect`,{x:`3`,y:`5`,width:`18`,height:`6`,rx:`3`}),(0,J.jsx)(`circle`,{cx:`8`,cy:`8`,r:`1.5`}),(0,J.jsx)(`rect`,{x:`3`,y:`13`,width:`18`,height:`6`,rx:`3`}),(0,J.jsx)(`circle`,{cx:`16`,cy:`16`,r:`1.5`})]}),config:(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`path`,{d:`M4 7h8M16 7h4M4 17h4M12 17h8`}),(0,J.jsx)(`circle`,{cx:`14`,cy:`7`,r:`2.2`}),(0,J.jsx)(`circle`,{cx:`10`,cy:`17`,r:`2.2`})]}),feed:(0,J.jsx)(`path`,{d:`M4 6h16M4 12h16M4 18h10`})}[e]})}function dX(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(null),[c,l]=(0,v.useState)(null),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(!1),[m,h]=(0,v.useState)(null),[g,_]=(0,v.useState)([]),[y,b]=(0,v.useState)(36e5),[x,S]=(0,v.useState)(!1),[C,w]=(0,v.useState)(`off`),[T,E]=(0,v.useState)(null),[D,O]=(0,v.useState)(()=>new Set),[k,A]=(0,v.useState)({}),[j,M]=(0,v.useState)({tool:``,risk:``,device:``,status:``,q:``}),N=(0,v.useRef)(x);N.current=x;let P=(0,v.useRef)(null);LY(P);let[F,I]=(0,v.useState)(aX),L=(0,v.useCallback)(e=>{I(e);try{iX()!==e&&(location.hash=e),localStorage.setItem(rX,e)}catch{}},[]);(0,v.useEffect)(()=>{if(iX()!==F)try{location.hash=F}catch{}let e=()=>{let e=iX();e&&L(e)};return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[]);let[ee,te]=(0,v.useState)(()=>{try{let e=localStorage.getItem(`mt-help-open`);return new Set(e?JSON.parse(e):[])}catch{return new Set}}),R=e=>te(t=>{let n=new Set(t);n.has(e)?n.delete(e):n.add(e);try{localStorage.setItem(`mt-help-open`,JSON.stringify([...n]))}catch{}return n}),[z,ne]=(0,v.useState)(``),[B,re]=(0,v.useState)(`all`),ie=(0,v.useMemo)(()=>{let e=i?.devices??[];return{online:e.filter(e=>e.status.reachable===!0).length,offline:e.filter(e=>e.status.reachable===!1).length,total:e.length}},[i]),ae=(0,v.useMemo)(()=>{let e=i?.devices??[],t=z.trim().toLowerCase();return e.filter(e=>!(B===`online`&&e.status.reachable!==!0||B===`offline`&&e.status.reachable!==!1||t&&!e.name.toLowerCase().includes(t)&&!(e.address??e.host??``).toLowerCase().includes(t)))},[i,z,B]);IY((0,v.useCallback)(e=>{if(N.current)return;_(t=>[e,...t].slice(0,kc));let t=e.device;t&&A(e=>({...e,[t]:(e[t]??0)+1}))},[]),(0,v.useCallback)(e=>w(e),[])),(0,v.useEffect)(()=>{fc(`/api/events?limit=${kc}`).then(e=>_(e.events)).catch(()=>{})},[]);let oe=(0,v.useCallback)(()=>{fc(`/api/stats?window=${y}&buckets=60`).then(t).catch(()=>{})},[y]);(0,v.useEffect)(()=>{oe();let e=()=>{oe(),fc(`/api/meta`).then(r).catch(()=>{}),fc(`/api/devices`).then(a).catch(()=>{}),fc(`/api/ssh-pool`).then(s).catch(()=>{}),fc(`/api/topology`).then(l).catch(()=>{})};e();let t=setInterval(()=>{N.current||e()},4e3);return()=>clearInterval(t)},[oe]),(0,v.useEffect)(()=>{let e=()=>void fc(`/api/config`).then(d).catch(()=>{});e();let t=setInterval(e,3e4);return()=>clearInterval(t)},[]),(0,v.useEffect)(()=>{let e=e=>{e.key===`Escape`&&E(null)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let se=(0,v.useMemo)(()=>{let e=j.q.trim().toLowerCase();return g.filter(t=>!(j.tool&&t.tool!==j.tool||j.risk&&t.risk!==j.risk||j.device&&t.device!==j.device||j.status===`ok`&&t.isError||j.status===`error`&&!t.isError||e&&!t.tool.toLowerCase().includes(e)&&!t.input.toLowerCase().includes(e)&&!t.output.toLowerCase().includes(e)&&!(t.error??``).toLowerCase().includes(e))).sort((e,t)=>t.ts-e.ts)},[g,j]),ce=!!(j.tool||j.risk||j.device||j.status||j.q),V=(0,v.useMemo)(()=>g.filter(e=>e.isError),[g]),le=(0,v.useMemo)(()=>({ok:g.length-V.length,error:V.length}),[g,V]),ue=(0,v.useCallback)(async e=>{try{E(await fc(`/api/event/${encodeURIComponent(e.id)}`))}catch{E(e)}},[]),de=(0,v.useMemo)(()=>se.slice(0,200),[se]),H=(0,v.useMemo)(()=>de.map(e=>e.id),[de]),fe=H.length>0&&H.every(e=>D.has(e)),pe=!fe&&H.some(e=>D.has(e)),me=(0,v.useCallback)(e=>{O(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),he=(0,v.useCallback)(()=>{O(e=>{let t=new Set(e);if(H.length>0&&H.every(e=>t.has(e)))for(let e of H)t.delete(e);else for(let e of H)t.add(e);return t})},[H]),[ge,_e]=(0,v.useState)(!1),ve=(0,v.useCallback)(async()=>{let e=[...D];if(e.length!==0)try{await mc({ids:e});let t=new Set(e);_(e=>e.filter(e=>!t.has(e.id))),O(new Set)}catch{}finally{_e(!1)}},[D]),ye=e=>{if(e===`json`){eX(`mcp-events.json`,JSON.stringify(se,null,2),`application/json`);return}let t=[`ts`,`tool`,`risk`,`device`,`durationMs`,`isError`,`error`],n=e=>/[",\n]/.test(e)?`"${e.replace(/"/g,`""`)}"`:e,r=se.map(e=>[new Date(e.ts).toISOString(),e.tool,e.risk,e.device??``,String(e.durationMs),String(e.isError),e.error??``].map(n).join(`,`)).join(`
|
|
81
|
+
`);eX(`mcp-events.csv`,`${t.join(`,`)}\n${r}\n`,`text/csv`)},be=e?e.errorRate>=.2?`is-bad`:e.errorRate>=.05?`is-warn`:`is-good`:``,xe=u?.mcp??{},Se=u?.dashboard??{},Ce=u?.ssh??{},we=(e,t,n)=>(0,J.jsxs)(`select`,{className:`btn`,value:j[e],onChange:t=>M(n=>({...n,[e]:t.target.value})),children:[(0,J.jsx)(`option`,{value:``,children:t}),n.map(e=>(0,J.jsx)(`option`,{value:e,children:e},e))]}),Te=tX.find(e=>e.id===F)??tX[0];return(0,J.jsxs)(`div`,{className:`shell`,ref:P,"data-view":F,style:{"--page-accent":sX[F][0],"--page-accent-2":sX[F][1]},children:[(0,J.jsxs)(`aside`,{className:`nav`,children:[(0,J.jsxs)(`div`,{className:`nav__brand`,children:[(0,J.jsx)(`div`,{className:`nav__mark`,children:(0,J.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,"aria-hidden":`true`,children:(0,J.jsxs)(`g`,{stroke:`#18181b`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,J.jsx)(`path`,{d:`M12 12 L4 5 M12 12 L20 5 M12 12 L12 20`}),(0,J.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`,fill:`#18181b`,stroke:`none`}),(0,J.jsx)(`circle`,{cx:`4`,cy:`5`,r:`1.9`,fill:`#18181b`,stroke:`none`}),(0,J.jsx)(`circle`,{cx:`20`,cy:`5`,r:`1.9`,fill:`#18181b`,stroke:`none`}),(0,J.jsx)(`circle`,{cx:`12`,cy:`20`,r:`1.9`,fill:`#18181b`,stroke:`none`})]})})}),(0,J.jsxs)(`div`,{className:`nav__brandtext`,children:[(0,J.jsx)(`b`,{children:`MikroTik MCP`}),(0,J.jsx)(`small`,{children:`Observability`})]})]}),(0,J.jsx)(`nav`,{className:`nav__items`,children:tX.map(e=>(0,J.jsxs)(`button`,{className:`nav__item${F===e.id?` is-active`:``}`,onClick:()=>L(e.id),children:[(0,J.jsx)(uX,{name:e.id}),(0,J.jsx)(`span`,{children:e.label}),e.id===`feed`&&g.length>0&&(0,J.jsx)(`span`,{className:`nav__badge`,children:g.length>999?`999+`:g.length},g.length)]},e.id))}),(0,J.jsxs)(`div`,{className:`nav__foot`,children:[(0,J.jsxs)(`span`,{className:`hero__live${C===`off`?``:` is-on`}${C===`ws`?` is-ws`:C===`sse`?` is-sse`:``}`,title:`Live transport: WebSocket (preferred) or SSE fallback`,children:[(0,J.jsx)(`span`,{className:`dot`}),C===`off`?`offline`:`live · ${C}`]}),(0,J.jsx)(`small`,{className:`muted`,children:n?`${wc(n.total)} events · ${n.transport}`:`connecting…`})]})]}),(0,J.jsxs)(`main`,{className:`main`,"data-view":F,children:[(0,J.jsxs)(`header`,{className:`topline reveal`,children:[(0,J.jsxs)(`div`,{className:`topline__txt`,children:[(0,J.jsx)(`h1`,{children:Te.label}),(0,J.jsx)(`small`,{children:Te.sub})]}),(0,J.jsx)(`span`,{className:`topline__spacer`}),F===`overview`&&(0,J.jsx)(`select`,{className:`btn`,value:y,onChange:e=>b(Number(e.target.value)),title:`Stats time window`,children:Oc.map(([e,t])=>(0,J.jsxs)(`option`,{value:t,children:[`window: `,e]},t))}),(0,J.jsxs)(`button`,{className:`help-toggle${ee.has(F)?` is-on`:``}`,onClick:()=>R(F),"aria-expanded":ee.has(F),title:`About this page`,children:[(0,J.jsx)(`span`,{className:`help-toggle__q`,"aria-hidden":`true`,children:`?`}),`Help`]})]}),ee.has(F)&&(0,J.jsx)(lX,{view:F}),F===`overview`&&(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsx)(`div`,{className:`cards reveal`,children:e?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(_c,{k:`Calls (window)`,v:wc(e.total)}),(0,J.jsx)(_c,{k:`Calls / min`,v:e.callsPerMin.toFixed(1)}),(0,J.jsx)(_c,{k:`Error rate`,v:`${(e.errorRate*100).toFixed(1)}%`,sub:`${e.errors} err`,cls:be}),(0,J.jsx)(_c,{k:`Avg latency`,v:xc(e.latency.avg)}),(0,J.jsx)(_c,{k:`p95 latency`,v:xc(e.latency.p95)}),(0,J.jsx)(_c,{k:`p99 latency`,v:xc(e.latency.p99)}),(0,J.jsx)(_c,{k:`Distinct tools`,v:wc(e.distinctTools)}),(0,J.jsx)(_c,{k:`Output volume`,v:Sc(e.outputBytes)})]}):(0,J.jsxs)(`div`,{className:`stat`,children:[(0,J.jsx)(`p`,{className:`k`,children:`Loading…`}),(0,J.jsx)(`div`,{className:`v`,children:`—`})]})}),(0,J.jsxs)(`div`,{className:`bento reveal`,children:[(0,J.jsx)(gc,{title:`Calls over time`,className:`b-series`,children:e?(0,J.jsx)(zJ,{series:e.series}):(0,J.jsx)(`div`,{className:`muted`,children:`no data`})}),e&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(gc,{title:`By risk`,className:`b-risk`,children:(0,J.jsx)(BJ,{segments:Object.keys(e.byRisk).map(t=>({label:t,value:e.byRisk[t],color:Dc[t]}))})}),(0,J.jsx)(gc,{title:`Top tools`,className:`b-tools`,children:(0,J.jsx)(vc,{rows:e.byTool.map(e=>({label:e.tool,value:e.count,sub:`${e.count}× · ${xc(e.p95Ms)} p95${e.errors?` · ${e.errors} err`:``}`,color:e.errors?`var(--mt-bad)`:void 0}))})}),(0,J.jsx)(gc,{title:`Status`,className:`b-status`,children:(0,J.jsx)(BJ,{centerLabel:`calls`,segments:[{label:`ok`,value:le.ok,color:`#a1a1a1`},{label:`error`,value:le.error,color:`#ff5c5c`}]})}),(0,J.jsx)(gc,{title:`By device`,className:`b-device`,children:e.byDevice.length?(0,J.jsx)(vc,{rows:e.byDevice.map(e=>({label:e.device,value:e.count}))}):(0,J.jsx)(`div`,{className:`muted`,children:`single device`})}),(0,J.jsx)(gc,{title:`Recent errors`,className:`b-errors`,children:V.length?(0,J.jsx)(`div`,{className:`hbar`,children:V.slice(0,8).map(e=>(0,J.jsxs)(`div`,{className:`hbar__row conn-errrow`,style:{gridTemplateColumns:`auto 1fr`},onClick:()=>void ue(e),children:[(0,J.jsx)(`span`,{className:`muted`,children:Cc(e.ts)}),(0,J.jsxs)(`span`,{style:{color:`var(--mt-bad)`,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`,minWidth:0},title:e.error??e.output,children:[e.tool,`: `,e.error??e.output??`error`]})]},e.id))}):(0,J.jsx)(`div`,{className:`muted`,children:`no errors 🎉`})})]})]})]}),F===`devices`&&(i&&i.devices.length>0?(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsxs)(`div`,{className:`dev-toolbar reveal`,children:[(0,J.jsx)(`input`,{className:`search`,type:`search`,placeholder:`Search devices by name or address…`,value:z,onChange:e=>ne(e.target.value),style:{flex:1,minWidth:180}}),(0,J.jsx)(`div`,{className:`dev-filters`,children:[`all`,`online`,`offline`].map(e=>(0,J.jsx)(`button`,{className:`dev-fbtn${B===e?` is-active`:``}`,onClick:()=>re(e),children:e===`all`?`All ${ie.total}`:e===`online`?`Online ${ie.online}`:`Offline ${ie.offline}`},e))}),(0,J.jsxs)(`span`,{className:`muted`,children:[ae.length,`/`,ie.total,` shown`]})]}),(0,J.jsxs)(`details`,{className:`dev-collapse reveal`,open:ie.total<=8,children:[(0,J.jsxs)(`summary`,{children:[`Connectivity radar`,(0,J.jsxs)(`span`,{className:`muted`,children:[` `,`· `,ie.online,` online · `,ie.offline,` offline ·`,` `,ie.total,` total`]})]}),(0,J.jsx)(jY,{payload:i,pulses:k})]}),(0,J.jsx)($Y,{devices:ae,poolPayload:o}),ae.length===0?(0,J.jsxs)(`div`,{className:`feed-empty reveal`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🔍`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No devices match`}),(0,J.jsx)(`p`,{className:`feed-empty__sub`,children:`Try a different search or status filter.`})]}):(0,J.jsx)(`div`,{className:`dev-grid-wide reveal`,children:ae.map(e=>(0,J.jsx)(MY,{d:e},e.name))}),ae.length>0&&(0,J.jsx)(gc,{title:`Device system health`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`CPU · memory · disk · latency · live probe`}),children:(0,J.jsx)(`div`,{className:`health-grid`,children:ae.map(e=>(0,J.jsx)(FY,{d:e},e.name))})})]}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🖧`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No devices configured`}),(0,J.jsx)(jc,{type:`secondary`,label:`Tip`,children:`Add a device to your config to see connectivity and system health here.`})]})),F===`clients`&&(0,J.jsx)(eY,{}),F===`aaa`&&(0,J.jsx)(pl,{}),F===`topology`&&(c&&c.nodes.length>0?(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsx)(gc,{title:`Network topology`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`Layer-2 neighbours via MNDP/CDP/LLDP · click a neighbour to onboard it`}),children:(0,J.jsx)(KY,{topo:c,onOnboard:(e,t)=>{h({name:e,body:t}),p(!0),L(`config`)}})})}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🛰️`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No neighbours discovered yet`}),(0,J.jsx)(`p`,{className:`feed-empty__sub`,children:`Layer-2 neighbours (MNDP / CDP / LLDP) appear here as the device reports them.`})]})),F===`packets`&&(0,J.jsx)(`section`,{className:`view`,children:(0,J.jsx)(gc,{title:`Packet capture`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`live TZSP decode · /tool sniffer streaming`}),children:(0,J.jsx)(HY,{})})}),F===`snapshots`&&(0,J.jsx)(WY,{}),F===`plan`&&(0,J.jsx)(hl,{}),F===`s3`&&(0,J.jsx)(UY,{}),F===`backups`&&(0,J.jsx)(Lc,{}),F===`modules`&&(0,J.jsx)(zY,{}),F===`config`&&(u?(0,J.jsxs)(`section`,{className:`view`,children:[(0,J.jsx)(gc,{title:`Configuration`,className:`reveal`,extra:(0,J.jsx)(`button`,{className:`btn`,onClick:()=>p(e=>!e),title:`Edit the config JSON with autocomplete, validation and safe-apply`,children:f?`View`:`✎ Edit config`}),children:f?(0,J.jsx)(vY,{initial:m?{...u,devices:{...u.devices,[m.name]:m.body}}:u,onClose:()=>{p(!1),h(null)},onReload:()=>{h(null),fc(`/api/config`).then(d).catch(()=>{})}},m?`seed-${m.name}`:`config`):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`div`,{className:`legend`,style:{margin:`0 0 10px`},children:[(0,J.jsxs)(`span`,{children:[`transport: `,Tc(xe.transport)]}),(0,J.jsxs)(`span`,{children:[`read-only: `,u.readOnly?`yes`:`no`]}),(0,J.jsxs)(`span`,{children:[`dashboard: `,Tc(Se.host),`:`,Tc(Se.port)]}),(0,J.jsxs)(`span`,{children:[`capture: `,Se.captureBody?`on`:`off`]}),(0,J.jsxs)(`span`,{children:[`s3: `,u.s3?`configured`:`off`]}),(0,J.jsxs)(`span`,{children:[`ssh pool: `,Ce.keepAlive===!1?`off`:`on`]})]}),(0,J.jsxs)(`details`,{className:`cfg`,children:[(0,J.jsx)(`summary`,{children:`Full effective configuration (secrets redacted)`}),(0,J.jsx)(mY,{value:u,maxHeight:340})]})]})}),(0,J.jsx)(gc,{title:`Version history`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`point-in-time snapshots · diff & restore`}),children:(0,J.jsx)(rY,{onRestored:()=>void fc(`/api/config`).then(d).catch(()=>{})})}),(0,J.jsx)(gc,{title:`Field guide`,className:`reveal`,extra:(0,J.jsx)(`span`,{className:`muted`,children:`every config option, documented from the schema`}),children:(0,J.jsx)(aY,{})})]}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(Pc,{}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`Loading configuration…`})]})),F===`feed`&&(0,J.jsxs)(`div`,{className:`panel reveal`,children:[(0,J.jsxs)(`div`,{className:`sheet__hd`,style:{marginBottom:12},children:[(0,J.jsx)(`h2`,{style:{margin:0},children:`Live tool calls`}),(0,J.jsx)(`span`,{style:{flex:1}}),(0,J.jsxs)(`span`,{className:`muted`,children:[se.length,` shown · `,g.length,` buffered`]})]}),(0,J.jsxs)(`div`,{className:`toolbar`,style:{marginBottom:12},children:[(0,J.jsx)(`div`,{className:`grow`,style:{flex:1,minWidth:180},children:(0,J.jsx)(`input`,{className:`search`,type:`search`,placeholder:`Search tool / input / output / error…`,value:j.q,onChange:e=>M(t=>({...t,q:e.target.value}))})}),we(`tool`,`all tools`,n?.tools??[]),we(`risk`,`all risk`,[`READ`,`WRITE`,`WRITE_IDEMPOTENT`,`DESTRUCTIVE`,`DANGEROUS`]),we(`device`,`all devices`,n?.devices??[]),we(`status`,`all status`,[`ok`,`error`]),(0,J.jsx)(`button`,{className:`btn${x?` is-active`:``}`,onClick:()=>S(e=>!e),children:x?`▶ Resume`:`⏸ Pause`}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>ye(`csv`),children:`CSV`}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>ye(`json`),children:`JSON`}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>M({tool:``,risk:``,device:``,status:``,q:``}),children:`Clear`}),ge&&D.size>0?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsxs)(`button`,{className:`btn btn-danger`,onClick:()=>void ve(),children:[`✓ Confirm delete (`,D.size,`)`]}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>_e(!1),children:`Cancel`})]}):(0,J.jsxs)(`button`,{className:`btn`,disabled:D.size===0,onClick:()=>_e(!0),title:`Delete the selected rows`,children:[`🗑 Delete`,D.size>0?` (${D.size})`:``]})]}),se.length===0?ce?(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__icon`,children:`🔍`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:`No calls match your filters`}),(0,J.jsxs)(`p`,{className:`feed-empty__sub`,children:[g.length,` call`,g.length===1?``:`s`,` buffered — try widening the search or the risk / device / status filters.`]}),(0,J.jsx)(`button`,{className:`btn`,onClick:()=>M({tool:``,risk:``,device:``,status:``,q:``}),children:`Clear filters`})]}):(0,J.jsxs)(`div`,{className:`feed-empty`,children:[(0,J.jsx)(`div`,{className:`feed-empty__pulse${C===`off`?``:` is-on`}`}),(0,J.jsx)(`p`,{className:`feed-empty__title`,children:C===`off`?`Not connected`:`Listening for tool calls…`}),(0,J.jsx)(`p`,{className:`feed-empty__sub`,children:C===`off`?`The live stream is offline — it will reconnect automatically.`:`Tool calls the LLM makes against this server stream in here in real time.`})]}):(0,J.jsx)(`div`,{className:`feedwrap`,children:(0,J.jsxs)(`table`,{className:`feed`,children:[(0,J.jsx)(`thead`,{children:(0,J.jsxs)(`tr`,{children:[(0,J.jsx)(`th`,{style:{width:28},children:(0,J.jsx)(`input`,{type:`checkbox`,"aria-label":`Select all shown rows`,checked:fe,ref:e=>{e&&(e.indeterminate=pe)},onChange:he})}),(0,J.jsx)(`th`,{children:`time`}),(0,J.jsx)(`th`,{children:`tool`}),(0,J.jsx)(`th`,{children:`risk`}),(0,J.jsx)(`th`,{children:`device`}),(0,J.jsx)(`th`,{className:`num`,children:`dur`}),(0,J.jsx)(`th`,{children:`status`}),(0,J.jsx)(`th`,{children:`output`})]})}),(0,J.jsx)(`tbody`,{children:de.map(e=>(0,J.jsxs)(`tr`,{className:`${e.isError?`is-err`:``}${D.has(e.id)?` is-selected`:``}`.trim()||void 0,onClick:()=>void ue(e),children:[(0,J.jsx)(`td`,{onClick:e=>e.stopPropagation(),children:(0,J.jsx)(`input`,{type:`checkbox`,"aria-label":`Select row`,checked:D.has(e.id),onChange:()=>me(e.id)})}),(0,J.jsx)(`td`,{children:Cc(e.ts)}),(0,J.jsx)(`td`,{children:e.tool}),(0,J.jsx)(`td`,{children:(0,J.jsx)(`span`,{className:`risk risk-${e.risk}`,children:e.risk.replace(`WRITE_IDEMPOTENT`,`WRITE·I`)})}),(0,J.jsx)(`td`,{children:e.device??`—`}),(0,J.jsx)(`td`,{className:`num`,children:xc(e.durationMs)}),(0,J.jsx)(`td`,{children:(0,J.jsx)(`span`,{className:e.isError?`status-err`:`status-ok`,children:e.isError?`error`:`ok`})}),(0,J.jsx)(`td`,{className:`preview`,children:e.isError?e.error??`error`:e.output||`—`})]},e.id))})]})})]})]}),T&&(0,J.jsx)(NY,{event:T,onClose:()=>E(null)})]})}var fX=document.getElementById(`root`);fX&&(0,y.createRoot)(fX).render((0,J.jsx)(dX,{}));
|
|
82
82
|
</script>
|
|
83
83
|
<style>
|
|
84
|
-
@import "https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:var(--mt-sans);--font-mono:var(--mt-mono)}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.isolate{isolation:isolate}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.shrink{flex-shrink:1}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}:root{--background:#0a0a0a;--foreground:#ededed;--card:#111;--card-foreground:#ededed;--popover:#111;--popover-foreground:#ededed;--primary:#ededed;--primary-foreground:#0a0a0a;--secondary:#1a1a1a;--secondary-foreground:#ededed;--muted:#1a1a1a;--muted-foreground:#a1a1a1;--accent:var(--page-accent,#3291ff);--accent-foreground:#0a0a0a;--destructive:#ff5c5c;--destructive-foreground:#fff;--success:#2dd4a7;--warning:#f5a623;--border:#2a2a2a;--input:#2a2a2a;--ring:var(--page-accent,#3291ff);--radius:.5rem}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}:root{--mt-bg:var(--color-background-primary,#0b0d10);--mt-surface:var(--color-background-secondary,#14171c);--mt-surface-2:var(--color-background-tertiary,#1b1f26);--mt-border:var(--color-border-primary,#262b33);--mt-text:var(--color-text-primary,#e8eaed);--mt-text-dim:var(--color-text-secondary,#9aa3af);--mt-text-faint:var(--color-text-tertiary,#6b7280);--mt-accent:var(--color-accent-primary,#6ea8fe);--mt-good:#34d399;--mt-warn:#fbbf24;--mt-bad:#f87171;--mt-radius:var(--border-radius-md,14px);--mt-radius-sm:var(--border-radius-sm,9px);--mt-mono:var(--font-mono,ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace);--mt-sans:var(--font-sans,system-ui, -apple-system, "Segoe UI", sans-serif);--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}*{box-sizing:border-box}body{background:var(--mt-bg);color:var(--mt-text);font-family:var(--mt-sans);-webkit-font-smoothing:antialiased;margin:0;padding:16px;font-size:13px;line-height:1.5}.app{gap:14px;max-width:960px;margin:0 auto;display:grid}.hd{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.hd__dot{background:var(--mt-good);width:9px;height:9px;box-shadow:0 0 0 4px color-mix(in srgb, var(--mt-good) 22%, transparent);border-radius:50%}.hd__title{letter-spacing:-.01em;margin:0;font-size:17px;font-weight:650}.hd__sub{color:var(--mt-text-dim);font-family:var(--mt-mono);margin:0;font-size:12px}.hd__spacer{flex:1}.pill{border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);font-family:var(--mt-mono);border-radius:999px;align-items:center;gap:6px;padding:3px 9px;font-size:11px;display:inline-flex}.pill b{color:var(--mt-text);font-weight:600}.grid{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;display:grid}.card{background:linear-gradient(180deg, var(--mt-surface), var(--mt-surface-2));border:1px solid var(--mt-border);border-radius:var(--mt-radius);padding:14px}.card__label{color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.06em;margin:0 0 8px;font-size:11px}.card__value{font-family:var(--mt-mono);letter-spacing:-.01em;font-size:20px;font-weight:600}.toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.toolbar .grow{flex:1;min-width:140px}.search{appearance:none;border:1px solid var(--mt-border);background:var(--mt-surface);width:100%;color:var(--mt-text);font:inherit;border-radius:var(--mt-radius-sm);padding:7px 11px;font-size:13px}.search:focus{border-color:var(--mt-accent);outline:none}.search::placeholder{color:var(--mt-text-faint)}.btn{appearance:none;border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text);font:inherit;border-radius:var(--mt-radius-sm);cursor:pointer;white-space:nowrap;padding:6px 11px;font-size:12px;transition:border-color .15s,background .15s}.btn:disabled{opacity:.5;cursor:default}.btn.is-active{border-color:var(--mt-accent);color:var(--mt-accent)}.chip{border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);font-family:var(--mt-mono);border-radius:999px;align-items:center;gap:4px;padding:1px 7px;font-size:11px;display:inline-flex}.chip.is-good{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 45%, var(--mt-border))}.chip.is-warn{color:var(--mt-warn);border-color:color-mix(in srgb, var(--mt-warn) 45%, var(--mt-border))}.chip.is-bad{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border))}.tablewrap{border:1px solid var(--mt-border);border-radius:var(--mt-radius);max-height:70vh;overflow:auto}table.tbl{border-collapse:collapse;width:100%;font-size:12px}table.tbl th,table.tbl td{text-align:left;border-bottom:1px solid color-mix(in srgb, var(--mt-border) 55%, transparent);white-space:nowrap;font-family:var(--mt-mono);padding:7px 12px}table.tbl thead th{z-index:1;background:var(--mt-surface-2);color:var(--mt-text-dim);cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:600;position:sticky;top:0}table.tbl thead th:hover{color:var(--mt-text)}table.tbl thead th .arrow{color:var(--mt-accent);margin-left:4px}table.tbl tbody tr{cursor:pointer}table.tbl tbody tr:hover{background:color-mix(in srgb, var(--mt-accent) 8%, transparent)}table.tbl tbody tr.is-disabled td,table.tbl td.col-num{color:var(--mt-text-faint)}.kv__body{border:1px solid var(--mt-border);border-radius:var(--mt-radius);grid-template-columns:minmax(120px,.4fr) 1fr;display:grid;overflow:hidden}.kv__body>div{border-bottom:1px solid color-mix(in srgb, var(--mt-border) 55%, transparent);overflow-wrap:anywhere;min-width:0;font-size:12px;font-family:var(--mt-mono);padding:7px 14px}.kv__k{color:var(--mt-text-dim);background:color-mix(in srgb, var(--mt-surface) 60%, transparent)}.kv__v{color:var(--mt-text)}.drawer{border:1px solid var(--mt-accent);border-radius:var(--mt-radius);background:var(--mt-surface);gap:10px;padding:12px;display:grid}.drawer__hd{align-items:center;gap:8px;display:flex}.drawer__hd b{font-family:var(--mt-mono)}pre.raw{border:1px solid var(--mt-border);border-radius:var(--mt-radius);background:var(--mt-surface);color:var(--mt-text);font-family:var(--mt-mono);white-space:pre;max-height:70vh;margin:0;padding:14px;font-size:12px;overflow:auto}.foot{color:var(--mt-text-faint);font-size:11px;font-family:var(--mt-mono);flex-wrap:wrap;align-items:center;gap:10px;display:flex}.foot .grow{flex:1}.skeleton,.empty{color:var(--mt-text-faint);text-align:center;padding:40px 0}:root{--mt-sans:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--mt-mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--mt-display:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--mt-bg:#0a0a0a;--mt-surface:#111;--mt-surface-2:#1a1a1a;--mt-border:#2a2a2a;--mt-border-strong:#3a3a3a;--mt-text:#ededed;--mt-text-dim:#a1a1a1;--mt-text-faint:#6e6e6e;--mt-good:#d4d4d8;--mt-warn:#a1a1a1;--mt-bad:#ff5c5c;--mt-radius:12px;--mt-radius-sm:8px;--sky:#3291ff;--teal:#2dd4bf;--cyan:#45d4ee;--lime:#69d05a;--coral:#ff5c5c;--amber:#f5a623;--pink:#ff4d8d;--violet:#9d7bff;--page-accent:#3291ff;--page-accent-2:#2dd4bf;--mt-accent:var(--page-accent);--grad:linear-gradient(115deg, var(--page-accent), var(--page-accent-2) 90%);--ease:cubic-bezier(.22, 1, .36, 1);--glass:#111111b8}html,body{background:var(--mt-bg);color:var(--mt-text);font-family:var(--mt-sans);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;margin:0;padding:0}body:after{content:"";z-index:-2;background-image:linear-gradient(color-mix(in srgb, var(--mt-border) 55%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--mt-border) 55%, transparent) 1px, transparent 1px);opacity:.32;pointer-events:none;background-size:52px 52px;position:fixed;inset:0;-webkit-mask-image:radial-gradient(circle at 50% 0,#000,#0000 72%);mask-image:radial-gradient(circle at 50% 0,#000,#0000 72%)}.main:before{content:"";z-index:-1;background:radial-gradient(52% 38% at 18% -8%, color-mix(in srgb, var(--page-accent) 14%, transparent), transparent 70%), radial-gradient(46% 36% at 100% 4%, color-mix(in srgb, var(--page-accent-2) 11%, transparent), transparent 68%);opacity:.9;transition:background .5s var(--ease);pointer-events:none;position:fixed;inset:0}.shell{grid-template-columns:250px minmax(0,1fr);align-items:start;min-height:100vh;display:grid}.nav{border-right:1px solid var(--mt-border);background:color-mix(in srgb, var(--mt-surface) 55%, transparent);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);flex-direction:column;gap:10px;height:100vh;padding:18px 14px;display:flex;position:sticky;top:0}.nav__brand{align-items:center;gap:11px;padding:6px 8px 14px;display:flex}.nav__mark{background:var(--grad);width:38px;height:38px;box-shadow:0 6px 20px color-mix(in srgb, var(--page-accent) 34%, transparent);transition:background .4s var(--ease), box-shadow .4s var(--ease);border-radius:11px;flex:none;place-items:center;display:grid}.nav__mark svg{width:22px;height:22px;display:block}.nav__brandtext{flex-direction:column;min-width:0;line-height:1.1;display:flex}.nav__brandtext b{font-family:var(--mt-display);letter-spacing:-.03em;font-size:15px;font-weight:700}.nav__brandtext small{font-family:var(--mt-mono);letter-spacing:.16em;text-transform:uppercase;color:var(--mt-text-dim);margin-top:3px;font-size:10px}.nav__items{flex-direction:column;flex:1;gap:3px;display:flex}.nav__item{color:var(--mt-text-dim);font-family:var(--mt-sans);cursor:pointer;text-align:left;transition:background .18s var(--ease), color .18s, border-color .18s, transform .18s var(--ease);background:0 0;border:1px solid #0000;border-radius:11px;align-items:center;gap:11px;padding:10px 12px;font-size:13px;font-weight:500;display:flex}.nav__item svg{opacity:.85;flex:none;width:18px;height:18px}.nav__item:hover{color:var(--mt-text);background:color-mix(in srgb, var(--mt-text) 7%, transparent)}.nav__item.is-active{color:var(--mt-text);border-color:color-mix(in srgb, var(--page-accent) 36%, var(--mt-border));background:linear-gradient(100deg, color-mix(in srgb, var(--page-accent) 16%, transparent), color-mix(in srgb, var(--page-accent-2) 7%, transparent))}.nav__item.is-active svg{opacity:1;color:var(--page-accent)}.nav__item.is-active:before{content:"";background:var(--page-accent);width:3px;box-shadow:0 0 12px color-mix(in srgb, var(--page-accent) 70%, transparent);border-radius:999px;position:absolute;top:18%;bottom:18%;left:-1px}.nav__item{position:relative}.nav__badge{font-family:var(--mt-mono);background:color-mix(in srgb, var(--page-accent) 24%, transparent);color:var(--mt-text);border-radius:999px;margin-left:auto;padding:1px 7px;font-size:10px;animation:.4s cubic-bezier(.19,1,.22,1) nav-badge-pop;display:inline-block}@keyframes nav-badge-pop{0%{transform:scale(1)}35%{background:color-mix(in srgb, var(--page-accent) 60%, transparent);transform:scale(1.35)}to{transform:scale(1)}}@media (prefers-reduced-motion:reduce){.nav__badge{animation:none}}.nav__foot{border-top:1px solid var(--mt-border);flex-direction:column;gap:8px;padding:10px 8px 2px;display:flex}.main{align-content:start;gap:18px;min-width:0;padding:22px clamp(16px,3vw,44px) 64px;display:grid}.topline{flex-wrap:wrap;align-items:center;gap:14px;display:flex}.topline__txt h1{font-family:var(--mt-display);letter-spacing:-.03em;background:linear-gradient(100deg, var(--mt-text) 30%, color-mix(in srgb, var(--page-accent) 78%, var(--mt-text)));-webkit-text-fill-color:transparent;transition:background .4s var(--ease);-webkit-background-clip:text;background-clip:text;margin:0;font-size:clamp(20px,2.4vw,28px);font-weight:700;line-height:1.15}.topline__txt small{color:var(--mt-text-dim);font-family:var(--mt-mono);margin-top:3px;font-size:12px;display:block}.topline__spacer{flex:1;min-width:8px}.help-toggle{border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);font-family:var(--mt-sans);cursor:pointer;transition:color .18s, border-color .18s, background .18s, transform .12s var(--ease);border-radius:999px;align-items:center;gap:7px;padding:7px 13px 7px 10px;font-size:12.5px;font-weight:500;display:inline-flex}.help-toggle:hover{color:var(--mt-text);border-color:var(--mt-border-strong);transform:translateY(-1px)}.help-toggle.is-on{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 45%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 12%, var(--mt-surface))}.help-toggle__q{background:color-mix(in srgb, var(--page-accent) 22%, transparent);width:17px;height:17px;color:var(--page-accent);border-radius:999px;place-items:center;font-size:11px;font-weight:700;display:grid}.pagehelp{border-radius:var(--mt-radius);border:1px solid color-mix(in srgb, var(--page-accent) 28%, var(--mt-border));background:linear-gradient(120deg, color-mix(in srgb, var(--page-accent) 9%, var(--mt-surface)), var(--mt-surface) 60%);gap:14px;padding:16px 18px;display:flex}.pagehelp__icon{color:#0a0a0a;background:var(--grad);width:30px;height:30px;box-shadow:0 4px 14px color-mix(in srgb, var(--page-accent) 35%, transparent);border-radius:9px;flex:none;place-items:center;font-size:15px;font-weight:700;display:grid}.pagehelp__body{min-width:0}.pagehelp__what{color:var(--mt-text);margin:2px 0 8px;font-size:13.5px;line-height:1.55}.pagehelp__tips{gap:4px;margin:0;padding-left:18px;display:grid}.pagehelp__tips li{color:var(--mt-text-dim);font-size:12.5px;line-height:1.5}.pagehelp__tips li::marker{color:var(--page-accent)}.view{align-content:start;gap:18px;display:grid}.bento{grid-template-columns:repeat(6,1fr);gap:18px;display:grid}.bento .panel{margin:0}.b-series{grid-column:span 4}.b-risk{grid-column:span 2}.b-tools,.b-status,.b-device,.b-errors{grid-column:span 3}.b-risk,.b-status{flex-direction:column;display:flex}@media (width<=1040px){.bento{grid-template-columns:repeat(2,1fr)}.b-series,.b-risk,.b-tools,.b-status,.b-device,.b-errors{grid-column:span 2}}@media (width<=900px){.shell{grid-template-columns:1fr}.nav{border-right:0;border-bottom:1px solid var(--mt-border);z-index:5;flex-direction:row;align-items:center;gap:8px;height:auto;padding:10px 12px;position:sticky;top:0;overflow-x:auto}.nav__brand{padding:0 6px 0 2px}.nav__brandtext{display:none}.nav__items{flex-direction:row;flex:1;gap:4px}.nav__item span{display:none}.nav__item{padding:9px 11px}.nav__foot{border-top:0;flex-direction:row;align-items:center;padding:0}.nav__foot .muted{display:none}}@media (width<=560px){.nav__brand{display:none}}@media (prefers-reduced-motion:no-preference){.js-motion .reveal{opacity:0}}.hero__live{border:1px solid var(--mt-border);background:var(--glass);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);font-family:var(--mt-mono);letter-spacing:.04em;text-transform:uppercase;color:var(--mt-text-dim);border-radius:999px;align-items:center;gap:7px;padding:7px 13px;font-size:11px;display:inline-flex}.hero__live .dot{background:var(--mt-bad);border-radius:50%;width:8px;height:8px;transition:background .3s}.hero__live.is-ws{--lc:#34d399}.hero__live.is-sse{--lc:#f59e0b}.hero__live.is-on{color:var(--mt-text);border-color:color-mix(in srgb, var(--lc,var(--mt-good)) 40%, var(--mt-border))}.hero__live.is-on .dot{background:var(--lc,var(--mt-good));box-shadow:0 0 0 4px color-mix(in srgb, var(--lc,var(--mt-good)) 22%, transparent);animation:1.8s ease-out infinite hero-pulse}@keyframes hero-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--lc,var(--mt-good)) 55%, transparent)}70%{box-shadow:0 0 0 9px color-mix(in srgb, var(--lc,var(--mt-good)) 0%, transparent)}to{box-shadow:0 0 0 0 color-mix(in srgb, var(--lc,var(--mt-good)) 0%, transparent)}}.panel>h2,.sheet__hd h2{font-family:var(--mt-sans)}.cards{grid-template-columns:repeat(2,1fr);gap:12px;display:grid}@media (width>=560px){.cards{grid-template-columns:repeat(4,1fr)}}@media (width>=1040px){.cards{grid-template-columns:repeat(8,1fr)}}.stat{background:linear-gradient(180deg, var(--mt-surface), color-mix(in srgb, var(--mt-surface-2) 80%, transparent));border:1px solid var(--mt-border);border-radius:var(--mt-radius);transition:transform .3s var(--ease), border-color .3s var(--ease);padding:14px 15px;position:relative;overflow:hidden}.stat:before{content:"";background:var(--grad);opacity:0;height:2px;transition:opacity .3s var(--ease);position:absolute;inset:0 0 auto}.stat:hover{border-color:color-mix(in srgb, var(--page-accent) 42%, var(--mt-border));transform:translateY(-3px)}.stat:hover:before{opacity:1}.stat .k{color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.08em;margin:0 0 7px;font-size:10px}.stat .v{font-family:var(--mt-mono);letter-spacing:-.02em;font-variant-numeric:tabular-nums;font-size:23px;font-weight:500}.stat .v small{color:var(--mt-text-dim);font-size:12px;font-weight:400}.stat.is-bad .v{color:var(--mt-bad)}.stat.is-warn .v{color:var(--mt-warn)}.stat.is-good .v{color:var(--mt-good)}.panel{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius);transition:border-color .25s var(--ease);padding:18px;position:relative;box-shadow:0 1px 2px #0000004d,inset 0 1px #ffffff08}.panel:hover{border-color:color-mix(in srgb, var(--mt-text) 13%, var(--mt-border))}.panel>h2{color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.07em;align-items:center;gap:9px;margin:0 0 14px;font-size:12px;font-weight:600;display:inline-flex}.panel>h2:before,.sheet__hd h2:first-child:before{content:"";background:var(--grad);border-radius:2px;flex:none;width:3px;height:13px}.cols{grid-template-columns:1.4fr 1fr;gap:18px;display:grid}@media (width<=820px){.cols{grid-template-columns:1fr}}.cols-3{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px;display:grid}.cols-3 .panel{flex-direction:column;display:flex}.hbar{gap:9px;display:grid}.hbar__row{grid-template-columns:minmax(90px,.9fr) 2fr auto;align-items:center;gap:10px;font-size:12px;display:grid}.hbar__label{font-family:var(--mt-mono);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.hbar__track{background:color-mix(in srgb, var(--mt-surface-2) 90%, transparent);border-radius:999px;height:8px;overflow:hidden}.hbar__fill{background:var(--grad);height:100%;box-shadow:0 0 10px color-mix(in srgb, var(--teal) 45%, transparent);border-radius:999px}.hbar__val{font-family:var(--mt-mono);color:var(--mt-text-dim);text-align:right;font-variant-numeric:tabular-nums;font-size:11px}.legend{font-family:var(--mt-mono);color:var(--mt-text-dim);flex-wrap:wrap;gap:12px;margin-top:12px;font-size:11px;display:flex}.legend span{align-items:center;gap:5px;display:inline-flex}.legend i{border-radius:2px;width:9px;height:9px;display:inline-block}.risk{font-family:var(--mt-mono);color:var(--rc,var(--mt-text-dim));border:1px solid color-mix(in srgb, var(--rc,var(--mt-border)) 45%, var(--mt-border));background:color-mix(in srgb, var(--rc,transparent) 12%, transparent);text-transform:uppercase;letter-spacing:.04em;border-radius:999px;padding:1px 8px;font-size:10px;display:inline-block}.risk-READ{--rc:#34d399}.risk-WRITE{--rc:#3291ff}.risk-WRITE_IDEMPOTENT{--rc:#2dd4bf}.risk-DESTRUCTIVE{--rc:#f59e0b}.risk-DANGEROUS{--rc:#ef4444}.feed{border-collapse:collapse;width:100%;font-size:12px}.feed th,.feed td{text-align:left;border-bottom:1px solid color-mix(in srgb, var(--mt-border) 55%, transparent);white-space:nowrap;font-family:var(--mt-mono);padding:7px 11px}.feed thead th{background:color-mix(in srgb, var(--mt-surface-2) 96%, transparent);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.05em;z-index:1;font-size:10px;font-weight:600;position:sticky;top:0}.feed tbody tr{cursor:pointer;transition:background .12s}.feed tbody tr:hover{background:color-mix(in srgb, var(--mt-accent) 9%, transparent)}.feed tbody tr.is-err{background:color-mix(in srgb, var(--mt-bad) 9%, transparent)}.feed tbody tr.is-selected{background:color-mix(in srgb, var(--mt-accent) 16%, transparent)}.feed td.preview{white-space:nowrap;text-overflow:ellipsis;max-width:320px;color:var(--mt-text-dim);overflow:hidden}.feed td.num{text-align:right;color:var(--mt-text-dim);font-variant-numeric:tabular-nums}.status-ok{color:var(--mt-good)}.status-err{color:var(--mt-bad)}.feedwrap{border:1px solid var(--mt-border);border-radius:var(--mt-radius);max-height:60vh;overflow:auto}.feed-empty{border:1px dashed var(--mt-border);border-radius:var(--mt-radius);text-align:center;justify-items:center;gap:8px;padding:54px 16px;display:grid}.feed-empty__icon{opacity:.8;font-size:28px}.feed-empty__title{color:var(--mt-text);margin:0;font-weight:600}.feed-empty__sub{max-width:460px;color:var(--mt-text-faint);margin:0;font-size:12px}.feed-empty .btn{margin-top:6px}.feed-empty__pulse{background:var(--mt-text-faint);border-radius:50%;width:12px;height:12px}.feed-empty__pulse.is-on{background:var(--mt-good);animation:1.6s ease-out infinite feed-pulse}@keyframes feed-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--mt-good) 55%, transparent)}70%{box-shadow:0 0 0 12px color-mix(in srgb, var(--mt-good) 0%, transparent)}to{box-shadow:0 0 0 0 color-mix(in srgb, var(--mt-good) 0%, transparent)}}.conn{display:block;overflow:visible}.conn-grid{fill:none;stroke:var(--mt-border);stroke-opacity:.7;stroke-dasharray:2 7}.conn-sonar{fill:none;stroke:var(--mt-accent);stroke-width:1.5px;opacity:0;animation:3.3s ease-out infinite conn-sonar}@keyframes conn-sonar{0%{r:30px;opacity:.5}to{r:150px;opacity:0}}.conn-link{fill:none;stroke-width:1.6px;opacity:.38}.conn-flow{fill:none;stroke-width:2.4px;stroke-linecap:round;stroke-dasharray:2 13;opacity:.9;filter:drop-shadow(0 0 4px);animation:1.05s linear infinite conn-flow}@keyframes conn-flow{to{stroke-dashoffset:-60px}}.conn-packet{filter:drop-shadow(0 0 6px var(--teal))}.conn-hub-glow{fill:var(--mt-accent);opacity:.22;filter:blur(11px)}.conn-hub-ring{fill:none;stroke:var(--mt-accent);stroke-width:1.4px;stroke-dasharray:4 9;opacity:.7;transform-box:fill-box;transform-origin:50%;animation:15s linear infinite conn-rot}@keyframes conn-rot{to{transform:rotate(360deg)}}.conn-node-halo{fill:none;stroke-width:2px;transform-box:fill-box;transform-origin:50%;animation:2.4s ease-in-out infinite conn-halo}@keyframes conn-halo{0%,to{opacity:.45;transform:scale(1)}50%{opacity:0;transform:scale(1.55)}}.conn-blink{animation:1.6s ease-in-out infinite conn-blink}@keyframes conn-blink{0%,to{opacity:1}50%{opacity:.35}}.conn-node text{pointer-events:none}@media (prefers-reduced-motion:reduce){.conn-sonar,.conn-flow,.conn-hub-ring,.conn-node-halo,.conn-blink,.conn-packet animateMotion{animation:none}.conn-sonar{display:none}}.dev-grid{grid-template-columns:1fr;align-content:start;gap:12px;display:grid}@media (width>=600px) and (width<=819px){.dev-grid{grid-template-columns:1fr 1fr}}.dev-toolbar{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.dev-filters{border:1px solid var(--mt-border);background:color-mix(in srgb, var(--mt-surface-2) 70%, transparent);border-radius:999px;gap:4px;padding:3px;display:inline-flex}.dev-fbtn{appearance:none;color:var(--mt-text-dim);font:11px var(--mt-mono);cursor:pointer;white-space:nowrap;background:0 0;border:0;border-radius:999px;padding:5px 12px;transition:background .18s,color .18s}.dev-fbtn:hover{color:var(--mt-text)}.dev-fbtn.is-active{background:var(--grad);color:var(--mt-bg);font-weight:600}.dev-grid-wide{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));align-content:start;gap:14px;display:grid}.dev-collapse{border:1px solid var(--mt-border);border-radius:var(--mt-radius);background:var(--glass);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);padding:6px 18px 18px}.dev-collapse>summary{cursor:pointer;text-transform:uppercase;letter-spacing:.07em;color:var(--mt-text-dim);align-items:center;gap:8px;padding:12px 0;font-size:12px;font-weight:600;list-style:none;display:flex}.dev-collapse>summary::-webkit-details-marker{display:none}.dev-collapse>summary:before{content:"▸";transition:transform .2s var(--ease);color:var(--teal);display:inline-block}.dev-collapse[open]>summary:before{transform:rotate(90deg)}.dev-card .dot--status{width:7px;height:7px}.dev-card{transition:transform .3s var(--ease), border-color .3s var(--ease);gap:8px;padding:14px 15px;display:grid}.dev-card:hover{border-color:color-mix(in srgb, var(--teal) 35%, var(--mt-border));transform:translateY(-2px)}.dev-card__top{align-items:center;gap:8px;display:flex}.dev-card__name{font-family:var(--mt-mono);font-size:13px;font-weight:500}.dev-card .dot{border-radius:50%;flex:none;width:9px;height:9px}.dev-card__meta{font-family:var(--mt-mono);color:var(--mt-text-dim);grid-template-columns:auto 1fr;gap:3px 12px;font-size:11px;display:grid}.dev-card__meta b{color:var(--mt-text);overflow-wrap:anywhere;font-weight:500}details.cfg>summary{cursor:pointer;color:var(--mt-text-dim);font-family:var(--mt-mono);-webkit-user-select:none;user-select:none;padding:4px 0;font-size:12px}.badge{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.06em;color:var(--mt-bg);background:var(--grad);border-radius:999px;padding:1px 7px;font-size:9px;font-weight:600}.overlay{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10;background:#0000009e;justify-content:flex-end;display:flex;position:fixed;inset:0}.sheet{background:color-mix(in srgb, var(--mt-surface) 96%, var(--mt-bg));border-left:1px solid color-mix(in srgb, var(--teal) 28%, var(--mt-border));align-content:start;gap:12px;width:min(580px,100%);height:100%;padding:18px;display:grid;overflow:auto;box-shadow:-24px 0 60px #00000080}.sheet__hd{align-items:center;gap:10px;display:flex}.sheet__hd h3{font-family:var(--mt-mono);margin:0;font-size:15px}pre.body{background:var(--mt-bg);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);font-family:var(--mt-mono);white-space:pre-wrap;word-break:break-word;max-height:40vh;margin:0;padding:12px;font-size:12px;overflow:auto}pre.body.json{color:#a1a1aa}pre.body.json .j-key{color:#7dd3fc}pre.body.json .j-str{color:#86efac}pre.body.json .j-num{color:#fcd34d}pre.body.json .j-bool{color:#d8b4fe}pre.body.json .j-null{color:#71717a}pre.body.ros{color:#c9c9d1}pre.body.ros .ros-key{color:#7dd3fc}pre.body.ros .ros-str{color:#86efac}pre.body.ros .ros-num{color:#fcd34d}pre.body.ros .ros-ip{color:#5eead4}pre.body.ros .ros-mac{color:#c4b5fd}pre.body.ros .ros-good{color:#4ade80;font-weight:500}pre.body.ros .ros-bad{color:#f87171;font-weight:500}pre.body.ros .ros-bool{color:#d8b4fe}pre.body.ros .ros-dim{color:#8b8b94}pre.body.ros .ros-comment{color:#6b7280;font-style:italic}.muted{color:var(--mt-text-faint);font-family:var(--mt-mono);font-size:11px}.btn-danger{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 12%, transparent)}.btn-danger:hover{background:color-mix(in srgb, var(--mt-bad) 22%, transparent);border-color:var(--mt-bad)}.btn:hover{border-color:color-mix(in srgb, var(--page-accent) 55%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 10%, var(--mt-surface-2))}.btn.is-active{border-color:color-mix(in srgb, var(--page-accent) 70%, var(--mt-border));color:var(--page-accent);background:color-mix(in srgb, var(--page-accent) 12%, var(--mt-surface-2))}:where(button,a,input,select,textarea,[tabindex]):focus-visible{outline:2px solid color-mix(in srgb, var(--page-accent) 70%, transparent);outline-offset:2px;border-radius:var(--mt-radius-sm)}.conn-legend{font-family:var(--mt-mono);color:var(--mt-text-dim);flex-wrap:wrap;justify-content:center;gap:16px;margin-top:8px;font-size:11px;display:flex}.conn-legend span{align-items:center;gap:6px;display:inline-flex}.conn-legend i{border-radius:3px;width:10px;height:10px;display:inline-block}.conn-chevron{fill:none;stroke-width:1.6px;stroke-linecap:round;stroke-linejoin:round;opacity:.85}.conn-errrow{cursor:pointer;border-radius:6px}.conn-errrow:hover{background:color-mix(in srgb, var(--mt-bad) 12%, transparent)}@media (prefers-reduced-motion:reduce){.conn-chevron{opacity:.6}}.health-grid{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px;display:grid}.health-card{flex-direction:column;gap:10px;padding:16px;display:flex}.health-card--na{justify-content:center;gap:6px;min-height:120px}.health-card__hd{align-items:center;gap:8px;display:flex}.health-card__sub{font-family:var(--mt-mono);margin-top:-4px;font-size:11px}.health-card__gauges{justify-content:space-around;gap:14px;display:flex}.gauge{flex-direction:column;align-items:center;gap:2px;display:flex}.gauge__label{font-family:var(--mt-mono);letter-spacing:.06em;color:var(--mt-text-dim);font-size:10px}.health-card__charts{gap:8px;display:grid}.health-chart{gap:2px;display:grid}.health-chart__k{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;color:var(--mt-text-dim);font-size:10px}.spark{background:color-mix(in srgb, var(--mt-surface-2) 60%, transparent);border-radius:6px;display:block}.spark--empty{font-family:var(--mt-mono);color:var(--mt-text-faint);text-align:center;padding:12px 6px;font-size:11px}.health-card__foot{font-family:var(--mt-mono);font-size:11px}.topo{flex-direction:column;gap:10px;display:flex}.topo svg{background:radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--mt-accent) 8%, transparent), transparent 60%);border-radius:var(--mt-radius-sm);width:100%;display:block}.topo-edge{stroke:color-mix(in srgb, var(--mt-text-faint) 55%, transparent);stroke-width:1.4px}.topo-edge.is-dashed{stroke:color-mix(in srgb, var(--mt-accent) 60%, transparent);stroke-dasharray:4 4}.topo-node{cursor:pointer}.topo-node rect{fill:var(--mt-surface-2);stroke-width:1.5px;transition:filter .15s}.topo-node.is-neighbor rect{fill:color-mix(in srgb, var(--mt-surface) 70%, transparent);stroke-dasharray:4 3}.topo-node.is-onboard rect{stroke-dasharray:4 3}.topo-node:hover rect,.topo-node.is-picked rect{filter:drop-shadow(0 0 6px color-mix(in srgb, var(--mt-accent) 55%, transparent))}.topo-node.is-picked rect{stroke-width:2.2px}.topo-label{fill:var(--mt-text);font:600 12px var(--mt-mono)}.topo-sub{fill:var(--mt-text-dim);font:10px var(--mt-mono)}.topo-bar-bg{fill:color-mix(in srgb, var(--mt-text-faint) 35%, transparent)}.topo-foot{flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.topo-foot .legend{margin-top:0}.topo-pop{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);flex:1;min-width:280px;max-width:460px;padding:12px}.topo-pop__hd{align-items:center;gap:8px;margin-bottom:6px;display:flex}.topo-pop__hd .muted{font-size:11px}.topo-stub{background:var(--mt-bg);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);font:11px/1.5 var(--mt-mono);color:var(--mt-text);white-space:pre;margin:0 0 8px;padding:8px 10px;overflow-x:auto}.topo-btn{font:11px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);cursor:pointer;padding:5px 10px;transition:border-color .15s,color .15s}.topo-btn:hover{border-color:var(--mt-accent);color:var(--mt-accent)}.cfgstudio{flex-direction:column;gap:10px;display:flex}.cfg-toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.cfg-status{font:11px var(--mt-mono);border:1px solid var(--mt-border);border-radius:999px;padding:4px 10px}.cfg-status.is-ok{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 45%, var(--mt-border));background:color-mix(in srgb, var(--mt-good) 10%, transparent)}.cfg-status.is-bad{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 10%, transparent)}.cfg-select{font:11px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);padding:5px 9px}.cfg-save{border-color:color-mix(in srgb, var(--mt-accent) 55%, var(--mt-border));color:var(--mt-accent)}.backup-path{align-items:center;gap:8px;max-width:min(60vw,520px);display:inline-flex}.backup-path>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.backup-path-input{font:11px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid color-mix(in srgb, var(--mt-accent) 45%, var(--mt-border));border-radius:var(--mt-radius-sm);width:min(48vw,380px);padding:5px 9px}.backup-opts{flex-wrap:wrap;align-items:center}.backup-opt{font:11px var(--mt-mono);color:var(--mt-text-dim);background:var(--mt-surface-2);border:1px solid var(--mt-border);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:100px;align-items:center;gap:6px;padding:5px 11px 5px 9px;transition:border-color .18s,color .18s,background .18s;display:inline-flex}.backup-opt input{accent-color:var(--mt-accent);cursor:pointer;margin:0}.backup-opt[data-on]{color:var(--mt-text);border-color:color-mix(in srgb, var(--mt-accent) 55%, var(--mt-border));background:color-mix(in srgb, var(--mt-accent) 12%, var(--mt-surface-2))}.backup-opt[data-disabled]{opacity:.45;cursor:not-allowed}.backup-opt[data-disabled] input{cursor:not-allowed}.linkish{font:inherit;color:var(--mt-accent);cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0}.linkish:hover{text-decoration:underline}.cfg-msg{font:12px var(--mt-mono);color:var(--mt-text-dim)}.cfg-banner{border-radius:var(--mt-radius-sm);background:color-mix(in srgb, var(--mt-warn) 12%, var(--mt-surface));border:1px solid color-mix(in srgb, var(--mt-warn) 45%, var(--mt-border));flex-wrap:wrap;align-items:center;gap:8px;padding:10px 13px;font-size:12px;display:flex}.cfg-count{font-family:var(--mt-mono);color:var(--mt-warn);font-weight:700}.cfg-warn{color:var(--mt-warn);font-size:11px}.cfg-editor{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-bg);max-height:420px;display:flex;overflow:hidden}.cfg-gutter{text-align:right;color:var(--mt-text-faint);background:var(--mt-surface-2);font:12px/1.5 var(--mt-mono);-webkit-user-select:none;user-select:none;min-width:38px;margin:0;padding:10px 8px;overflow:hidden}.cfg-ta-wrap{flex:1;position:relative}.cfg-hl,.cfg-ta{box-sizing:border-box;font:12px/1.5 var(--mt-mono);white-space:pre;tab-size:2;letter-spacing:normal;border:0;margin:0;padding:10px 12px}.cfg-hl{z-index:0;pointer-events:none;color:var(--mt-text-dim);position:absolute;inset:0;overflow:hidden}.cfg-ta{z-index:1;resize:vertical;color:#0000;width:100%;height:400px;caret-color:var(--mt-accent);background:0 0;outline:none;position:relative}.cfg-ta::selection{background:color-mix(in srgb, var(--mt-accent) 35%, transparent)}.cfg-hl .j-key{color:#7dd3fc}.cfg-hl .j-str{color:#86efac}.cfg-hl .j-num{color:#fcd34d}.cfg-hl .j-bool{color:#d8b4fe}.cfg-hl .j-null{color:#71717a}.cfg-ac{z-index:5;background:var(--mt-surface);border:1px solid var(--mt-accent);border-radius:var(--mt-radius-sm);min-width:150px;max-height:184px;position:absolute;overflow-y:auto;box-shadow:0 8px 24px #00000080}.cfg-ac-item{font:12px var(--mt-mono);color:var(--mt-text-dim);cursor:pointer;padding:5px 11px}.cfg-ac-item.is-sel{background:color-mix(in srgb, var(--mt-accent) 22%, transparent);color:var(--mt-text)}.cfg-chips{flex-wrap:wrap;gap:6px;display:flex}.cfg-chip{font:11px var(--mt-mono);border:1px solid var(--mt-border);border-radius:999px;padding:4px 10px}.cfg-chip.is-ok{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 45%, var(--mt-border))}.cfg-chip.is-bad{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border))}.cfg-errors{flex-direction:column;gap:3px;display:flex}.cfg-err{font:11px var(--mt-mono);color:var(--mt-bad)}.cfg-err code{color:var(--mt-warn)}.cfg-preview{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);overflow:hidden}.cfg-preview__hd{background:var(--mt-surface-2);align-items:center;gap:8px;padding:9px 13px;font-size:12px;display:flex}.cfg-diff{max-height:320px;font:11px/1.5 var(--mt-mono);color:var(--mt-text-dim);background:var(--mt-bg);margin:0;padding:10px 12px;overflow:auto}.cfg-diff .d-add{color:var(--mt-good)}.cfg-diff .d-del{color:var(--mt-bad)}.cfg-diff .d-hunk{color:var(--mt-accent)}.cap-idle{font-size:13px;line-height:1.5}.cap-idle code{color:var(--mt-accent);font-family:var(--mt-mono)}.cap{flex-direction:column;gap:12px;display:flex}.cap-bar{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.cap-dot{background:var(--mt-text-faint);border-radius:999px;width:9px;height:9px}.cap-dot.is-on{background:var(--mt-good);box-shadow:0 0 0 4px color-mix(in srgb, var(--mt-good) 22%, transparent);animation:1.6s ease-out infinite feed-pulse}.cap-cols{grid-template-columns:220px 1fr;gap:12px;display:grid}@media (width<=720px){.cap-cols{grid-template-columns:1fr}}.cap-side{flex-direction:column;gap:5px;display:flex}.cap-h{text-transform:uppercase;letter-spacing:.05em;color:var(--mt-text-dim);font-size:11px}.cap-pbar{font:11px var(--mt-mono);grid-template-columns:52px 1fr 34px;align-items:center;gap:6px;display:grid}.cap-ptrack{background:var(--mt-surface-2);border-radius:999px;height:8px;overflow:hidden}.cap-ptrack i{border-radius:999px;height:100%;display:block}.cap-pn{text-align:right;color:var(--mt-text-dim)}.cap-talker{font:11px var(--mt-mono);color:var(--mt-text-dim);justify-content:space-between;display:flex}.cap-talker b{color:var(--mt-text)}.cap-list{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-bg);height:360px;font:11px/1.6 var(--mt-mono);overflow-y:auto}.cap-row{white-space:nowrap;grid-template-columns:90px 64px 48px 1fr;gap:8px;padding:1px 10px;display:grid;overflow:hidden}.cap-row:nth-child(odd){background:color-mix(in srgb, var(--mt-surface) 40%, transparent)}.cap-tt{color:var(--mt-text-faint)}.cap-proto{font-weight:600}.cap-len{color:var(--mt-text-dim);text-align:right}.cap-info{color:var(--mt-text);text-overflow:ellipsis;overflow:hidden}.plan-input{resize:vertical;box-sizing:border-box;border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-bg);width:100%;min-height:160px;color:var(--mt-text);font:12px/1.6 var(--mt-mono);outline:none;padding:12px 14px}.plan-input:focus{border-color:color-mix(in srgb, var(--teal) 55%, var(--mt-border))}.plan-input::placeholder{color:var(--mt-text-faint)}.plan-steps{flex-direction:column;gap:6px;margin-top:12px;display:flex}.plan-step{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:color-mix(in srgb, var(--mt-surface-2) 50%, transparent);font:12px var(--mt-mono);border-left-width:3px;align-items:center;gap:10px;padding:8px 12px;display:flex}.plan-step code{color:var(--mt-text);overflow-wrap:anywhere;flex:1}.plan-step.risk-high{border-left-color:var(--mt-bad)}.plan-step.risk-medium{border-left-color:var(--mt-warn)}.plan-step.risk-low{border-left-color:var(--mt-good)}.plan-op{background:color-mix(in srgb, var(--teal) 18%, transparent);width:18px;height:18px;color:var(--teal);border-radius:5px;flex:none;place-items:center;font-weight:700;display:grid}.plan-risk{text-transform:uppercase;letter-spacing:.05em;color:var(--mt-text-dim);font-size:10px}.plan-lock{color:var(--mt-bad);border:1px solid color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border));border-radius:999px;padding:1px 7px;font-size:10px}.cfgver-cp{align-items:center;gap:8px;display:inline-flex}.cfgver{gap:2px;margin:0;padding:0 0 0 4px;list-style:none;display:grid}.cfgver__row{border-radius:var(--mt-radius-sm);transition:background .18s var(--ease);grid-template-columns:18px minmax(0,1fr) auto;align-items:start;gap:10px;padding:11px 6px;display:grid;position:relative}.cfgver__row:hover{background:color-mix(in srgb, var(--mt-text) 4%, transparent)}.cfgver__row:before{content:"";background:var(--mt-border);width:1.5px;position:absolute;top:22px;bottom:-2px;left:12px}.cfgver__row:last-child:before{display:none}.cfgver__dot{border:2px solid var(--mt-border-strong);background:var(--mt-surface);z-index:1;border-radius:999px;width:11px;height:11px;margin-top:5px}.cfgver__row.is-head .cfgver__dot{border-color:var(--page-accent);background:var(--page-accent);box-shadow:0 0 0 4px color-mix(in srgb, var(--page-accent) 22%, transparent)}.cfgver__main{min-width:0}.cfgver__line{flex-wrap:wrap;align-items:center;gap:9px;font-size:12.5px;display:flex}.cfgver__kind{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;border:1px solid var(--mt-border);color:var(--mt-text-dim);border-radius:999px;padding:2px 7px;font-size:10px}.cfgver__kind--checkpoint{color:var(--amber);border-color:color-mix(in srgb, var(--amber) 45%, var(--mt-border));background:color-mix(in srgb, var(--amber) 12%, transparent)}.cfgver__label{color:var(--mt-text);font-weight:600}.cfgver__time{font-family:var(--mt-mono);color:var(--mt-text-dim);font-size:11.5px}.cfgver__cur{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;color:var(--page-accent);font-size:10px}.cfgver__same{color:var(--mt-text-faint);font-size:11.5px}.cfgver__drift{font-family:var(--mt-mono);align-items:baseline;gap:7px;font-size:11.5px;display:inline-flex}.cfgver__drift .add{color:var(--mt-good)}.cfgver__drift .rem{color:var(--mt-bad)}.cfgver__diff{margin-top:9px}.cfgver__diff pre.body{max-height:280px;margin:0;overflow:auto}.cfgver__actions{flex:none;align-items:center;gap:6px;display:inline-flex}.cfgver__del{color:var(--mt-text-faint);padding-left:8px;padding-right:8px}.cfgver__del:hover{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border))}.fguide{gap:18px;display:grid}.fguide__sechd{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.09em;color:var(--page-accent);margin:0 0 9px;font-size:11px}.fguide__list{gap:9px;display:grid}.fguide__item{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:color-mix(in srgb, var(--mt-surface-2) 45%, transparent);transition:border-color .18s, transform .12s var(--ease);padding:11px 13px}.fguide__item:hover{border-color:color-mix(in srgb, var(--page-accent) 40%, var(--mt-border));transform:translate(2px)}.fguide__top{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}.fguide__path{font-family:var(--mt-mono);color:var(--mt-text);font-size:12.5px;font-weight:500}.fguide__type{font-family:var(--mt-mono);color:var(--page-accent);background:color-mix(in srgb, var(--page-accent) 13%, transparent);border-radius:999px;padding:1px 7px;font-size:10.5px}.fguide__req{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;color:var(--mt-bad);font-size:10px}.fguide__def{color:var(--mt-text-faint);font-size:11px}.fguide__def code{color:var(--mt-text-dim)}.fguide__desc{color:var(--mt-text-dim);margin:6px 0 0;font-size:12.5px;line-height:1.5}.fguide__enum{flex-wrap:wrap;gap:6px;margin-top:7px;display:flex}.fguide__enum code{font-family:var(--mt-mono);border:1px solid var(--mt-border);color:var(--mt-text-dim);border-radius:6px;padding:1px 7px;font-size:11px}.copybtn{position:relative}.copybtn.is-copied{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 55%, var(--mt-border))}.copybtn__tip{background:var(--page-accent);color:#0a0a0a;font-family:var(--mt-sans);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .16s, transform .16s var(--ease);z-index:50;border-radius:6px;padding:3px 9px;font-size:11px;font-weight:600;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%,4px)}.copybtn__tip:after{content:"";border:4px solid #0000;border-top-color:var(--page-accent);position:absolute;top:100%;left:50%;transform:translate(-50%)}.copybtn.is-copied .copybtn__tip{opacity:1;transform:translate(-50%)}.iconbtn{border:1px solid var(--mt-border);background:var(--mt-surface);width:26px;height:26px;color:var(--mt-text-dim);cursor:pointer;border-radius:7px;place-items:center;padding:0;transition:color .16s,border-color .16s,background .16s;display:inline-grid}.iconbtn:hover{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 50%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 10%, var(--mt-surface))}.copybtn--icon.is-copied{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 55%, var(--mt-border))}.sheet__tool{align-items:center;gap:9px;display:inline-flex}.chart{width:100%;font-family:var(--mt-mono)}.chart .recharts-cartesian-grid line{stroke:color-mix(in srgb, var(--mt-border) 80%, transparent)}.chart .recharts-text,.chart text{fill:var(--mt-text-faint)}.chart .recharts-surface:focus,.chart svg:focus{outline:none}.chart-tip{background:color-mix(in srgb, var(--mt-surface) 96%, transparent);border:1px solid var(--mt-border-strong);border-radius:var(--mt-radius-sm);font-family:var(--mt-mono);min-width:120px;padding:8px 10px;font-size:11.5px;box-shadow:0 8px 24px #00000073}.chart-tip__label{color:var(--mt-text-dim);margin-bottom:5px;font-size:10.5px}.chart-tip__row{align-items:center;gap:7px;display:flex}.chart-tip__dot{border-radius:3px;flex:none;width:9px;height:9px}.chart-tip__name{color:var(--mt-text-dim);text-transform:capitalize}.chart-tip__val{color:var(--mt-text);font-variant-numeric:tabular-nums;margin-left:auto;font-weight:500}.chart--donut{flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}.chart-donut__svg{width:100%;max-width:200px}.chart-legend{font-family:var(--mt-mono);color:var(--mt-text-dim);flex-wrap:wrap;justify-content:center;gap:6px 14px;font-size:11px;display:flex}.chart-legend span{align-items:center;gap:6px;display:inline-flex}.chart-legend i{border-radius:3px;width:9px;height:9px}.chart-legend b{color:var(--mt-text);font-weight:500}.chart--spark{position:relative}.chart-spark__last{font-family:var(--mt-mono);z-index:1;font-size:10px;font-weight:600;position:absolute;top:0;right:2px}.gauge__radial{place-items:center;width:72px;height:72px;display:grid;position:relative}.gauge__pct{font-family:var(--mt-mono);pointer-events:none;place-items:center;font-size:13px;font-weight:700;display:grid;position:absolute;inset:0}.geist-btn{font-family:var(--mt-sans);border-radius:var(--mt-radius-sm);border:1px solid var(--mt-border-strong);background:var(--mt-surface);color:var(--mt-text);cursor:pointer;white-space:nowrap;transition:background .16s var(--ease), border-color .16s, color .16s, transform .1s var(--ease), box-shadow .16s;justify-content:center;align-items:center;gap:7px;font-size:13px;font-weight:500;line-height:1;display:inline-flex}.geist-btn--sm{padding:6px 11px;font-size:12px}.geist-btn--md{padding:9px 15px}.geist-btn:hover{border-color:var(--mt-text);transform:translateY(-1px)}.geist-btn:active{transform:translateY(0)}.geist-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}.geist-btn__icon{display:inline-flex}.geist-btn--accent{background:var(--page-accent);border-color:var(--page-accent);color:#0a0a0a;font-weight:600}.geist-btn--accent:hover{box-shadow:0 4px 16px color-mix(in srgb, var(--page-accent) 40%, transparent);border-color:var(--page-accent)}.geist-btn--success{border-color:color-mix(in srgb, var(--mt-good) 55%, var(--mt-border));color:var(--mt-good)}.geist-btn--warning{border-color:color-mix(in srgb, var(--mt-warn) 55%, var(--mt-border));color:var(--mt-warn)}.geist-btn--error{border-color:color-mix(in srgb, var(--mt-bad) 55%, var(--mt-border));color:var(--mt-bad)}.geist-btn--error:hover{background:color-mix(in srgb, var(--mt-bad) 14%, var(--mt-surface));border-color:var(--mt-bad)}.geist-btn--secondary{color:var(--mt-text-dim);border-color:var(--mt-border)}.geist-btn--ghost{background:0 0;border-color:#0000}.geist-btn--ghost:hover{background:color-mix(in srgb, var(--mt-text) 7%, transparent);border-color:var(--mt-border)}.geist-note{border-radius:var(--mt-radius-sm);border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);padding:11px 14px;font-size:13px;line-height:1.55}.geist-note__label{color:var(--mt-text);text-transform:capitalize}.geist-note--secondary{border-color:color-mix(in srgb, var(--page-accent) 30%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 7%, var(--mt-surface))}.geist-note--success{border-color:color-mix(in srgb, var(--mt-good) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-good) 8%, var(--mt-surface))}.geist-note--success .geist-note__label{color:var(--mt-good)}.geist-note--warning{border-color:color-mix(in srgb, var(--mt-warn) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-warn) 8%, var(--mt-surface))}.geist-note--warning .geist-note__label{color:var(--mt-warn)}.geist-note--error{border-color:color-mix(in srgb, var(--mt-bad) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 8%, var(--mt-surface))}.geist-note--error .geist-note__label{color:var(--mt-bad)}.geist-badge{font-family:var(--mt-mono);border:1px solid var(--mt-border);background:var(--mt-surface-2);color:var(--mt-text-dim);border-radius:999px;align-items:center;gap:5px;padding:2px 8px;font-size:10.5px;font-weight:500;display:inline-flex}.geist-badge--accent{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 40%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 12%, transparent)}.geist-badge--success{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-good) 10%, transparent)}.geist-badge--warning{color:var(--mt-warn);border-color:color-mix(in srgb, var(--mt-warn) 40%, var(--mt-border))}.geist-badge--error{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 10%, transparent)}.geist-dot{background:var(--mt-text-faint);border-radius:999px;flex:none;width:9px;height:9px;display:inline-block}.geist-dot--success{background:var(--mt-good)}.geist-dot--warning{background:var(--mt-warn)}.geist-dot--error{background:var(--mt-bad)}.geist-dot--accent{background:var(--page-accent)}.geist-dot.is-pulse{box-shadow:0 0 0 0 color-mix(in srgb, currentColor 60%, transparent);animation:1.8s infinite geist-pulse}@keyframes geist-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--mt-good) 55%, transparent)}70%{box-shadow:0 0 0 7px #0000}to{box-shadow:0 0 #0000}}.geist-spinner{width:16px;height:16px;display:inline-block;position:relative}.geist-spinner--sm{width:13px;height:13px}.geist-spinner span{transform-origin:50% 178%;opacity:.15;background:currentColor;border-radius:2px;width:8%;height:28%;animation:1.2s linear infinite geist-spin;position:absolute;top:0;left:46%}@keyframes geist-spin{0%{opacity:1}to{opacity:.15}}.geist-input,.geist-select{font-family:var(--mt-mono);color:var(--mt-text);background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);padding:8px 11px;font-size:12.5px;transition:border-color .16s,box-shadow .16s}.geist-input:focus,.geist-select:focus{border-color:var(--page-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--page-accent) 22%, transparent);outline:none}.geist-card{border:1px solid var(--mt-border);border-radius:var(--mt-radius);background:var(--mt-surface);padding:16px}.geist-card.is-hoverable{transition:border-color .18s, transform .18s var(--ease)}.geist-card.is-hoverable:hover{border-color:color-mix(in srgb, var(--page-accent) 40%, var(--mt-border));transform:translateY(-2px)}.geist-tooltip{display:inline-flex;position:relative}.geist-tooltip__pop{border-radius:var(--mt-radius-sm);background:var(--mt-surface);border:1px solid var(--mt-border-strong);color:var(--mt-text);font-family:var(--mt-mono);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .16s, transform .16s var(--ease);z-index:60;padding:6px 10px;font-size:11.5px;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%,4px);box-shadow:0 8px 24px #00000073}.geist-tooltip:hover .geist-tooltip__pop,.geist-tooltip:focus-visible .geist-tooltip__pop{opacity:1;transform:translate(-50%)}.clients-toolbar{align-items:center;gap:8px;display:flex}.clients-toolbar .geist-input{width:200px}.clients-counts{margin-bottom:10px;font-size:12px}.clients-error{margin-bottom:10px}.clients-table{flex-direction:column;gap:2px;display:flex}.clients-row{border-radius:var(--mt-radius-sm);cursor:pointer;grid-template-columns:120px 1.3fr 150px 80px 130px minmax(280px,auto);align-items:center;gap:10px;padding:8px 10px;font-size:13px;display:grid}.clients-row--head{cursor:default;color:var(--mt-text-faint);text-transform:uppercase;letter-spacing:.04em;font-size:11px}.clients-row:not(.clients-row--head):hover{background:var(--mt-surface-2)}.clients-row.is-selected{background:color-mix(in srgb, var(--page-accent) 14%, var(--mt-surface-2))}.clients-row.is-blocked .clients-ip,.clients-row.is-blocked .clients-name{color:var(--mt-text-faint);text-decoration:line-through}.clients-ip,.clients-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.clients-mac{color:var(--mt-text-dim);font-family:ui-monospace,SF Mono,Menlo,monospace;font-size:11.5px}.clients-badges{align-items:center;gap:6px;display:flex;overflow:hidden}.clients-actions,.clients-actions-h{justify-content:flex-end;gap:6px;display:flex}.clients-detail{border-top:1px solid var(--mt-border);margin-top:14px;padding-top:14px}.clients-detail__hd{flex-wrap:wrap;align-items:baseline;gap:12px;margin-bottom:10px;display:flex}.clients-detail__title{font-size:14px;font-weight:600}.clients-rates{font-variant-numeric:tabular-nums;gap:18px;margin-bottom:8px;display:flex}.clients-rates .rate{font-weight:600}.clients-rates .rate.rx{color:var(--lime)}.clients-rates .rate.tx{color:var(--amber)}.clients-chart{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);width:100%;max-width:520px;height:150px;display:block}.clients-chart .line{fill:none;stroke-width:2px}.clients-chart .rx.line{stroke:var(--lime)}.clients-chart .tx.line{stroke:var(--amber)}.clients-chart .rx.area{fill:color-mix(in srgb, var(--lime) 18%, transparent);stroke:none}.clients-chart .tx.area{fill:color-mix(in srgb, var(--amber) 14%, transparent);stroke:none}.clients-totals{font-variant-numeric:tabular-nums;margin-top:8px;font-size:12px}.clients-edit{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-surface-2);flex-wrap:wrap;align-items:center;gap:8px;margin-top:14px;padding:10px 12px;display:flex}.clients-edit__label{color:var(--mt-text-dim);font-size:13px}.clients-edit .geist-input{width:220px}.aaa-tabs{border-bottom:1px solid var(--mt-border);flex-wrap:wrap;gap:4px;margin-bottom:14px;display:flex}.aaa-tab{appearance:none;color:var(--mt-text-dim);font:inherit;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-1px;padding:7px 12px;font-size:13px}.aaa-tab:hover{color:var(--mt-text)}.aaa-tab.is-active{color:var(--mt-text);border-bottom-color:var(--page-accent)}.aaa-entity__toolbar{align-items:center;gap:10px;margin-bottom:12px;display:flex}.aaa-filter{width:200px}.aaa-error{margin-bottom:10px}.aaa-empty{padding:20px 4px}.aaa-table{flex-direction:column;gap:2px;display:flex}.aaa-table--scroll{overflow-x:auto}.aaa-row{border-radius:var(--mt-radius-sm);align-items:center;gap:10px;padding:8px 10px;font-size:13px;display:grid}.aaa-row--head{color:var(--mt-text-faint);text-transform:uppercase;letter-spacing:.04em;font-size:11px}.aaa-row:not(.aaa-row--head):hover{background:var(--mt-surface-2)}.aaa-row.is-off .aaa-cell{color:var(--mt-text-faint)}.aaa-row--sessions{grid-template-columns:repeat(9,minmax(90px,1fr));min-width:900px}.aaa-cell{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aaa-actions,.aaa-actions-h{justify-content:flex-end;gap:6px;display:flex}.aaa-form,.aaa-singleton{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-surface-2);margin-bottom:14px;padding:14px}.aaa-form__title,.aaa-singleton__title{margin-bottom:10px;font-size:13px;font-weight:600}.aaa-singleton__current{margin-bottom:12px;font-size:12px}.aaa-form__grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px 14px;display:grid}.aaa-field{flex-direction:column;gap:4px;display:flex}.aaa-field__label{color:var(--mt-text-dim);font-size:11.5px}.aaa-form__actions{align-items:center;gap:10px;margin-top:14px;display:flex}.aaa-settings{flex-direction:column;gap:8px;display:flex}.clients-limits{border-top:1px solid var(--mt-border);max-width:520px;margin-top:14px;padding-top:12px}.clients-limits__hd{align-items:baseline;gap:12px;margin-bottom:8px;display:flex}.clients-limits__label{font-size:13px;font-weight:600}.clients-limits__row{flex-wrap:wrap;align-items:flex-end;gap:8px;display:flex}.clients-limits__field{flex-direction:column;gap:3px;font-size:11.5px;display:flex}.clients-limits__field .geist-input{width:150px}.clients-limits__msg{margin-top:6px;font-size:12px}.usage-chart__empty{padding:16px 4px;font-size:12.5px}.usage-chart__legend{font-variant-numeric:tabular-nums;align-items:baseline;gap:14px;margin-bottom:6px;font-size:12px;display:flex}.usage-chart__legend .rate{font-weight:600}.usage-chart__legend .rate.rx{color:var(--lime)}.usage-chart__legend .rate.tx{color:var(--amber)}.usage-chart__svg{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);width:100%;height:160px;display:block}.usage-chart__svg .line{fill:none;stroke-width:2px;vector-effect:non-scaling-stroke}.usage-chart__svg .rx.line{stroke:var(--lime)}.usage-chart__svg .tx.line{stroke:var(--amber)}.usage-chart__svg .rx.area{fill:color-mix(in srgb, var(--lime) 18%, transparent);stroke:none}.usage-chart__svg .tx.area{fill:color-mix(in srgb, var(--amber) 14%, transparent);stroke:none}.clients-history,.aaa-usage__section{margin-top:16px}.clients-history__hd,.aaa-usage__title{color:var(--mt-text-dim);margin-bottom:8px;font-size:12px;font-weight:600}.aaa-usage__bar{align-items:center;gap:8px;margin-bottom:12px;display:flex}.heatmap__hd{align-items:baseline;gap:10px;margin-bottom:6px;display:flex}.heatmap__title{font-size:12.5px;font-weight:600}.heatmap__scroll{padding-bottom:4px;overflow-x:auto}.heatmap__svg{display:block}.heatmap__month,.heatmap__wd{fill:var(--mt-text-dim);font-family:inherit;font-size:9px}.heatmap{position:relative}.heatmap__cell{stroke:color-mix(in srgb, var(--mt-border) 60%, transparent);stroke-width:1px;cursor:pointer;transition:stroke .1s}.heatmap__cell.is-hover{stroke:var(--mt-text);stroke-width:1.5px}.heatmap__tip{z-index:30;background:linear-gradient(180deg, color-mix(in srgb, var(--mt-surface-2) 92%, var(--lime)), var(--mt-surface-2));border:1px solid color-mix(in srgb, var(--lime) 35%, var(--mt-border));pointer-events:none;min-width:150px;animation:heatmap-tip-in .12s var(--ease);border-radius:10px;padding:8px 10px;position:absolute;transform:translate(-50%,calc(-100% - 9px));box-shadow:0 8px 24px #00000073}.heatmap__tip:after{content:"";background:var(--mt-surface-2);border-right:1px solid color-mix(in srgb, var(--lime) 35%, var(--mt-border));border-bottom:1px solid color-mix(in srgb, var(--lime) 35%, var(--mt-border));width:11px;height:11px;position:absolute;bottom:-6px;left:50%;transform:translate(-50%)rotate(45deg)}@keyframes heatmap-tip-in{0%{opacity:0;transform:translate(-50%,calc(-100% - 3px))}to{opacity:1;transform:translate(-50%,calc(-100% - 9px))}}.heatmap__tip-head{align-items:center;gap:7px;font-size:13px;display:flex}.heatmap__tip-head b{font-weight:600}.heatmap__tip-head .heatmap__swatch{width:12px;height:12px}.heatmap__tip-date{color:var(--mt-text-dim);font-variant-numeric:tabular-nums;margin-top:3px;font-size:11.5px}.heatmap__cell.lvl0,.heatmap__swatch.lvl0{fill:var(--mt-surface-2);background:var(--mt-surface-2)}.heatmap__cell.lvl1,.heatmap__swatch.lvl1{fill:color-mix(in srgb, var(--lime) 30%, var(--mt-surface-2));background:color-mix(in srgb, var(--lime) 30%, var(--mt-surface-2))}.heatmap__cell.lvl2,.heatmap__swatch.lvl2{fill:color-mix(in srgb, var(--lime) 50%, var(--mt-surface-2));background:color-mix(in srgb, var(--lime) 50%, var(--mt-surface-2))}.heatmap__cell.lvl3,.heatmap__swatch.lvl3{fill:color-mix(in srgb, var(--lime) 72%, transparent);background:color-mix(in srgb, var(--lime) 72%, transparent)}.heatmap__cell.lvl4,.heatmap__swatch.lvl4{fill:var(--lime);background:var(--lime)}.heatmap__legend{align-items:center;gap:4px;margin-top:8px;font-size:11px;display:flex}.heatmap__swatch{border-radius:2px;width:11px;height:11px;display:inline-block}.input{font:12px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);width:min(52vw,420px);padding:6px 10px}.input:focus{border-color:color-mix(in srgb, var(--mt-accent) 55%, var(--mt-border));outline:none}.btn-sm{padding:3px 8px;font-size:10px}.mod-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:6px;display:flex}.mod-groups{flex-direction:column;gap:18px;margin-top:12px;display:flex}.mod-group__hd{border-bottom:1px solid var(--mt-border);align-items:center;gap:10px;margin-bottom:8px;padding-bottom:6px;display:flex}.mod-group__title{color:var(--mt-text);margin:0;font-size:13px;font-weight:600}.mod-list{grid-template-columns:repeat(auto-fill,minmax(min(100%,360px),1fr));gap:8px;display:grid}.mod-row{background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none;align-items:flex-start;gap:10px;padding:9px 11px;transition:border-color .18s,background .18s;display:flex}.mod-row:hover{border-color:color-mix(in srgb, var(--mt-accent) 35%, var(--mt-border))}.mod-row[data-on]{border-color:color-mix(in srgb, var(--mt-accent) 50%, var(--mt-border));background:color-mix(in srgb, var(--mt-accent) 10%, var(--mt-surface-2))}.mod-row input{accent-color:var(--mt-accent);cursor:pointer;margin:2px 0 0}.mod-row__main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.mod-row__name{color:var(--mt-text);flex-wrap:wrap;align-items:center;gap:7px;font-size:12px;font-weight:600;display:flex}.mod-row__slug{font:10px var(--mt-mono);color:var(--mt-text-dim);background:var(--mt-bg);border:1px solid var(--mt-border);border-radius:4px;padding:1px 5px}.mod-row__desc{font-size:11px;line-height:1.35}.mod-row__count{font:10px var(--mt-mono);white-space:nowrap;padding-top:1px}.conn-tunnel-halo{fill:none;stroke-width:8px;stroke-linecap:round;opacity:.1}.conn-tunnel{fill:none;stroke-width:2.4px;stroke-linecap:round;stroke-dasharray:6 6;animation:.9s linear infinite conn-tunnel-flow}@keyframes conn-tunnel-flow{to{stroke-dashoffset:-24px}}.conn-tunnel-lock{filter:drop-shadow(0 0 4px #f59e0bcc)}.conn-tunnel-sat{stroke-width:1.5px;filter:drop-shadow(0 0 5px #f59e0b88)}.conn-tunnel-badge{fill:#30220a;stroke:color-mix(in srgb, #f59e0b 60%, var(--mt-border));stroke-width:1px}.conn-tunnel-badge-tx{fill:#fbbf24;font-family:var(--mt-mono);letter-spacing:.02em;font-weight:700}.jump-route{background:color-mix(in srgb, #f59e0b 7%, var(--mt-surface-2));border:1px solid color-mix(in srgb, #f59e0b 28%, var(--mt-border));font:10px var(--mt-mono);border-radius:10px;align-items:center;gap:6px;margin:10px 0 2px;padding:7px 9px;display:flex;overflow:hidden}.jump-route__hop{background:var(--mt-bg);border:1px solid var(--mt-border);color:var(--mt-text);white-space:nowrap;border-radius:7px;align-items:center;gap:5px;padding:3px 8px;display:inline-flex}.jump-route__hop--src{padding:3px 7px;font-size:12px}.jump-route__hop--bastion{border-color:color-mix(in srgb, #f59e0b 60%, var(--mt-border));color:#fbbf24;box-shadow:0 0 10px -3px #f59e0b99}.jump-route__tag{text-transform:uppercase;letter-spacing:.08em;color:#0a0a0a;background:#f59e0b;border-radius:4px;padding:1px 4px;font-size:7px;font-style:normal}.jump-route__wire{background-image:linear-gradient(90deg, var(--mt-border) 0 50%, transparent 50% 100%);background-size:8px 2px;border-radius:2px;flex:1;min-width:18px;height:2px;animation:.7s linear infinite jump-wire}.jump-route__wire--enc{background-image:linear-gradient(90deg,#f59e0b 0 55%,#0000 55% 100%);background-size:10px 3px;min-width:34px;height:3px;position:relative;box-shadow:0 0 8px -1px #f59e0b88}.jump-route__lock{filter:drop-shadow(0 0 3px #f59e0b);font-size:11px;animation:2.2s linear infinite jump-lock;position:absolute;top:50%}@keyframes jump-wire{to{background-position:8px 0}}@keyframes jump-lock{0%{left:-4px;transform:translateY(-50%)scale(.9)}50%{transform:translateY(-50%)scale(1.1)}to{left:calc(100% - 8px);transform:translateY(-50%)scale(.9)}}@media (prefers-reduced-motion:reduce){.conn-tunnel,.jump-route__wire,.jump-route__wire--enc,.jump-route__lock{animation:none}.conn-tunnel-lock animatemotion{display:none}}.pool-panel{margin:12px 0}.pool-disabled{color:#71717a;margin:4px 0;font-size:13px}.pool-disabled code{color:#7c9cff;font-size:12px}.pool-stats{flex-wrap:wrap;gap:8px;margin-bottom:12px;display:flex}.pool-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;display:grid}.pool-card{background:#18181b;border:1px solid #27272a;border-radius:8px;padding:10px 12px;transition:border-color .2s}.pool-card:hover{border-color:#3f3f46}.pool-card--idle{border-color:#22c55e59}.pool-card--busy{border-color:#3b82f680}.pool-card--dead{border-color:#ef444480}.pool-card--disconnected{opacity:.6;border-style:dashed}.pool-card__hd{align-items:center;gap:6px;margin-bottom:6px;display:flex}.pool-card__dot{border-radius:50%;flex-shrink:0;width:7px;height:7px}.pool-card__name{color:#e4e4e7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:600;overflow:hidden}.pool-card__badge{text-transform:uppercase;letter-spacing:.04em;margin-left:auto;font-size:10px;font-weight:600}.pool-pipe{background:#27272a;border-radius:3px;height:6px;position:relative;overflow:hidden}.pool-pipe__fill{opacity:.65;border-radius:3px;height:100%;transition:width .4s}.pool-pipe__fill--pulse{animation:1.5s ease-in-out infinite pool-pulse}.pool-pipe__label{color:#fafafa;text-shadow:0 0 3px #0009;font-size:8px;font-weight:700;line-height:8px;position:absolute;top:-1px;right:4px}@keyframes pool-pulse{0%,to{opacity:.5}50%{opacity:.9}}
|
|
84
|
+
@import "https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap";@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:var(--mt-sans);--font-mono:var(--mt-mono)}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.isolate{isolation:isolate}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.shrink{flex-shrink:1}.grow{flex-grow:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}:root{--background:#0a0a0a;--foreground:#ededed;--card:#111;--card-foreground:#ededed;--popover:#111;--popover-foreground:#ededed;--primary:#ededed;--primary-foreground:#0a0a0a;--secondary:#1a1a1a;--secondary-foreground:#ededed;--muted:#1a1a1a;--muted-foreground:#a1a1a1;--accent:var(--page-accent,#3291ff);--accent-foreground:#0a0a0a;--destructive:#ff5c5c;--destructive-foreground:#fff;--success:#2dd4a7;--warning:#f5a623;--border:#2a2a2a;--input:#2a2a2a;--ring:var(--page-accent,#3291ff);--radius:.5rem}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}:root{--mt-bg:var(--color-background-primary,#0b0d10);--mt-surface:var(--color-background-secondary,#14171c);--mt-surface-2:var(--color-background-tertiary,#1b1f26);--mt-border:var(--color-border-primary,#262b33);--mt-text:var(--color-text-primary,#e8eaed);--mt-text-dim:var(--color-text-secondary,#9aa3af);--mt-text-faint:var(--color-text-tertiary,#6b7280);--mt-accent:var(--color-accent-primary,#6ea8fe);--mt-good:#34d399;--mt-warn:#fbbf24;--mt-bad:#f87171;--mt-radius:var(--border-radius-md,14px);--mt-radius-sm:var(--border-radius-sm,9px);--mt-mono:var(--font-mono,ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace);--mt-sans:var(--font-sans,system-ui, -apple-system, "Segoe UI", sans-serif);--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}*{box-sizing:border-box}body{background:var(--mt-bg);color:var(--mt-text);font-family:var(--mt-sans);-webkit-font-smoothing:antialiased;margin:0;padding:16px;font-size:13px;line-height:1.5}.app{gap:14px;max-width:960px;margin:0 auto;display:grid}.hd{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.hd__dot{background:var(--mt-good);width:9px;height:9px;box-shadow:0 0 0 4px color-mix(in srgb, var(--mt-good) 22%, transparent);border-radius:50%}.hd__title{letter-spacing:-.01em;margin:0;font-size:17px;font-weight:650}.hd__sub{color:var(--mt-text-dim);font-family:var(--mt-mono);margin:0;font-size:12px}.hd__spacer{flex:1}.pill{border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);font-family:var(--mt-mono);border-radius:999px;align-items:center;gap:6px;padding:3px 9px;font-size:11px;display:inline-flex}.pill b{color:var(--mt-text);font-weight:600}.grid{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;display:grid}.card{background:linear-gradient(180deg, var(--mt-surface), var(--mt-surface-2));border:1px solid var(--mt-border);border-radius:var(--mt-radius);padding:14px}.card__label{color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.06em;margin:0 0 8px;font-size:11px}.card__value{font-family:var(--mt-mono);letter-spacing:-.01em;font-size:20px;font-weight:600}.toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.toolbar .grow{flex:1;min-width:140px}.search{appearance:none;border:1px solid var(--mt-border);background:var(--mt-surface);width:100%;color:var(--mt-text);font:inherit;border-radius:var(--mt-radius-sm);padding:7px 11px;font-size:13px}.search:focus{border-color:var(--mt-accent);outline:none}.search::placeholder{color:var(--mt-text-faint)}.btn{appearance:none;border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text);font:inherit;border-radius:var(--mt-radius-sm);cursor:pointer;white-space:nowrap;padding:6px 11px;font-size:12px;transition:border-color .15s,background .15s}.btn:disabled{opacity:.5;cursor:default}.btn.is-active{border-color:var(--mt-accent);color:var(--mt-accent)}.chip{border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);font-family:var(--mt-mono);border-radius:999px;align-items:center;gap:4px;padding:1px 7px;font-size:11px;display:inline-flex}.chip.is-good{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 45%, var(--mt-border))}.chip.is-warn{color:var(--mt-warn);border-color:color-mix(in srgb, var(--mt-warn) 45%, var(--mt-border))}.chip.is-bad{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border))}.tablewrap{border:1px solid var(--mt-border);border-radius:var(--mt-radius);max-height:70vh;overflow:auto}table.tbl{border-collapse:collapse;width:100%;font-size:12px}table.tbl th,table.tbl td{text-align:left;border-bottom:1px solid color-mix(in srgb, var(--mt-border) 55%, transparent);white-space:nowrap;font-family:var(--mt-mono);padding:7px 12px}table.tbl thead th{z-index:1;background:var(--mt-surface-2);color:var(--mt-text-dim);cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:600;position:sticky;top:0}table.tbl thead th:hover{color:var(--mt-text)}table.tbl thead th .arrow{color:var(--mt-accent);margin-left:4px}table.tbl tbody tr{cursor:pointer}table.tbl tbody tr:hover{background:color-mix(in srgb, var(--mt-accent) 8%, transparent)}table.tbl tbody tr.is-disabled td,table.tbl td.col-num{color:var(--mt-text-faint)}.kv__body{border:1px solid var(--mt-border);border-radius:var(--mt-radius);grid-template-columns:minmax(120px,.4fr) 1fr;display:grid;overflow:hidden}.kv__body>div{border-bottom:1px solid color-mix(in srgb, var(--mt-border) 55%, transparent);overflow-wrap:anywhere;min-width:0;font-size:12px;font-family:var(--mt-mono);padding:7px 14px}.kv__k{color:var(--mt-text-dim);background:color-mix(in srgb, var(--mt-surface) 60%, transparent)}.kv__v{color:var(--mt-text)}.drawer{border:1px solid var(--mt-accent);border-radius:var(--mt-radius);background:var(--mt-surface);gap:10px;padding:12px;display:grid}.drawer__hd{align-items:center;gap:8px;display:flex}.drawer__hd b{font-family:var(--mt-mono)}pre.raw{border:1px solid var(--mt-border);border-radius:var(--mt-radius);background:var(--mt-surface);color:var(--mt-text);font-family:var(--mt-mono);white-space:pre;max-height:70vh;margin:0;padding:14px;font-size:12px;overflow:auto}.foot{color:var(--mt-text-faint);font-size:11px;font-family:var(--mt-mono);flex-wrap:wrap;align-items:center;gap:10px;display:flex}.foot .grow{flex:1}.skeleton,.empty{color:var(--mt-text-faint);text-align:center;padding:40px 0}:root{--mt-sans:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--mt-mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--mt-display:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;--mt-bg:#0a0a0a;--mt-surface:#111;--mt-surface-2:#1a1a1a;--mt-border:#2a2a2a;--mt-border-strong:#3a3a3a;--mt-text:#ededed;--mt-text-dim:#a1a1a1;--mt-text-faint:#6e6e6e;--mt-good:#d4d4d8;--mt-warn:#a1a1a1;--mt-bad:#ff5c5c;--mt-radius:12px;--mt-radius-sm:8px;--sky:#3291ff;--teal:#2dd4bf;--cyan:#45d4ee;--lime:#69d05a;--coral:#ff5c5c;--amber:#f5a623;--pink:#ff4d8d;--violet:#9d7bff;--page-accent:#3291ff;--page-accent-2:#2dd4bf;--mt-accent:var(--page-accent);--grad:linear-gradient(115deg, var(--page-accent), var(--page-accent-2) 90%);--ease:cubic-bezier(.22, 1, .36, 1);--glass:#111111b8}html,body{background:var(--mt-bg);color:var(--mt-text);font-family:var(--mt-sans);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;margin:0;padding:0}body:after{content:"";z-index:-2;background-image:linear-gradient(color-mix(in srgb, var(--mt-border) 55%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--mt-border) 55%, transparent) 1px, transparent 1px);opacity:.32;pointer-events:none;background-size:52px 52px;position:fixed;inset:0;-webkit-mask-image:radial-gradient(circle at 50% 0,#000,#0000 72%);mask-image:radial-gradient(circle at 50% 0,#000,#0000 72%)}.main:before{content:"";z-index:-1;background:radial-gradient(52% 38% at 18% -8%, color-mix(in srgb, var(--page-accent) 14%, transparent), transparent 70%), radial-gradient(46% 36% at 100% 4%, color-mix(in srgb, var(--page-accent-2) 11%, transparent), transparent 68%);opacity:.9;transition:background .5s var(--ease);pointer-events:none;position:fixed;inset:0}.shell{grid-template-columns:250px minmax(0,1fr);align-items:start;min-height:100vh;display:grid}.nav{border-right:1px solid var(--mt-border);background:color-mix(in srgb, var(--mt-surface) 55%, transparent);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);flex-direction:column;gap:10px;height:100vh;padding:18px 14px;display:flex;position:sticky;top:0}.nav__brand{align-items:center;gap:11px;padding:6px 8px 14px;display:flex}.nav__mark{background:var(--grad);width:38px;height:38px;box-shadow:0 6px 20px color-mix(in srgb, var(--page-accent) 34%, transparent);transition:background .4s var(--ease), box-shadow .4s var(--ease);border-radius:11px;flex:none;place-items:center;display:grid}.nav__mark svg{width:22px;height:22px;display:block}.nav__brandtext{flex-direction:column;min-width:0;line-height:1.1;display:flex}.nav__brandtext b{font-family:var(--mt-display);letter-spacing:-.03em;font-size:15px;font-weight:700}.nav__brandtext small{font-family:var(--mt-mono);letter-spacing:.16em;text-transform:uppercase;color:var(--mt-text-dim);margin-top:3px;font-size:10px}.nav__items{flex-direction:column;flex:1;gap:3px;display:flex}.nav__item{color:var(--mt-text-dim);font-family:var(--mt-sans);cursor:pointer;text-align:left;transition:background .18s var(--ease), color .18s, border-color .18s, transform .18s var(--ease);background:0 0;border:1px solid #0000;border-radius:11px;align-items:center;gap:11px;padding:10px 12px;font-size:13px;font-weight:500;display:flex}.nav__item svg{opacity:.85;flex:none;width:18px;height:18px}.nav__item:hover{color:var(--mt-text);background:color-mix(in srgb, var(--mt-text) 7%, transparent)}.nav__item.is-active{color:var(--mt-text);border-color:color-mix(in srgb, var(--page-accent) 36%, var(--mt-border));background:linear-gradient(100deg, color-mix(in srgb, var(--page-accent) 16%, transparent), color-mix(in srgb, var(--page-accent-2) 7%, transparent))}.nav__item.is-active svg{opacity:1;color:var(--page-accent)}.nav__item.is-active:before{content:"";background:var(--page-accent);width:3px;box-shadow:0 0 12px color-mix(in srgb, var(--page-accent) 70%, transparent);border-radius:999px;position:absolute;top:18%;bottom:18%;left:-1px}.nav__item{position:relative}.nav__badge{font-family:var(--mt-mono);background:color-mix(in srgb, var(--page-accent) 24%, transparent);color:var(--mt-text);border-radius:999px;margin-left:auto;padding:1px 7px;font-size:10px;animation:.4s cubic-bezier(.19,1,.22,1) nav-badge-pop;display:inline-block}@keyframes nav-badge-pop{0%{transform:scale(1)}35%{background:color-mix(in srgb, var(--page-accent) 60%, transparent);transform:scale(1.35)}to{transform:scale(1)}}@media (prefers-reduced-motion:reduce){.nav__badge{animation:none}}.nav__foot{border-top:1px solid var(--mt-border);flex-direction:column;gap:8px;padding:10px 8px 2px;display:flex}.main{align-content:start;gap:18px;min-width:0;padding:22px clamp(16px,3vw,44px) 64px;display:grid}.topline{flex-wrap:wrap;align-items:center;gap:14px;display:flex}.topline__txt h1{font-family:var(--mt-display);letter-spacing:-.03em;background:linear-gradient(100deg, var(--mt-text) 30%, color-mix(in srgb, var(--page-accent) 78%, var(--mt-text)));-webkit-text-fill-color:transparent;transition:background .4s var(--ease);-webkit-background-clip:text;background-clip:text;margin:0;font-size:clamp(20px,2.4vw,28px);font-weight:700;line-height:1.15}.topline__txt small{color:var(--mt-text-dim);font-family:var(--mt-mono);margin-top:3px;font-size:12px;display:block}.topline__spacer{flex:1;min-width:8px}.help-toggle{border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);font-family:var(--mt-sans);cursor:pointer;transition:color .18s, border-color .18s, background .18s, transform .12s var(--ease);border-radius:999px;align-items:center;gap:7px;padding:7px 13px 7px 10px;font-size:12.5px;font-weight:500;display:inline-flex}.help-toggle:hover{color:var(--mt-text);border-color:var(--mt-border-strong);transform:translateY(-1px)}.help-toggle.is-on{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 45%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 12%, var(--mt-surface))}.help-toggle__q{background:color-mix(in srgb, var(--page-accent) 22%, transparent);width:17px;height:17px;color:var(--page-accent);border-radius:999px;place-items:center;font-size:11px;font-weight:700;display:grid}.pagehelp{border-radius:var(--mt-radius);border:1px solid color-mix(in srgb, var(--page-accent) 28%, var(--mt-border));background:linear-gradient(120deg, color-mix(in srgb, var(--page-accent) 9%, var(--mt-surface)), var(--mt-surface) 60%);gap:14px;padding:16px 18px;display:flex}.pagehelp__icon{color:#0a0a0a;background:var(--grad);width:30px;height:30px;box-shadow:0 4px 14px color-mix(in srgb, var(--page-accent) 35%, transparent);border-radius:9px;flex:none;place-items:center;font-size:15px;font-weight:700;display:grid}.pagehelp__body{min-width:0}.pagehelp__what{color:var(--mt-text);margin:2px 0 8px;font-size:13.5px;line-height:1.55}.pagehelp__tips{gap:4px;margin:0;padding-left:18px;display:grid}.pagehelp__tips li{color:var(--mt-text-dim);font-size:12.5px;line-height:1.5}.pagehelp__tips li::marker{color:var(--page-accent)}.view{align-content:start;gap:18px;display:grid}.bento{grid-template-columns:repeat(6,1fr);gap:18px;display:grid}.bento .panel{margin:0}.b-series{grid-column:span 4}.b-risk{grid-column:span 2}.b-tools,.b-status,.b-device,.b-errors{grid-column:span 3}.b-risk,.b-status{flex-direction:column;display:flex}@media (width<=1040px){.bento{grid-template-columns:repeat(2,1fr)}.b-series,.b-risk,.b-tools,.b-status,.b-device,.b-errors{grid-column:span 2}}@media (width<=900px){.shell{grid-template-columns:1fr}.nav{border-right:0;border-bottom:1px solid var(--mt-border);z-index:5;flex-direction:row;align-items:center;gap:8px;height:auto;padding:10px 12px;position:sticky;top:0;overflow-x:auto}.nav__brand{padding:0 6px 0 2px}.nav__brandtext{display:none}.nav__items{flex-direction:row;flex:1;gap:4px}.nav__item span{display:none}.nav__item{padding:9px 11px}.nav__foot{border-top:0;flex-direction:row;align-items:center;padding:0}.nav__foot .muted{display:none}}@media (width<=560px){.nav__brand{display:none}}@media (prefers-reduced-motion:no-preference){.js-motion .reveal{opacity:0}}.hero__live{border:1px solid var(--mt-border);background:var(--glass);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);font-family:var(--mt-mono);letter-spacing:.04em;text-transform:uppercase;color:var(--mt-text-dim);border-radius:999px;align-items:center;gap:7px;padding:7px 13px;font-size:11px;display:inline-flex}.hero__live .dot{background:var(--mt-bad);border-radius:50%;width:8px;height:8px;transition:background .3s}.hero__live.is-ws{--lc:#34d399}.hero__live.is-sse{--lc:#f59e0b}.hero__live.is-on{color:var(--mt-text);border-color:color-mix(in srgb, var(--lc,var(--mt-good)) 40%, var(--mt-border))}.hero__live.is-on .dot{background:var(--lc,var(--mt-good));box-shadow:0 0 0 4px color-mix(in srgb, var(--lc,var(--mt-good)) 22%, transparent);animation:1.8s ease-out infinite hero-pulse}@keyframes hero-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--lc,var(--mt-good)) 55%, transparent)}70%{box-shadow:0 0 0 9px color-mix(in srgb, var(--lc,var(--mt-good)) 0%, transparent)}to{box-shadow:0 0 0 0 color-mix(in srgb, var(--lc,var(--mt-good)) 0%, transparent)}}.panel>h2,.sheet__hd h2{font-family:var(--mt-sans)}.cards{grid-template-columns:repeat(2,1fr);gap:12px;display:grid}@media (width>=560px){.cards{grid-template-columns:repeat(4,1fr)}}@media (width>=1040px){.cards{grid-template-columns:repeat(8,1fr)}}.stat{background:linear-gradient(180deg, var(--mt-surface), color-mix(in srgb, var(--mt-surface-2) 80%, transparent));border:1px solid var(--mt-border);border-radius:var(--mt-radius);transition:transform .3s var(--ease), border-color .3s var(--ease);padding:14px 15px;position:relative;overflow:hidden}.stat:before{content:"";background:var(--grad);opacity:0;height:2px;transition:opacity .3s var(--ease);position:absolute;inset:0 0 auto}.stat:hover{border-color:color-mix(in srgb, var(--page-accent) 42%, var(--mt-border));transform:translateY(-3px)}.stat:hover:before{opacity:1}.stat .k{color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.08em;margin:0 0 7px;font-size:10px}.stat .v{font-family:var(--mt-mono);letter-spacing:-.02em;font-variant-numeric:tabular-nums;font-size:23px;font-weight:500}.stat .v small{color:var(--mt-text-dim);font-size:12px;font-weight:400}.stat.is-bad .v{color:var(--mt-bad)}.stat.is-warn .v{color:var(--mt-warn)}.stat.is-good .v{color:var(--mt-good)}.panel{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius);transition:border-color .25s var(--ease);padding:18px;position:relative;box-shadow:0 1px 2px #0000004d,inset 0 1px #ffffff08}.panel:hover{border-color:color-mix(in srgb, var(--mt-text) 13%, var(--mt-border))}.panel>h2{color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.07em;align-items:center;gap:9px;margin:0 0 14px;font-size:12px;font-weight:600;display:inline-flex}.panel>h2:before,.sheet__hd h2:first-child:before{content:"";background:var(--grad);border-radius:2px;flex:none;width:3px;height:13px}.cols{grid-template-columns:1.4fr 1fr;gap:18px;display:grid}@media (width<=820px){.cols{grid-template-columns:1fr}}.cols-3{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px;display:grid}.cols-3 .panel{flex-direction:column;display:flex}.hbar{gap:9px;display:grid}.hbar__row{grid-template-columns:minmax(90px,.9fr) 2fr auto;align-items:center;gap:10px;font-size:12px;display:grid}.hbar__label{font-family:var(--mt-mono);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.hbar__track{background:color-mix(in srgb, var(--mt-surface-2) 90%, transparent);border-radius:999px;height:8px;overflow:hidden}.hbar__fill{background:var(--grad);height:100%;box-shadow:0 0 10px color-mix(in srgb, var(--teal) 45%, transparent);border-radius:999px}.hbar__val{font-family:var(--mt-mono);color:var(--mt-text-dim);text-align:right;font-variant-numeric:tabular-nums;font-size:11px}.legend{font-family:var(--mt-mono);color:var(--mt-text-dim);flex-wrap:wrap;gap:12px;margin-top:12px;font-size:11px;display:flex}.legend span{align-items:center;gap:5px;display:inline-flex}.legend i{border-radius:2px;width:9px;height:9px;display:inline-block}.risk{font-family:var(--mt-mono);color:var(--rc,var(--mt-text-dim));border:1px solid color-mix(in srgb, var(--rc,var(--mt-border)) 45%, var(--mt-border));background:color-mix(in srgb, var(--rc,transparent) 12%, transparent);text-transform:uppercase;letter-spacing:.04em;border-radius:999px;padding:1px 8px;font-size:10px;display:inline-block}.risk-READ{--rc:#34d399}.risk-WRITE{--rc:#3291ff}.risk-WRITE_IDEMPOTENT{--rc:#2dd4bf}.risk-DESTRUCTIVE{--rc:#f59e0b}.risk-DANGEROUS{--rc:#ef4444}.feed{border-collapse:collapse;width:100%;font-size:12px}.feed th,.feed td{text-align:left;border-bottom:1px solid color-mix(in srgb, var(--mt-border) 55%, transparent);white-space:nowrap;font-family:var(--mt-mono);padding:7px 11px}.feed thead th{background:color-mix(in srgb, var(--mt-surface-2) 96%, transparent);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--mt-text-dim);text-transform:uppercase;letter-spacing:.05em;z-index:1;font-size:10px;font-weight:600;position:sticky;top:0}.feed tbody tr{cursor:pointer;transition:background .12s}.feed tbody tr:hover{background:color-mix(in srgb, var(--mt-accent) 9%, transparent)}.feed tbody tr.is-err{background:color-mix(in srgb, var(--mt-bad) 9%, transparent)}.feed tbody tr.is-selected{background:color-mix(in srgb, var(--mt-accent) 16%, transparent)}.feed td.preview{white-space:nowrap;text-overflow:ellipsis;max-width:320px;color:var(--mt-text-dim);overflow:hidden}.feed td.num{text-align:right;color:var(--mt-text-dim);font-variant-numeric:tabular-nums}.status-ok{color:var(--mt-good)}.status-err{color:var(--mt-bad)}.feedwrap{border:1px solid var(--mt-border);border-radius:var(--mt-radius);max-height:60vh;overflow:auto}.feed-empty{border:1px dashed var(--mt-border);border-radius:var(--mt-radius);text-align:center;justify-items:center;gap:8px;padding:54px 16px;display:grid}.feed-empty__icon{opacity:.8;font-size:28px}.feed-empty__title{color:var(--mt-text);margin:0;font-weight:600}.feed-empty__sub{max-width:460px;color:var(--mt-text-faint);margin:0;font-size:12px}.feed-empty .btn{margin-top:6px}.feed-empty__pulse{background:var(--mt-text-faint);border-radius:50%;width:12px;height:12px}.feed-empty__pulse.is-on{background:var(--mt-good);animation:1.6s ease-out infinite feed-pulse}@keyframes feed-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--mt-good) 55%, transparent)}70%{box-shadow:0 0 0 12px color-mix(in srgb, var(--mt-good) 0%, transparent)}to{box-shadow:0 0 0 0 color-mix(in srgb, var(--mt-good) 0%, transparent)}}.conn{display:block;overflow:visible}.conn-grid{fill:none;stroke:var(--mt-border);stroke-opacity:.7;stroke-dasharray:2 7}.conn-sonar{fill:none;stroke:var(--mt-accent);stroke-width:1.5px;opacity:0;animation:3.3s ease-out infinite conn-sonar}@keyframes conn-sonar{0%{r:30px;opacity:.5}to{r:150px;opacity:0}}.conn-link{fill:none;stroke-width:1.6px;opacity:.38}.conn-flow{fill:none;stroke-width:2.4px;stroke-linecap:round;stroke-dasharray:2 13;opacity:.9;filter:drop-shadow(0 0 4px);animation:1.05s linear infinite conn-flow}@keyframes conn-flow{to{stroke-dashoffset:-60px}}.conn-packet{filter:drop-shadow(0 0 6px var(--teal))}.conn-hub-glow{fill:var(--mt-accent);opacity:.22;filter:blur(11px)}.conn-hub-ring{fill:none;stroke:var(--mt-accent);stroke-width:1.4px;stroke-dasharray:4 9;opacity:.7;transform-box:fill-box;transform-origin:50%;animation:15s linear infinite conn-rot}@keyframes conn-rot{to{transform:rotate(360deg)}}.conn-node-halo{fill:none;stroke-width:2px;transform-box:fill-box;transform-origin:50%;animation:2.4s ease-in-out infinite conn-halo}@keyframes conn-halo{0%,to{opacity:.45;transform:scale(1)}50%{opacity:0;transform:scale(1.55)}}.conn-blink{animation:1.6s ease-in-out infinite conn-blink}@keyframes conn-blink{0%,to{opacity:1}50%{opacity:.35}}.conn-node text{pointer-events:none}@media (prefers-reduced-motion:reduce){.conn-sonar,.conn-flow,.conn-hub-ring,.conn-node-halo,.conn-blink,.conn-packet animateMotion{animation:none}.conn-sonar{display:none}}.dev-grid{grid-template-columns:1fr;align-content:start;gap:12px;display:grid}@media (width>=600px) and (width<=819px){.dev-grid{grid-template-columns:1fr 1fr}}.dev-toolbar{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.dev-filters{border:1px solid var(--mt-border);background:color-mix(in srgb, var(--mt-surface-2) 70%, transparent);border-radius:999px;gap:4px;padding:3px;display:inline-flex}.dev-fbtn{appearance:none;color:var(--mt-text-dim);font:11px var(--mt-mono);cursor:pointer;white-space:nowrap;background:0 0;border:0;border-radius:999px;padding:5px 12px;transition:background .18s,color .18s}.dev-fbtn:hover{color:var(--mt-text)}.dev-fbtn.is-active{background:var(--grad);color:var(--mt-bg);font-weight:600}.dev-grid-wide{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));align-content:start;gap:14px;display:grid}.dev-collapse{border:1px solid var(--mt-border);border-radius:var(--mt-radius);background:var(--glass);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);padding:6px 18px 18px}.dev-collapse>summary{cursor:pointer;text-transform:uppercase;letter-spacing:.07em;color:var(--mt-text-dim);align-items:center;gap:8px;padding:12px 0;font-size:12px;font-weight:600;list-style:none;display:flex}.dev-collapse>summary::-webkit-details-marker{display:none}.dev-collapse>summary:before{content:"▸";transition:transform .2s var(--ease);color:var(--teal);display:inline-block}.dev-collapse[open]>summary:before{transform:rotate(90deg)}.dev-card .dot--status{width:7px;height:7px}.dev-card{transition:transform .3s var(--ease), border-color .3s var(--ease);gap:8px;padding:14px 15px;display:grid}.dev-card:hover{border-color:color-mix(in srgb, var(--teal) 35%, var(--mt-border));transform:translateY(-2px)}.dev-card__top{align-items:center;gap:8px;display:flex}.dev-card__name{font-family:var(--mt-mono);font-size:13px;font-weight:500}.dev-card .dot{border-radius:50%;flex:none;width:9px;height:9px}.dev-card__meta{font-family:var(--mt-mono);color:var(--mt-text-dim);grid-template-columns:auto 1fr;gap:3px 12px;font-size:11px;display:grid}.dev-card__meta b{color:var(--mt-text);overflow-wrap:anywhere;font-weight:500}details.cfg>summary{cursor:pointer;color:var(--mt-text-dim);font-family:var(--mt-mono);-webkit-user-select:none;user-select:none;padding:4px 0;font-size:12px}.badge{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.06em;color:var(--mt-bg);background:var(--grad);border-radius:999px;padding:1px 7px;font-size:9px;font-weight:600}.overlay{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);z-index:10;background:#0000009e;justify-content:flex-end;display:flex;position:fixed;inset:0}.sheet{background:color-mix(in srgb, var(--mt-surface) 96%, var(--mt-bg));border-left:1px solid color-mix(in srgb, var(--teal) 28%, var(--mt-border));align-content:start;gap:12px;width:min(580px,100%);height:100%;padding:18px;display:grid;overflow:auto;box-shadow:-24px 0 60px #00000080}.sheet__hd{align-items:center;gap:10px;display:flex}.sheet__hd h3{font-family:var(--mt-mono);margin:0;font-size:15px}pre.body{background:var(--mt-bg);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);font-family:var(--mt-mono);white-space:pre-wrap;word-break:break-word;max-height:40vh;margin:0;padding:12px;font-size:12px;overflow:auto}pre.body.json{color:#a1a1aa}pre.body.json .j-key{color:#7dd3fc}pre.body.json .j-str{color:#86efac}pre.body.json .j-num{color:#fcd34d}pre.body.json .j-bool{color:#d8b4fe}pre.body.json .j-null{color:#71717a}pre.body.ros{color:#c9c9d1}pre.body.ros .ros-key{color:#7dd3fc}pre.body.ros .ros-str{color:#86efac}pre.body.ros .ros-num{color:#fcd34d}pre.body.ros .ros-ip{color:#5eead4}pre.body.ros .ros-mac{color:#c4b5fd}pre.body.ros .ros-good{color:#4ade80;font-weight:500}pre.body.ros .ros-bad{color:#f87171;font-weight:500}pre.body.ros .ros-bool{color:#d8b4fe}pre.body.ros .ros-dim{color:#8b8b94}pre.body.ros .ros-comment{color:#6b7280;font-style:italic}.muted{color:var(--mt-text-faint);font-family:var(--mt-mono);font-size:11px}.btn-danger{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 12%, transparent)}.btn-danger:hover{background:color-mix(in srgb, var(--mt-bad) 22%, transparent);border-color:var(--mt-bad)}.btn:hover{border-color:color-mix(in srgb, var(--page-accent) 55%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 10%, var(--mt-surface-2))}.btn.is-active{border-color:color-mix(in srgb, var(--page-accent) 70%, var(--mt-border));color:var(--page-accent);background:color-mix(in srgb, var(--page-accent) 12%, var(--mt-surface-2))}:where(button,a,input,select,textarea,[tabindex]):focus-visible{outline:2px solid color-mix(in srgb, var(--page-accent) 70%, transparent);outline-offset:2px;border-radius:var(--mt-radius-sm)}.conn-legend{font-family:var(--mt-mono);color:var(--mt-text-dim);flex-wrap:wrap;justify-content:center;gap:16px;margin-top:8px;font-size:11px;display:flex}.conn-legend span{align-items:center;gap:6px;display:inline-flex}.conn-legend i{border-radius:3px;width:10px;height:10px;display:inline-block}.conn-chevron{fill:none;stroke-width:1.6px;stroke-linecap:round;stroke-linejoin:round;opacity:.85}.conn-errrow{cursor:pointer;border-radius:6px}.conn-errrow:hover{background:color-mix(in srgb, var(--mt-bad) 12%, transparent)}@media (prefers-reduced-motion:reduce){.conn-chevron{opacity:.6}}.health-grid{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px;display:grid}.health-card{flex-direction:column;gap:10px;padding:16px;display:flex}.health-card--na{justify-content:center;gap:6px;min-height:120px}.health-card__hd{align-items:center;gap:8px;display:flex}.health-card__sub{font-family:var(--mt-mono);margin-top:-4px;font-size:11px}.health-card__gauges{justify-content:space-around;gap:14px;display:flex}.gauge{flex-direction:column;align-items:center;gap:2px;display:flex}.gauge__label{font-family:var(--mt-mono);letter-spacing:.06em;color:var(--mt-text-dim);font-size:10px}.health-card__charts{gap:8px;display:grid}.health-chart{gap:2px;display:grid}.health-chart__k{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;color:var(--mt-text-dim);font-size:10px}.spark{background:color-mix(in srgb, var(--mt-surface-2) 60%, transparent);border-radius:6px;display:block}.spark--empty{font-family:var(--mt-mono);color:var(--mt-text-faint);text-align:center;padding:12px 6px;font-size:11px}.health-card__foot{font-family:var(--mt-mono);font-size:11px}.topo{flex-direction:column;gap:10px;display:flex}.topo svg{background:radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--mt-accent) 8%, transparent), transparent 60%);border-radius:var(--mt-radius-sm);width:100%;display:block}.topo-edge{stroke:color-mix(in srgb, var(--mt-text-faint) 55%, transparent);stroke-width:1.4px}.topo-edge.is-dashed{stroke:color-mix(in srgb, var(--mt-accent) 60%, transparent);stroke-dasharray:4 4}.topo-node{cursor:pointer}.topo-node rect{fill:var(--mt-surface-2);stroke-width:1.5px;transition:filter .15s}.topo-node.is-neighbor rect{fill:color-mix(in srgb, var(--mt-surface) 70%, transparent);stroke-dasharray:4 3}.topo-node.is-onboard rect{stroke-dasharray:4 3}.topo-node:hover rect,.topo-node.is-picked rect{filter:drop-shadow(0 0 6px color-mix(in srgb, var(--mt-accent) 55%, transparent))}.topo-node.is-picked rect{stroke-width:2.2px}.topo-label{fill:var(--mt-text);font:600 12px var(--mt-mono)}.topo-sub{fill:var(--mt-text-dim);font:10px var(--mt-mono)}.topo-bar-bg{fill:color-mix(in srgb, var(--mt-text-faint) 35%, transparent)}.topo-foot{flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.topo-foot .legend{margin-top:0}.topo-pop{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);flex:1;min-width:280px;max-width:460px;padding:12px}.topo-pop__hd{align-items:center;gap:8px;margin-bottom:6px;display:flex}.topo-pop__hd .muted{font-size:11px}.topo-stub{background:var(--mt-bg);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);font:11px/1.5 var(--mt-mono);color:var(--mt-text);white-space:pre;margin:0 0 8px;padding:8px 10px;overflow-x:auto}.topo-btn{font:11px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);cursor:pointer;padding:5px 10px;transition:border-color .15s,color .15s}.topo-btn:hover{border-color:var(--mt-accent);color:var(--mt-accent)}.cfgstudio{flex-direction:column;gap:10px;display:flex}.cfg-toolbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.cfg-status{font:11px var(--mt-mono);border:1px solid var(--mt-border);border-radius:999px;padding:4px 10px}.cfg-status.is-ok{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 45%, var(--mt-border));background:color-mix(in srgb, var(--mt-good) 10%, transparent)}.cfg-status.is-bad{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 10%, transparent)}.cfg-select{font:11px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);padding:5px 9px}.cfg-save{border-color:color-mix(in srgb, var(--mt-accent) 55%, var(--mt-border));color:var(--mt-accent)}.backup-path{align-items:center;gap:8px;max-width:min(60vw,520px);display:inline-flex}.backup-path>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.backup-path-input{font:11px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid color-mix(in srgb, var(--mt-accent) 45%, var(--mt-border));border-radius:var(--mt-radius-sm);width:min(48vw,380px);padding:5px 9px}.backup-opts{flex-wrap:wrap;align-items:center}.backup-opt{font:11px var(--mt-mono);color:var(--mt-text-dim);background:var(--mt-surface-2);border:1px solid var(--mt-border);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:100px;align-items:center;gap:6px;padding:5px 11px 5px 9px;transition:border-color .18s,color .18s,background .18s;display:inline-flex}.backup-opt input{accent-color:var(--mt-accent);cursor:pointer;margin:0}.backup-opt[data-on]{color:var(--mt-text);border-color:color-mix(in srgb, var(--mt-accent) 55%, var(--mt-border));background:color-mix(in srgb, var(--mt-accent) 12%, var(--mt-surface-2))}.backup-opt[data-disabled]{opacity:.45;cursor:not-allowed}.backup-opt[data-disabled] input{cursor:not-allowed}.linkish{font:inherit;color:var(--mt-accent);cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0}.linkish:hover{text-decoration:underline}.cfg-msg{font:12px var(--mt-mono);color:var(--mt-text-dim)}.cfg-banner{border-radius:var(--mt-radius-sm);background:color-mix(in srgb, var(--mt-warn) 12%, var(--mt-surface));border:1px solid color-mix(in srgb, var(--mt-warn) 45%, var(--mt-border));flex-wrap:wrap;align-items:center;gap:8px;padding:10px 13px;font-size:12px;display:flex}.cfg-count{font-family:var(--mt-mono);color:var(--mt-warn);font-weight:700}.cfg-warn{color:var(--mt-warn);font-size:11px}.cfg-editor{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-bg);max-height:420px;display:flex;overflow:hidden}.cfg-gutter{text-align:right;color:var(--mt-text-faint);background:var(--mt-surface-2);font:12px/1.5 var(--mt-mono);-webkit-user-select:none;user-select:none;min-width:38px;margin:0;padding:10px 8px;overflow:hidden}.cfg-ta-wrap{flex:1;position:relative}.cfg-hl,.cfg-ta{box-sizing:border-box;font:12px/1.5 var(--mt-mono);white-space:pre;tab-size:2;letter-spacing:normal;border:0;margin:0;padding:10px 12px}.cfg-hl{z-index:0;pointer-events:none;color:var(--mt-text-dim);position:absolute;inset:0;overflow:hidden}.cfg-ta{z-index:1;resize:vertical;color:#0000;width:100%;height:400px;caret-color:var(--mt-accent);background:0 0;outline:none;position:relative}.cfg-ta::selection{background:color-mix(in srgb, var(--mt-accent) 35%, transparent)}.cfg-hl .j-key{color:#7dd3fc}.cfg-hl .j-str{color:#86efac}.cfg-hl .j-num{color:#fcd34d}.cfg-hl .j-bool{color:#d8b4fe}.cfg-hl .j-null{color:#71717a}.cfg-ac{z-index:5;background:var(--mt-surface);border:1px solid var(--mt-accent);border-radius:var(--mt-radius-sm);min-width:150px;max-height:184px;position:absolute;overflow-y:auto;box-shadow:0 8px 24px #00000080}.cfg-ac-item{font:12px var(--mt-mono);color:var(--mt-text-dim);cursor:pointer;padding:5px 11px}.cfg-ac-item.is-sel{background:color-mix(in srgb, var(--mt-accent) 22%, transparent);color:var(--mt-text)}.cfg-chips{flex-wrap:wrap;gap:6px;display:flex}.cfg-chip{font:11px var(--mt-mono);border:1px solid var(--mt-border);border-radius:999px;padding:4px 10px}.cfg-chip.is-ok{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 45%, var(--mt-border))}.cfg-chip.is-bad{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border))}.cfg-errors{flex-direction:column;gap:3px;display:flex}.cfg-err{font:11px var(--mt-mono);color:var(--mt-bad)}.cfg-err code{color:var(--mt-warn)}.cfg-preview{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);overflow:hidden}.cfg-preview__hd{background:var(--mt-surface-2);align-items:center;gap:8px;padding:9px 13px;font-size:12px;display:flex}.cfg-diff{max-height:320px;font:11px/1.5 var(--mt-mono);color:var(--mt-text-dim);background:var(--mt-bg);margin:0;padding:10px 12px;overflow:auto}.cfg-diff .d-add{color:var(--mt-good)}.cfg-diff .d-del{color:var(--mt-bad)}.cfg-diff .d-hunk{color:var(--mt-accent)}.cap-idle{font-size:13px;line-height:1.5}.cap-idle code{color:var(--mt-accent);font-family:var(--mt-mono)}.cap{flex-direction:column;gap:12px;display:flex}.cap-bar{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.cap-dot{background:var(--mt-text-faint);border-radius:999px;width:9px;height:9px}.cap-dot.is-on{background:var(--mt-good);box-shadow:0 0 0 4px color-mix(in srgb, var(--mt-good) 22%, transparent);animation:1.6s ease-out infinite feed-pulse}.cap-cols{grid-template-columns:220px 1fr;gap:12px;display:grid}@media (width<=720px){.cap-cols{grid-template-columns:1fr}}.cap-side{flex-direction:column;gap:5px;display:flex}.cap-h{text-transform:uppercase;letter-spacing:.05em;color:var(--mt-text-dim);font-size:11px}.cap-pbar{font:11px var(--mt-mono);grid-template-columns:52px 1fr 34px;align-items:center;gap:6px;display:grid}.cap-ptrack{background:var(--mt-surface-2);border-radius:999px;height:8px;overflow:hidden}.cap-ptrack i{border-radius:999px;height:100%;display:block}.cap-pn{text-align:right;color:var(--mt-text-dim)}.cap-talker{font:11px var(--mt-mono);color:var(--mt-text-dim);justify-content:space-between;display:flex}.cap-talker b{color:var(--mt-text)}.cap-list{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-bg);height:360px;font:11px/1.6 var(--mt-mono);overflow-y:auto}.cap-row{white-space:nowrap;grid-template-columns:90px 64px 48px 1fr;gap:8px;padding:1px 10px;display:grid;overflow:hidden}.cap-row:nth-child(odd){background:color-mix(in srgb, var(--mt-surface) 40%, transparent)}.cap-tt{color:var(--mt-text-faint)}.cap-proto{font-weight:600}.cap-len{color:var(--mt-text-dim);text-align:right}.cap-info{color:var(--mt-text);text-overflow:ellipsis;overflow:hidden}.plan-input{resize:vertical;box-sizing:border-box;border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-bg);width:100%;min-height:160px;color:var(--mt-text);font:12px/1.6 var(--mt-mono);outline:none;padding:12px 14px}.plan-input:focus{border-color:color-mix(in srgb, var(--teal) 55%, var(--mt-border))}.plan-input::placeholder{color:var(--mt-text-faint)}.plan-steps{flex-direction:column;gap:6px;margin-top:12px;display:flex}.plan-step{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:color-mix(in srgb, var(--mt-surface-2) 50%, transparent);font:12px var(--mt-mono);border-left-width:3px;align-items:center;gap:10px;padding:8px 12px;display:flex}.plan-step code{color:var(--mt-text);overflow-wrap:anywhere;flex:1}.plan-step.risk-high{border-left-color:var(--mt-bad)}.plan-step.risk-medium{border-left-color:var(--mt-warn)}.plan-step.risk-low{border-left-color:var(--mt-good)}.plan-op{background:color-mix(in srgb, var(--teal) 18%, transparent);width:18px;height:18px;color:var(--teal);border-radius:5px;flex:none;place-items:center;font-weight:700;display:grid}.plan-risk{text-transform:uppercase;letter-spacing:.05em;color:var(--mt-text-dim);font-size:10px}.plan-lock{color:var(--mt-bad);border:1px solid color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border));border-radius:999px;padding:1px 7px;font-size:10px}.cfgver-cp{align-items:center;gap:8px;display:inline-flex}.cfgver{gap:2px;margin:0;padding:0 0 0 4px;list-style:none;display:grid}.cfgver__row{border-radius:var(--mt-radius-sm);transition:background .18s var(--ease);grid-template-columns:18px minmax(0,1fr) auto;align-items:start;gap:10px;padding:11px 6px;display:grid;position:relative}.cfgver__row:hover{background:color-mix(in srgb, var(--mt-text) 4%, transparent)}.cfgver__row:before{content:"";background:var(--mt-border);width:1.5px;position:absolute;top:22px;bottom:-2px;left:12px}.cfgver__row:last-child:before{display:none}.cfgver__dot{border:2px solid var(--mt-border-strong);background:var(--mt-surface);z-index:1;border-radius:999px;width:11px;height:11px;margin-top:5px}.cfgver__row.is-head .cfgver__dot{border-color:var(--page-accent);background:var(--page-accent);box-shadow:0 0 0 4px color-mix(in srgb, var(--page-accent) 22%, transparent)}.cfgver__main{min-width:0}.cfgver__line{flex-wrap:wrap;align-items:center;gap:9px;font-size:12.5px;display:flex}.cfgver__kind{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;border:1px solid var(--mt-border);color:var(--mt-text-dim);border-radius:999px;padding:2px 7px;font-size:10px}.cfgver__kind--checkpoint{color:var(--amber);border-color:color-mix(in srgb, var(--amber) 45%, var(--mt-border));background:color-mix(in srgb, var(--amber) 12%, transparent)}.cfgver__label{color:var(--mt-text);font-weight:600}.cfgver__time{font-family:var(--mt-mono);color:var(--mt-text-dim);font-size:11.5px}.cfgver__cur{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;color:var(--page-accent);font-size:10px}.cfgver__same{color:var(--mt-text-faint);font-size:11.5px}.cfgver__drift{font-family:var(--mt-mono);align-items:baseline;gap:7px;font-size:11.5px;display:inline-flex}.cfgver__drift .add{color:var(--mt-good)}.cfgver__drift .rem{color:var(--mt-bad)}.cfgver__diff{margin-top:9px}.cfgver__diff pre.body{max-height:280px;margin:0;overflow:auto}.cfgver__actions{flex:none;align-items:center;gap:6px;display:inline-flex}.cfgver__del{color:var(--mt-text-faint);padding-left:8px;padding-right:8px}.cfgver__del:hover{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 45%, var(--mt-border))}.fguide{gap:18px;display:grid}.fguide__sechd{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.09em;color:var(--page-accent);margin:0 0 9px;font-size:11px}.fguide__list{gap:9px;display:grid}.fguide__item{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:color-mix(in srgb, var(--mt-surface-2) 45%, transparent);transition:border-color .18s, transform .12s var(--ease);padding:11px 13px}.fguide__item:hover{border-color:color-mix(in srgb, var(--page-accent) 40%, var(--mt-border));transform:translate(2px)}.fguide__top{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}.fguide__path{font-family:var(--mt-mono);color:var(--mt-text);font-size:12.5px;font-weight:500}.fguide__type{font-family:var(--mt-mono);color:var(--page-accent);background:color-mix(in srgb, var(--page-accent) 13%, transparent);border-radius:999px;padding:1px 7px;font-size:10.5px}.fguide__req{font-family:var(--mt-mono);text-transform:uppercase;letter-spacing:.05em;color:var(--mt-bad);font-size:10px}.fguide__def{color:var(--mt-text-faint);font-size:11px}.fguide__def code{color:var(--mt-text-dim)}.fguide__desc{color:var(--mt-text-dim);margin:6px 0 0;font-size:12.5px;line-height:1.5}.fguide__enum{flex-wrap:wrap;gap:6px;margin-top:7px;display:flex}.fguide__enum code{font-family:var(--mt-mono);border:1px solid var(--mt-border);color:var(--mt-text-dim);border-radius:6px;padding:1px 7px;font-size:11px}.copybtn{position:relative}.copybtn.is-copied{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 55%, var(--mt-border))}.copybtn__tip{background:var(--page-accent);color:#0a0a0a;font-family:var(--mt-sans);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .16s, transform .16s var(--ease);z-index:50;border-radius:6px;padding:3px 9px;font-size:11px;font-weight:600;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%,4px)}.copybtn__tip:after{content:"";border:4px solid #0000;border-top-color:var(--page-accent);position:absolute;top:100%;left:50%;transform:translate(-50%)}.copybtn.is-copied .copybtn__tip{opacity:1;transform:translate(-50%)}.iconbtn{border:1px solid var(--mt-border);background:var(--mt-surface);width:26px;height:26px;color:var(--mt-text-dim);cursor:pointer;border-radius:7px;place-items:center;padding:0;transition:color .16s,border-color .16s,background .16s;display:inline-grid}.iconbtn:hover{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 50%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 10%, var(--mt-surface))}.copybtn--icon.is-copied{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 55%, var(--mt-border))}.sheet__tool{align-items:center;gap:9px;display:inline-flex}.chart{width:100%;font-family:var(--mt-mono)}.chart .recharts-cartesian-grid line{stroke:color-mix(in srgb, var(--mt-border) 80%, transparent)}.chart .recharts-text,.chart text{fill:var(--mt-text-faint)}.chart .recharts-surface:focus,.chart svg:focus{outline:none}.chart-tip{background:color-mix(in srgb, var(--mt-surface) 96%, transparent);border:1px solid var(--mt-border-strong);border-radius:var(--mt-radius-sm);font-family:var(--mt-mono);min-width:120px;padding:8px 10px;font-size:11.5px;box-shadow:0 8px 24px #00000073}.chart-tip__label{color:var(--mt-text-dim);margin-bottom:5px;font-size:10.5px}.chart-tip__row{align-items:center;gap:7px;display:flex}.chart-tip__dot{border-radius:3px;flex:none;width:9px;height:9px}.chart-tip__name{color:var(--mt-text-dim);text-transform:capitalize}.chart-tip__val{color:var(--mt-text);font-variant-numeric:tabular-nums;margin-left:auto;font-weight:500}.chart--donut{flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;display:flex}.chart-donut__svg{width:100%;max-width:200px}.chart-legend{font-family:var(--mt-mono);color:var(--mt-text-dim);flex-wrap:wrap;justify-content:center;gap:6px 14px;font-size:11px;display:flex}.chart-legend span{align-items:center;gap:6px;display:inline-flex}.chart-legend i{border-radius:3px;width:9px;height:9px}.chart-legend b{color:var(--mt-text);font-weight:500}.chart--spark{position:relative}.chart-spark__last{font-family:var(--mt-mono);z-index:1;font-size:10px;font-weight:600;position:absolute;top:0;right:2px}.gauge__radial{place-items:center;width:72px;height:72px;display:grid;position:relative}.gauge__pct{font-family:var(--mt-mono);pointer-events:none;place-items:center;font-size:13px;font-weight:700;display:grid;position:absolute;inset:0}.geist-btn{font-family:var(--mt-sans);border-radius:var(--mt-radius-sm);border:1px solid var(--mt-border-strong);background:var(--mt-surface);color:var(--mt-text);cursor:pointer;white-space:nowrap;transition:background .16s var(--ease), border-color .16s, color .16s, transform .1s var(--ease), box-shadow .16s;justify-content:center;align-items:center;gap:7px;font-size:13px;font-weight:500;line-height:1;display:inline-flex}.geist-btn--sm{padding:6px 11px;font-size:12px}.geist-btn--md{padding:9px 15px}.geist-btn:hover{border-color:var(--mt-text);transform:translateY(-1px)}.geist-btn:active{transform:translateY(0)}.geist-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}.geist-btn__icon{display:inline-flex}.geist-btn--accent{background:var(--page-accent);border-color:var(--page-accent);color:#0a0a0a;font-weight:600}.geist-btn--accent:hover{box-shadow:0 4px 16px color-mix(in srgb, var(--page-accent) 40%, transparent);border-color:var(--page-accent)}.geist-btn--success{border-color:color-mix(in srgb, var(--mt-good) 55%, var(--mt-border));color:var(--mt-good)}.geist-btn--warning{border-color:color-mix(in srgb, var(--mt-warn) 55%, var(--mt-border));color:var(--mt-warn)}.geist-btn--error{border-color:color-mix(in srgb, var(--mt-bad) 55%, var(--mt-border));color:var(--mt-bad)}.geist-btn--error:hover{background:color-mix(in srgb, var(--mt-bad) 14%, var(--mt-surface));border-color:var(--mt-bad)}.geist-btn--secondary{color:var(--mt-text-dim);border-color:var(--mt-border)}.geist-btn--ghost{background:0 0;border-color:#0000}.geist-btn--ghost:hover{background:color-mix(in srgb, var(--mt-text) 7%, transparent);border-color:var(--mt-border)}.geist-note{border-radius:var(--mt-radius-sm);border:1px solid var(--mt-border);background:var(--mt-surface);color:var(--mt-text-dim);padding:11px 14px;font-size:13px;line-height:1.55}.geist-note__label{color:var(--mt-text);text-transform:capitalize}.geist-note--secondary{border-color:color-mix(in srgb, var(--page-accent) 30%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 7%, var(--mt-surface))}.geist-note--success{border-color:color-mix(in srgb, var(--mt-good) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-good) 8%, var(--mt-surface))}.geist-note--success .geist-note__label{color:var(--mt-good)}.geist-note--warning{border-color:color-mix(in srgb, var(--mt-warn) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-warn) 8%, var(--mt-surface))}.geist-note--warning .geist-note__label{color:var(--mt-warn)}.geist-note--error{border-color:color-mix(in srgb, var(--mt-bad) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 8%, var(--mt-surface))}.geist-note--error .geist-note__label{color:var(--mt-bad)}.geist-badge{font-family:var(--mt-mono);border:1px solid var(--mt-border);background:var(--mt-surface-2);color:var(--mt-text-dim);border-radius:999px;align-items:center;gap:5px;padding:2px 8px;font-size:10.5px;font-weight:500;display:inline-flex}.geist-badge--accent{color:var(--page-accent);border-color:color-mix(in srgb, var(--page-accent) 40%, var(--mt-border));background:color-mix(in srgb, var(--page-accent) 12%, transparent)}.geist-badge--success{color:var(--mt-good);border-color:color-mix(in srgb, var(--mt-good) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-good) 10%, transparent)}.geist-badge--warning{color:var(--mt-warn);border-color:color-mix(in srgb, var(--mt-warn) 40%, var(--mt-border))}.geist-badge--error{color:var(--mt-bad);border-color:color-mix(in srgb, var(--mt-bad) 40%, var(--mt-border));background:color-mix(in srgb, var(--mt-bad) 10%, transparent)}.geist-dot{background:var(--mt-text-faint);border-radius:999px;flex:none;width:9px;height:9px;display:inline-block}.geist-dot--success{background:var(--mt-good)}.geist-dot--warning{background:var(--mt-warn)}.geist-dot--error{background:var(--mt-bad)}.geist-dot--accent{background:var(--page-accent)}.geist-dot.is-pulse{box-shadow:0 0 0 0 color-mix(in srgb, currentColor 60%, transparent);animation:1.8s infinite geist-pulse}@keyframes geist-pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--mt-good) 55%, transparent)}70%{box-shadow:0 0 0 7px #0000}to{box-shadow:0 0 #0000}}.geist-spinner{width:16px;height:16px;display:inline-block;position:relative}.geist-spinner--sm{width:13px;height:13px}.geist-spinner span{transform-origin:50% 178%;opacity:.15;background:currentColor;border-radius:2px;width:8%;height:28%;animation:1.2s linear infinite geist-spin;position:absolute;top:0;left:46%}@keyframes geist-spin{0%{opacity:1}to{opacity:.15}}.geist-input,.geist-select{font-family:var(--mt-mono);color:var(--mt-text);background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);padding:8px 11px;font-size:12.5px;transition:border-color .16s,box-shadow .16s}.geist-input:focus,.geist-select:focus{border-color:var(--page-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--page-accent) 22%, transparent);outline:none}.geist-card{border:1px solid var(--mt-border);border-radius:var(--mt-radius);background:var(--mt-surface);padding:16px}.geist-card.is-hoverable{transition:border-color .18s, transform .18s var(--ease)}.geist-card.is-hoverable:hover{border-color:color-mix(in srgb, var(--page-accent) 40%, var(--mt-border));transform:translateY(-2px)}.geist-tooltip{display:inline-flex;position:relative}.geist-tooltip__pop{border-radius:var(--mt-radius-sm);background:var(--mt-surface);border:1px solid var(--mt-border-strong);color:var(--mt-text);font-family:var(--mt-mono);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .16s, transform .16s var(--ease);z-index:60;padding:6px 10px;font-size:11.5px;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%,4px);box-shadow:0 8px 24px #00000073}.geist-tooltip:hover .geist-tooltip__pop,.geist-tooltip:focus-visible .geist-tooltip__pop{opacity:1;transform:translate(-50%)}.clients-toolbar{align-items:center;gap:8px;display:flex}.clients-toolbar .geist-input{width:200px}.clients-counts{margin-bottom:10px;font-size:12px}.clients-error{margin-bottom:10px}.clients-table{flex-direction:column;gap:2px;display:flex}.clients-row{border-radius:var(--mt-radius-sm);cursor:pointer;grid-template-columns:120px 1.3fr 150px 80px 130px minmax(150px,190px) minmax(240px,auto);align-items:center;gap:10px;padding:8px 10px;font-size:13px;display:grid}.clients-row--head{cursor:default;color:var(--mt-text-faint);text-transform:uppercase;letter-spacing:.04em;font-size:11px}.clients-row:not(.clients-row--head):hover{background:var(--mt-surface-2)}.clients-row.is-selected{background:color-mix(in srgb, var(--page-accent) 14%, var(--mt-surface-2))}.clients-row.is-blocked .clients-ip,.clients-row.is-blocked .clients-name{color:var(--mt-text-faint);text-decoration:line-through}.clients-ip,.clients-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.clients-mac{color:var(--mt-text-dim);font-family:ui-monospace,SF Mono,Menlo,monospace;font-size:11.5px}.clients-badges{align-items:center;gap:6px;display:flex;overflow:hidden}.clients-actions,.clients-actions-h{justify-content:flex-end;gap:6px;display:flex}.clients-detail{border-top:1px solid var(--mt-border);margin-top:14px;padding-top:14px}.clients-detail__hd{flex-wrap:wrap;align-items:baseline;gap:12px;margin-bottom:10px;display:flex}.clients-detail__title{font-size:14px;font-weight:600}.clients-rates{font-variant-numeric:tabular-nums;gap:18px;margin-bottom:8px;display:flex}.clients-rates .rate{font-weight:600}.clients-rates .rate.rx{color:var(--lime)}.clients-rates .rate.tx{color:var(--amber)}.clients-chart{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);width:100%;max-width:520px;height:150px;display:block}.clients-chart .line{fill:none;stroke-width:2px}.clients-chart .rx.line{stroke:var(--lime)}.clients-chart .tx.line{stroke:var(--amber)}.clients-chart .rx.area{fill:color-mix(in srgb, var(--lime) 18%, transparent);stroke:none}.clients-chart .tx.area{fill:color-mix(in srgb, var(--amber) 14%, transparent);stroke:none}.clients-totals{font-variant-numeric:tabular-nums;margin-top:8px;font-size:12px}.clients-traffic{font-variant-numeric:tabular-nums;align-items:center;gap:4px;font-size:11px;display:flex;overflow:hidden}.clients-traffic__rates{white-space:nowrap;flex-direction:column;gap:0;min-width:48px;line-height:1.3;display:flex}.clients-traffic__rates .rx{color:var(--lime,#84cc16)}.clients-traffic__rates .tx{color:var(--amber,#f59e0b)}.mini-spark{background:#ffffff08;border-radius:3px;flex-shrink:0;width:80px;height:18px}.mini-spark .line{fill:none;stroke-width:1px;vector-effect:non-scaling-stroke}.mini-spark .rx.line{stroke:var(--lime,#84cc16)}.mini-spark .tx.line{stroke:var(--amber,#f59e0b)}.mini-spark .rx.area{fill:var(--lime,#84cc16);opacity:.18}.mini-spark .tx.area{fill:var(--amber,#f59e0b);opacity:.14}.clients-edit{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-surface-2);flex-wrap:wrap;align-items:center;gap:8px;margin-top:14px;padding:10px 12px;display:flex}.clients-edit__label{color:var(--mt-text-dim);font-size:13px}.clients-edit .geist-input{width:220px}.aaa-tabs{border-bottom:1px solid var(--mt-border);flex-wrap:wrap;gap:4px;margin-bottom:14px;display:flex}.aaa-tab{appearance:none;color:var(--mt-text-dim);font:inherit;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-1px;padding:7px 12px;font-size:13px}.aaa-tab:hover{color:var(--mt-text)}.aaa-tab.is-active{color:var(--mt-text);border-bottom-color:var(--page-accent)}.aaa-entity__toolbar{align-items:center;gap:10px;margin-bottom:12px;display:flex}.aaa-filter{width:200px}.aaa-error{margin-bottom:10px}.aaa-empty{padding:20px 4px}.aaa-table{flex-direction:column;gap:2px;display:flex}.aaa-table--scroll{overflow-x:auto}.aaa-row{border-radius:var(--mt-radius-sm);align-items:center;gap:10px;padding:8px 10px;font-size:13px;display:grid}.aaa-row--head{color:var(--mt-text-faint);text-transform:uppercase;letter-spacing:.04em;font-size:11px}.aaa-row:not(.aaa-row--head):hover{background:var(--mt-surface-2)}.aaa-row.is-off .aaa-cell{color:var(--mt-text-faint)}.aaa-row--sessions{grid-template-columns:repeat(9,minmax(90px,1fr));min-width:900px}.aaa-cell{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.aaa-actions,.aaa-actions-h{justify-content:flex-end;gap:6px;display:flex}.aaa-form,.aaa-singleton{border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);background:var(--mt-surface-2);margin-bottom:14px;padding:14px}.aaa-form__title,.aaa-singleton__title{margin-bottom:10px;font-size:13px;font-weight:600}.aaa-singleton__current{margin-bottom:12px;font-size:12px}.aaa-form__grid{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px 14px;display:grid}.aaa-field{flex-direction:column;gap:4px;display:flex}.aaa-field__label{color:var(--mt-text-dim);font-size:11.5px}.aaa-form__actions{align-items:center;gap:10px;margin-top:14px;display:flex}.aaa-settings{flex-direction:column;gap:8px;display:flex}.clients-limits{border-top:1px solid var(--mt-border);max-width:520px;margin-top:14px;padding-top:12px}.clients-limits__hd{align-items:baseline;gap:12px;margin-bottom:8px;display:flex}.clients-limits__label{font-size:13px;font-weight:600}.clients-limits__row{flex-wrap:wrap;align-items:flex-end;gap:8px;display:flex}.clients-limits__field{flex-direction:column;gap:3px;font-size:11.5px;display:flex}.clients-limits__field .geist-input{width:150px}.clients-limits__msg{margin-top:6px;font-size:12px}.usage-chart__empty{padding:16px 4px;font-size:12.5px}.usage-chart__legend{font-variant-numeric:tabular-nums;align-items:baseline;gap:14px;margin-bottom:6px;font-size:12px;display:flex}.usage-chart__legend .rate{font-weight:600}.usage-chart__legend .rate.rx{color:var(--lime)}.usage-chart__legend .rate.tx{color:var(--amber)}.usage-chart__svg{background:var(--mt-surface);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);width:100%;height:160px;display:block}.usage-chart__svg .line{fill:none;stroke-width:2px;vector-effect:non-scaling-stroke}.usage-chart__svg .rx.line{stroke:var(--lime)}.usage-chart__svg .tx.line{stroke:var(--amber)}.usage-chart__svg .rx.area{fill:color-mix(in srgb, var(--lime) 18%, transparent);stroke:none}.usage-chart__svg .tx.area{fill:color-mix(in srgb, var(--amber) 14%, transparent);stroke:none}.clients-history,.aaa-usage__section{margin-top:16px}.clients-history__hd,.aaa-usage__title{color:var(--mt-text-dim);margin-bottom:8px;font-size:12px;font-weight:600}.aaa-usage__bar{align-items:center;gap:8px;margin-bottom:12px;display:flex}.heatmap__hd{align-items:baseline;gap:10px;margin-bottom:6px;display:flex}.heatmap__title{font-size:12.5px;font-weight:600}.heatmap__scroll{padding-bottom:4px;overflow-x:auto}.heatmap__svg{display:block}.heatmap__month,.heatmap__wd{fill:var(--mt-text-dim);font-family:inherit;font-size:9px}.heatmap{position:relative}.heatmap__cell{stroke:color-mix(in srgb, var(--mt-border) 60%, transparent);stroke-width:1px;cursor:pointer;transition:stroke .1s}.heatmap__cell.is-hover{stroke:var(--mt-text);stroke-width:1.5px}.heatmap__tip{z-index:30;background:linear-gradient(180deg, color-mix(in srgb, var(--mt-surface-2) 92%, var(--lime)), var(--mt-surface-2));border:1px solid color-mix(in srgb, var(--lime) 35%, var(--mt-border));pointer-events:none;min-width:150px;animation:heatmap-tip-in .12s var(--ease);border-radius:10px;padding:8px 10px;position:absolute;transform:translate(-50%,calc(-100% - 9px));box-shadow:0 8px 24px #00000073}.heatmap__tip:after{content:"";background:var(--mt-surface-2);border-right:1px solid color-mix(in srgb, var(--lime) 35%, var(--mt-border));border-bottom:1px solid color-mix(in srgb, var(--lime) 35%, var(--mt-border));width:11px;height:11px;position:absolute;bottom:-6px;left:50%;transform:translate(-50%)rotate(45deg)}@keyframes heatmap-tip-in{0%{opacity:0;transform:translate(-50%,calc(-100% - 3px))}to{opacity:1;transform:translate(-50%,calc(-100% - 9px))}}.heatmap__tip-head{align-items:center;gap:7px;font-size:13px;display:flex}.heatmap__tip-head b{font-weight:600}.heatmap__tip-head .heatmap__swatch{width:12px;height:12px}.heatmap__tip-date{color:var(--mt-text-dim);font-variant-numeric:tabular-nums;margin-top:3px;font-size:11.5px}.heatmap__cell.lvl0,.heatmap__swatch.lvl0{fill:var(--mt-surface-2);background:var(--mt-surface-2)}.heatmap__cell.lvl1,.heatmap__swatch.lvl1{fill:color-mix(in srgb, var(--lime) 30%, var(--mt-surface-2));background:color-mix(in srgb, var(--lime) 30%, var(--mt-surface-2))}.heatmap__cell.lvl2,.heatmap__swatch.lvl2{fill:color-mix(in srgb, var(--lime) 50%, var(--mt-surface-2));background:color-mix(in srgb, var(--lime) 50%, var(--mt-surface-2))}.heatmap__cell.lvl3,.heatmap__swatch.lvl3{fill:color-mix(in srgb, var(--lime) 72%, transparent);background:color-mix(in srgb, var(--lime) 72%, transparent)}.heatmap__cell.lvl4,.heatmap__swatch.lvl4{fill:var(--lime);background:var(--lime)}.heatmap__legend{align-items:center;gap:4px;margin-top:8px;font-size:11px;display:flex}.heatmap__swatch{border-radius:2px;width:11px;height:11px;display:inline-block}.input{font:12px var(--mt-mono);color:var(--mt-text);background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);width:min(52vw,420px);padding:6px 10px}.input:focus{border-color:color-mix(in srgb, var(--mt-accent) 55%, var(--mt-border));outline:none}.btn-sm{padding:3px 8px;font-size:10px}.mod-toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:6px;display:flex}.mod-groups{flex-direction:column;gap:18px;margin-top:12px;display:flex}.mod-group__hd{border-bottom:1px solid var(--mt-border);align-items:center;gap:10px;margin-bottom:8px;padding-bottom:6px;display:flex}.mod-group__title{color:var(--mt-text);margin:0;font-size:13px;font-weight:600}.mod-list{grid-template-columns:repeat(auto-fill,minmax(min(100%,360px),1fr));gap:8px;display:grid}.mod-row{background:var(--mt-surface-2);border:1px solid var(--mt-border);border-radius:var(--mt-radius-sm);cursor:pointer;-webkit-user-select:none;user-select:none;align-items:flex-start;gap:10px;padding:9px 11px;transition:border-color .18s,background .18s;display:flex}.mod-row:hover{border-color:color-mix(in srgb, var(--mt-accent) 35%, var(--mt-border))}.mod-row[data-on]{border-color:color-mix(in srgb, var(--mt-accent) 50%, var(--mt-border));background:color-mix(in srgb, var(--mt-accent) 10%, var(--mt-surface-2))}.mod-row input{accent-color:var(--mt-accent);cursor:pointer;margin:2px 0 0}.mod-row__main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.mod-row__name{color:var(--mt-text);flex-wrap:wrap;align-items:center;gap:7px;font-size:12px;font-weight:600;display:flex}.mod-row__slug{font:10px var(--mt-mono);color:var(--mt-text-dim);background:var(--mt-bg);border:1px solid var(--mt-border);border-radius:4px;padding:1px 5px}.mod-row__desc{font-size:11px;line-height:1.35}.mod-row__count{font:10px var(--mt-mono);white-space:nowrap;padding-top:1px}.conn-tunnel-halo{fill:none;stroke-width:8px;stroke-linecap:round;opacity:.1}.conn-tunnel{fill:none;stroke-width:2.4px;stroke-linecap:round;stroke-dasharray:6 6;animation:.9s linear infinite conn-tunnel-flow}@keyframes conn-tunnel-flow{to{stroke-dashoffset:-24px}}.conn-tunnel-lock{filter:drop-shadow(0 0 4px #f59e0bcc)}.conn-tunnel-sat{stroke-width:1.5px;filter:drop-shadow(0 0 5px #f59e0b88)}.conn-tunnel-badge{fill:#30220a;stroke:color-mix(in srgb, #f59e0b 60%, var(--mt-border));stroke-width:1px}.conn-tunnel-badge-tx{fill:#fbbf24;font-family:var(--mt-mono);letter-spacing:.02em;font-weight:700}.jump-route{background:color-mix(in srgb, #f59e0b 7%, var(--mt-surface-2));border:1px solid color-mix(in srgb, #f59e0b 28%, var(--mt-border));font:10px var(--mt-mono);border-radius:10px;align-items:center;gap:6px;margin:10px 0 2px;padding:7px 9px;display:flex;overflow:hidden}.jump-route__hop{background:var(--mt-bg);border:1px solid var(--mt-border);color:var(--mt-text);white-space:nowrap;border-radius:7px;align-items:center;gap:5px;padding:3px 8px;display:inline-flex}.jump-route__hop--src{padding:3px 7px;font-size:12px}.jump-route__hop--bastion{border-color:color-mix(in srgb, #f59e0b 60%, var(--mt-border));color:#fbbf24;box-shadow:0 0 10px -3px #f59e0b99}.jump-route__tag{text-transform:uppercase;letter-spacing:.08em;color:#0a0a0a;background:#f59e0b;border-radius:4px;padding:1px 4px;font-size:7px;font-style:normal}.jump-route__wire{background-image:linear-gradient(90deg, var(--mt-border) 0 50%, transparent 50% 100%);background-size:8px 2px;border-radius:2px;flex:1;min-width:18px;height:2px;animation:.7s linear infinite jump-wire}.jump-route__wire--enc{background-image:linear-gradient(90deg,#f59e0b 0 55%,#0000 55% 100%);background-size:10px 3px;min-width:34px;height:3px;position:relative;box-shadow:0 0 8px -1px #f59e0b88}.jump-route__lock{filter:drop-shadow(0 0 3px #f59e0b);font-size:11px;animation:2.2s linear infinite jump-lock;position:absolute;top:50%}@keyframes jump-wire{to{background-position:8px 0}}@keyframes jump-lock{0%{left:-4px;transform:translateY(-50%)scale(.9)}50%{transform:translateY(-50%)scale(1.1)}to{left:calc(100% - 8px);transform:translateY(-50%)scale(.9)}}@media (prefers-reduced-motion:reduce){.conn-tunnel,.jump-route__wire,.jump-route__wire--enc,.jump-route__lock{animation:none}.conn-tunnel-lock animatemotion{display:none}}.pool-panel{margin:12px 0}.pool-disabled{color:#71717a;margin:4px 0;font-size:13px}.pool-disabled code{color:#7c9cff;font-size:12px}.pool-stats{flex-wrap:wrap;gap:8px;margin-bottom:12px;display:flex}.pool-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:8px;display:grid}.pool-card{background:#18181b;border:1px solid #27272a;border-radius:8px;padding:10px 12px;transition:border-color .2s}.pool-card:hover{border-color:#3f3f46}.pool-card--idle{border-color:#22c55e59}.pool-card--busy{border-color:#3b82f680}.pool-card--dead{border-color:#ef444480}.pool-card--disconnected{opacity:.6;border-style:dashed}.pool-card__hd{align-items:center;gap:6px;margin-bottom:6px;display:flex}.pool-card__dot{border-radius:50%;flex-shrink:0;width:7px;height:7px}.pool-card__name{color:#e4e4e7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:600;overflow:hidden}.pool-card__badge{text-transform:uppercase;letter-spacing:.04em;margin-left:auto;font-size:10px;font-weight:600}.pool-pipe{background:#27272a;border-radius:3px;height:6px;position:relative;overflow:hidden}.pool-pipe__fill{opacity:.65;border-radius:3px;height:100%;transition:width .4s}.pool-pipe__fill--pulse{animation:1.5s ease-in-out infinite pool-pulse}.pool-pipe__label{color:#fafafa;text-shadow:0 0 3px #0009;font-size:8px;font-weight:700;line-height:8px;position:absolute;top:-1px;right:4px}@keyframes pool-pulse{0%,to{opacity:.5}50%{opacity:.9}}
|
|
85
85
|
/*$vite$:1*/
|
|
86
86
|
</style>
|
|
87
87
|
</head>
|
package/package.json
CHANGED