var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},ee=Object.prototype.hasOwnProperty;function te(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function ne(e,t){return te(e.type,t,e.props)}function T(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function re(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ie=/\/+/g;function E(e,t){return typeof e==`object`&&e&&e.key!=null?re(``+e.key):t.toString(36)}function ae(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function oe(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,oe(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+E(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(ie,`$&/`)+`/`),oe(o,r,i,``,function(e){return e})):o!=null&&(T(o)&&(o=ne(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ie,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,T());else{var t=n(l);t!==null&&E(x,t.startTime-e)}}var S=!1,C=-1,w=5,ee=-1;function te(){return g?!0:!(e.unstable_now()-eet&&te());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&E(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?T():S=!1}}}var T;if(typeof y==`function`)T=function(){y(ne)};else if(typeof MessageChannel<`u`){var re=new MessageChannel,ie=re.port2;re.port1.onmessage=ne,T=function(){ie.postMessage(null)}}else T=function(){_(ne,0)};function E(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,E(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,T()))),r},e.unstable_shouldYield=te,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1k||(e.current=ue[k],ue[k]=null,k--)}function A(e,t){k++,ue[k]=e.current,e.current=t}var pe=de(null),me=de(null),he=de(null),ge=de(null);function _e(e,t){switch(A(he,t),A(me,e),A(pe,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}fe(pe),A(pe,e)}function ve(){fe(pe),fe(me),fe(he)}function ye(e){e.memoizedState!==null&&A(ge,e);var t=pe.current,n=Hd(t,e.type);t!==n&&(A(me,e),A(pe,n))}function be(e){me.current===e&&(fe(pe),fe(me)),ge.current===e&&(fe(ge),Qf._currentValue=le)}var xe,Se;function Ce(e){if(xe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);xe=t&&t[1]||``,Se=-1)`:-1i||c[r]!==l[i]){var u=` `+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{we=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?Ce(n):``}function Te(e,t){switch(e.tag){case 26:case 27:case 5:return Ce(e.type);case 16:return Ce(`Lazy`);case 13:return e.child!==t&&t!==null?Ce(`Suspense Fallback`):Ce(`Suspense`);case 19:return Ce(`SuspenseList`);case 0:case 15:return j(e.type,!1);case 11:return j(e.type.render,!1);case 1:return j(e.type,!0);case 31:return Ce(`Activity`);default:return``}}function Ee(e){try{var t=``,n=null;do t+=Te(e,n),n=e,e=e.return;while(e);return t}catch(e){return` Error generating stack: `+e.message+` `+e.stack}}var De=Object.prototype.hasOwnProperty,Oe=t.unstable_scheduleCallback,ke=t.unstable_cancelCallback,Ae=t.unstable_shouldYield,je=t.unstable_requestPaint,Me=t.unstable_now,Ne=t.unstable_getCurrentPriorityLevel,Pe=t.unstable_ImmediatePriority,Fe=t.unstable_UserBlockingPriority,Ie=t.unstable_NormalPriority,Le=t.unstable_LowPriority,Re=t.unstable_IdlePriority,ze=t.log,Be=t.unstable_setDisableYieldValue,Ve=null,He=null;function Ue(e){if(typeof ze==`function`&&Be(e),He&&typeof He.setStrictMode==`function`)try{He.setStrictMode(Ve,e)}catch{}}var We=Math.clz32?Math.clz32:qe,Ge=Math.log,Ke=Math.LN2;function qe(e){return e>>>=0,e===0?32:31-(Ge(e)/Ke|0)|0}var Je=256,Ye=262144,Xe=4194304;function Ze(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Qe(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Ze(n))):i=Ze(o):i=Ze(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Ze(n))):i=Ze(o)):i=Ze(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function $e(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function et(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function tt(){var e=Xe;return Xe<<=1,!(Xe&62914560)&&(Xe=4194304),e}function M(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function nt(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function rt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),hn=!1;if(mn)try{var gn={};Object.defineProperty(gn,`passive`,{get:function(){hn=!0}}),window.addEventListener(`test`,gn,gn),window.removeEventListener(`test`,gn,gn)}catch{hn=!1}var _n=null,vn=null,yn=null;function P(){if(yn)return yn;var e,t=vn,n=t.length,r,i=`value`in _n?_n.value:_n.textContent,a=i.length;for(e=0;e=Yn),Qn=` `,$n=!1;function er(e,t){switch(e){case`keyup`:return qn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function tr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var nr=!1;function L(e,t){switch(e){case`compositionend`:return tr(t);case`keypress`:return t.which===32?($n=!0,Qn):null;case`textInput`:return e=t.data,e===Qn&&$n?null:e;default:return null}}function R(e,t){if(nr)return e===`compositionend`||!Jn&&er(e,t)?(e=P(),yn=vn=_n=null,nr=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=wr(n)}}function Er(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Er(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Dr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Ht(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Ht(e.document)}return t}function Or(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var kr=mn&&`documentMode`in document&&11>=document.documentMode,Ar=null,jr=null,Mr=null,Nr=!1;function Pr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Nr||Ar==null||Ar!==Ht(r)||(r=Ar,`selectionStart`in r&&Or(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Mr&&Cr(Mr,r)||(Mr=r,r=Td(jr,`onSelect`),0>=o,i-=o,xi=1<<32-We(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),G&&Ci(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),G&&Ci(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return G&&Ci(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),G&&Ci(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===T&&xa(l)===r.type){n(e,r.sibling),c=a(r,o.props),Oa(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=di(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=ui(o.type,o.key,o.props,null,e.mode,c),Oa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=pi(o,e.mode,c),c.return=e,e=c}return s(e);case T:return o=xa(o),b(e,r,o,c)}if(ce(o))return h(e,r,o,c);if(ae(o)){if(l=ae(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Da(o),c);if(o.$$typeof===C)return b(e,r,Yi(e,o),c);ka(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=V(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Ea=0;var i=b(e,t,n,r);return Ta=null,i}catch(t){if(t===ha||t===_a)throw t;var a=oi(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var ja=Aa(!0),Ma=Aa(!1),Na=!1;function Pa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Fa(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ia(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function La(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,J&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ri(e),ni(e,null,n),t}return ei(e,r,t,n),ri(e)}function Ra(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}function za(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ba=!1;function Va(){if(Ba){var e=oa;if(e!==null)throw e}}function Ha(e,t,n,r){Ba=!1;var i=e.updateQueue;Na=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(X&f)===f:(r&f)===f){f!==0&&f===aa&&(Ba=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:Na=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Wl|=o,e.lanes=o,e.memoizedState=d}}function Ua(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Wa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=D.T,s={};D.T=s,As(e,!1,t,n);try{var c=i(),l=D.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?ks(e,t,la(c,r),fu(e)):ks(e,t,r,fu(e))}catch(n){ks(e,t,{then:function(){},status:`rejected`,reason:n},fu())}finally{O.p=a,o!==null&&s.types!==null&&(o.types=s.types),D.T=o}}function ys(){}function bs(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=xs(e).queue;vs(e,a,t,le,n===null?ys:function(){return Ss(e),n(r)})}function xs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:le,baseState:le,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:jo,lastRenderedState:le},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:jo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Ss(e){var t=xs(e);t.next===null&&(t=e.alternate.memoizedState),ks(e,t.next.queue,{},fu())}function Cs(){return Ji(Qf)}function ws(){return Eo().memoizedState}function Ts(){return Eo().memoizedState}function Es(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=fu();e=Ia(n);var r=La(t,e,n);r!==null&&(mu(r,t,n),Ra(r,t,n)),t={cache:ta()},e.payload=t;return}t=t.return}}function Ds(e,t,n){var r=fu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},js(e)?Ms(t,n):(n=ti(e,t,n,r),n!==null&&(mu(n,e,r),Ns(n,t,r)))}function Os(e,t,n){ks(e,t,n,fu())}function ks(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(js(e))Ms(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Sr(s,o))return ei(e,t,i,0),Ll===null&&$r(),!1}catch{}if(n=ti(e,t,i,r),n!==null)return mu(n,e,r),Ns(n,t,r),!0}return!1}function As(e,t,n,r){if(r={lane:2,revertLane:ud(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},js(e)){if(t)throw Error(i(479))}else t=ti(e,n,r,2),t!==null&&mu(t,e,2)}function js(e){var t=e.alternate;return e===q||t!==null&&t===q}function Ms(e,t){lo=co=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ns(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,at(e,n)}}var Ps={readContext:Ji,use:ko,useCallback:go,useContext:go,useEffect:go,useImperativeHandle:go,useLayoutEffect:go,useInsertionEffect:go,useMemo:go,useReducer:go,useRef:go,useState:go,useDebugValue:go,useDeferredValue:go,useTransition:go,useSyncExternalStore:go,useId:go,useHostTransitionStatus:go,useFormState:go,useActionState:go,useOptimistic:go,useMemoCache:go,useCacheRefresh:go};Ps.useEffectEvent=go;var Fs={readContext:Ji,use:ko,useCallback:function(e,t){return To().memoizedState=[e,t===void 0?null:t],e},useContext:Ji,useEffect:as,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),rs(4194308,4,ds.bind(null,t,e),n)},useLayoutEffect:function(e,t){return rs(4194308,4,e,t)},useInsertionEffect:function(e,t){rs(4,2,e,t)},useMemo:function(e,t){var n=To();t=t===void 0?null:t;var r=e();if(uo){Ue(!0);try{e()}finally{Ue(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=To();if(n!==void 0){var i=n(t);if(uo){Ue(!0);try{n(t)}finally{Ue(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Ds.bind(null,q,e),[r.memoizedState,e]},useRef:function(e){var t=To();return e={current:e},t.memoizedState=e},useState:function(e){e=Vo(e);var t=e.queue,n=Os.bind(null,q,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:ps,useDeferredValue:function(e,t){return gs(To(),e,t)},useTransition:function(){var e=Vo(!1);return e=vs.bind(null,q,e.queue,!0,!1),To().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=q,a=To();if(G){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),Ll===null)throw Error(i(349));X&127||Io(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,as(Ro.bind(null,r,o,e),[e]),r.flags|=2048,ts(9,{destroy:void 0},Lo.bind(null,r,o,n,t),null),n},useId:function(){var e=To(),t=Ll.identifierPrefix;if(G){var n=Si,r=xi;n=(r&~(1<<32-We(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=fo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[ft]=t,o[pt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&kc(t)}}return Pc(t),Ac(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&kc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=he.current,Pi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Oi,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[ft]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||jd(e.nodeValue,n)),e||K(t,!0)}else e=Bd(e).createTextNode(r),e[ft]=t,t.stateNode=e}return Pc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Pi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[ft]=t}else Fi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Pc(t),e=!1}else n=Ii(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(no(t),t):(no(t),null);if(t.flags&128)throw Error(i(558))}return Pc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Pi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[ft]=t}else Fi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Pc(t),a=!1}else a=Ii(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(no(t),t):(no(t),null)}return no(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Mc(t,t.updateQueue),Pc(t),null);case 4:return ve(),e===null&&xd(t.stateNode.containerInfo),Pc(t),null;case 10:return Hi(t.type),Pc(t),null;case 19:if(fe(ro),r=t.memoizedState,r===null)return Pc(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Nc(r,!1);else{if(Ul!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=io(e),o!==null){for(t.flags|=128,Nc(r,!1),e=o.updateQueue,t.updateQueue=e,Mc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)li(n,e),n=n.sibling;return A(ro,ro.current&1|2),G&&Ci(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Me()>eu&&(t.flags|=128,a=!0,Nc(r,!1),t.lanes=4194304)}else{if(!a)if(e=io(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Mc(t,e),Nc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!G)return Pc(t),null}else 2*Me()-r.renderingStartTime>eu&&n!==536870912&&(t.flags|=128,a=!0,Nc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Pc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Me(),e.sibling=null,n=ro.current,A(ro,a?n&1|2:n&1),G&&Ci(t,r.treeForkCount),e);case 22:case 23:return no(t),Ya(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Pc(t),t.subtreeFlags&6&&(t.flags|=8192)):Pc(t),n=t.updateQueue,n!==null&&Mc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&fe(da),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Hi(ea),Pc(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function Ic(e,t){switch(Ei(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Hi(ea),ve(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return be(t),null;case 31:if(t.memoizedState!==null){if(no(t),t.alternate===null)throw Error(i(340));Fi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(no(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Fi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return fe(ro),null;case 4:return ve(),null;case 10:return Hi(t.type),null;case 22:case 23:return no(t),Ya(),e!==null&&fe(da),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Hi(ea),null;case 25:return null;default:return null}}function Lc(e,t){switch(Ei(t),t.tag){case 3:Hi(ea),ve();break;case 26:case 27:case 5:be(t);break;case 4:ve();break;case 31:t.memoizedState!==null&&no(t);break;case 13:no(t);break;case 19:fe(ro);break;case 10:Hi(t.type);break;case 22:case 23:no(t),Ya(),e!==null&&fe(da);break;case 24:Hi(ea)}}function Rc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Q(t,t.return,e)}}function zc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Q(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Q(t,t.return,e)}}function Bc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Wa(t,n)}catch(t){Q(e,e.return,t)}}}function Vc(e,t,n){n.props=Hs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Q(e,t,n)}}function Hc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Q(e,t,n)}}function Uc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Q(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Q(e,t,n)}else n.current=null}function Wc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Q(e,e.return,t)}}function Gc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[pt]=t}catch(t){Q(e,e.return,t)}}function Kc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function qc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Kc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Jc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=an));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Jc(e,t,n),e=e.sibling;e!==null;)Jc(e,t,n),e=e.sibling}function Yc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Yc(e,t,n),e=e.sibling;e!==null;)Yc(e,t,n),e=e.sibling}function Xc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[ft]=e,t[pt]=n}catch(t){Q(e,e.return,t)}}var Zc=!1,Qc=!1,$c=!1,el=typeof WeakSet==`function`?WeakSet:Set,tl=null;function nl(e,t){if(e=e.containerInfo,Rd=sp,e=Dr(e),Or(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,tl=t;tl!==null;)if(t=tl,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,tl=e;else for(;tl!==null;){switch(t=tl,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[ft]=e,Tt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Tr(s,h),v=Tr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,D.T=null,n=cu,cu=null;var o=iu,s=ou;if(ru=0,au=iu=null,ou=0,J&6)throw Error(i(331));var c=J;if(J|=4,Ml(o.current),wl(o,o.current,s,n),J=c,rd(0,!1),He&&typeof He.onPostCommitFiberRoot==`function`)try{He.onPostCommitFiberRoot(Ve,o)}catch{}return!0}finally{O.p=a,D.T=r,Bu(e,t)}}function Uu(e,t,n){t=H(n,t),t=Js(e.stateNode,t,2),e=La(e,t,2),e!==null&&(nt(e,2),nd(e))}function Q(e,t,n){if(e.tag===3)Uu(e,e,n);else for(;t!==null;){if(t.tag===3){Uu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(nu===null||!nu.has(r))){e=H(n,e),n=Ys(2),r=La(t,n,2),r!==null&&(Xs(n,r,t,e),nt(r,2),nd(r));break}}t=t.return}}function Wu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Il;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Vl=!0,i.add(n),e=Gu.bind(null,e,t,n),t.then(e,e))}function Gu(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Ll===e&&(X&n)===n&&(Ul===4||Ul===3&&(X&62914560)===X&&300>Me()-Ql?!(J&2)&&xu(e,0):Kl|=n,Jl===X&&(Jl=0)),nd(e)}function Ku(e,t){t===0&&(t=tt()),e=B(e,t),e!==null&&(nt(e,t),nd(e))}function qu(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),Ku(e,n)}function Ju(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),Ku(e,n)}function Yu(e,t){return Oe(e,t)}var Xu=null,Zu=null,Qu=!1,$u=!1,ed=!1,td=0;function nd(e){e!==Zu&&e.next===null&&(Zu===null?Xu=Zu=e:Zu=Zu.next=e),$u=!0,Qu||(Qu=!0,ld())}function rd(e,t){if(!ed&&$u){ed=!0;do for(var n=!1,r=Xu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-We(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,cd(r,a))}else a=X,a=Qe(r,r===Ll?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||$e(r,a)||(n=!0,cd(r,a));r=r.next}while(n);ed=!1}}function id(){ad()}function ad(){$u=Qu=!1;var e=0;td!==0&&Gd()&&(e=td);for(var t=Me(),n=null,r=Xu;r!==null;){var i=r.next,a=od(r,t);a===0?(r.next=null,n===null?Xu=i:n.next=i,i===null&&(Zu=n)):(n=r,(e!==0||a&3)&&($u=!0)),r=i}ru!==0&&ru!==5||rd(e,!1),td!==0&&(td=0)}function od(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Wt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),Tt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Wt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Wt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Wt(n.imageSizes)+`"]`)):i+=`[href="`+Wt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),Tt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Wt(r)+`"][href="`+Wt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),Tt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=wt(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);Tt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=wt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Tt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=wt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),Tt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=he.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=wt(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=wt(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=wt(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Wt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),Tt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Wt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Wt(n.href)+`"]`);if(r)return t.instance=r,Tt(r),r;var a=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Tt(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,Tt(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),Tt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,Tt(a),a):(r=n,(a=mf.get(o))&&(r=h({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Tt(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Tt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),Tt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=c(u(),1),v=g(),y=class{baseUrl;actorUserId;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,``),this.actorUserId=e.actorUserId.trim()}async login(e){return this.post(`/auth/login`,{email:e.email,password:e.password,device_fingerprint:b(),device_label:e.deviceLabel,trust_device:e.trustDevice})}async refresh(e){return this.post(`/auth/refresh`,{refresh_token:e.refreshToken})}async getInstallationStatus(){return(await this.request(`/installation/status`,{method:`GET`})).installation}async bootstrapOwner(e){return this.post(`/installation/bootstrap-owner`,{email:e.email,password:e.password,activation_payload:e.activationPayload,activation_signature:e.activationSignature||``})}async revokeAuthSession(e){await this.post(`/auth/sessions/revoke`,{user_id:e.userId,auth_session_id:e.authSessionId,reason:e.reason})}async listClusters(){return(await this.get(`/clusters`)).clusters??[]}async createCluster(e){return(await this.post(`/clusters/`,{actor_user_id:this.actorUserId,slug:e.slug,name:e.name,region:e.region||null,metadata:{}})).cluster}async updateCluster(e,t){return(await this.put(`/clusters/${e}`,{actor_user_id:this.actorUserId,name:t.name,status:t.status,region:t.region||null,metadata:t.metadata||{}})).cluster}async listClusterSummaries(){return(await this.get(`/cluster-admin-summaries`)).cluster_summaries??[]}async getClusterAuthority(e){return(await this.get(`/clusters/${e}/authority`)).authority_state}async updateClusterAuthority(e,t){return(await this.put(`/clusters/${e}/authority`,{actor_user_id:this.actorUserId,authority_state:t.authorityState,mutation_mode:t.mutationMode,notes:t.notes||null})).authority_state}async listNodes(e){return(await this.get(`/clusters/${e}/nodes`)).nodes??[]}async listNodeGroups(e){return(await this.get(`/clusters/${e}/node-groups`)).node_groups??[]}async createNodeGroup(e,t){return(await this.post(`/clusters/${e}/node-groups`,{actor_user_id:this.actorUserId,parent_group_id:t.parentGroupId||null,name:t.name,description:t.description||null,sort_order:t.sortOrder||0,metadata:{}})).node_group}async assignNodeGroup(e,t,n){return(await this.put(`/clusters/${e}/nodes/${t}/group`,{actor_user_id:this.actorUserId,group_id:n||null})).node}async disableMembership(e,t,n){await this.post(`/clusters/${e}/nodes/${t}/membership/disable`,{actor_user_id:this.actorUserId,reason:n})}async attachExistingNode(e,t,n){return(await this.post(`/clusters/${e}/nodes/${t}/membership/attach`,{actor_user_id:this.actorUserId,roles:n})).node}async revokeNodeIdentity(e,t,n){await this.post(`/clusters/${e}/nodes/${t}/identity/revoke`,{actor_user_id:this.actorUserId,reason:n})}async deleteClusterNode(e,t,n){await this.delete(`/clusters/${e}/nodes/${t}`,{actor_user_id:this.actorUserId,reason:n})}async listJoinRequests(e){return(await this.get(`/clusters/${e}/join-requests`)).join_requests??[]}async createJoinToken(e,t){let n=new Date(Date.now()+Math.max(t.ttlHours,1)*60*60*1e3).toISOString();return(await this.post(`/clusters/${e}/join-tokens`,{actor_user_id:this.actorUserId,scope:t.scope,expires_at:n,max_uses:Math.max(t.maxUses,1)})).join_token}async listJoinTokens(e){return(await this.get(`/clusters/${e}/join-tokens`)).join_tokens??[]}async revokeJoinToken(e,t){return(await this.post(`/clusters/${e}/join-tokens/${t}/revoke`,{actor_user_id:this.actorUserId})).join_token}async approveJoinRequest(e,t){await this.post(`/clusters/${e}/join-requests/${t}/approve`,{actor_user_id:this.actorUserId,ownership_type:`platform_managed`})}async rejectJoinRequest(e,t,n){await this.post(`/clusters/${e}/join-requests/${t}/reject`,{actor_user_id:this.actorUserId,reason:n})}async listNodeRoles(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/roles`)).role_assignments??[]}async assignRole(e,t,n,r){await this.setRoleStatus(e,t,n,`active`,r)}async setRoleStatus(e,t,n,r,i){await this.post(`/clusters/${e}/nodes/${t}/roles`,{actor_user_id:this.actorUserId,organization_id:i||null,role:n,status:r,policy:{}})}async listWorkloadStatuses(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/workloads/status`)).workload_statuses??[]}async listDesiredWorkloads(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/workloads/desired`)).desired_workloads??[]}async listNodeHeartbeats(e,t,n=100){return(await this.get(`/clusters/${e}/nodes/${t}/heartbeats?limit=${n}`)).heartbeats??[]}async listNodeTelemetry(e,t,n=120){return(await this.get(`/clusters/${e}/nodes/${t}/telemetry?limit=${n}`)).telemetry??[]}async listReleaseVersions(e,t=`rap-node-agent`,n=`dev`){let r=new URLSearchParams({product:t,channel:n});return(await this.get(`/clusters/${e}/updates/releases?${r.toString()}`)).release_versions??[]}async getNodeUpdatePlan(e,t,n){let r=new URLSearchParams({product:n.product||`rap-node-agent`,current_version:n.currentVersion||``,os:n.os||`linux`,arch:n.arch||`amd64`,install_type:n.installType||`docker`,channel:n.channel||`dev`});return(await this.get(`/clusters/${e}/nodes/${t}/updates/plan?${r.toString()}`)).node_update_plan}async upsertNodeUpdatePolicy(e,t,n){return(await this.put(`/clusters/${e}/nodes/${t}/updates/policy`,{actor_user_id:this.actorUserId,product:n.product,channel:n.channel||`dev`,target_version:n.targetVersion??null,strategy:n.strategy||`rolling`,enabled:n.enabled??!0,rollback_allowed:n.rollbackAllowed??!0,health_window_seconds:n.healthWindowSeconds||180})).node_update_policy}async listNodeUpdateStatuses(e,t,n=80){let r=new URLSearchParams({actor_user_id:this.actorUserId,limit:String(n)});return(await this.get(`/clusters/${e}/nodes/${t}/updates/statuses?${r.toString()}`)).node_update_statuses??[]}async listFabricTestingFlags(){return(await this.get(`/fabric/testing-flags`)).testing_flags??[]}async updateFabricTestingFlag(e){return(await this.put(`/fabric/testing-flags`,{actor_user_id:this.actorUserId,scope_type:e.scopeType,scope_id:e.scopeId||null,cluster_id:e.clusterId||null,enabled:e.enabled,telemetry_enabled:e.telemetryEnabled,synthetic_links_enabled:e.syntheticLinksEnabled,history_retention_hours:e.historyRetentionHours,metadata:e.metadata||{}})).testing_flag}async setDesiredWorkload(e,t,n,r){await this.put(`/clusters/${e}/nodes/${t}/workloads/${n}/desired`,{actor_user_id:this.actorUserId,desired_state:r.desiredState,version:r.version||null,runtime_mode:r.runtimeMode,artifact_ref:null,config:r.config,environment:r.environment})}async listMeshLinks(e){return(await this.get(`/clusters/${e}/mesh/links`)).mesh_links??[]}async getNodeSyntheticMeshConfig(e,t){return(await this.get(`/clusters/${e}/nodes/${t}/mesh/synthetic-config`)).synthetic_mesh_config}async listQoSPolicies(e){return(await this.get(`/clusters/${e}/mesh/qos-policies`)).qos_policies??[]}async listFabricEntryPoints(e){return(await this.get(`/clusters/${e}/fabric/entry-points`)).entry_points??[]}async createFabricEntryPoint(e,t){return(await this.post(`/clusters/${e}/fabric/entry-points`,{actor_user_id:this.actorUserId,name:t.name,status:`active`,endpoint_type:t.endpointType||`client_access`,public_endpoint:t.publicEndpoint||null,policy:t.policy||{},metadata:t.metadata||{}})).entry_point}async listFabricEntryPointNodes(e,t){return(await this.get(`/clusters/${e}/fabric/entry-points/${t}/nodes`)).entry_point_nodes??[]}async setFabricEntryPointNode(e,t,n,r={}){return(await this.put(`/clusters/${e}/fabric/entry-points/${t}/nodes/${n}`,{actor_user_id:this.actorUserId,status:r.status||`active`,priority:r.priority||100,metadata:r.metadata||{}})).entry_point_node}async listFabricEgressPools(e){return(await this.get(`/clusters/${e}/fabric/egress-pools`)).egress_pools??[]}async createFabricEgressPool(e,t){return(await this.post(`/clusters/${e}/fabric/egress-pools`,{actor_user_id:this.actorUserId,name:t.name,status:`active`,description:t.description||null,route_scope:t.routeScope||{},policy:t.policy||{},metadata:t.metadata||{}})).egress_pool}async listFabricEgressPoolNodes(e,t){return(await this.get(`/clusters/${e}/fabric/egress-pools/${t}/nodes`)).egress_pool_nodes??[]}async setFabricEgressPoolNode(e,t,n,r={}){return(await this.put(`/clusters/${e}/fabric/egress-pools/${t}/nodes/${n}`,{actor_user_id:this.actorUserId,status:r.status||`active`,priority:r.priority||100,metadata:r.metadata||{}})).egress_pool_node}async listVPNConnections(e){return(await this.get(`/clusters/${e}/vpn-connections`)).vpn_connections??[]}async createVPNConnection(e,t){return(await this.post(`/clusters/${e}/vpn-connections`,{actor_user_id:this.actorUserId,organization_id:t.organizationId,name:t.name,target_endpoint:t.targetEndpoint,protocol_family:t.protocolFamily,credential_ref:t.credentialRef||null,mode:`single_active`,desired_state:t.desiredState,allowed_node_policy:t.allowedNodePolicy,routing_usage:t.routingUsage,route_policy:t.routePolicy,qos_policy:t.qosPolicy,placement_policy:t.placementPolicy,metadata:{}})).vpn_connection}async updateVPNConnectionDesiredState(e,t,n){return(await this.put(`/clusters/${e}/vpn-connections/${t}/desired-state`,{actor_user_id:this.actorUserId,desired_state:n})).vpn_connection}async getActiveVPNLease(e,t){try{return(await this.get(`/clusters/${e}/vpn-connections/${t}/leases/active`)).lease}catch{return null}}async getVPNPacketStats(e,t){return(await this.get(`/clusters/${e}/vpn-connections/${t}/tunnel/stats`)).vpn_packet_stats??{}}async getVPNClientDiagnosticStatus(e,t){if(!t.trim())return null;try{return(await this.get(`/clusters/${e}/vpn/client-diagnostics/${encodeURIComponent(t.trim())}/status`)).vpn_client_diagnostic_status??null}catch{return null}}async listVPNClientDiagnosticStatuses(e){return(await this.get(`/clusters/${e}/vpn/client-diagnostics`)).vpn_client_diagnostic_statuses??[]}async enqueueVPNClientDiagnosticCommand(e,t,n){return(await this.post(`/clusters/${e}/vpn/client-diagnostics/${encodeURIComponent(t.trim())}/commands`,n)).vpn_client_diagnostic_command}async expireStaleVPNLeases(e){return(await this.post(`/clusters/${e}/vpn-connection-leases/expire-stale`,{actor_user_id:this.actorUserId})).expired_leases??[]}async listAudit(e){return(await this.get(`/clusters/${e}/audit?limit=100`)).audit_events??[]}clusterEventsURL(e){return`${this.baseUrl}/clusters/${encodeURIComponent(e)}/events?actor_user_id=${encodeURIComponent(this.actorUserId)}`}async getOrganizationAdminSummary(e){return(await this.get(`/organizations/${e}/admin-summary`)).admin_summary}async listOrganizations(){return(await this.request(`/organizations?user_id=${encodeURIComponent(this.actorUserId)}`,{method:`GET`})).organizations??[]}async createOrganization(e){return(await this.post(`/organizations/`,{actor_user_id:this.actorUserId,slug:e.slug,name:e.name,metadata:e.metadata||{}})).organization}async listUsers(){return(await this.get(`/users/`)).users??[]}async createUser(e){return(await this.post(`/users/`,{actor_user_id:this.actorUserId,email:e.email,password:e.password,platform_role:e.platformRole||`user`})).user}async listOrganizationMemberships(e){return(await this.request(`/organizations/${e}/memberships?user_id=${encodeURIComponent(this.actorUserId)}`,{method:`GET`})).memberships??[]}async addOrganizationMembership(e,t){return(await this.post(`/organizations/${e}/memberships`,{actor_user_id:this.actorUserId,user_id:t.userId,role_id:t.roleId})).membership}async listResources(e){let t=new URLSearchParams({user_id:this.actorUserId});return e&&t.set(`organization_id`,e),(await this.request(`/resources?${t.toString()}`,{method:`GET`})).resources??[]}async createResource(e){return(await this.post(`/resources/`,{actor_user_id:this.actorUserId,organization_id:e.organizationId,name:e.name,address:e.address,protocol:e.protocol||`rdp`,secret_ref:e.secretRef||null,certificate_verification_mode:e.certificateVerificationMode||`strict`,render_quality_profile:e.renderQualityProfile||`balanced`,clipboard_mode:e.clipboardMode||`disabled`,file_transfer_mode:e.fileTransferMode||`disabled`,metadata:e.metadata||{}})).resource}async upsertResourceSecret(e,t){await this.put(`/resources/${e}/secret`,{actor_user_id:this.actorUserId,payload:{username:t.username||``,password:t.password||``,domain:t.domain||``},metadata:{source:`web-admin`}})}async get(e){let t=e.includes(`?`)?`&`:`?`;return this.request(`${e}${t}actor_user_id=${encodeURIComponent(this.actorUserId)}`,{method:`GET`})}async post(e,t){return this.request(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})}async put(e,t){return this.request(e,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})}async delete(e,t){return this.request(e,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})}async request(e,t){let n=await fetch(`${this.baseUrl}${e}`,t);if(!n.ok){let e=`Запрос завершился ошибкой HTTP ${n.status}`;try{let t=await n.json();e=t.error?.fallback_message||t.error?.code||e}catch{}throw Error(e)}return await n.json()}};function b(){let e=`rap.webAdmin.deviceFingerprint`,t=localStorage.getItem(e);if(t)return t;let n=`web-admin-${x()}`;return localStorage.setItem(e,n),n}function x(){if(typeof globalThis.crypto?.randomUUID==`function`)return globalThis.crypto.randomUUID();if(typeof globalThis.crypto?.getRandomValues==`function`){let e=new Uint8Array(16);globalThis.crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}var S=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),C=o(((e,t)=>{t.exports=S()}))(),w={baseUrl:`rap.webAdmin.baseUrl`,actorUserId:`rap.webAdmin.actorUserId`,auth:`rap.webAdmin.auth`,language:`rap.webAdmin.language`,vpnDiagnosticDeviceId:`rap.webAdmin.vpnDiagnosticDeviceId`},ee=`/api/v1`,te=`http://192.168.200.61:8080/api/v1`,ne=[`entry-node`,`relay-node`,`core-mesh`,`rdp-worker`,`vnc-worker`,`vpn-exit`,`vpn-connector`,`file-storage-cache`,`update-cache`,`video-relay`],T={"entry-node":`Entry node`,"relay-node":`Relay node`,"core-mesh":`Mesh core`,"rdp-worker":`RDP worker`,"vnc-worker":`VNC worker`,"vpn-exit":`VPN exit`,"vpn-connector":`VPN connector`,"file-storage-cache":`File/cache storage`,"update-cache":`Update cache`,"video-relay":`Video relay`},re={"entry-node":[`can_accept_client_ingress`],"relay-node":[`mesh_rendezvous_relay_control_contract`,`mesh_peer_connection_manager`],"core-mesh":[`native_node_agent`,`mesh_peer_connection_manager`,`mesh_listener_diagnostics`],"rdp-worker":[`can_run_rdp_worker`],"vnc-worker":[`can_run_vnc_worker`],"vpn-exit":[`can_run_vpn_exit`],"vpn-connector":[`can_run_vpn_connector`],"file-storage-cache":[`can_run_file_cache`],"update-cache":[`can_run_update_cache`],"video-relay":[`can_run_video_relay`]},ie=[{id:`command`,ru:`Обзор`,en:`Command`},{id:`clusters`,ru:`Кластеры`,en:`Clusters`},{id:`cluster-settings`,ru:`Настройки кластера`,en:`Cluster Settings`},{id:`nodes`,ru:`Узлы`,en:`Nodes`},{id:`enrollment`,ru:`Новый узел`,en:`New Node`},{id:`roles`,ru:`Роли`,en:`Roles`},{id:`workloads`,ru:`Сервисы`,en:`Workloads`},{id:`fabric`,ru:`Связи Fabric`,en:`Fabric Links`},{id:`vpn`,ru:`VPN Control`,en:`VPN Control`},{id:`servers`,ru:`Серверы`,en:`Servers`},{id:`org-safe`,ru:`Организации`,en:`Organizations`},{id:`audit`,ru:`Аудит`,en:`Audit`}];function E(e){if(!e||typeof e!=`object`)return null;let t=e;return typeof t.userId!=`string`||typeof t.email!=`string`||typeof t.authSessionId!=`string`||typeof t.accessToken!=`string`||typeof t.refreshToken!=`string`||typeof t.accessTokenExpiresAt!=`string`||typeof t.refreshTokenExpiresAt!=`string`||!t.userId||!t.refreshToken?null:{userId:t.userId,email:t.email,authSessionId:t.authSessionId,accessToken:t.accessToken,refreshToken:t.refreshToken,accessTokenExpiresAt:t.accessTokenExpiresAt,refreshTokenExpiresAt:t.refreshTokenExpiresAt}}function ae(e){let t=Date.parse(e);return!Number.isFinite(t)||t<=Date.now()}function oe(){try{let e=localStorage.getItem(w.auth);if(!e)return null;let t=E(JSON.parse(e));return!t||ae(t.refreshTokenExpiresAt)?null:t}catch{return null}}var se={ttlHours:24,maxUses:1,roles:[`core-mesh`],nodeName:``,nodeGroupId:``,ownershipType:`platform_managed`,purpose:``,installMode:`docker`,dockerImage:`rap-node-agent:dev-enrollment-bootstrap-smoke`,dockerContainerName:``,dockerNetwork:`host`,windowsStartupMode:`auto`,windowsInstallDir:``,windowsNodeAgentSHA256:``,linuxInstallDir:``,linuxNodeAgentSHA256:``,meshListenAddr:`:19131`,meshListenPortMode:`auto`,meshListenAutoPortStart:19131,meshListenAutoPortEnd:19231,meshAdvertiseEndpoint:``,meshAdvertiseTransport:`direct_http`,meshConnectivityMode:`private_lan`,meshNATType:`none`,meshRegion:`docker-test`,controlPlaneEndpoint:``,artifactEndpoints:``,dockerImageArtifactSHA256:``,pullImage:!1,replace:!0,syntheticRuntime:!0},ce={ru:{productOwner:`Владелец продукта`,controlPlane:`Панель управления`,sideText:`Главная панель владельца платформы для кластеров, узлов, доверия, ролей и безопасного desired state.`,signInTitle:`Вход`,signInText:`Введите учетные данные.`,bootstrapTitle:`Первый владелец`,bootstrapText:`Пустая установка принимает только подписанную активацию продукта.`,activationPayload:`Activation manifest JSON`,activationSignature:`Подпись manifest`,createOwner:`Создать владельца`,creatingOwner:`Создание...`,ownerCreated:`Владелец создан. Теперь можно войти.`,installationLocked:`Установка уже активирована`,insecureBootstrapDisabled:`Insecure bootstrap выключен. Нужна strict-активация с ключом продукта.`,email:`Логин`,password:`Пароль`,backendApi:`Backend API`,useLocalProxy:`Использовать локальный /api/v1 proxy`,language:`Язык`,deviceLabel:`Устройство`,rememberMe:`Запомнить меня`,trustDevice:`Доверять этому устройству`,signIn:`Войти`,signingIn:`Вход...`,logout:`Выйти`,profile:`Профиль`,refresh:`Обновить`,refreshing:`Обновление...`,autoRefresh:`Автообновление`,lastRefresh:`Данные обновлены`,activeCluster:`Активный кластер`,slugLabel:`Технический код`,slugHelp:`Slug — постоянный короткий технический идентификатор кластера для URL, скриптов, логов и интеграций. Его лучше не менять после создания.`,clusterCatalog:`Каталог кластеров`,clusterCatalogText:`Список реальных кластеров из Control Plane. Выберите активный кластер или раскройте карточку для подробностей.`,makeActive:`Сделать активным`,openSettings:`Открыть настройки`,selected:`Выбран`,createCluster:`Создать кластер`,clusterDetails:`Подробнее`,consoleTitle:`Панель владельца платформы`,boundary:`WEB является только представлением. Решения кластера проходят через Control Plane API, PostgreSQL как source of truth и аудит.`,noLoginError:`Войдите как владелец продукта или администратор платформы, чтобы загрузить панель.`,accessDenied:`Доступ к этой панели запрещен.`,sessionMode:`Режим сессии`,sessionModeAdmin:`Админ`,sessionModeUser:`Пользователь`,sessionRefreshedAt:`Сессия обновлена`,emptyLiveTitle:`Кластер пока пустой`,emptyLiveText:`Это реальные данные, не заглушка: в выбранном кластере ещё нет одобренных node-agent узлов. Создайте join token, запустите rap-node-agent и подтвердите join request.`,realDataNote:`Показываются только данные из PostgreSQL/Control Plane. Если значения нулевые, значит соответствующих узлов, ролей или сервисов пока нет.`,signedInAs:`Вход выполнен`,actorUser:`Actor user`,testMode:`Тестирование`,testModeText:`Включает тестовую телеметрию и синтетические наблюдения связей. Это не production mesh runtime.`,platformTestFlag:`Тестирование сервера`,nodeTelemetry:`Телеметрия узла`,heartbeatHistory:`История heartbeat`,noTelemetry:`Телеметрии пока нет`,enableTelemetry:`Включить телеметрию`,enableSyntheticLinks:`Включить тестовые связи`,saveTestFlag:`Сохранить флаг`,nodeManagement:`Управление узлом`,nodeScope:`Область просмотра`,currentClusterNodes:`Узлы активного кластера`,allNodes:`Все узлы платформы`,showAllPlatformNodes:`Показать все узлы платформы`,currentClusterMembership:`Участие в активном кластере`,clusterMemberships:`Участие по кластерам`,notMemberOfActiveCluster:`не состоит`,nodeIdentity:`Физическая идентичность узла`,activeClusterScope:`Область активного кластера`,activeClusterScopeText:`Один физический узел может состоять в нескольких кластерах. Роли и desired-сервисы ниже относятся только к выбранному активному кластеру.`,capabilityConfirmed:`способность подтверждена heartbeat`,capabilityMissing:`способность не заявлена узлом`,capabilityUnknown:`способность не подтверждена: нет heartbeat`,nodeGlobalInventoryText:`Один физический узел показан один раз. Участие и роли остаются кластерными: в разных кластерах этот же узел может иметь разные назначения.`,nodeSearch:`Поиск узлов`,groupNodesBy:`Группировать`,groupByMembership:`по участию`,groupByHealth:`по здоровью`,groupByOwnership:`по владению`,groupByClusterCount:`по числу кластеров`,nodeGroups:`Группы узлов`,nodeGroupTree:`Дерево групп`,nodeGroupFilter:`Фильтр по группе`,allNodeGroups:`Все группы`,nodeGroupCreatePanel:`Создание группы`,nodeGroupName:`Название группы`,parentNodeGroup:`Родительская группа`,rootNodeGroup:`Корень`,ungroupedNodes:`Без группы`,createNodeGroup:`Создать группу`,createSubgroup:`Создать подгруппу`,collapseGroup:`Свернуть`,expandGroup:`Развернуть`,assignNodeGroup:`Переместить в группу`,removeFromNodeGroup:`Убрать из группы`,connectExistingNode:`Подключить к активному кластеру`,connectExistingNodeTitle:`Подключить существующий узел`,connectExistingNodeText:`Будет создано или повторно включено участие конкретного физического узла в активном кластере. Роли ниже назначаются только в этом кластере.`,connectWithRoles:`Подключить с ролями`,nodeDetails:`Сведения`,manageNode:`Настроить`,nodeFunctions:`Функции узла`,nodeFunctionsText:`Одна строка управляет функцией целиком: роль задает разрешение в активном кластере, desired-сервис задает запуск, observed показывает факт от node-agent.`,rolePermission:`Разрешение`,permissionGranted:`разрешено`,permissionDenied:`нет разрешения`,organizationScopeForEnable:`Область организации для новых включений, опционально`,clusterWideRolePlaceholder:`пусто = роль на весь кластер`,desiredRuntime:`Желаемое состояние`,observedRuntime:`Фактически`,enableFunction:`Включить функцию`,disableFunction:`Выключить функцию`,close:`Закрыть`,nodeBriefList:`Краткий список узлов`,noActiveClusterMembership:`Узел не входит в активный кластер`,nodeBriefListHelp:`Список сгруппирован деревом активного кластера. Полные сведения, управление, роли, сервисы и статистика открываются из строки узла.`,nodeSearchPlaceholder:`имя, ключ, кластер, статус`,nodeGroupInventoryText:`Группы — это кластерная инвентарная структура. Перенос узла в группу меняет только его размещение внутри активного кластера, не роли и не членство.`,nodeGroupCreated:`Группа узлов создана.`,noNodesTitle:`Нет узлов`,noNodesByFilter:`По текущему фильтру узлы не найдены.`,cancel:`Отмена`,alreadyMember:`Уже в активном кластере`,revokedMembership:`Участие отозвано`,addNode:`Подключить узел`,addNodeText:`Подключение существующего физического узла к активному кластеру выполняется из списка узлов: включите общий режим и нажмите «Подключить к активному кластеру».`,joinTokenTitle:`Создать новый Docker-узел`,joinTokenText:`Сначала создается одноразовый install token и Docker install profile. Затем команда запускается на Docker-хосте, агент отправляет заявку, а владелец платформы подтверждает ее.`,ttlHours:`Срок действия, часов`,ttlHelp:`Через это время token станет недействительным, даже если им никто не воспользовался. Для ручного подключения обычно достаточно 1–24 часов.`,maxUses:`Максимум использований`,maxUsesHelp:`Сколько node-agent смогут использовать этот token. Самый безопасный вариант — 1 token на 1 новый узел.`,tokenPurpose:`Назначение token`,nodeOwnership:`Тип владения узлом`,suggestedRoles:`Разрешенные/ожидаемые роли`,generatedScope:`Сгенерированная область действия`,generatedScopeHelp:`JSON формируется автоматически из настроек выше. Оператор не должен писать его руками, чтобы не ошибиться синтаксисом или областью доступа.`,manualApprovalRequired:`Подтверждение заявки вручную обязательно`,nodeRoles:`Роли узла`,desiredServices:`Желаемые сервисы`,observedServices:`Наблюдаемые сервисы`,noRoles:`Ролей пока нет`,noServices:`Сервисов пока нет`,manageInCluster:`Управлять в кластере`,rolesAndServices:`Роли и сервисы`,links:`Связи`,fabricMap:`Карта трафика Fabric`,fabricIngressLayer:`Входы`,fabricNodeLayer:`Узлы кластера`,fabricEgressLayer:`Выходные зоны`,observedPeerLinks:`Наблюдаемые связи`,placementIntent:`control-plane назначение`,fabricEntryPoints:`Точки входа`,fabricEntryPointHelp:`Логические внешние входы в кластер. Они скрывают конкретные узлы от организаций и клиентов.`,fabricEgressPools:`Выходные зоны`,fabricEgressPoolHelp:`Логические выходы к внешним сетям, например “Офис Москва”. Организации используют зону, а не конкретный узел.`,endpointName:`Название`,publicEndpoint:`Публичный адрес`,endpointType:`Тип входа`,description:`Описание`,routeScope:`Область маршрутов JSON`,createEntryPoint:`Создать точку входа`,createEgressPool:`Создать выходную зону`,endpointNodes:`Назначенные узлы`,assignEndpointNode:`Назначить узел`,selectNode:`Выберите узел`,assignedNodesEmpty:`Узлы пока не назначены`,entryPointsEmpty:`Точки входа пока не созданы.`,egressPoolsEmpty:`Выходные зоны пока не созданы.`,addressNotSet:`адрес не задан`,descriptionNotSet:`описание не задано`,servicePlacement:`Размещение сервисов`,trafficFlow:`Потоки между узлами`,organizationTestFlag:`Тестирование организации`,organizationId:`ID организации`,saveOrganizationFlag:`Сохранить флаг организации`,noLinks:`Связей пока нет`,recentHeartbeats:`Последние heartbeat`,memory:`Память`,cpu:`Процессор`,processes:`Процессы`},en:{productOwner:`Product Owner`,controlPlane:`Control Plane`,sideText:`Full platform-owner panel for clusters, nodes, trust, placement, and safe service desired state.`,signInTitle:`Sign in`,signInText:`Enter your credentials.`,bootstrapTitle:`First owner`,bootstrapText:`An empty installation accepts only a signed product activation.`,activationPayload:`Activation manifest JSON`,activationSignature:`Manifest signature`,createOwner:`Create owner`,creatingOwner:`Creating...`,ownerCreated:`Owner created. You can sign in now.`,installationLocked:`Installation is already active`,insecureBootstrapDisabled:`Insecure bootstrap is disabled. Strict product-key activation is required.`,email:`Login`,password:`Password`,backendApi:`Backend API`,useLocalProxy:`Use local /api/v1 proxy`,language:`Language`,deviceLabel:`Device`,rememberMe:`Remember me`,trustDevice:`Trust this device`,signIn:`Sign in`,signingIn:`Signing in...`,logout:`Logout`,profile:`Profile`,refresh:`Refresh`,refreshing:`Refreshing...`,autoRefresh:`Auto refresh`,lastRefresh:`Data refreshed`,activeCluster:`Active cluster`,slugLabel:`Technical code`,slugHelp:`Slug is a stable short technical identifier for URLs, scripts, logs, and integrations. It should generally not change after creation.`,clusterCatalog:`Cluster catalog`,clusterCatalogText:`Real clusters from the Control Plane. Select the active cluster or expand a card for details.`,makeActive:`Make active`,openSettings:`Open settings`,selected:`Selected`,createCluster:`Create cluster`,clusterDetails:`Details`,consoleTitle:`Platform Owner Console`,boundary:`WEB is presentation only. Cluster decisions go through Control Plane APIs, PostgreSQL source of truth, and audit.`,noLoginError:`Sign in as a product owner or platform administrator to load the panel.`,accessDenied:`Access to this panel is denied.`,sessionMode:`Session mode`,sessionModeAdmin:`Admin`,sessionModeUser:`User`,sessionRefreshedAt:`Session refreshed`,emptyLiveTitle:`Cluster has no live nodes yet`,emptyLiveText:`These are real values, not placeholders: the selected cluster has no approved node-agent nodes yet. Create a join token, run rap-node-agent, and approve the join request.`,realDataNote:`Only PostgreSQL/Control Plane data is shown. Zero values mean the corresponding nodes, roles, or services do not exist yet.`,signedInAs:`Signed in`,actorUser:`Actor user`,testMode:`Testing`,testModeText:`Enables test telemetry and synthetic link observations. This is not production mesh runtime.`,platformTestFlag:`Server testing`,nodeTelemetry:`Node telemetry`,heartbeatHistory:`Heartbeat history`,noTelemetry:`No telemetry yet`,enableTelemetry:`Enable telemetry`,enableSyntheticLinks:`Enable test links`,saveTestFlag:`Save flag`,nodeManagement:`Node management`,nodeScope:`View scope`,currentClusterNodes:`Active cluster nodes`,allNodes:`All platform nodes`,showAllPlatformNodes:`Show all platform nodes`,currentClusterMembership:`Active cluster membership`,clusterMemberships:`Cluster memberships`,notMemberOfActiveCluster:`not a member`,nodeIdentity:`Physical node identity`,activeClusterScope:`Active cluster scope`,activeClusterScopeText:`One physical node may belong to multiple clusters. Roles and desired services below belong only to the selected active cluster.`,capabilityConfirmed:`capability confirmed by heartbeat`,capabilityMissing:`capability not reported by node`,capabilityUnknown:`capability unconfirmed: no heartbeat`,nodeGlobalInventoryText:`Each physical node is shown once. Membership and roles remain cluster-scoped, so the same node may have different assignments in different clusters.`,nodeSearch:`Node search`,groupNodesBy:`Group by`,groupByMembership:`membership`,groupByHealth:`health`,groupByOwnership:`ownership`,groupByClusterCount:`cluster count`,nodeGroups:`Node groups`,nodeGroupTree:`Group tree`,nodeGroupFilter:`Group filter`,allNodeGroups:`All groups`,nodeGroupCreatePanel:`Create group`,nodeGroupName:`Group name`,parentNodeGroup:`Parent group`,rootNodeGroup:`Root`,ungroupedNodes:`Ungrouped`,createNodeGroup:`Create group`,createSubgroup:`Create subgroup`,collapseGroup:`Collapse`,expandGroup:`Expand`,assignNodeGroup:`Move to group`,removeFromNodeGroup:`Remove from group`,connectExistingNode:`Connect to active cluster`,connectExistingNodeTitle:`Connect existing node`,connectExistingNodeText:`This creates or re-enables membership for one concrete physical node in the active cluster. Roles below are assigned only in this cluster.`,connectWithRoles:`Connect with roles`,nodeDetails:`Details`,manageNode:`Configure`,nodeFunctions:`Node functions`,nodeFunctionsText:`One row controls the whole function: role grants permission in the active cluster, desired service requests runtime start, observed state reports node-agent facts.`,rolePermission:`Permission`,permissionGranted:`granted`,permissionDenied:`not allowed`,organizationScopeForEnable:`Organization scope for new enables, optional`,clusterWideRolePlaceholder:`empty = cluster-wide role`,desiredRuntime:`Desired state`,observedRuntime:`Observed`,enableFunction:`Enable function`,disableFunction:`Disable function`,close:`Close`,nodeBriefList:`Compact node list`,noActiveClusterMembership:`Node is not a member of the active cluster`,nodeBriefListHelp:`The list is grouped as the active cluster tree. Full details, management, roles, services, and statistics open from the node row.`,nodeSearchPlaceholder:`name, key, cluster, status`,nodeGroupInventoryText:`Groups are a cluster inventory structure. Moving a node to a group changes only its placement inside the active cluster, not roles or membership.`,nodeGroupCreated:`Node group created.`,noNodesTitle:`No nodes`,noNodesByFilter:`No nodes match the current filter.`,cancel:`Cancel`,alreadyMember:`Already in active cluster`,revokedMembership:`Membership revoked`,addNode:`Add node`,addNodeText:`Connect an existing physical node to the active cluster from the node list: enable platform-wide view and click “Connect to active cluster”.`,joinTokenTitle:`Create new Docker node`,joinTokenText:`First create a one-time install token and Docker install profile. Then run the generated command on the Docker host; the agent submits a request and the platform owner approves it.`,ttlHours:`Lifetime, hours`,ttlHelp:`After this time the token becomes invalid even if unused. For manual enrollment, 1–24 hours is usually enough.`,maxUses:`Maximum uses`,maxUsesHelp:`How many node-agents may use this token. The safest default is one token for one new node.`,tokenPurpose:`Token purpose`,nodeOwnership:`Node ownership type`,suggestedRoles:`Allowed/expected roles`,generatedScope:`Generated scope`,generatedScopeHelp:`JSON is generated automatically from the settings above. Operators should not hand-write it and risk syntax or access-scope mistakes.`,manualApprovalRequired:`Manual request approval is required`,nodeRoles:`Node roles`,desiredServices:`Desired services`,observedServices:`Observed services`,noRoles:`No roles yet`,noServices:`No services yet`,manageInCluster:`Manage in cluster`,rolesAndServices:`Roles and services`,links:`Links`,fabricMap:`Fabric traffic map`,fabricIngressLayer:`Ingress`,fabricNodeLayer:`Cluster nodes`,fabricEgressLayer:`Egress pools`,observedPeerLinks:`Observed links`,placementIntent:`control-plane placement`,fabricEntryPoints:`Entry points`,fabricEntryPointHelp:`Logical external ingress points for the cluster. They hide concrete nodes from organizations and clients.`,fabricEgressPools:`Egress pools`,fabricEgressPoolHelp:`Logical exits to external networks, for example “Office Moscow”. Organizations use the pool, not a concrete node.`,endpointName:`Name`,publicEndpoint:`Public endpoint`,endpointType:`Entry type`,description:`Description`,routeScope:`Route scope JSON`,createEntryPoint:`Create entry point`,createEgressPool:`Create egress pool`,endpointNodes:`Assigned nodes`,assignEndpointNode:`Assign node`,selectNode:`Select node`,assignedNodesEmpty:`No nodes assigned yet`,entryPointsEmpty:`No entry points created yet.`,egressPoolsEmpty:`No egress pools created yet.`,addressNotSet:`address not set`,descriptionNotSet:`description not set`,servicePlacement:`Service placement`,trafficFlow:`Node traffic flows`,organizationTestFlag:`Organization testing`,organizationId:`Organization ID`,saveOrganizationFlag:`Save organization flag`,noLinks:`No links yet`,recentHeartbeats:`Recent heartbeats`,memory:`Memory`,cpu:`CPU`,processes:`Processes`}};function D(e){return{userId:e.user.id||e.user.ID||``,email:e.user.email||e.user.Email||``,authSessionId:e.auth_session.id||e.auth_session.ID||``,accessToken:e.tokens.access_token,refreshToken:e.tokens.refresh_token,accessTokenExpiresAt:e.tokens.access_token_expires_at,refreshTokenExpiresAt:e.tokens.refresh_token_expires_at}}async function O(e){try{return await e.listClusterSummaries(),`admin`}catch{try{return await Promise.all([e.listOrganizations(),e.listResources()]),`user`}catch{return null}}}function le(){let[e,t]=(0,_.useState)(!1),[n,r]=(0,_.useState)(()=>!!oe()),[i]=(0,_.useState)(()=>{let e=localStorage.getItem(w.baseUrl)?.trim();return!e||e.startsWith(te)?ee:e}),[a,o]=(0,_.useState)(()=>oe()),[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(()=>localStorage.getItem(w.language)===`en`?`en`:`ru`),[p,m]=(0,_.useState)(a?.userId??localStorage.getItem(w.actorUserId)??``),[h,g]=(0,_.useState)({email:``,password:``,deviceLabel:`Панель владельца платформы`,trustDevice:!0,rememberMe:!0,showPassword:!1}),[v,b]=(0,_.useState)(null),[x,S]=(0,_.useState)({email:``,password:``,activationPayload:``,activationSignature:``}),[T,re]=(0,_.useState)(`command`),[E,le]=(0,_.useState)(``),[he,_e]=(0,_.useState)([]),[xe,Se]=(0,_.useState)([]),[Ce,we]=(0,_.useState)(null),[j,Te]=(0,_.useState)([]),[Ee,De]=(0,_.useState)([]),[Oe,ke]=(0,_.useState)({}),[Fe,ze]=(0,_.useState)([]),[Be,Ve]=(0,_.useState)([]),[Ue,Ge]=(0,_.useState)([]),[Je,Ze]=(0,_.useState)({}),[Qe,$e]=(0,_.useState)({}),[tt,nt]=(0,_.useState)({}),[it,at]=(0,_.useState)({}),[ot,yt]=(0,_.useState)({}),[St,Ct]=(0,_.useState)({}),[Nt,Pt]=(0,_.useState)({}),[Ft,It]=(0,_.useState)([]),[Lt,Rt]=(0,_.useState)({}),[zt,Bt]=(0,_.useState)([]),[Vt,Ht]=(0,_.useState)([]),[Ut,Wt]=(0,_.useState)({}),[Gt,Kt]=(0,_.useState)([]),[qt,Jt]=(0,_.useState)({}),[N,Yt]=(0,_.useState)([]),[Xt,en]=(0,_.useState)([]),[tn,nn]=(0,_.useState)({}),[sn,cn]=(0,_.useState)({}),[ln,un]=(0,_.useState)(()=>localStorage.getItem(w.vpnDiagnosticDeviceId)||``),[dn,fn]=(0,_.useState)([]),[pn,mn]=(0,_.useState)(null),[gn,_n]=(0,_.useState)(`http://2ip.ru/`),[xn,Sn]=(0,_.useState)(null),[Cn,wn]=(0,_.useState)([]),[Tn,En]=(0,_.useState)([]),[Dn,On]=(0,_.useState)([]),[kn,An]=(0,_.useState)({}),[jn,Mn]=(0,_.useState)([]),[Nn,Pn]=(0,_.useState)(``),[Fn,In]=(0,_.useState)(`poll`),[Ln,Rn]=(0,_.useState)(``),[zn,Bn]=(0,_.useState)(null),[Vn,Hn]=(0,_.useState)(!1),[Un,Wn]=(0,_.useState)(``),[Gn,Kn]=(0,_.useState)(``),[qn,Jn]=(0,_.useState)({slug:``,name:``,region:``}),[Yn,Xn]=(0,_.useState)({name:``,status:`active`,region:``,metadataJson:`{}`}),[Zn,Qn]=(0,_.useState)({name:``,parentGroupId:``}),[$n,er]=(0,_.useState)({name:``,endpointType:`client_access`,publicEndpoint:``}),[tr,nr]=(0,_.useState)({name:``,description:``,routeScope:`{ "routes": [] }`}),[L,R]=(0,_.useState)(se),[rr,ir]=(0,_.useState)(null),[ar,or]=(0,_.useState)({authorityState:`authoritative`,mutationMode:`normal`,notes:``}),[sr,cr]=(0,_.useState)(``),[lr,ur]=(0,_.useState)(`cluster`),[dr,fr]=(0,_.useState)(``),[pr,mr]=(0,_.useState)(``),[hr,gr]=(0,_.useState)([]),[_r,vr]=(0,_.useState)(`membership`),[yr,br]=(0,_.useState)(null),[xr,Sr]=(0,_.useState)([]),[Cr,wr]=(0,_.useState)(null),[Tr,Er]=(0,_.useState)(`details`),[Dr,Or]=(0,_.useState)({}),[kr,Ar]=(0,_.useState)({}),[jr,Mr]=(0,_.useState)({}),[Nr,Pr]=(0,_.useState)({}),[Fr,Ir]=(0,_.useState)({}),[Lr,Rr]=(0,_.useState)({}),[zr,Br]=(0,_.useState)(``),[Vr,Hr]=(0,_.useState)({telemetry:!0,links:!0}),[Ur,Wr]=(0,_.useState)({nodeId:``,serviceType:`entry-node`,desiredState:`enabled`,runtimeMode:`container`,version:``,configJson:`{}`,environmentJson:`{}`}),[z,Gr]=(0,_.useState)({organizationId:``,name:``,protocolFamily:`generic`,desiredState:`disabled`,credentialRef:``,targetEndpointJson:`{}`,allowedNodePolicyJson:`{"mode":"explicit","node_ids":[]}`,routingUsageJson:`[]`,routePolicyJson:`{}`,qosPolicyJson:`{}`,placementPolicyJson:`{}`}),[Kr,qr]=(0,_.useState)({slug:``,name:``}),[Jr,Yr]=(0,_.useState)({email:``,password:``,platformRole:`user`}),[Xr,Zr]=(0,_.useState)({organizationId:``,userId:``,roleId:`org_member`}),[Qr,$r]=(0,_.useState)(null),[ei,ti]=(0,_.useState)({username:``,password:``,domain:``}),[B,ni]=(0,_.useState)({organizationId:``,name:``,address:``,protocol:`rdp`,routeMode:`vpn_exit`,entryNode:``,exitNode:``,tags:``,username:``,password:``,domain:``}),[ri,ii]=(0,_.useState)(``),[ai,oi]=(0,_.useState)(``),[si,ci]=(0,_.useState)(``),li=`rap-android-rdp-vpn-latest-release.apk`,[ui,di]=(0,_.useState)(li),V=(0,_.useMemo)(()=>new y({baseUrl:i,actorUserId:p}),[i,p]),fi=(0,_.useMemo)(()=>new y({baseUrl:i,actorUserId:``}),[i]),pi=(0,_.useRef)(0),mi=(0,_.useRef)(!1),H=ce[d],U=he.find(e=>e.id===E)||null,hi=xe.find(e=>e.cluster_id===E)||null,gi=(0,_.useMemo)(()=>yn(i),[i]),_i=(0,_.useCallback)((e,t)=>{if(!e)return t;let n=e.trim();return n?/^https?:\/\//i.test(n)||n.startsWith(`/`)?n.startsWith(`/`)?n.substring(1):n:n.startsWith(`downloads/`)?n:`downloads/${n.replace(/^\.\/+/,``).replace(/^\/+/,``)}`:t},[]),vi=_i(ui,li),yi=si?_i(si,vi):vi,bi=si?yi:vi,xi=`${/^https?:\/\//i.test(bi)?bi:`${gi}/${bi}`}${ai?`?_v=${encodeURIComponent(ai)}`:``}`,Si=(0,_.useMemo)(()=>gt(L),[L]),Ci=(0,_.useMemo)(()=>rr?_t(rr.scope,L):L,[rr,L]),wi=(0,_.useMemo)(()=>{let e=new Map;for(let t of he)for(let n of Oe[t.id]||[]){let r=e.get(n.id);r?(r.memberships.push({cluster:t,node:n}),(n.last_seen_at||``)>(r.node.last_seen_at||``)&&(r.node=n)):e.set(n.id,{node:n,memberships:[{cluster:t,node:n}]})}return Array.from(e.values()).sort((e,t)=>e.node.name.localeCompare(t.node.name))},[Oe,he]);(0,_.useMemo)(()=>Qt(wi,E,dr,_r,d),[wi,_r,dr,d,E]);let Ti=(0,_.useMemo)(()=>{let e=dr.trim().toLowerCase(),t=pr?new Set([pr,...pt(pr,Ee)]):null;return wi.filter(n=>{let r=n.memberships.some(e=>e.cluster.id===E);if(lr!==`all`&&!r)return!1;if(t){let e=n.memberships.find(e=>e.cluster.id===E);if(!e?.node.node_group_id||!t.has(e.node.node_group_id))return!1}return!e||$t(n,e)})},[wi,dr,pr,Ee,lr,E]),Ei=(0,_.useCallback)((e,t=!1)=>{if(e&&t){localStorage.setItem(w.auth,JSON.stringify(e)),localStorage.setItem(w.actorUserId,e.userId),r(!0);return}r(!1),localStorage.removeItem(w.auth),localStorage.removeItem(w.actorUserId)},[]),Di=(0,_.useCallback)(async()=>{try{let e=`${gi}/downloads/rap-android-rdp-vpn-build.json?_cb=${Date.now()}`,t=await fetch(e,{cache:`no-store`});if(!t.ok){ii(``),oi(new Date().toISOString()),ci(``),di(li);return}let n=await t.json();ii(n.version?.name||``),oi(n.published?.timestamp_utc||``),ci(n.release_paths?.versioned||``),di(n.published?.path||n.release_paths?.latest||li)}catch{ii(``),oi(new Date().toISOString()),ci(``),di(li)}},[gi]),Oi=(0,_.useMemo)(()=>mt(Ti,Ee,E,H,new Set(hr)),[hr,Ee,E,H,Ti]);(0,_.useEffect)(()=>{if(e)return;t(!0);let n=oe();if(n){if(ae(n.refreshTokenExpiresAt)){localStorage.removeItem(w.auth),localStorage.removeItem(w.actorUserId),r(!1);return}(async()=>{try{let e=D(await fi.refresh({refreshToken:n.refreshToken}));if(!e.userId||!e.authSessionId)throw Error(`Не удалось восстановить сессию.`);let t=await O(new y({baseUrl:i,actorUserId:e.userId}));if(!t)throw Error(`Доступ к этой панели запрещен.`);m(e.userId),Ei(e,!0),o(e),u(new Date().toISOString()),g(t=>({...t,email:e.email})),c(t)}catch{localStorage.removeItem(w.auth),localStorage.removeItem(w.actorUserId),r(!1),u(``),o(null),m(``),c(null)}})()}},[fi,e,i,Ei]),(0,_.useEffect)(()=>{let e=!1;return fi.getInstallationStatus().then(t=>{e||b(t)}).catch(t=>{e||Wn(t instanceof Error?t.message:`Не удалось загрузить статус установки.`)}),()=>{e=!0}},[fi]),(0,_.useEffect)(()=>{if(!U){Xn({name:``,status:`active`,region:``,metadataJson:`{}`});return}Xn({name:U.name,status:U.status||`active`,region:U.region||``,metadataJson:JSON.stringify(U.metadata||{},null,2)})},[U]),(0,_.useEffect)(()=>{mr(``),Qn({name:``,parentGroupId:``}),gr([])},[E]),(0,_.useEffect)(()=>{br(null),Sr([])},[E]),(0,_.useEffect)(()=>{localStorage.setItem(w.baseUrl,i),localStorage.setItem(w.language,d),a&&localStorage.setItem(`${w.language}.${a.userId}`,d),(!a||!n)&&(localStorage.removeItem(w.auth),localStorage.removeItem(w.actorUserId))},[i,d,n,a]),(0,_.useEffect)(()=>{if(!a)return;let e=localStorage.getItem(`${w.language}.${a.userId}`);(e===`ru`||e===`en`)&&f(e)},[a?.userId]),(0,_.useEffect)(()=>{a&&W()},[a?.userId]),(0,_.useEffect)(()=>{if(!a||s!==`admin`||!E)return;let e=!1,t=()=>{e||Vn||mi.current||document.visibilityState===`hidden`||(mi.current=!0,ki(E).catch(t=>{e||Wn(t instanceof Error?t.message:`Не удалось автообновить данные панели.`)}).finally(()=>{mi.current=!1}))},n=null;typeof window.EventSource==`function`&&(n=new EventSource(V.clusterEventsURL(E)),n.onopen=()=>{e||In(`sse`)},n.onerror=()=>{e||In(`poll`)},n.addEventListener(`cluster.changed`,t));let r=window.setInterval(t,n?3e4:1e4);return()=>{e=!0,n?.close(),window.clearInterval(r)}},[V,s,Vn,E,a?.userId]);async function W(e=E){if(!p.trim()){Wn(H.noLoginError);return}if(s===`user`){await G();return}Hn(!0),Wn(``),Kn(``);try{let[t,n,r,i,a]=await Promise.all([V.listClusters(),V.listClusterSummaries(),V.listOrganizations(),V.listUsers(),V.listResources()]);_e(t),Se(n),wn(r),En(i),On(a),!Ln&&r[0]?.id&&Rn(r[0].id),Zr(e=>({...e,organizationId:e.organizationId||r[0]?.id||``})),ni(e=>({...e,organizationId:e.organizationId||r[0]?.id||``}));let o=await Promise.all(r.map(async e=>[e.id,await V.listOrganizationMemberships(e.id)]));An(Object.fromEntries(o));let s=await Promise.all(t.map(async e=>[e.id,await V.listNodes(e.id)]));ke(Object.fromEntries(s));let c=e||t[0]?.id||``;le(c),c&&await Ai(c),Pn(new Date().toISOString())}catch(e){Wn(e instanceof Error?e.message:`Неизвестная ошибка панели управления платформой.`)}finally{Hn(!1)}}async function G(){if(!p.trim()){Wn(`Войдите, чтобы загрузить личный кабинет.`);return}Hn(!0),Wn(``),Kn(``);try{await Di();let[e,t]=await Promise.all([V.listOrganizations(),V.listResources()]);wn(e),On(t),!Ln&&e[0]?.id&&Rn(e[0].id);let n=await Promise.all(e.map(async e=>[e.id,await V.listOrganizationMemberships(e.id)]));An(Object.fromEntries(n)),Pn(new Date().toISOString())}catch(e){Wn(e instanceof Error?e.message:`Не удалось загрузить личный кабинет.`)}finally{Hn(!1)}}async function ki(e){if(!p.trim())return;let[t,n,r,i,a]=await Promise.all([V.listClusterSummaries(),V.listNodes(e),V.listOrganizations(),V.listUsers(),V.listResources()]);Se(t),wn(r),En(i),On(a),ke(t=>({...t,[e]:n})),await Ai(e,{preserveEditableForms:!0}),Pn(new Date().toISOString())}async function Ai(e,t={}){let n=++pi.current,[r,i,a,o,s,c,l,u,d,f,p,m,h]=await Promise.all([V.listNodes(e),V.listNodeGroups(e),V.listJoinRequests(e),V.listJoinTokens(e),V.listReleaseVersions(e,`rap-node-agent`,`dev`),V.getClusterAuthority(e),V.listAudit(e),V.listMeshLinks(e),V.listQoSPolicies(e),V.listFabricEntryPoints(e),V.listFabricEgressPools(e),V.listVPNConnections(e),V.listFabricTestingFlags()]);if(n!==pi.current)return;Te(r),De(i),ze(a),Ve(o),Ge(s),we(c),t.preserveEditableForms||or({authorityState:c.authority_state,mutationMode:c.mutation_mode,notes:c.notes||``}),Mn(l),It(u),Bt(d),Ht(f),Kt(p),en(m),Yt(h);let g=await V.listVPNClientDiagnosticStatuses(e);if(n!==pi.current)return;fn(g);let _=g.find(e=>e.device_id===ln.trim())||g[0]||null;mn(_),!ln.trim()&&_&&(un(_.device_id),localStorage.setItem(w.vpnDiagnosticDeviceId,_.device_id));let[v,y]=await Promise.all([Promise.all(f.map(async t=>[t.id,await V.listFabricEntryPointNodes(e,t.id)])),Promise.all(p.map(async t=>[t.id,await V.listFabricEgressPoolNodes(e,t.id)]))]);if(n!==pi.current)return;Wt(Object.fromEntries(v)),Jt(Object.fromEntries(y));let b=await Promise.all(r.map(async t=>[t.id,await V.listNodeRoles(e,t.id)]));if(n!==pi.current)return;nt(Object.fromEntries(b));let x=await Promise.all(r.map(async t=>[t.id,await V.listDesiredWorkloads(e,t.id)]));if(n!==pi.current)return;at(Object.fromEntries(x));let S=await Promise.all(r.map(async t=>[t.id,await V.listWorkloadStatuses(e,t.id)]));if(n!==pi.current)return;yt(Object.fromEntries(S));let C=await Promise.all(r.map(async t=>[t.id,await V.listNodeHeartbeats(e,t.id,60)]));if(n!==pi.current)return;Ct(Object.fromEntries(C));let ee=await Promise.all(r.map(async t=>[t.id,await V.getNodeUpdatePlan(e,t.id,{currentVersion:t.reported_version})]));if(n!==pi.current)return;Ze(Object.fromEntries(ee));let te=await Promise.all(r.map(async t=>[t.id,await V.listNodeUpdateStatuses(e,t.id,80)]));if(n!==pi.current)return;$e(Object.fromEntries(te));let ne=await Promise.all(r.map(async t=>[t.id,await V.listNodeTelemetry(e,t.id,120)]));if(n!==pi.current)return;Pt(Object.fromEntries(ne));let T=await Promise.all(r.map(async t=>[t.id,await V.getNodeSyntheticMeshConfig(e,t.id)]));if(n!==pi.current)return;Rt(Object.fromEntries(T));let re=await Promise.all(m.map(async t=>[t.id,await V.getActiveVPNLease(e,t.id)]));if(n!==pi.current)return;nn(Object.fromEntries(re));let ie=await Promise.all(m.map(async t=>[t.id,await V.getVPNPacketStats(e,t.id)]));n===pi.current&&cn(Object.fromEntries(ie))}function ji(){Te([]),De([]),ze([]),Ve([]),Ge([]),Ze({}),we(null),nt({}),at({}),yt({}),Ct({}),$e({}),Pt({}),It([]),Rt({}),Bt([]),Ht([]),Wt({}),Kt([]),Jt({}),Yt([]),en([]),nn({}),cn({}),fn([]),mn(null),wn([]),En([]),On([]),An({}),Mn([])}async function K(e,t){Hn(!0),Wn(``),Kn(``);try{await e(),Kn(t),await W()}catch(e){Wn(e instanceof Error?e.message:`Действие не выполнено.`)}finally{Hn(!1)}}async function Mi(){if(!E){mn(null);return}let e=await V.listVPNClientDiagnosticStatuses(E);fn(e);let t=ln.trim()||e[0]?.device_id||``;t&&(localStorage.setItem(w.vpnDiagnosticDeviceId,t),un(t));let n=e.find(e=>e.device_id===t)||(t?await V.getVPNClientDiagnosticStatus(E,t):null);mn(n),Kn(n?`Диагностика VPN-клиента обновлена.`:`Диагностика VPN-клиента не найдена.`)}async function Ni(e,t){if(!E){Wn(`Выбери кластер перед отправкой команды.`);return}let n=ln.trim();if(!n){Wn(`Укажи Android device id или выбери найденный клиент.`);return}Hn(!0),Wn(``),Kn(``);try{Sn(await V.enqueueVPNClientDiagnosticCommand(E,n,e)),Kn(`${t}: команда поставлена в очередь. Клиент заберет ее через диагностический канал.`),window.setTimeout(()=>{Mi()},3500)}catch(e){Wn(e instanceof Error?e.message:`Команда VPN-клиенту не отправлена.`)}finally{Hn(!1)}}async function Pi(){Hn(!0),Wn(``),Kn(``);try{let e=D(await fi.login({email:h.email,password:h.password,deviceLabel:h.deviceLabel,trustDevice:h.trustDevice}));if(!e.userId||!e.authSessionId)throw Error(`Ответ входа не содержит пользователя или сессию.`);let t=new y({baseUrl:i,actorUserId:e.userId}),n=`admin`;try{await t.listClusterSummaries(),n=`admin`}catch{try{let[e,r]=await Promise.all([t.listOrganizations(),t.listResources()]);wn(e),On(r),e[0]?.id&&Rn(e[0].id);let i=await Promise.all(e.map(async e=>[e.id,await t.listOrganizationMemberships(e.id)]));An(Object.fromEntries(i)),n=`user`}catch{try{await fi.revokeAuthSession({userId:e.userId,authSessionId:e.authSessionId,reason:`user_portal_access_denied`})}catch{}throw Error(H.accessDenied)}}r(h.rememberMe),Ei(e,h.rememberMe),o(e),m(e.userId),g(t=>({...t,email:e.email,password:``})),u(new Date().toISOString()),c(n),Kn(`${H.signedInAs}: ${e.email}`)}catch(e){Wn(e instanceof Error?e.message:`Вход не выполнен.`)}finally{Hn(!1)}}async function Fi(){Hn(!0),Wn(``),Kn(``);try{let e;if(v?.strict_authority){if(!x.activationPayload.trim()||!x.activationSignature.trim())throw Error(H.bootstrapText);e=JSON.parse(x.activationPayload)}b((await fi.bootstrapOwner({email:x.email,password:x.password,activationPayload:e,activationSignature:x.activationSignature})).installation),g({...h,email:x.email,password:x.password}),Kn(H.ownerCreated)}catch(e){Wn(e instanceof Error?e.message:`Создание владельца не выполнено.`)}finally{Hn(!1)}}async function Ii(){let e=a;if(o(null),r(!1),u(``),Ei(null),c(null),m(``),_e([]),Se([]),ji(),ke({}),le(``),e?.userId&&e.authSessionId)try{await fi.revokeAuthSession({userId:e.userId,authSessionId:e.authSessionId,reason:`platform_owner_console_logout`})}catch{}}async function Li(e){le(e),ji(),Hn(!0),Wn(``),Kn(``);try{await Ai(e)}catch(e){Wn(e instanceof Error?e.message:`Не удалось загрузить кластер.`)}finally{Hn(!1)}}let Ri=Fe.filter(e=>e.status===`pending`).length,zi=j.filter(e=>e.health_status===`healthy`).length,Bi=j.filter(e=>e.health_status!==`healthy`||e.membership_status!==`active`).length,Vi=Object.values(tt).flat().filter(e=>e.status===`active`).length,Hi=N.find(e=>e.scope_type===`platform`&&!e.scope_id)||null;N.find(e=>e.scope_type===`organization`&&e.scope_id===zr&&(!e.cluster_id||e.cluster_id===E));let Ui=Object.values(Lt),Wi=Ui.filter(e=>e.enabled).length,Gi=Ui.reduce((e,t)=>e+t.routes.length,0),Ki=Ui.reduce((e,t)=>e+Object.keys(t.peer_endpoints||{}).length,0),qi=Ui.reduce((e,t)=>e+st(t),0),Ji=Ui.reduce((e,t)=>e+(t.peer_directory?.length??0),0),Yi=Ui.reduce((e,t)=>e+(t.recovery_seeds?.length??0),0),Xi=Ui.filter(e=>e.production_forwarding).length,Zi=v?.bootstrapped===!1,Qi=Zi&&!v?.strict_authority&&!v?.insecure_bootstrap_allowed,$i=s===`admin`?H.sessionModeAdmin:H.sessionModeUser;if(!a)return(0,C.jsxs)(`main`,{className:`loginShell`,children:[v&&(0,C.jsxs)(`section`,{className:`loginCard`,children:[(0,C.jsx)(`h1`,{children:v.bootstrapped?H.installationLocked:H.bootstrapTitle}),(0,C.jsx)(A,{label:`Authority`,value:`${v.authority_mode}/${v.authority_state}`}),(0,C.jsx)(A,{label:`Strict`,value:v.strict_authority?`enabled`:`legacy`}),v.root_fingerprint&&(0,C.jsx)(A,{label:`Root key`,value:P(v.root_fingerprint)})]}),Zi?(0,C.jsxs)(`section`,{className:`loginCard`,children:[(0,C.jsx)(`h1`,{children:H.bootstrapTitle}),(0,C.jsx)(`p`,{className:`loginHint`,children:Qi?H.insecureBootstrapDisabled:H.bootstrapText}),(0,C.jsxs)(`label`,{children:[H.email,(0,C.jsx)(`input`,{value:x.email,onChange:e=>S({...x,email:e.target.value}),autoComplete:`username`})]}),(0,C.jsxs)(`label`,{children:[H.password,(0,C.jsx)(`input`,{value:x.password,onChange:e=>S({...x,password:e.target.value}),type:`password`,autoComplete:`new-password`})]}),v?.strict_authority&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`label`,{children:[H.activationPayload,(0,C.jsx)(`textarea`,{value:x.activationPayload,onChange:e=>S({...x,activationPayload:e.target.value}),spellCheck:!1})]}),(0,C.jsxs)(`label`,{children:[H.activationSignature,(0,C.jsx)(`input`,{value:x.activationSignature,onChange:e=>S({...x,activationSignature:e.target.value}),spellCheck:!1})]})]}),Un&&(0,C.jsx)(`div`,{className:`errorPanel`,children:Un}),Gn&&(0,C.jsx)(`div`,{className:`noticePanel`,children:Gn}),(0,C.jsx)(`button`,{className:`primary wide`,onClick:()=>void Fi(),disabled:Vn||Qi||!x.email||x.password.length<12||v?.strict_authority&&(!x.activationPayload||!x.activationSignature),children:Vn?H.creatingOwner:H.createOwner})]}):(0,C.jsxs)(`section`,{className:`loginCard`,children:[(0,C.jsx)(`h1`,{children:H.signInTitle}),(0,C.jsxs)(`label`,{children:[H.email,(0,C.jsx)(`input`,{value:h.email,onChange:e=>g({...h,email:e.target.value.trim()}),autoComplete:`username`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1})]}),(0,C.jsxs)(`label`,{children:[H.password,(0,C.jsx)(`input`,{value:h.password,onChange:e=>g({...h,password:e.target.value}),type:h.showPassword?`text`:`password`,autoComplete:`current-password`,autoCapitalize:`none`,autoCorrect:`off`,spellCheck:!1,onKeyDown:e=>{e.key===`Enter`&&Pi()}})]}),(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:h.showPassword,onChange:e=>g({...h,showPassword:e.target.checked})}),`Показать пароль`]}),(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:h.trustDevice,onChange:e=>g({...h,trustDevice:e.target.checked})}),H.trustDevice]}),(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:h.rememberMe,onChange:e=>g({...h,rememberMe:e.target.checked})}),H.rememberMe]}),Un&&(0,C.jsx)(`div`,{className:`errorPanel`,children:Un}),Gn&&(0,C.jsx)(`div`,{className:`noticePanel`,children:Gn}),(0,C.jsx)(`button`,{className:`primary wide`,onClick:()=>void Pi(),disabled:Vn||!h.email||!h.password,children:Vn?H.signingIn:H.signIn})]})]});if(a&&!s)return(0,C.jsx)(`main`,{className:`loginShell`,children:(0,C.jsx)(`section`,{className:`loginCard`,children:(0,C.jsx)(`p`,{children:Vn?H.lastRefresh:`Восстанавливаем сессию...`})})});if(s===`user`){let e=Cn.find(e=>e.id===Ln)||Cn[0]||null,t=e?Dn.filter(t=>t.organization_id===e.id):Dn,n=e?(kn[e.id]||[]).find(e=>e.user_id===a.userId):null,r=t.reduce((e,t)=>(e[t.protocol]=(e[t.protocol]||0)+1,e),{});return(0,C.jsxs)(`main`,{className:`portalShell`,children:[(0,C.jsxs)(`aside`,{className:`portalRail`,children:[(0,C.jsx)(`div`,{className:`brandMark`,children:`RAP`}),(0,C.jsx)(`p`,{className:`sideKicker`,children:`Личный кабинет`}),(0,C.jsx)(`h1`,{children:`Мой доступ`}),(0,C.jsx)(`p`,{className:`sideText`,children:`Установки, доступные серверы и состояние рабочей области пользователя.`}),(0,C.jsx)(A,{label:H.sessionMode,value:`${$i} • ${l?bn(l):`н/д`}`}),(0,C.jsx)(A,{label:H.actorUser,value:a.email}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>void Ii(),disabled:Vn,children:H.logout})]}),(0,C.jsxs)(`section`,{className:`portalWorkspace`,children:[(0,C.jsxs)(`header`,{className:`portalTop`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`p`,{className:`eyebrow`,children:`Secure Access Fabric`}),(0,C.jsx)(`h2`,{children:e?.name||`Личный кабинет`}),(0,C.jsx)(`p`,{className:`muted`,children:a.email})]}),(0,C.jsxs)(`label`,{children:[`Организация`,(0,C.jsx)(`select`,{value:e?.id||``,onChange:e=>Rn(e.target.value),children:Cn.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,C.jsx)(`button`,{className:`primary`,onClick:()=>void G(),disabled:Vn,children:Vn?H.refreshing:H.refresh})]}),Un&&(0,C.jsx)(`div`,{className:`errorPanel`,children:Un}),Gn&&(0,C.jsx)(`div`,{className:`noticePanel`,children:Gn}),(0,C.jsxs)(`section`,{className:`grid three`,children:[(0,C.jsx)(ue,{label:`Организации`,value:Cn.length,tone:`steel`}),(0,C.jsx)(ue,{label:`Серверы`,value:t.length,tone:`green`}),(0,C.jsx)(ue,{label:`Установки`,value:2,tone:`amber`})]}),(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:`Установки`}),(0,C.jsx)(`p`,{className:`muted`,children:ri?`Актуальная версия Android: ${ri}`:`Скачивайте актуальные клиенты только отсюда, чтобы не ловить старую сборку.`})]}),(0,C.jsx)(`span`,{className:`status active`,children:`latest`})]}),(0,C.jsxs)(`div`,{className:`portalInstallList`,children:[(0,C.jsxs)(`a`,{className:`installTile primaryInstall`,href:xi,children:[(0,C.jsx)(`strong`,{children:`Android VPN`}),(0,C.jsx)(`span`,{children:`Последняя сборка RAP HOME VPN для телефона`}),(0,C.jsx)(`small`,{children:si||bi})]}),(0,C.jsxs)(`a`,{className:`installTile`,href:`${gi}/downloads/rap-windows-rdp-client-latest-win-x64.zip`,children:[(0,C.jsx)(`strong`,{children:`Windows RDP клиент`}),(0,C.jsx)(`span`,{children:`Клиент удаленного рабочего стола, когда нужен доступ к серверам`}),(0,C.jsx)(`small`,{children:`latest win-x64`})]})]})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Профиль`}),(0,C.jsx)(A,{label:`Пользователь`,value:a.email}),(0,C.jsx)(A,{label:`Роль в организации`,value:n?.role_id||`участник`}),(0,C.jsx)(A,{label:`Организация`,value:e?.name||`нет`}),(0,C.jsx)(A,{label:`Последнее обновление`,value:Nn?F(Nn):`нет`})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsx)(`div`,{className:`cardHead`,children:(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:`Доступные серверы`}),(0,C.jsx)(`p`,{className:`muted`,children:`Список ресурсов, которые уже разрешены пользователю через организацию.`})]})}),(0,C.jsx)(je,{columns:[`имя`,`адрес`,`протокол`,`секрет`,`передача файлов`],rows:t.map(e=>[e.name,e.address,e.protocol,e.has_secret?`настроен`:`нет`,I(e.file_transfer_mode||`disabled`)])})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Сервисы`}),(0,C.jsx)(je,{columns:[`тип`,`количество`],rows:Object.entries(r).map(([e,t])=>[e,String(t)])})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Что здесь будет дальше`}),(0,C.jsxs)(`div`,{className:`portalRoadmap`,children:[(0,C.jsx)(`span`,{children:`Устройства и доверенные входы`}),(0,C.jsx)(`span`,{children:`Активные VPN/RDP сессии`}),(0,C.jsx)(`span`,{children:`Обновление профиля VPN без ручных ключей`}),(0,C.jsx)(`span`,{children:`Самостоятельная смена пароля`})]})]})]})]})]})}return(0,C.jsxs)(`main`,{className:`consoleShell`,children:[(0,C.jsxs)(`aside`,{className:`sideRail`,children:[(0,C.jsx)(`div`,{className:`brandMark`,children:`SAF`}),(0,C.jsx)(`p`,{className:`sideKicker`,children:H.productOwner}),(0,C.jsx)(`h1`,{children:H.controlPlane}),(0,C.jsx)(`p`,{className:`sideText`,children:H.sideText}),(0,C.jsx)(`nav`,{className:`railNav`,children:ie.filter(e=>e.id!==`roles`).map(e=>(0,C.jsx)(`button`,{className:T===e.id?`active`:``,onClick:()=>re(e.id),children:e[d]},e.id))})]}),(0,C.jsxs)(`section`,{className:`workspace`,children:[(0,C.jsxs)(`header`,{className:`topBar`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`p`,{className:`eyebrow`,children:`Secure Access Fabric`}),(0,C.jsx)(`h2`,{children:U?U.name:H.consoleTitle}),(0,C.jsx)(`p`,{className:`muted`,children:H.boundary})]}),(0,C.jsxs)(`div`,{className:`clusterPicker`,children:[(0,C.jsxs)(`label`,{children:[H.activeCluster,(0,C.jsx)(`select`,{value:E,onChange:e=>void Li(e.target.value),children:he.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,C.jsxs)(`span`,{children:[H.slugLabel,`: `,U?.slug||`н/д`]})]}),(0,C.jsx)(`button`,{className:`primary`,onClick:()=>void W(),disabled:Vn,children:Vn?H.refreshing:H.refresh}),(0,C.jsxs)(`div`,{className:`refreshStatus`,children:[(0,C.jsx)(`strong`,{children:H.autoRefresh}),(0,C.jsx)(`span`,{children:Nn?`${H.lastRefresh}: ${bn(Nn)} / ${Fn.toUpperCase()}`:Fn.toUpperCase()})]}),(0,C.jsxs)(`div`,{className:`profilePanel`,children:[(0,C.jsx)(`strong`,{children:H.profile}),(0,C.jsx)(`span`,{children:a.email}),(0,C.jsxs)(`span`,{children:[H.sessionMode,`: `,$i,` | `,H.sessionRefreshedAt,`: `,l?bn(l):`н/д`]}),(0,C.jsxs)(`label`,{children:[H.language,(0,C.jsxs)(`select`,{value:d,onChange:e=>f(e.target.value),children:[(0,C.jsx)(`option`,{value:`ru`,children:`Русский`}),(0,C.jsx)(`option`,{value:`en`,children:d===`ru`?`Английский`:`English`})]})]}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>void Ii(),disabled:Vn,children:H.logout})]})]}),Un&&(0,C.jsx)(`div`,{className:`errorPanel`,children:Un}),Gn&&(0,C.jsx)(`div`,{className:`noticePanel`,children:Gn}),U&&j.length===0&&(0,C.jsxs)(`div`,{className:`noticePanel`,children:[(0,C.jsxs)(`strong`,{children:[H.emptyLiveTitle,`.`]}),` `,H.emptyLiveText]}),T===`command`&&(0,C.jsxs)(`section`,{className:`grid five`,children:[(0,C.jsx)(ue,{label:`Кластеры`,value:he.length,tone:`steel`}),(0,C.jsx)(ue,{label:`Узлы в области`,value:j.length,tone:`green`}),(0,C.jsx)(ue,{label:`Здоровые узлы`,value:zi,tone:`green`}),(0,C.jsx)(ue,{label:`Ожидают подключения`,value:Ri,tone:`amber`}),(0,C.jsx)(ue,{label:`Рискованные состояния`,value:Bi,tone:`red`}),(0,C.jsxs)(`article`,{className:`card span3`,children:[(0,C.jsx)(`h3`,{children:`Общее состояние кластеров`}),(0,C.jsx)(je,{columns:[`кластер`,`authority`,`ключ`,`режим изменений`,`узлы`,`заявки`,`роли`,`последний сигнал`],rows:xe.map(e=>[e.name,e.authority_state,P(e.cluster_key_fingerprint),e.mutation_mode,`${e.healthy_node_count}/${e.node_count}`,String(e.pending_join_count),String(e.active_role_assignment_count),F(e.last_node_seen_at)])})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsx)(`h3`,{children:`Authority выбранного кластера`}),Ce?(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Authority`,value:Ce.authority_state}),(0,C.jsx)(A,{label:`Режим изменений`,value:Ce.mutation_mode}),(0,C.jsx)(A,{label:`Терм`,value:String(Ce.term)}),(0,C.jsx)(A,{label:`Cluster key`,value:P(hi?.cluster_key_fingerprint)}),(0,C.jsx)(A,{label:`Обновлено`,value:F(Ce.updated_at)})]}):(0,C.jsx)(pe,{title:`Нет состояния authority`,text:`Выберите кластер, чтобы загрузить состояние authority.`})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsx)(`h3`,{children:`Граница платформы`}),(0,C.jsx)(`p`,{className:`muted`,children:`Эта панель предназначена для владельца продукта / владельца платформы. Панели организаций должны использовать безопасные проекции и не раскрывать mesh internals, peer cache, route cache, секреты или данные других tenants.`})]}),(0,C.jsxs)(`article`,{className:`card span3`,children:[(0,C.jsx)(`h3`,{children:`Текущие сигналы кластера`}),(0,C.jsxs)(`div`,{className:`signalStrip`,children:[(0,C.jsx)(k,{label:`Активные роли`,value:String(Vi)}),(0,C.jsx)(k,{label:`Отчеты сервисов`,value:String(Object.values(ot).filter(e=>e.length>0).length)}),(0,C.jsx)(k,{label:`Наблюдения связей`,value:String(Ft.length)}),(0,C.jsx)(k,{label:`Synthetic configs`,value:`${Wi}/${j.length}`})]})]})]}),T===`clusters`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:H.clusterCatalog}),(0,C.jsx)(`p`,{className:`muted`,children:H.clusterCatalogText})]}),(0,C.jsx)(`span`,{className:`pill`,children:hn(he.length,d)})]}),(0,C.jsxs)(`div`,{className:`clusterCatalog`,children:[he.map(e=>{let t=xe.find(t=>t.cluster_id===e.id),n=e.id===E;return(0,C.jsxs)(`article`,{className:`clusterCard ${n?`selected`:``}`,children:[(0,C.jsxs)(`div`,{className:`clusterCardMain`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`p`,{className:`eyebrow`,children:e.region||`регион не задан`}),(0,C.jsx)(`h4`,{children:e.name}),(0,C.jsxs)(`p`,{className:`muted`,children:[H.slugLabel,`: `,(0,C.jsx)(`strong`,{children:e.slug})]})]}),(0,C.jsxs)(`div`,{className:`clusterCardActions`,children:[(0,C.jsx)(de,{value:e.status}),n?(0,C.jsx)(`span`,{className:`pill good`,children:H.selected}):(0,C.jsx)(`button`,{onClick:()=>void Li(e.id),children:H.makeActive}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>{Li(e.id),re(`cluster-settings`)},children:H.openSettings})]})]}),(0,C.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,C.jsx)(k,{label:`Узлы`,value:t?`${t.healthy_node_count}/${t.node_count}`:`н/д`}),(0,C.jsx)(k,{label:`Заявки`,value:String(t?.pending_join_count??`н/д`)}),(0,C.jsx)(k,{label:`Роли`,value:String(t?.active_role_assignment_count??`н/д`)}),(0,C.jsx)(k,{label:`Последний сигнал`,value:F(t?.last_node_seen_at)})]}),(0,C.jsxs)(`details`,{children:[(0,C.jsx)(`summary`,{children:H.clusterDetails}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`ID`,value:e.id}),(0,C.jsx)(A,{label:H.slugLabel,value:e.slug}),(0,C.jsx)(A,{label:`Статус`,value:I(e.status)}),(0,C.jsx)(A,{label:`Authority`,value:t?`${t.authority_state}/${t.mutation_mode}`:`неизвестно`}),(0,C.jsx)(A,{label:`Создан`,value:F(e.created_at)}),(0,C.jsx)(A,{label:`Обновлен`,value:F(e.updated_at||e.created_at)})]})]})]},e.id)}),he.length===0&&(0,C.jsx)(pe,{title:`Кластеров нет`,text:`Создайте первый кластер, затем подключите стартовый node-agent.`})]})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:H.createCluster}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[H.slugLabel,(0,C.jsx)(`input`,{value:qn.slug,onChange:e=>Jn({...qn,slug:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Название`,(0,C.jsx)(`input`,{value:qn.name,onChange:e=>Jn({...qn,name:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Регион`,(0,C.jsx)(`input`,{value:qn.region,onChange:e=>Jn({...qn,region:e.target.value})})]})]}),(0,C.jsx)(`p`,{className:`muted`,children:H.slugHelp}),(0,C.jsx)(`button`,{className:`primary`,disabled:!qn.slug||!qn.name,onClick:()=>void K(async()=>{await V.createCluster({slug:qn.slug,name:qn.name,region:qn.region||null}),Jn({slug:``,name:``,region:``})},`Кластер создан.`),children:H.createCluster})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Что такое технический код?`}),(0,C.jsx)(`p`,{className:`muted`,children:H.slugHelp}),(0,C.jsx)(`p`,{className:`muted`,children:`Для человека основное поле — название. Для системы и операторов — технический код. Он нужен, чтобы сценарии, логи и будущие endpoint-адреса не зависели от переименования кластера.`})]})]}),T===`cluster-settings`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[!U&&(0,C.jsx)(pe,{title:`Кластер не выбран`,text:`Выберите активный кластер, чтобы открыть настройки.`}),U&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Identity кластера`}),(0,C.jsx)(`p`,{className:`muted`,children:`Базовые параметры хранятся в PostgreSQL. Slug остается неизменяемым идентификатором для операторов и скриптов.`}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`ID`,(0,C.jsx)(`input`,{value:U.id,readOnly:!0})]}),(0,C.jsxs)(`label`,{children:[`Slug`,(0,C.jsx)(`input`,{value:U.slug,readOnly:!0})]}),(0,C.jsxs)(`label`,{children:[`Название`,(0,C.jsx)(`input`,{value:Yn.name,onChange:e=>Xn({...Yn,name:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Статус`,(0,C.jsxs)(`select`,{value:Yn.status,onChange:e=>Xn({...Yn,status:e.target.value}),children:[(0,C.jsx)(`option`,{value:`active`,children:`active, работает`}),(0,C.jsx)(`option`,{value:`disabled`,children:`disabled, отключен`})]})]}),(0,C.jsxs)(`label`,{children:[`Регион`,(0,C.jsx)(`input`,{value:Yn.region,onChange:e=>Xn({...Yn,region:e.target.value}),placeholder:`например ru-msk-1`})]}),(0,C.jsxs)(`label`,{children:[`Обновлен`,(0,C.jsx)(`input`,{value:F(U.updated_at||U.created_at),readOnly:!0})]})]}),(0,C.jsxs)(`label`,{className:`wideLabel`,children:[`Metadata JSON`,(0,C.jsx)(`textarea`,{value:Yn.metadataJson,onChange:e=>Xn({...Yn,metadataJson:e.target.value}),rows:8,spellCheck:!1})]}),(0,C.jsx)(`button`,{className:`primary`,disabled:!Yn.name.trim(),onClick:()=>vn(`Сохранить базовые настройки кластера`)&&void K(async()=>{let e=Me(Yn.metadataJson||`{}`,`Metadata JSON`);await V.updateCluster(U.id,{name:Yn.name,status:Yn.status,region:Yn.region||null,metadata:e})},`Настройки кластера сохранены.`),children:`Сохранить настройки кластера`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Authority и режим изменений`}),(0,C.jsx)(`p`,{className:`muted`,children:`Эта секция защищает кластер от split-brain: minority/read-only сегменты не должны принимать изменения политик.`}),(0,C.jsxs)(`div`,{className:`stateGrid`,children:[(0,C.jsx)(A,{label:`Authority`,value:Ce?.authority_state||`неизвестно`}),(0,C.jsx)(A,{label:`Mutation mode`,value:Ce?.mutation_mode||`неизвестно`}),(0,C.jsx)(A,{label:`Term`,value:String(Ce?.term??`н/д`)}),(0,C.jsx)(A,{label:`Cluster key`,value:P(hi?.cluster_key_fingerprint)}),(0,C.jsx)(A,{label:`Последнее изменение`,value:F(Ce?.updated_at)})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Состояние authority`,(0,C.jsxs)(`select`,{value:ar.authorityState,onChange:e=>or({...ar,authorityState:e.target.value}),children:[(0,C.jsx)(`option`,{value:`authoritative`,children:`authoritative, основной`}),(0,C.jsx)(`option`,{value:`minority`,children:`minority, меньшинство`}),(0,C.jsx)(`option`,{value:`isolated`,children:`isolated, изолирован`}),(0,C.jsx)(`option`,{value:`recovery`,children:`recovery, восстановление`})]})]}),(0,C.jsxs)(`label`,{children:[`Режим изменений`,(0,C.jsxs)(`select`,{value:ar.mutationMode,onChange:e=>or({...ar,mutationMode:e.target.value}),children:[(0,C.jsx)(`option`,{value:`normal`,children:`normal, обычный`}),(0,C.jsx)(`option`,{value:`read_only`,children:`read_only, только чтение`}),(0,C.jsx)(`option`,{value:`recovery_override`,children:`recovery_override, восстановление`})]})]}),(0,C.jsxs)(`label`,{children:[`Примечание`,(0,C.jsx)(`input`,{value:ar.notes,onChange:e=>or({...ar,notes:e.target.value})})]})]}),(0,C.jsx)(`button`,{disabled:!E,onClick:()=>vn(`Изменить authority state кластера`)&&void K(()=>V.updateClusterAuthority(E,{authorityState:ar.authorityState,mutationMode:ar.mutationMode,notes:ar.notes}),`Authority кластера обновлен.`),children:`Обновить authority`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Safety / quorum`}),(0,C.jsxs)(`div`,{className:`stateGrid`,children:[(0,C.jsx)(A,{label:`Узлы`,value:String(hi?.node_count??j.length)}),(0,C.jsx)(A,{label:`Healthy`,value:String(hi?.healthy_node_count??zi)}),(0,C.jsx)(A,{label:`Pending join`,value:String(hi?.pending_join_count??Fe.filter(e=>e.status===`pending`).length)}),(0,C.jsx)(A,{label:`Последний узел`,value:F(hi?.last_node_seen_at)})]}),(0,C.jsx)(`p`,{className:`muted`,children:`Минимальный размер, quorum policy и split-brain rules пока не имеют отдельного runtime-переключателя. Сейчас защита выполняется через authority/mutation mode, explicit node approval и аудит.`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Telemetry / testing`}),(0,C.jsxs)(`div`,{className:`stateGrid`,children:[(0,C.jsx)(A,{label:`Telemetry flag`,value:Hi?.telemetry_enabled?`включен`:`выключен`}),(0,C.jsx)(A,{label:`Synthetic links`,value:Hi?.synthetic_links_enabled?`включены`:`выключены`}),(0,C.jsx)(A,{label:`Хранение истории, часов`,value:String(Hi?.history_retention_hours??`н/д`)})]}),(0,C.jsx)(`p`,{className:`muted`,children:`Это тестовый контур наблюдаемости: heartbeat/telemetry реальные, а связи Fabric сейчас synthetic. Production mesh traffic здесь пока не отображается.`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Storage / updates`}),(0,C.jsxs)(`div`,{className:`stateGrid`,children:[(0,C.jsx)(A,{label:`Version Storage`,value:`архитектура зафиксирована, runtime не реализован`}),(0,C.jsx)(A,{label:`Update cache`,value:`${ht(`update-cache`,tt).length} узл.`}),(0,C.jsx)(A,{label:`File/config cache`,value:`${ht(`file-storage-cache`,tt).length} узл.`})]}),(0,C.jsx)(`p`,{className:`muted`,children:`Version Storage будет хранить stable/current/candidate и signed artifacts. Сейчас это не production updater runtime.`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Admin endpoints`}),(0,C.jsxs)(`div`,{className:`stateGrid`,children:[(0,C.jsx)(A,{label:`Entry nodes`,value:`${ht(`entry-node`,tt).length} узл.`}),(0,C.jsx)(A,{label:`Relay nodes`,value:`${ht(`relay-node`,tt).length} узл.`}),(0,C.jsx)(A,{label:`Core mesh`,value:`${ht(`core-mesh`,tt).length} узл.`})]}),(0,C.jsx)(`p`,{className:`muted`,children:`Панель кластера не переезжает автоматически на storage-узел. Cluster Admin Endpoint должен быть назначен отдельной explicit ролью на ingress/admin-capable узле.`})]})]})]}),T===`nodes`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:H.nodeManagement}),(0,C.jsx)(`p`,{className:`muted`,children:`Единый краткий список узлов. По умолчанию показан активный кластер; включите общий режим, чтобы увидеть весь инвентарь платформы.`})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:lr===`all`,onChange:e=>ur(e.target.checked?`all`:`cluster`)}),H.showAllPlatformNodes]}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>{ur(`all`),fr(``)},children:H.showAllPlatformNodes})]})]}),(0,C.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,C.jsx)(k,{label:`Узлы активного кластера`,value:String(j.length)}),(0,C.jsx)(k,{label:`Все узлы`,value:String(wi.length)}),(0,C.jsx)(k,{label:`Заявки`,value:String(Ri)}),(0,C.jsx)(k,{label:`Активные роли`,value:String(Vi)})]}),(0,C.jsx)(`p`,{className:`muted`,children:H.addNodeText})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:H.nodeBriefList}),(0,C.jsx)(`p`,{className:`muted`,children:H.nodeBriefListHelp})]}),(0,C.jsx)(`span`,{className:`pill`,children:Ti.length})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[H.nodeSearch,(0,C.jsx)(`input`,{value:dr,onChange:e=>fr(e.target.value),placeholder:H.nodeSearchPlaceholder})]}),(0,C.jsxs)(`label`,{children:[H.nodeGroupFilter,(0,C.jsxs)(`select`,{value:pr,onChange:e=>mr(e.target.value),children:[(0,C.jsx)(`option`,{value:``,children:H.allNodeGroups}),Ee.map(e=>(0,C.jsx)(`option`,{value:e.id,children:dt(e,Ee)},e.id))]})]})]}),(0,C.jsx)(`p`,{className:`muted`,children:H.nodeGroupInventoryText}),(0,C.jsx)(`h4`,{children:H.nodeGroupCreatePanel}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[H.nodeGroupName,(0,C.jsx)(`input`,{value:Zn.name,onChange:e=>Qn({...Zn,name:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[H.parentNodeGroup,(0,C.jsxs)(`select`,{value:Zn.parentGroupId,onChange:e=>Qn({...Zn,parentGroupId:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:H.rootNodeGroup}),Ee.map(e=>(0,C.jsx)(`option`,{value:e.id,children:dt(e,Ee)},e.id))]})]}),(0,C.jsxs)(`label`,{children:[H.createNodeGroup,(0,C.jsx)(`button`,{className:`primary`,disabled:!Zn.name.trim(),onClick:()=>void K(async()=>{await V.createNodeGroup(E,{name:Zn.name,parentGroupId:Zn.parentGroupId||null}),Qn({name:``,parentGroupId:``})},H.nodeGroupCreated),children:H.createNodeGroup})]})]}),(0,C.jsxs)(`div`,{className:`nodeList`,children:[Oi.map(e=>{if(e.kind===`group`){let t=hr.includes(e.key);return(0,C.jsxs)(`div`,{className:`nodeListGroup`,style:{paddingLeft:`${e.depth*18}px`},children:[(0,C.jsxs)(`div`,{className:`nodeListMain`,children:[(0,C.jsx)(`strong`,{children:e.label}),e.groupId&&(0,C.jsx)(`span`,{children:ft(e.groupId,Ee)})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`span`,{className:`pill`,children:e.count}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>gr(Zt(hr,e.key)),children:t?H.expandGroup:H.collapseGroup}),e.groupId&&(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>Qn({name:``,parentGroupId:e.groupId||``}),children:H.createSubgroup})]})]},e.key)}let t=e.entry,n=t.memberships.find(e=>e.cluster.id===E),r=n?.node||t.node,i=rt(r,St[r.id]||[],Ft),a=Re(r,Je[r.id],Ue),o=We(Qe[r.id]||[]),s=n?.node.membership_status===`active`,c=n?.node.membership_status===`revoked`;return(0,C.jsxs)(`div`,{className:`nodeListRow`,style:{marginLeft:`${e.depth*18}px`},children:[(0,C.jsxs)(`div`,{className:`nodeListMain`,children:[(0,C.jsx)(`strong`,{children:r.name}),(0,C.jsx)(`span`,{children:r.node_key}),(0,C.jsx)(`small`,{className:`muted`,children:i.address})]}),(0,C.jsx)(de,{value:r.health_status}),(0,C.jsx)(ve,{runtime:i}),(0,C.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,C.jsx)(`strong`,{children:r.reported_version||`версия неизвестна`}),(0,C.jsx)(`small`,{children:a.targetLabel})]}),(0,C.jsx)(de,{value:a.status}),(0,C.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,C.jsx)(`strong`,{className:`pill ${o.tone}`,children:o.label}),(0,C.jsx)(`small`,{children:o.detail})]}),(0,C.jsx)(`span`,{className:`muted`,children:F(r.last_seen_at)}),n?(0,C.jsx)(de,{value:n.node.membership_status}):(0,C.jsx)(`span`,{className:`muted`,children:H.notMemberOfActiveCluster}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{onClick:()=>{wr(t),Er(`details`)},children:H.nodeDetails}),s?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(`button`,{className:`primary`,onClick:()=>{wr(t),Er(`manage`)},children:H.manageNode}),(0,C.jsx)(`button`,{className:`danger`,onClick:()=>vn(`Удалить узел ${r.name} из кластера`)&&void K(()=>V.deleteClusterNode(E,r.id,`Удалено из списка узлов панели владельца платформы.`),`Узел удален из кластера.`),children:`Удалить`})]}):c?(0,C.jsx)(`span`,{className:`muted`,children:H.revokedMembership}):(0,C.jsx)(`button`,{className:`primary`,onClick:()=>{br(t),Sr([])},children:H.connectExistingNode})]})]},e.key)}),Oi.length===0&&(0,C.jsx)(pe,{title:H.noNodesTitle,text:H.noNodesByFilter})]})]}),yr&&(0,C.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,C.jsxs)(`div`,{className:`modalCard`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`attach-node-title`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{id:`attach-node-title`,children:H.connectExistingNodeTitle}),(0,C.jsx)(`p`,{className:`muted`,children:H.connectExistingNodeText})]}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>br(null),children:H.cancel})]}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Узел`,value:yr.node.name}),(0,C.jsx)(A,{label:`Node key`,value:yr.node.node_key}),(0,C.jsx)(A,{label:H.activeCluster,value:U?.name||E})]}),(0,C.jsx)(`div`,{className:`checkGrid`,children:ne.map(e=>(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:xr.includes(e),onChange:()=>Sr(Zt(xr,e))}),Ie(e)]},e))}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{className:`primary`,onClick:()=>void K(async()=>{await V.attachExistingNode(E,yr.node.id,xr),br(null),Sr([]),ur(`cluster`)},`Узел подключен к активному кластеру.`),children:H.connectWithRoles}),(0,C.jsx)(`button`,{onClick:()=>br(null),children:H.cancel})]})]})}),Cr&&(()=>{let e=Cr.memberships.find(e=>e.cluster.id===E),t=e?.node||Cr.node,n=e?(St[t.id]||[])[0]:void 0,r=e?(tt[t.id]||[]).filter(e=>e.status===`active`):[],i=e&&it[t.id]||[],a=e&&ot[t.id]||[];return(0,C.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,C.jsxs)(`div`,{className:`modalCard wide`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`node-info-title`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsxs)(`h3`,{id:`node-info-title`,children:[Tr===`manage`?H.manageNode:H.nodeDetails,`: `,t.name]}),(0,C.jsx)(`p`,{className:`muted`,children:t.node_key})]}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>{wr(null),Er(`details`)},children:H.close})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:H.nodeIdentity}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Node ID`,value:P(t.id)}),(0,C.jsx)(A,{label:`Ключ узла`,value:t.node_key}),(0,C.jsx)(A,{label:`Тип владения`,value:I(t.ownership_type)}),(0,C.jsx)(A,{label:`Owner org`,value:P(t.owner_organization_id)}),(0,C.jsx)(A,{label:`Регистрация`,value:I(t.registration_status)}),(0,C.jsx)(A,{label:`Здоровье`,value:I(t.health_status)}),(0,C.jsx)(A,{label:`Версия`,value:t.reported_version||`неизвестно`}),(0,C.jsx)(A,{label:`Последний сигнал`,value:F(t.last_seen_at)})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:H.clusterMemberships}),(0,C.jsx)(`div`,{className:`membershipList`,children:Cr.memberships.map(e=>(0,C.jsxs)(`span`,{className:e.cluster.id===E?`pill good`:`pill`,children:[e.cluster.name,`: `,I(e.node.membership_status)]},e.cluster.id))})]}),e?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:H.activeClusterScope}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Участие`,value:I(t.membership_status)}),(0,C.jsx)(A,{label:`Сегмент`,value:I(t.partition_state)}),(0,C.jsx)(A,{label:`Группа`,value:t.node_group_name||H.ungroupedNodes}),(0,C.jsx)(A,{label:`Ролей`,value:String(r.length)}),(0,C.jsx)(A,{label:`Desired-сервисов`,value:String(i.length)}),(0,C.jsx)(A,{label:`Observed-сервисов`,value:String(a.length)})]})]}),Tr===`details`&&(0,C.jsx)(ge,{node:t,memberships:Cr.memberships,activeRoles:r,desiredWorkloads:i,observedWorkloads:a,heartbeats:St[t.id]||[],telemetry:Nt[t.id]||[],updatePlan:Je[t.id],updateStatuses:Qe[t.id]||[],meshLinks:Ft.filter(e=>e.source_node_id===t.id||e.target_node_id===t.id),syntheticConfig:Lt[t.id],allNodes:j,onSetUpdatePolicy:(e,t,n)=>void K(async()=>{await V.upsertNodeUpdatePolicy(E,e.id,{product:t,channel:`dev`,targetVersion:n,strategy:`rolling`,enabled:!0,rollbackAllowed:!0,healthWindowSeconds:180})},n?`${t} поставлен в target ${n}.`:`${t} будет следовать latest dev.`),labels:H}),Tr===`manage`&&(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:H.nodeFunctions}),(0,C.jsx)(`p`,{className:`muted`,children:H.nodeFunctionsText}),(0,C.jsxs)(`label`,{className:`wideLabel`,children:[H.organizationScopeForEnable,(0,C.jsx)(`input`,{value:sr,onChange:e=>cr(e.target.value),placeholder:H.clusterWideRolePlaceholder})]}),(0,C.jsx)(`div`,{className:`functionList`,children:ne.map(e=>{let o=r.find(t=>t.role===e),s=i.find(t=>t.service_type===e),c=a.find(t=>t.service_type===e),l=rn(e,n),u=s?.desired_state||`not_configured`,f=c?.reported_state||`missing`,p=!!o&&u===`enabled`;return(0,C.jsxs)(`div`,{className:`functionRow`,children:[(0,C.jsxs)(`div`,{className:`nodeListMain`,children:[(0,C.jsx)(`strong`,{children:Ie(e)}),(0,C.jsx)(`span`,{children:on(e,n,d)})]}),(0,C.jsx)(fe,{label:H.rolePermission,value:o?H.permissionGranted:H.permissionDenied,tone:o?`info`:``}),(0,C.jsx)(fe,{label:H.desiredRuntime,value:I(u),tone:u===`enabled`?`good`:``}),(0,C.jsx)(fe,{label:H.observedRuntime,value:I(f),tone:f===`running`?`good`:f===`missing`?`warn`:``}),(0,C.jsx)(`span`,{className:`pill ${l}`,children:an(e,n,H)}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{className:p?``:`primary`,disabled:p,onClick:()=>void K(async()=>{o||await V.setRoleStatus(E,t.id,e,`active`,sr||void 0),await V.setDesiredWorkload(E,t.id,e,{desiredState:`enabled`,runtimeMode:`container`,config:{},environment:{}})},`${e}: функция включена.`),children:H.enableFunction}),(0,C.jsx)(`button`,{disabled:!o&&u!==`enabled`,onClick:()=>void K(async()=>{await V.setDesiredWorkload(E,t.id,e,{desiredState:`disabled`,runtimeMode:s?.runtime_mode||`container`,config:s?.config||{},environment:s?.environment||{}}),o&&await V.setRoleStatus(E,t.id,e,`disabled`,o.organization_id||void 0)},`${e}: функция выключена.`),children:H.disableFunction})]})]},e)})}),(()=>{let e=i.find(e=>e.service_type===`mesh-listener`)?.config||{},n=jr[t.id]||{listenAddr:String(e.listen_addr||`:19131`),mode:String(e.listen_port_mode||`auto`),autoRange:`${Number(e.auto_port_start||19131)}-${Number(e.auto_port_end||19231)}`,advertiseEndpoint:String(e.advertise_endpoint||``),advertiseTransport:String(e.advertise_transport||`direct_http`),connectivity:String(e.connectivity_mode||`private_lan`),nat:String(e.nat_type||`none`),region:String(e.region||``)},r=e=>Mr({...jr,[t.id]:{...n,...e}});return(0,C.jsxs)(`section`,{className:`nodePanel nestedPanel`,children:[(0,C.jsx)(`h4`,{children:`Mesh listener`}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Listen addr`,(0,C.jsx)(`input`,{value:n.listenAddr,onChange:e=>r({listenAddr:e.target.value}),placeholder:`0.0.0.0:19131 или :19131`})]}),(0,C.jsxs)(`label`,{children:[`Port mode`,(0,C.jsxs)(`select`,{value:n.mode,onChange:e=>r({mode:e.target.value}),children:[(0,C.jsx)(`option`,{value:`auto`,children:`auto`}),(0,C.jsx)(`option`,{value:`manual`,children:`manual`}),(0,C.jsx)(`option`,{value:`disabled`,children:`disabled`})]})]}),(0,C.jsxs)(`label`,{children:[`Auto ports`,(0,C.jsx)(`input`,{value:n.autoRange,onChange:e=>r({autoRange:e.target.value}),placeholder:`19131-19231`})]}),(0,C.jsxs)(`label`,{children:[`Advertise endpoint`,(0,C.jsx)(`input`,{value:n.advertiseEndpoint,onChange:e=>r({advertiseEndpoint:e.target.value}),placeholder:`http://external-or-lan-ip:19131`})]}),(0,C.jsxs)(`label`,{children:[`Advertise transport`,(0,C.jsxs)(`select`,{value:n.advertiseTransport,onChange:e=>r({advertiseTransport:e.target.value}),children:[(0,C.jsx)(`option`,{value:`direct_http`,children:`direct_http`}),(0,C.jsx)(`option`,{value:`direct_https`,children:`direct_https`}),(0,C.jsx)(`option`,{value:`wss`,children:`wss`})]})]}),(0,C.jsxs)(`label`,{children:[`Connectivity`,(0,C.jsxs)(`select`,{value:n.connectivity,onChange:e=>r({connectivity:e.target.value}),children:[(0,C.jsx)(`option`,{value:`private_lan`,children:`private_lan`}),(0,C.jsx)(`option`,{value:`direct`,children:`direct`}),(0,C.jsx)(`option`,{value:`outbound_only`,children:`outbound_only`}),(0,C.jsx)(`option`,{value:`relay_required`,children:`relay_required`})]})]}),(0,C.jsxs)(`label`,{children:[`NAT`,(0,C.jsxs)(`select`,{value:n.nat,onChange:e=>r({nat:e.target.value}),children:[(0,C.jsx)(`option`,{value:`none`,children:`none`}),(0,C.jsx)(`option`,{value:`unknown`,children:`unknown`}),(0,C.jsx)(`option`,{value:`port_restricted`,children:`port_restricted`}),(0,C.jsx)(`option`,{value:`symmetric`,children:`symmetric`})]})]}),(0,C.jsxs)(`label`,{children:[`Region/site`,(0,C.jsx)(`input`,{value:n.region,onChange:e=>r({region:e.target.value}),placeholder:`dc1, office, docker-test`})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{className:`primary`,onClick:()=>void K(async()=>{let[e,r]=n.autoRange.split(`-`).map(e=>Number(e.trim())),i=Number.isFinite(e)?e:19131,a=Number.isFinite(r)?r:i;await V.setDesiredWorkload(E,t.id,`mesh-listener`,{desiredState:n.mode===`disabled`?`disabled`:`enabled`,version:`listener-${Date.now()}`,runtimeMode:`container`,config:{listen_addr:n.listenAddr,listen_port_mode:n.mode,auto_port_start:i,auto_port_end:a,advertise_endpoint:n.advertiseEndpoint.trim().replace(/\/$/,``)||null,advertise_transport:n.advertiseTransport||`direct_http`,connectivity_mode:n.connectivity,nat_type:n.nat,region:n.region||null},environment:{}})},`Mesh listener config обновлен.`),children:`Применить listener`})})]})})(),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsxs)(`select`,{value:t.node_group_id||``,onChange:e=>void K(()=>V.assignNodeGroup(E,t.id,e.target.value||null),e.target.value?`Узел перемещен в группу.`:`Узел убран из группы.`),children:[(0,C.jsx)(`option`,{value:``,children:H.ungroupedNodes}),Ee.map(e=>(0,C.jsx)(`option`,{value:e.id,children:dt(e,Ee)},e.id))]})}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{onClick:()=>vn(`Отключить участие узла ${t.name}`)&&void K(()=>V.disableMembership(E,t.id,`Отключено из панели владельца платформы.`),`Участие узла отключено.`),children:`Отключить участие`}),(0,C.jsx)(`button`,{className:`danger`,onClick:()=>vn(`Отозвать identity узла ${t.name}`)&&void K(()=>V.revokeNodeIdentity(E,t.id,`Отозвано из панели владельца платформы.`),`Identity узла отозван.`),children:`Отозвать identity`})]})]})]}):(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:H.noActiveClusterMembership}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{className:`primary`,onClick:()=>{br(Cr),Sr([]),wr(null)},children:H.connectExistingNode})})]})]})})})(),!1]}),T===`enrollment`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:H.joinTokenTitle}),(0,C.jsx)(`p`,{className:`muted`,children:H.joinTokenText}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[H.ttlHours,(0,C.jsx)(`input`,{type:`number`,min:1,max:720,value:L.ttlHours,onChange:e=>R({...L,ttlHours:Number(e.target.value)})}),(0,C.jsx)(`small`,{children:H.ttlHelp})]}),(0,C.jsxs)(`label`,{children:[H.maxUses,(0,C.jsx)(`input`,{type:`number`,min:1,max:100,value:L.maxUses,onChange:e=>R({...L,maxUses:Number(e.target.value)})}),(0,C.jsx)(`small`,{children:H.maxUsesHelp})]}),(0,C.jsxs)(`label`,{children:[H.nodeOwnership,(0,C.jsxs)(`select`,{value:L.ownershipType,onChange:e=>R({...L,ownershipType:e.target.value}),children:[(0,C.jsx)(`option`,{value:`platform_managed`,children:`platform_managed, управляется платформой`}),(0,C.jsx)(`option`,{value:`customer_managed`,children:`customer_managed, управляется клиентом`})]})]}),(0,C.jsxs)(`label`,{children:[H.tokenPurpose,(0,C.jsx)(`input`,{value:L.purpose,onChange:e=>R({...L,purpose:e.target.value}),placeholder:`например: стартовый entry-node в ru-msk-1`})]}),(0,C.jsxs)(`label`,{children:[`Имя нового узла`,(0,C.jsx)(`input`,{value:L.nodeName,onChange:e=>R({...L,nodeName:e.target.value}),placeholder:Et(L,U)}),(0,C.jsx)(`small`,{children:`Если оставить пустым, панель подставит имя автоматически.`})]}),(0,C.jsxs)(`label`,{children:[`Группа узла`,(0,C.jsxs)(`select`,{value:L.nodeGroupId,onChange:e=>R({...L,nodeGroupId:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Без группы`}),Ee.map(e=>(0,C.jsx)(`option`,{value:e.id,children:dt(e,Ee)},e.id))]})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Install profile`}),(0,C.jsx)(`p`,{className:`muted`,children:`Эти поля попадут в install profile. Для Windows без админ-прав будет создан user startup task, с админ-правами - system startup task.`}),(0,C.jsx)(`div`,{className:`segmented`,children:[[`docker`,`Docker Linux`],[`linux_binary`,`Ubuntu service`],[`windows_service`,`Windows`]].map(([e,t])=>(0,C.jsx)(`button`,{type:`button`,className:L.installMode===e?`active`:``,onClick:()=>R({...L,installMode:e}),children:t},e))}),(0,C.jsx)(`div`,{className:`segmented`,children:[[`private_lan`,`LAN`],[`direct`,`Public`],[`nat_forward`,`NAT`],[`outbound_only`,`Outbound`]].map(([e,t])=>(0,C.jsx)(`button`,{type:`button`,className:wt(L)===e?`active`:``,onClick:()=>R(Tt(L,e)),children:t},e))}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Control-plane endpoint`,(0,C.jsx)(`input`,{value:L.controlPlaneEndpoint,onChange:e=>R({...L,controlPlaneEndpoint:e.target.value}),placeholder:bt()})]}),(0,C.jsxs)(`label`,{children:[L.installMode===`windows_service`?`Windows node-agent artifact`:L.installMode===`linux_binary`?`Linux node-agent artifact`:`Docker image`,(0,C.jsx)(`input`,{value:L.dockerImage,onChange:e=>R({...L,dockerImage:e.target.value})})]}),L.installMode===`windows_service`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`label`,{children:[`Windows startup`,(0,C.jsxs)(`select`,{value:L.windowsStartupMode,onChange:e=>R({...L,windowsStartupMode:e.target.value}),children:[(0,C.jsx)(`option`,{value:`auto`,children:`auto: system task, fallback user task`}),(0,C.jsx)(`option`,{value:`system-task`,children:`system task, admin required`}),(0,C.jsx)(`option`,{value:`user-task`,children:`user task, no admin`}),(0,C.jsx)(`option`,{value:`none`,children:`none`})]})]}),(0,C.jsxs)(`label`,{children:[`Install dir`,(0,C.jsx)(`input`,{value:L.windowsInstallDir,onChange:e=>R({...L,windowsInstallDir:e.target.value}),placeholder:`C:\\\\Program Files\\\\RAP\\\\node-name`})]}),(0,C.jsxs)(`label`,{children:[`Windows node-agent SHA256`,(0,C.jsx)(`input`,{value:L.windowsNodeAgentSHA256,onChange:e=>R({...L,windowsNodeAgentSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]})]}),L.installMode===`linux_binary`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`label`,{children:[`Linux install dir`,(0,C.jsx)(`input`,{value:L.linuxInstallDir,onChange:e=>R({...L,linuxInstallDir:e.target.value}),placeholder:`/opt/rap/node-name`})]}),(0,C.jsxs)(`label`,{children:[`Linux node-agent SHA256`,(0,C.jsx)(`input`,{value:L.linuxNodeAgentSHA256,onChange:e=>R({...L,linuxNodeAgentSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]})]}),L.installMode===`docker`&&(0,C.jsxs)(`label`,{children:[`Container name`,(0,C.jsx)(`input`,{value:L.dockerContainerName,onChange:e=>R({...L,dockerContainerName:e.target.value}),placeholder:Dt(L,U)})]}),(0,C.jsxs)(`label`,{children:[`Artifact endpoints`,(0,C.jsx)(`input`,{value:L.artifactEndpoints,onChange:e=>R({...L,artifactEndpoints:e.target.value}),placeholder:xt()}),(0,C.jsx)(`small`,{children:`Через запятую: public/LAN/cache узлы, где host-agent сможет скачать image tar до входа в mesh.`})]}),L.installMode===`docker`&&(0,C.jsxs)(`label`,{children:[`Docker image tar SHA256`,(0,C.jsx)(`input`,{value:L.dockerImageArtifactSHA256,onChange:e=>R({...L,dockerImageArtifactSHA256:e.target.value}),placeholder:`опционально, но желательно для production`})]}),L.installMode===`docker`&&(0,C.jsxs)(`label`,{children:[`Docker network`,(0,C.jsxs)(`select`,{value:L.dockerNetwork,onChange:e=>R({...L,dockerNetwork:e.target.value}),children:[(0,C.jsx)(`option`,{value:`host`,children:`host`}),(0,C.jsx)(`option`,{value:`bridge`,children:`bridge`})]})]}),(0,C.jsxs)(`label`,{children:[`Listen addr`,(0,C.jsx)(`input`,{value:L.meshListenAddr,onChange:e=>R({...L,meshListenAddr:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Listen mode`,(0,C.jsxs)(`select`,{value:L.meshListenPortMode,onChange:e=>R({...L,meshListenPortMode:e.target.value}),children:[(0,C.jsx)(`option`,{value:`auto`,children:`auto`}),(0,C.jsx)(`option`,{value:`manual`,children:`manual`}),(0,C.jsx)(`option`,{value:`disabled`,children:`disabled`})]})]}),(0,C.jsxs)(`label`,{children:[`Auto ports`,(0,C.jsx)(`input`,{value:`${L.meshListenAutoPortStart}-${L.meshListenAutoPortEnd}`,onChange:e=>{let[t,n]=e.target.value.split(`-`).map(e=>Number(e.trim()));R({...L,meshListenAutoPortStart:Number.isFinite(t)?t:L.meshListenAutoPortStart,meshListenAutoPortEnd:Number.isFinite(n)?n:L.meshListenAutoPortEnd})}})]}),(0,C.jsxs)(`label`,{children:[`Advertise endpoint`,(0,C.jsx)(`input`,{value:L.meshAdvertiseEndpoint,onChange:e=>R({...L,meshAdvertiseEndpoint:e.target.value}),placeholder:`http://public-or-private-ip:19131`})]}),(0,C.jsxs)(`label`,{children:[`Connectivity`,(0,C.jsxs)(`select`,{value:L.meshConnectivityMode,onChange:e=>R({...L,meshConnectivityMode:e.target.value}),children:[(0,C.jsx)(`option`,{value:`direct`,children:`direct`}),(0,C.jsx)(`option`,{value:`private_lan`,children:`private_lan`}),(0,C.jsx)(`option`,{value:`outbound_only`,children:`outbound_only`}),(0,C.jsx)(`option`,{value:`relay_required`,children:`relay_required`})]})]}),(0,C.jsxs)(`label`,{children:[`NAT`,(0,C.jsxs)(`select`,{value:L.meshNATType,onChange:e=>R({...L,meshNATType:e.target.value}),children:[(0,C.jsx)(`option`,{value:`none`,children:`none`}),(0,C.jsx)(`option`,{value:`unknown`,children:`unknown`}),(0,C.jsx)(`option`,{value:`full_cone`,children:`full_cone`}),(0,C.jsx)(`option`,{value:`port_restricted`,children:`port_restricted`}),(0,C.jsx)(`option`,{value:`symmetric`,children:`symmetric`})]})]}),(0,C.jsxs)(`label`,{children:[`Region/site`,(0,C.jsx)(`input`,{value:L.meshRegion,onChange:e=>R({...L,meshRegion:e.target.value})})]}),L.installMode===`docker`&&(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:L.pullImage,onChange:e=>R({...L,pullImage:e.target.checked})}),`Pull image`]}),(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:L.replace,onChange:e=>R({...L,replace:e.target.checked})}),`Replace existing install`]})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:H.suggestedRoles}),(0,C.jsx)(`p`,{className:`muted`,children:`Роли записываются в install token и автоматически назначаются узлу при approval. После создания token изменение чекбоксов не меняет уже выданный token.`}),(0,C.jsx)(`div`,{className:`checkGrid`,children:ne.map(e=>(0,C.jsxs)(`label`,{className:`checkLine`,children:[(0,C.jsx)(`input`,{type:`checkbox`,checked:L.roles.includes(e),onChange:()=>R({...L,roles:Zt(L.roles,e)})}),Ie(e)]},e))})]}),(0,C.jsxs)(`details`,{children:[(0,C.jsx)(`summary`,{children:H.generatedScope}),(0,C.jsx)(`p`,{className:`muted`,children:H.generatedScopeHelp}),(0,C.jsx)(`pre`,{className:`codePreview`,children:JSON.stringify(Si,null,2)})]}),(0,C.jsxs)(`p`,{className:`muted`,children:[H.manualApprovalRequired,`.`]}),(0,C.jsx)(`button`,{className:`primary`,disabled:!E,onClick:()=>void K(async()=>{ir(await V.createJoinToken(E,{ttlHours:L.ttlHours,maxUses:L.maxUses,scope:Si}))},`Join token создан.`),children:`Создать install token`}),rr&&(0,C.jsxs)(`div`,{className:`secretOnce`,children:[(0,C.jsx)(`strong`,{children:`Исходный token, возвращается один раз`}),(0,C.jsx)(`code`,{children:rr.token}),(0,C.jsxs)(`span`,{className:`muted`,children:[`Authority key: `,P(rr.authority_signature?.key_fingerprint)]}),(0,C.jsx)(`strong`,{children:`Scope выданного token`}),(0,C.jsx)(`pre`,{className:`codePreview`,children:JSON.stringify(rr.scope,null,2)}),(0,C.jsx)(`strong`,{children:`Docker host-agent install`}),(0,C.jsx)(`pre`,{className:`codePreview`,children:Ot(rr,U,Ci)}),(0,C.jsx)(`strong`,{children:`Profile-based Docker install`}),(0,C.jsx)(`pre`,{className:`codePreview`,children:kt(rr,U,Ci)}),(0,C.jsx)(`strong`,{children:`Profile-based Ubuntu service install`}),(0,C.jsx)(`pre`,{className:`codePreview`,children:At(rr,U,Ci)}),(0,C.jsx)(`strong`,{children:`Profile-based Windows PowerShell install`}),(0,C.jsx)(`pre`,{className:`codePreview`,children:jt(rr,U,Ci)}),(0,C.jsx)(`strong`,{children:`Profile-based Windows CMD install`}),(0,C.jsx)(`pre`,{className:`codePreview`,children:Mt(rr,U,Ci)})]})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Как добавить узел`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsxs)(`div`,{className:`stateLine`,children:[(0,C.jsx)(`span`,{children:`1`}),(0,C.jsx)(`strong`,{children:`Заполните Docker install profile слева.`})]}),(0,C.jsxs)(`div`,{className:`stateLine`,children:[(0,C.jsx)(`span`,{children:`2`}),(0,C.jsx)(`strong`,{children:`Нажмите “Создать install token”.`})]}),(0,C.jsxs)(`div`,{className:`stateLine`,children:[(0,C.jsx)(`span`,{children:`3`}),(0,C.jsx)(`strong`,{children:`Скопируйте “Profile-based Docker install” и выполните на Docker-хосте.`})]}),(0,C.jsxs)(`div`,{className:`stateLine`,children:[(0,C.jsx)(`span`,{children:`4`}),(0,C.jsx)(`strong`,{children:`Подтвердите join request в этой же вкладке.`})]})]})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Install tokens`}),(0,C.jsx)(je,{columns:[`scope`,`status`,`uses`,`expires`,`created`,`action`],rows:Be.map(e=>[Ke(e),I(e.status),`${e.used_count}/${e.max_uses}`,F(e.expires_at),F(e.created_at),e.status===`active`?(0,C.jsx)(`button`,{className:`danger`,onClick:()=>vn(`Отозвать install token ${P(e.id)}`)&&void K(()=>V.revokeJoinToken(E,e.id),`Install token отозван.`),children:`Отозвать`}):(0,C.jsx)(`span`,{className:`muted`,children:I(e.status)})])})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Заявки на подключение`}),(0,C.jsxs)(`div`,{className:`stack`,children:[Fe.map(e=>(0,C.jsxs)(`div`,{className:`requestCard`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`strong`,{children:e.node_name}),(0,C.jsx)(`p`,{children:e.node_fingerprint}),(0,C.jsx)(de,{value:e.status}),e.approval_signature?.key_fingerprint&&(0,C.jsxs)(`small`,{className:`muted`,children:[`approval key `,P(e.approval_signature.key_fingerprint)]})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{disabled:e.status!==`pending`,onClick:()=>void K(()=>V.approveJoinRequest(E,e.id),`Заявка одобрена.`),children:`Одобрить`}),(0,C.jsx)(`button`,{disabled:e.status!==`pending`,onClick:()=>void K(()=>V.rejectJoinRequest(E,e.id,`Отклонено из панели владельца платформы.`),`Заявка отклонена.`),children:`Отклонить`})]})]},e.id)),Fe.length===0&&(0,C.jsx)(pe,{title:`Нет заявок`,text:`Новые подключения node-agent появятся здесь.`})]})]})]}),T===`roles`&&(0,C.jsxs)(`section`,{className:`stack`,children:[(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Область ролей`}),(0,C.jsx)(`p`,{className:`muted`,children:`Capabilities — технические факты. Роли — явные разрешения. Область организации может ограничивать сервисные роли.`}),(0,C.jsxs)(`label`,{children:[`UUID организации для новых назначений ролей, опционально`,(0,C.jsx)(`input`,{value:sr,onChange:e=>cr(e.target.value),placeholder:`пусто = роль на весь кластер`})]})]}),j.map(e=>(0,C.jsxs)(`article`,{className:`card roleRow`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:e.name}),(0,C.jsx)(`p`,{children:Pe(tt[e.id]||[])})]}),(0,C.jsxs)(`select`,{defaultValue:``,onChange:t=>{let n=t.target.value;t.currentTarget.value=``,n&&K(()=>V.assignRole(E,e.id,n,sr||void 0),`${n} назначена узлу ${e.name}.`)},children:[(0,C.jsx)(`option`,{value:``,children:`Назначить роль...`}),ne.map(e=>(0,C.jsx)(`option`,{value:e,children:Ie(e)},e))]})]},e.id))]}),T===`workloads`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Желаемое состояние сервиса`}),(0,C.jsx)(`p`,{className:`muted`,children:`Здесь задается только желаемое состояние. Runtime-исполнение остается под контролем node-agent и политик.`}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Узел`,(0,C.jsxs)(`select`,{value:Ur.nodeId,onChange:e=>Wr({...Ur,nodeId:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Выберите узел...`}),j.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,C.jsxs)(`label`,{children:[`Сервис`,(0,C.jsx)(`select`,{value:Ur.serviceType,onChange:e=>Wr({...Ur,serviceType:e.target.value}),children:ne.map(e=>(0,C.jsx)(`option`,{value:e,children:Ie(e)},e))})]}),(0,C.jsxs)(`label`,{children:[`Желаемое состояние`,(0,C.jsxs)(`select`,{value:Ur.desiredState,onChange:e=>Wr({...Ur,desiredState:e.target.value}),children:[(0,C.jsx)(`option`,{value:`enabled`,children:`включено`}),(0,C.jsx)(`option`,{value:`disabled`,children:`выключено`})]})]}),(0,C.jsxs)(`label`,{children:[`Режим runtime`,(0,C.jsxs)(`select`,{value:Ur.runtimeMode,onChange:e=>Wr({...Ur,runtimeMode:e.target.value}),children:[(0,C.jsx)(`option`,{value:`container`,children:`контейнер`}),(0,C.jsx)(`option`,{value:`native`,children:`нативно`})]})]}),(0,C.jsxs)(`label`,{children:[`Версия`,(0,C.jsx)(`input`,{value:Ur.version,onChange:e=>Wr({...Ur,version:e.target.value})})]})]}),(0,C.jsxs)(`label`,{children:[`Config JSON`,(0,C.jsx)(`textarea`,{value:Ur.configJson,onChange:e=>Wr({...Ur,configJson:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Environment JSON`,(0,C.jsx)(`textarea`,{value:Ur.environmentJson,onChange:e=>Wr({...Ur,environmentJson:e.target.value})})]}),(0,C.jsx)(`button`,{className:`primary`,disabled:!Ur.nodeId||!E,onClick:()=>void K(()=>V.setDesiredWorkload(E,Ur.nodeId,Ur.serviceType,{desiredState:Ur.desiredState,runtimeMode:Ur.runtimeMode,version:Ur.version,config:Me(Ur.configJson,`config сервиса`),environment:Me(Ur.environmentJson,`environment сервиса`)}),`Желаемое состояние сервиса обновлено.`),children:`Задать желаемое состояние`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Отчеты сервисов`}),(0,C.jsx)(`div`,{className:`stack`,children:j.map(e=>(0,C.jsxs)(`div`,{className:`workloadBlock`,children:[(0,C.jsx)(`strong`,{children:e.name}),(ot[e.id]||[]).length===0?(0,C.jsx)(`p`,{className:`muted`,children:`Статус пока не получен.`}):(0,C.jsx)(je,{columns:[`сервис`,`состояние`,`runtime`,`наблюдение`],rows:(ot[e.id]||[]).map(e=>[e.service_type,e.reported_state,e.runtime_mode,F(e.observed_at)])})]},e.id))})]})]}),T===`fabric`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsx)(`h3`,{children:`Граница подготовки Fabric`}),(0,C.jsx)(`p`,{className:`muted`,children:"Этот экран показывает synthetic/control-plane подготовку и C17Z11 boundary: production forwarding доступен только для route-bound `fabric.control` при явном gate. Service traffic, RDP, VPN и произвольный relay здесь не включены."}),(0,C.jsxs)(`div`,{className:`signalStrip`,children:[(0,C.jsx)(k,{label:`Synthetic configs`,value:`${Wi}/${j.length}`}),(0,C.jsx)(k,{label:`Routes`,value:String(Gi)}),(0,C.jsx)(k,{label:`Endpoints / candidates`,value:`${Ki}/${qi}`}),(0,C.jsx)(k,{label:`Peer dir / seeds`,value:`${Ji}/${Yi}`}),(0,C.jsx)(k,{label:`Scoped production flag`,value:Xi===0?`false`:`true:${Xi}`})]})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:H.fabricEntryPoints}),(0,C.jsx)(`p`,{className:`muted`,children:H.fabricEntryPointHelp})]}),(0,C.jsx)(`span`,{className:`pill`,children:Vt.length})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[H.endpointName,(0,C.jsx)(`input`,{value:$n.name,onChange:e=>er({...$n,name:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[H.endpointType,(0,C.jsxs)(`select`,{value:$n.endpointType,onChange:e=>er({...$n,endpointType:e.target.value}),children:[(0,C.jsx)(`option`,{value:`client_access`,children:`client_access`}),(0,C.jsx)(`option`,{value:`admin`,children:`admin`}),(0,C.jsx)(`option`,{value:`api`,children:`api`}),(0,C.jsx)(`option`,{value:`other`,children:`other`})]})]}),(0,C.jsxs)(`label`,{className:`span2`,children:[H.publicEndpoint,(0,C.jsx)(`input`,{placeholder:`wss://entry.example.com`,value:$n.publicEndpoint,onChange:e=>er({...$n,publicEndpoint:e.target.value})})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{className:`primary`,disabled:!$n.name.trim(),onClick:()=>void K(async()=>{await V.createFabricEntryPoint(E,{name:$n.name,endpointType:$n.endpointType,publicEndpoint:$n.publicEndpoint||null}),er({name:``,endpointType:`client_access`,publicEndpoint:``})},`Точка входа создана.`),children:H.createEntryPoint})}),(0,C.jsxs)(`div`,{className:`stack`,children:[Vt.map(e=>{let t=Ut[e.id]||[];return(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h4`,{children:e.name}),(0,C.jsxs)(`p`,{className:`muted`,children:[e.endpoint_type,` · `,e.public_endpoint||H.addressNotSet]})]}),(0,C.jsx)(de,{value:e.status})]}),(0,C.jsx)(`h5`,{children:H.endpointNodes}),t.length===0?(0,C.jsx)(`p`,{className:`muted`,children:H.assignedNodesEmpty}):(0,C.jsx)(`div`,{className:`membershipList`,children:t.map(t=>(0,C.jsxs)(`span`,{className:t.status===`active`?`pill good`:`pill`,children:[ut(j,t.node_id),` · `,I(t.status),` · p`,t.priority]},`${e.id}-${t.node_id}`))}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsxs)(`select`,{value:Nr[e.id]||``,onChange:t=>Pr({...Nr,[e.id]:t.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:H.selectNode}),j.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,C.jsx)(`button`,{disabled:!Nr[e.id],onClick:()=>void K(()=>V.setFabricEntryPointNode(E,e.id,Nr[e.id],{status:`active`}),`Узел назначен точке входа.`),children:H.assignEndpointNode})]})]},e.id)}),Vt.length===0&&(0,C.jsx)(pe,{title:H.fabricEntryPoints,text:H.entryPointsEmpty})]})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:H.fabricEgressPools}),(0,C.jsx)(`p`,{className:`muted`,children:H.fabricEgressPoolHelp})]}),(0,C.jsx)(`span`,{className:`pill`,children:Gt.length})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[H.endpointName,(0,C.jsx)(`input`,{value:tr.name,onChange:e=>nr({...tr,name:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[H.description,(0,C.jsx)(`input`,{value:tr.description,onChange:e=>nr({...tr,description:e.target.value})})]}),(0,C.jsxs)(`label`,{className:`span2`,children:[H.routeScope,(0,C.jsx)(`textarea`,{rows:5,value:tr.routeScope,onChange:e=>nr({...tr,routeScope:e.target.value})})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{className:`primary`,disabled:!tr.name.trim(),onClick:()=>void K(async()=>{let e=Me(tr.routeScope,`Route scope JSON`);await V.createFabricEgressPool(E,{name:tr.name,description:tr.description||null,routeScope:e}),nr({name:``,description:``,routeScope:`{ "routes": [] }`})},`Выходная зона создана.`),children:H.createEgressPool})}),(0,C.jsxs)(`div`,{className:`stack`,children:[Gt.map(e=>{let t=qt[e.id]||[];return(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h4`,{children:e.name}),(0,C.jsx)(`p`,{className:`muted`,children:e.description||H.descriptionNotSet})]}),(0,C.jsx)(de,{value:e.status})]}),(0,C.jsx)(`p`,{className:`muted`,children:JSON.stringify(e.route_scope||{})}),(0,C.jsx)(`h5`,{children:H.endpointNodes}),t.length===0?(0,C.jsx)(`p`,{className:`muted`,children:H.assignedNodesEmpty}):(0,C.jsx)(`div`,{className:`membershipList`,children:t.map(t=>(0,C.jsxs)(`span`,{className:t.status===`active`?`pill good`:`pill`,children:[ut(j,t.node_id),` · `,I(t.status),` · p`,t.priority]},`${e.id}-${t.node_id}`))}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsxs)(`select`,{value:Fr[e.id]||``,onChange:t=>Ir({...Fr,[e.id]:t.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:H.selectNode}),j.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,C.jsx)(`button`,{disabled:!Fr[e.id],onClick:()=>void K(()=>V.setFabricEgressPoolNode(E,e.id,Fr[e.id],{status:`active`}),`Узел назначен выходной зоне.`),children:H.assignEndpointNode})]})]},e.id)}),Gt.length===0&&(0,C.jsx)(pe,{title:H.fabricEgressPools,text:H.egressPoolsEmpty})]})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:H.fabricMap}),(0,C.jsx)(`p`,{className:`muted`,children:`Визуальный слой показывает, какие узлы живы, какие сервисы на них назначены и какие тестовые наблюдения связей проходят между ними.`})]}),(0,C.jsx)(de,{value:Hi?.synthetic_links_enabled?`enabled`:`disabled`})]}),(0,C.jsx)(be,{nodes:j,links:Ft,syntheticMeshConfigsByNode:Lt,entryPoints:Vt,entryPointNodesById:Ut,egressPools:Gt,egressPoolNodesById:qt,rolesByNode:tt,workloadsByNode:ot,telemetryByNode:Nt,labels:H,emptyText:H.noLinks})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:`Synthetic mesh config`}),(0,C.jsx)(`p`,{className:`muted`,children:`Node-scoped config from Control Plane. Endpoint candidates and scoring inputs are visible to the platform owner only; production forwarding for service traffic must remain disabled here.`})]}),(0,C.jsxs)(`span`,{className:Xi===0?`pill good`:`pill bad`,children:[`production_forwarding=`,Xi===0?`false`:`true`]})]}),(0,C.jsx)(je,{columns:[`узел`,`config`,`routes`,`peer endpoints`,`candidates`,`peer dir`,`recovery seeds`,`rendezvous leases`,`relay policy`,`path decisions`,`authority`,`scoped production`],rows:j.map(e=>{let t=Lt[e.id];return[e.name,t?t.enabled?`enabled`:`disabled`:`не загружен`,String(t?.routes.length??0),String(Object.keys(t?.peer_endpoints||{}).length),String(t?st(t):0),String(t?.peer_directory?.length??0),String(t?.recovery_seeds?.length??0),String(t?.rendezvous_leases?.length??0),ct(t),lt(t),t?.authority_required?P(t.authority_signature?.key_fingerprint):`не требуется`,t?.production_forwarding?`true`:`false`]})}),(0,C.jsx)(`p`,{className:`muted`,children:`Health-aware scoring не выбирает service route и не открывает service-соединения. C17Z19 показывает control-plane route/path decisions, route generation status, synthetic route-health effective path и relay feedback scoring, но не переносит RDP/VPN/file/video/service payload.`})]}),(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsx)(`h3`,{children:H.servicePlacement}),(0,C.jsx)(je,{columns:[`узел`,`runtime`,`адрес`,`здоровье`,`роли`,`желаемые / reported сервисы`,`последний heartbeat`],rows:j.map(e=>{let t=rt(e,St[e.id]||[],Ft);return[e.name,(0,C.jsx)(ve,{runtime:t}),t.address,e.health_status,Pe(tt[e.id]||[]),Le(ot[e.id]||[]),F((St[e.id]||[])[0]?.observed_at||e.last_seen_at)]})})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:H.trafficFlow}),(0,C.jsx)(je,{columns:[`источник`,`цель`,`тип`,`route/path`,`статус`,`задержка`,`качество`,`наблюдение`],rows:qe(Ft).filter(e=>e.source_node_id!==e.target_node_id).map(e=>{let t=j.find(t=>t.id===e.source_node_id),n=j.find(t=>t.id===e.target_node_id);return[(0,C.jsx)(ye,{node:t,fallback:ut(j,e.source_node_id),heartbeatsByNode:St,meshLinks:Ft}),(0,C.jsx)(ye,{node:n,fallback:ut(j,e.target_node_id),heartbeatsByNode:St,meshLinks:Ft}),Ye(e),Xe(e,j),e.link_status,e.latency_ms==null?`н/д`:`${e.latency_ms} мс`,e.quality_score==null?`н/д`:`${e.quality_score}/100`,F(e.observed_at)]})})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Политики QoS`}),(0,C.jsx)(je,{columns:[`класс`,`приоритет`,`надежность`,`политика сброса`],rows:zt.map(e=>[e.service_class,String(e.priority),e.reliability_mode,e.drop_policy])})]})]}),T===`vpn`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Создать желаемое состояние VPN-подключения`}),(0,C.jsx)(`p`,{className:`muted`,children:`Только control-plane. Здесь не выполняются TUN/TAP, маршруты, DNS, firewall, QoS или packet forwarding.`}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`ID организации`,(0,C.jsx)(`input`,{value:z.organizationId,onChange:e=>Gr({...z,organizationId:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Название`,(0,C.jsx)(`input`,{value:z.name,onChange:e=>Gr({...z,name:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Протокол`,(0,C.jsxs)(`select`,{value:z.protocolFamily,onChange:e=>Gr({...z,protocolFamily:e.target.value}),children:[(0,C.jsx)(`option`,{value:`generic`,children:`generic`}),(0,C.jsx)(`option`,{value:`wireguard`,children:`wireguard`}),(0,C.jsx)(`option`,{value:`ipsec`,children:`ipsec`}),(0,C.jsx)(`option`,{value:`openvpn`,children:`openvpn`})]})]}),(0,C.jsxs)(`label`,{children:[`Желаемое состояние`,(0,C.jsxs)(`select`,{value:z.desiredState,onChange:e=>Gr({...z,desiredState:e.target.value}),children:[(0,C.jsx)(`option`,{value:`disabled`,children:`выключено`}),(0,C.jsx)(`option`,{value:`enabled`,children:`включено`})]})]}),(0,C.jsxs)(`label`,{children:[`Ссылка на credential`,(0,C.jsx)(`input`,{value:z.credentialRef,onChange:e=>Gr({...z,credentialRef:e.target.value})})]})]}),(0,C.jsxs)(`label`,{children:[`Целевой endpoint JSON`,(0,C.jsx)(`textarea`,{value:z.targetEndpointJson,onChange:e=>Gr({...z,targetEndpointJson:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Политика разрешенных узлов JSON`,(0,C.jsx)(`textarea`,{value:z.allowedNodePolicyJson,onChange:e=>Gr({...z,allowedNodePolicyJson:e.target.value})})]}),(0,C.jsxs)(`details`,{children:[(0,C.jsx)(`summary`,{children:`Расширенные routing / QoS / placement JSON`}),(0,C.jsxs)(`label`,{children:[`Использование маршрутизации JSON`,(0,C.jsx)(`textarea`,{value:z.routingUsageJson,onChange:e=>Gr({...z,routingUsageJson:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Политика маршрута JSON`,(0,C.jsx)(`textarea`,{value:z.routePolicyJson,onChange:e=>Gr({...z,routePolicyJson:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Политика QoS JSON`,(0,C.jsx)(`textarea`,{value:z.qosPolicyJson,onChange:e=>Gr({...z,qosPolicyJson:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Политика размещения JSON`,(0,C.jsx)(`textarea`,{value:z.placementPolicyJson,onChange:e=>Gr({...z,placementPolicyJson:e.target.value})})]})]}),(0,C.jsx)(`button`,{className:`primary`,disabled:!E||!z.organizationId||!z.name,onClick:()=>void K(()=>V.createVPNConnection(E,{organizationId:z.organizationId,name:z.name,protocolFamily:z.protocolFamily,credentialRef:z.credentialRef||null,desiredState:z.desiredState,targetEndpoint:Me(z.targetEndpointJson,`target endpoint`),allowedNodePolicy:Me(z.allowedNodePolicyJson,`allowed node policy`),routingUsage:Ne(z.routingUsageJson,`routing usage`),routePolicy:Me(z.routePolicyJson,`route policy`),qosPolicy:Me(z.qosPolicyJson,`qos policy`),placementPolicy:Me(z.placementPolicyJson,`placement policy`)}),`Желаемое состояние VPN создано.`),children:`Создать желаемое состояние VPN`})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:`VPN-подключения`}),(0,C.jsx)(`p`,{className:`muted`,children:`Cluster-managed состояние, gateway packet stats и диагностика Android-клиента.`})]}),(0,C.jsxs)(`div`,{className:`actions compactActions`,children:[(0,C.jsx)(`button`,{onClick:()=>void K(async()=>{Kn(`Истекшие VPN lease: ${(await V.expireStaleVPNLeases(E)).length}.`)},`Stale VPN lease проверены.`),children:`Проверить stale lease`}),(0,C.jsx)(`button`,{onClick:()=>void Mi(),children:`Обновить клиент`})]})]}),(0,C.jsxs)(`div`,{className:`inlineForm`,children:[(0,C.jsxs)(`label`,{children:[`Android device id`,(0,C.jsx)(`input`,{value:ln,placeholder:`0315f630-...`,onChange:e=>un(e.target.value),onBlur:()=>localStorage.setItem(w.vpnDiagnosticDeviceId,ln.trim())})]}),dn.length>0&&(0,C.jsxs)(`label`,{children:[`Найденные клиенты`,(0,C.jsx)(`select`,{value:ln,onChange:e=>{let t=e.target.value;un(t),localStorage.setItem(w.vpnDiagnosticDeviceId,t),mn(dn.find(e=>e.device_id===t)||null)},children:dn.map(e=>{let t=et(e.payload)||{};return(0,C.jsxs)(`option`,{value:e.device_id,children:[P(e.device_id),` / `,M(t,`app_version`,`н/д`),` / `,F(e.observed_at)]},e.device_id)})})]})]}),(0,C.jsxs)(`div`,{className:`diagnosticCommandPanel`,children:[(0,C.jsxs)(`label`,{children:[`URL для теста`,(0,C.jsx)(`input`,{value:gn,onChange:e=>_n(e.target.value)})]}),(0,C.jsxs)(`div`,{className:`actions compactActions`,children:[(0,C.jsx)(`button`,{onClick:()=>void Ni({type:`refresh_profile`},`Профиль`),children:`Обновить профиль`}),(0,C.jsx)(`button`,{onClick:()=>void Ni({type:`start_vpn`},`VPN`),children:`Старт VPN`}),(0,C.jsx)(`button`,{onClick:()=>void Ni({type:`stop_vpn`},`VPN`),children:`Стоп VPN`}),(0,C.jsx)(`button`,{onClick:()=>void Ni({type:`vpn_stats`},`Stats`),children:`Stats`}),(0,C.jsx)(`button`,{onClick:()=>void Ni({type:`vpn_http_get`,url:gn},`VPN HTTP`),children:`VPN HTTP`}),(0,C.jsx)(`button`,{onClick:()=>void Ni({type:`open_url`,url:gn},`Открыть URL`),children:`Открыть URL`}),(0,C.jsx)(`button`,{className:`primary`,onClick:()=>void Ni({type:`full_vpn_test`,url:gn,watch_seconds:45},`Полный VPN test`),children:`Полный тест`})]}),xn&&(0,C.jsxs)(`p`,{className:`muted`,children:[`Последняя команда: `,M(xn.payload,`type`,`н/д`),` / `,F(xn.created_at)]})]}),me(pn),(0,C.jsxs)(`div`,{className:`stack`,children:[Xt.map(e=>{let t=et(e.metadata?.client_config),n=et(t?.vpn_fabric_route),r=vt(n?.entry_pool_node_ids||e.placement_policy?.entry_node_ids),i=vt(n?.exit_pool_node_ids||e.placement_policy?.exit_node_ids),a=String(n?.selected_entry_node_id||r[0]||``),o=String(n?.selected_exit_node_id||tn[e.id]?.owner_node_id||e.placement_policy?.exit_node_id||i[0]||``),s=sn[e.id]||{};return(0,C.jsxs)(`div`,{className:`vpnCard`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`strong`,{children:e.name}),(0,C.jsxs)(`p`,{className:`muted`,children:[e.protocol_family,` / `,e.mode,` / организация `,P(e.organization_id)]}),(0,C.jsx)(de,{value:e.desired_state}),(0,C.jsx)(de,{value:e.status}),(0,C.jsx)(`span`,{className:`pill ${t?.packet_forwarding?`good`:`warn`}`,children:t?.packet_forwarding?`gateway packet relay active`:`gateway packet relay inactive`}),(0,C.jsxs)(`span`,{className:`pill`,children:[String(n?.preferred_data_plane||`backend_relay`),` / fallback `,String(n?.fallback_data_plane||`н/д`)]})]}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Секрет`,value:e.credential_ref?`задан`:`не задан`}),(0,C.jsx)(A,{label:`Активный lease`,value:tn[e.id]?P(tn[e.id]?.owner_node_id):`нет`}),(0,C.jsx)(A,{label:`Fabric route`,value:`${a?ut(j,a):`entry auto`} -> ${o?ut(j,o):`exit auto`}`}),(0,C.jsx)(A,{label:`Entry pool`,value:r.map(e=>ut(j,e)).join(`, `)||`н/д`}),(0,C.jsx)(A,{label:`Exit pool`,value:i.map(e=>ut(j,e)).join(`, `)||`н/д`}),(0,C.jsx)(A,{label:`Runtime`,value:String(t?.runtime_status||`н/д`)}),(0,C.jsx)(A,{label:`Gateway`,value:String(t?.gateway_assignment_status||`н/д`)}),(0,C.jsx)(A,{label:`Client -> gateway`,value:He(s.client_to_gateway)}),(0,C.jsx)(A,{label:`Gateway -> client`,value:He(s.gateway_to_client)}),(0,C.jsx)(A,{label:`Обновлено`,value:F(e.updated_at)})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{disabled:e.desired_state===`enabled`,onClick:()=>void K(()=>V.updateVPNConnectionDesiredState(E,e.id,`enabled`),`Желаемое состояние VPN включено.`),children:`Включить`}),(0,C.jsx)(`button`,{disabled:e.desired_state===`disabled`,onClick:()=>void K(()=>V.updateVPNConnectionDesiredState(E,e.id,`disabled`),`Желаемое состояние VPN выключено.`),children:`Выключить`})]})]},e.id)}),Xt.length===0&&(0,C.jsx)(pe,{title:`Нет желаемого состояния VPN`,text:`Control-plane записи C18 появятся здесь.`})]})]})]}),T===`org-safe`&&(0,C.jsxs)(`section`,{className:`grid two`,children:[(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:`Организации и пользователи`}),(0,C.jsx)(`p`,{className:`muted`,children:`Операционный слой для владельца платформы: tenant scope, роли участников и безопасная сводка без раскрытия core mesh.`})]}),(0,C.jsx)(`span`,{className:`pill`,children:Cn.length})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Slug`,(0,C.jsx)(`input`,{value:Kr.slug,onChange:e=>qr({...Kr,slug:e.target.value}),placeholder:`home`})]}),(0,C.jsxs)(`label`,{children:[`Название`,(0,C.jsx)(`input`,{value:Kr.name,onChange:e=>qr({...Kr,name:e.target.value}),placeholder:`HOME`})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{className:`primary`,disabled:!Kr.slug.trim()||!Kr.name.trim(),onClick:()=>void K(async()=>{let e=await V.createOrganization(Kr);qr({slug:``,name:``}),Rn(e.id),Zr(t=>({...t,organizationId:e.id})),ni(t=>({...t,organizationId:e.id}))},`Организация создана.`),children:`Создать организацию`})}),(0,C.jsx)(je,{columns:[`организация`,`slug`,`статус`,`ресурсы`,`участники`,`действие`],rows:Cn.map(e=>{let t=Dn.filter(t=>t.organization_id===e.id),n=kn[e.id]||[];return[e.name,e.slug,(0,C.jsx)(de,{value:e.status}),String(t.length),String(n.length),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{onClick:()=>void K(async()=>{Rn(e.id),Bn(await V.getOrganizationAdminSummary(e.id))},`Сводка организации загружена.`),children:`Открыть`})},e.id)]})})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Пользователь`}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Email / логин`,(0,C.jsx)(`input`,{value:Jr.email,onChange:e=>Yr({...Jr,email:e.target.value}),placeholder:`user@example.com`})]}),(0,C.jsxs)(`label`,{children:[`Пароль`,(0,C.jsx)(`input`,{type:`password`,value:Jr.password,onChange:e=>Yr({...Jr,password:e.target.value}),placeholder:`минимум 8 символов`})]}),(0,C.jsxs)(`label`,{children:[`Роль платформы`,(0,C.jsxs)(`select`,{value:Jr.platformRole,onChange:e=>Yr({...Jr,platformRole:e.target.value}),children:[(0,C.jsx)(`option`,{value:`user`,children:`user`}),(0,C.jsx)(`option`,{value:`platform_admin`,children:`platform_admin`}),(0,C.jsx)(`option`,{value:`platform_recovery_admin`,children:`platform_recovery_admin`})]})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{disabled:!Jr.email.trim()||Jr.password.length<8,onClick:()=>void K(async()=>{let e=await V.createUser(Jr);En(await V.listUsers()),Yr({email:``,password:``,platformRole:`user`}),Zr(t=>({...t,userId:e.id}))},`Пользователь создан.`),children:`Создать пользователя`})}),(0,C.jsx)(je,{columns:[`пользователь`,`роль платформы`,`id`],rows:Tn.map(e=>[e.email,(0,C.jsx)(de,{value:e.platform_role||`user`}),(0,C.jsx)(`code`,{children:e.id})])})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Участник организации`}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Организация`,(0,C.jsxs)(`select`,{value:Xr.organizationId,onChange:e=>Zr({...Xr,organizationId:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Выберите организацию`}),Cn.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,C.jsxs)(`label`,{children:[`Пользователь`,(0,C.jsxs)(`select`,{value:Xr.userId,onChange:e=>Zr({...Xr,userId:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Выберите пользователя`}),Tn.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.email},e.id))]})]}),(0,C.jsxs)(`label`,{children:[`Роль`,(0,C.jsxs)(`select`,{value:Xr.roleId,onChange:e=>Zr({...Xr,roleId:e.target.value}),children:[(0,C.jsx)(`option`,{value:`org_owner`,children:`org_owner`}),(0,C.jsx)(`option`,{value:`org_admin`,children:`org_admin`}),(0,C.jsx)(`option`,{value:`org_operator`,children:`org_operator`}),(0,C.jsx)(`option`,{value:`org_member`,children:`org_member`}),(0,C.jsx)(`option`,{value:`org_viewer`,children:`org_viewer`})]})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{disabled:!Xr.organizationId||!Xr.userId.trim(),onClick:()=>void K(()=>V.addOrganizationMembership(Xr.organizationId,{userId:Xr.userId,roleId:Xr.roleId}),`Участник организации сохранен.`),children:`Сохранить участника`})})]}),(0,C.jsxs)(`article`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Безопасная сводка`}),(0,C.jsxs)(`div`,{className:`inlineForm`,children:[(0,C.jsxs)(`select`,{value:Ln,onChange:e=>Rn(e.target.value),children:[(0,C.jsx)(`option`,{value:``,children:`Выберите организацию`}),Cn.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,C.jsx)(`button`,{disabled:!Ln,onClick:()=>void K(async()=>{Bn(await V.getOrganizationAdminSummary(Ln))},`Сводка организации загружена.`),children:`Обновить`})]}),zn?(0,C.jsxs)(`div`,{className:`stack`,children:[(0,C.jsx)(ue,{label:`Ресурсы`,value:zn.resource_count,tone:`steel`}),(0,C.jsx)(ue,{label:`Активные сессии`,value:zn.active_session_count,tone:`green`}),(0,C.jsx)(A,{label:`Topology exposure`,value:zn.topology_exposure}),(0,C.jsx)(je,{columns:[`контур`,`состояние`],rows:Object.entries(zn.connector_status||{}).map(([e,t])=>[e,typeof t==`string`?I(t):JSON.stringify(t)])}),(0,C.jsx)(je,{columns:[`протокол`,`количество`],rows:zn.service_endpoints.map(e=>[e.protocol,String(e.count)])})]}):(0,C.jsx)(pe,{title:`Сводка не выбрана`,text:`Выберите организацию, чтобы проверить tenant-safe состояние.`})]})]}),T===`servers`&&(0,C.jsx)(`section`,{className:`grid two`,children:(0,C.jsxs)(`article`,{className:`card span2`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{children:`Справочник серверов`}),(0,C.jsx)(`p`,{className:`muted`,children:`Единый каталог целей для RDP/VPN: адрес сервера, организация, протокол и предпочтительный вход/выход маршрута.`})]}),(0,C.jsx)(`span`,{className:`pill`,children:Dn.length})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Организация`,(0,C.jsxs)(`select`,{value:B.organizationId,onChange:e=>ni({...B,organizationId:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Выберите организацию`}),Cn.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,C.jsxs)(`label`,{children:[`Имя сервера`,(0,C.jsx)(`input`,{value:B.name,onChange:e=>ni({...B,name:e.target.value}),placeholder:`Office RDP`})]}),(0,C.jsxs)(`label`,{children:[`Адрес`,(0,C.jsx)(`input`,{value:B.address,onChange:e=>ni({...B,address:e.target.value}),placeholder:`192.168.1.10:3389`})]}),(0,C.jsxs)(`label`,{children:[`Протокол`,(0,C.jsxs)(`select`,{value:B.protocol,onChange:e=>ni({...B,protocol:e.target.value}),children:[(0,C.jsx)(`option`,{value:`rdp`,children:`RDP`}),(0,C.jsx)(`option`,{value:`vpn`,children:`VPN`}),(0,C.jsx)(`option`,{value:`ssh`,children:`SSH`}),(0,C.jsx)(`option`,{value:`http`,children:`HTTP`})]})]}),(0,C.jsxs)(`label`,{children:[`Вход`,(0,C.jsxs)(`select`,{value:B.entryNode,onChange:e=>ni({...B,entryNode:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Автоматически`}),j.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,C.jsxs)(`label`,{children:[`Выход`,(0,C.jsxs)(`select`,{value:B.exitNode,onChange:e=>ni({...B,exitNode:e.target.value}),children:[(0,C.jsx)(`option`,{value:``,children:`Автоматически`}),j.map(e=>(0,C.jsx)(`option`,{value:e.id,children:e.name},e.id))]})]}),(0,C.jsxs)(`label`,{children:[`Теги`,(0,C.jsx)(`input`,{value:B.tags,onChange:e=>ni({...B,tags:e.target.value}),placeholder:`home, accounting`})]}),(0,C.jsxs)(`label`,{children:[`RDP пользователь`,(0,C.jsx)(`input`,{value:B.username,onChange:e=>ni({...B,username:e.target.value}),placeholder:`user или DOMAIN\\\\user`})]}),(0,C.jsxs)(`label`,{children:[`RDP пароль`,(0,C.jsx)(`input`,{type:`password`,value:B.password,onChange:e=>ni({...B,password:e.target.value}),placeholder:`хранится как secret`})]}),(0,C.jsxs)(`label`,{children:[`Домен`,(0,C.jsx)(`input`,{value:B.domain,onChange:e=>ni({...B,domain:e.target.value}),placeholder:`опционально`})]})]}),(0,C.jsx)(`div`,{className:`actions`,children:(0,C.jsx)(`button`,{className:`primary`,disabled:!B.organizationId||!B.name.trim()||!B.address.trim(),onClick:()=>void K(async()=>{let e=[`rdp`,`vnc`,`ssh`].includes(B.protocol)?`rap-secret://org/${B.organizationId}/resources/${crypto.randomUUID()}/primary`:null,t=await V.createResource({organizationId:B.organizationId,name:B.name,address:B.address,protocol:B.protocol,secretRef:e,certificateVerificationMode:B.protocol===`rdp`?`ignore`:`strict`,clipboardMode:B.protocol===`rdp`?`bidirectional`:`disabled`,fileTransferMode:B.protocol===`rdp`?`bidirectional`:`disabled`,metadata:{route_mode:B.routeMode,preferred_entry_node_id:B.entryNode||null,preferred_exit_node_id:B.exitNode||null,tags:B.tags.split(`,`).map(e=>e.trim()).filter(Boolean)}});[`rdp`,`vnc`,`ssh`].includes(B.protocol)&&(B.username.trim()||B.password)&&await V.upsertResourceSecret(t.id,{username:B.username.trim(),password:B.password,domain:B.domain.trim()}),ni({...B,name:``,address:``,tags:``,username:``,password:``,domain:``})},`Сервер добавлен в справочник.`),children:`Добавить сервер`})}),(0,C.jsx)(je,{columns:[`сервер`,`адрес`,`протокол`,`секрет`,`организация`,`маршрут`,`создано`,`действия`],rows:Dn.map(e=>{let t=e.metadata||{},n=Cn.find(t=>t.id===e.organization_id);return[e.name,e.address,e.protocol,e.has_secret?`сохранен`:e.secret_ref?`нужен payload`:`нет`,n?.name||P(e.organization_id),`${P(String(t.preferred_entry_node_id||``))||`auto`} -> ${P(String(t.preferred_exit_node_id||``))||`auto`}`,F(e.created_at),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>{$r(e),ti({username:``,password:``,domain:``})},children:`Обновить secret`})]})}),Qr&&(0,C.jsx)(`div`,{className:`modalBackdrop`,role:`presentation`,children:(0,C.jsxs)(`div`,{className:`modalCard`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`resource-secret-title`,children:[(0,C.jsxs)(`div`,{className:`cardHead`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(`h3`,{id:`resource-secret-title`,children:`Учетные данные RDP`}),(0,C.jsxs)(`p`,{className:`muted`,children:[Qr.name,` · `,Qr.address]})]}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>$r(null),children:`Закрыть`})]}),(0,C.jsxs)(Ae,{children:[(0,C.jsxs)(`label`,{children:[`Пользователь`,(0,C.jsx)(`input`,{value:ei.username,onChange:e=>ti({...ei,username:e.target.value}),placeholder:`user или DOMAIN\\\\user`})]}),(0,C.jsxs)(`label`,{children:[`Пароль`,(0,C.jsx)(`input`,{type:`password`,value:ei.password,onChange:e=>ti({...ei,password:e.target.value})})]}),(0,C.jsxs)(`label`,{children:[`Домен`,(0,C.jsx)(`input`,{value:ei.domain,onChange:e=>ti({...ei,domain:e.target.value}),placeholder:`опционально`})]})]}),(0,C.jsx)(`p`,{className:`muted`,children:`Пароль сохраняется как encrypted resource secret. В metadata ресурса он не попадет.`}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{className:`primary`,disabled:!ei.username.trim()||!ei.password,onClick:()=>void K(async()=>{await V.upsertResourceSecret(Qr.id,{username:ei.username.trim(),password:ei.password,domain:ei.domain.trim()}),$r(null),ti({username:``,password:``,domain:``})},`Secret ресурса обновлен.`),children:`Сохранить secret`}),(0,C.jsx)(`button`,{onClick:()=>$r(null),children:`Отмена`})]})]})})]})}),T===`audit`&&(0,C.jsxs)(`section`,{className:`card`,children:[(0,C.jsx)(`h3`,{children:`Аудит кластера`}),(0,C.jsx)(je,{columns:[`событие`,`цель`,`actor`,`создано`],rows:jn.map(e=>[e.event_type,`${e.target_type}${e.target_id?`:${P(e.target_id)}`:``}`,e.actor_user_id?P(e.actor_user_id):`system`,F(e.created_at)])})]})]})]})}function ue({label:e,value:t,tone:n}){return(0,C.jsxs)(`article`,{className:`metric ${n}`,children:[(0,C.jsx)(`span`,{children:e}),(0,C.jsx)(`strong`,{children:t})]})}function k({label:e,value:t}){return(0,C.jsxs)(`div`,{className:`signal`,children:[(0,C.jsx)(`span`,{children:e}),(0,C.jsx)(`strong`,{children:t})]})}function de({value:e}){return(0,C.jsx)(`span`,{className:`status ${e.replace(/_/g,`-`)}`,children:I(e)})}function fe({label:e,value:t,tone:n}){return(0,C.jsxs)(`span`,{className:`functionState ${n||``}`,children:[(0,C.jsx)(`small`,{children:e}),(0,C.jsx)(`strong`,{children:t})]})}function A({label:e,value:t}){return(0,C.jsxs)(`div`,{className:`stateLine`,children:[(0,C.jsx)(`span`,{children:e}),(0,C.jsx)(`strong`,{children:t})]})}function pe({title:e,text:t}){return(0,C.jsxs)(`article`,{className:`empty`,children:[(0,C.jsx)(`h3`,{children:e}),(0,C.jsx)(`p`,{children:t})]})}function me(e){if(!e)return(0,C.jsx)(`p`,{className:`muted`,children:`Диагностика Android-клиента не загружена. Укажи device id из приложения и нажми “Обновить клиент”.`});let t=et(e.payload)||{},n=et(t.runtime),r=et(t.vpn_config),i=M(t,`app_version`,`н/д`),a=M(t,`service_state`,`н/д`),o=M(t,`control_network_mode`,`н/д`),s=M(r,`packet_relay_active_base_url`)||M(r,`packet_relay_base_url`,`н/д`),c=M(r,`packet_relay_profile_base_url`,`н/д`),l=M(r,`packet_relay_candidate_urls`,`н/д`),u=it(n,`uplink_read_total`),d=it(n,`uplink_sent_total`),f=it(n,`downlink_received_total`),p=it(n,`uplink_dropped_packets`)+it(n,`downlink_dropped_packets`),m=it(n,`uplink_bypassed_control_packets`),h=it(n,`downlink_received_bytes`),g=it(n,`uplink_sent_bytes`),_=M(n,`state`,`н/д`),v=M(n,`message`,``),y=it(n,`uplink_sent_mbps`),b=it(n,`downlink_received_mbps`),x=M(t,`last_command_type`,`н/д`),S=M(t,`last_command_result`,`н/д`);return(0,C.jsxs)(`div`,{className:`vpnCard diagnosticCard`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsxs)(`strong`,{children:[`Android client `,P(e.device_id)]}),(0,C.jsxs)(`p`,{className:`muted`,children:[i,` / `,a,` / `,F(e.observed_at)]}),(0,C.jsx)(de,{value:Date.now()-new Date(e.observed_at).getTime()<3e4?`active`:`degraded`}),(0,C.jsx)(`span`,{className:`pill`,children:o})]}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Relay active`,value:s}),(0,C.jsx)(A,{label:`Relay profile`,value:c}),(0,C.jsx)(A,{label:`Relay candidates`,value:l}),(0,C.jsx)(A,{label:`Packets read/sent/down`,value:`${u} / ${d} / ${f}`}),(0,C.jsx)(A,{label:`Drops / control bypass`,value:`${p} / ${m}`}),(0,C.jsx)(A,{label:`Bytes up/down`,value:`${xn(g)} / ${xn(h)}`}),(0,C.jsx)(A,{label:`Rate up/down`,value:`${y.toFixed(2)} / ${b.toFixed(2)} Mbps`}),(0,C.jsx)(A,{label:`Runtime`,value:v?`${_}: ${v}`:_}),(0,C.jsx)(A,{label:`Last command`,value:`${x}: ${S}`})]})]})}function he({items:e,emptyText:t}){if(e.length===0)return(0,C.jsx)(pe,{title:t,text:`Тестовая телеметрия появится здесь после отчета node-agent.`});let n=[...e].reverse().slice(-24),r=e[0],i=Math.max(...n.map(e=>e.memory_used_bytes||0),1);return(0,C.jsxs)(`div`,{className:`telemetryBox`,children:[(0,C.jsxs)(`div`,{className:`signalStrip compact`,children:[(0,C.jsx)(k,{label:`Память`,value:`${xn(r.memory_used_bytes)} / ${xn(r.memory_total_bytes)}`}),(0,C.jsx)(k,{label:`Процессор`,value:r.cpu_percent==null?`н/д`:`${r.cpu_percent.toFixed(1)}%`}),(0,C.jsx)(k,{label:`Процессы`,value:r.process_count==null?`н/д`:String(r.process_count)}),(0,C.jsx)(k,{label:`Обновлено`,value:F(r.observed_at)})]}),(0,C.jsx)(`div`,{className:`sparkline`,"aria-label":`memory telemetry`,children:n.map(e=>(0,C.jsx)(`span`,{style:{height:`${Math.max(8,Math.round((e.memory_used_bytes||0)/i*100))}%`}},e.id))})]})}function ge({node:e,memberships:t,activeRoles:n,desiredWorkloads:r,observedWorkloads:i,heartbeats:a,telemetry:o,meshLinks:s,syntheticConfig:c,allNodes:l,onSetUpdatePolicy:u,updatePlan:d,updateStatuses:f,labels:p}){let m=a[0],h=o[0],g=et(m?.metadata?.mesh_listener_report),v=et(m?.metadata?.mesh_endpoint_report),y=et(m?.metadata?.mesh_outbound_session_report),b=c?.mesh_listener,x=et(m?.metadata?.mesh_peer_recovery_report),S=et(m?.metadata?.mesh_peer_connection_intent_report),w=et(m?.metadata?.mesh_peer_connection_manager_report),ee=et(m?.metadata?.mesh_rendezvous_lease_report),te=et(m?.metadata?.mesh_route_path_decision_report),ne=et(m?.metadata?.mesh_route_generation_report),T=et(m?.metadata?.mesh_route_health_config_report),re=qe(s).filter(e=>e.source_node_id!==e.target_node_id),ie=re.filter(e=>e.link_status===`reachable`),E=re.filter(e=>e.link_status!==`reachable`),ae=Object.entries(m?.capabilities||{}).sort(([e],[t])=>e.localeCompare(t)),oe=tt(w?.probe_results),[se,ce]=(0,_.useState)(`network`),D=ze(f,`rap-node-agent`),O=ze(f,`rap-host-agent`),le=f[0],ue=We(f),fe=t.find(t=>t.node.id===e.id)?.cluster.id||t[0]?.cluster.id||``,pe=tt(v?.endpoint_candidates),me=pe[0],ge=nt(v,[`peer_endpoint`,`advertised_endpoint`,`endpoint`])||M(me,`address`,``)||``,ve=nt(v,[`transport`,`advertise_transport`])||M(me,`transport`,``)||`н/д`,ye=nt(v,[`connectivity_mode`,`connectivity`])||M(me,`connectivity_mode`,``)||M(g,`inbound_reachability`,``)||`н/д`,be=M(v,`nat_type`,M(me,`nat_type`,`н/д`)),xe=M(v,`region`,M(g,`region`,M(me,`region`,`н/д`))),Se=M(v,`observed_at`,M(g,`observed_at`,m?.observed_at||`н/д`)),Ce=M(g,`status`,``)||(ge?`нет listener report, есть advertised endpoint`:`report отсутствует`),we=M(g,`effective_listen_addr`,``)||`н/д`,j=M(g,`configured_listen_addr`,``)||`н/д`,Te=pe.length>0?pe:ge?[{endpoint_id:`${e.id}-reported`,address:ge,transport:ve,reachability:ye,connectivity_mode:ye,nat_type:be,priority:`н/д`,last_verified_at:Se}]:[],Ee=Object.entries(c?.peer_endpoints||{}),De=Object.entries(c?.peer_endpoint_candidates||{}).flatMap(([e,t])=>t.map(t=>({peerID:e,candidate:t}))),Oe=new Set(ie.map(t=>t.source_node_id===e.id?t.target_node_id:t.source_node_id)),ke=De.filter(({peerID:e})=>!Oe.has(e)),Ae=[g?`listener report: есть`:`listener report: не прислан агентом`,v?`endpoint report: есть`:`endpoint report: не прислан агентом`,y?`outbound session: есть`:`outbound session: не прислан агентом`,c?`scoped config: ${c.enabled?`enabled`:`disabled`}`:`scoped config: не загружен`,`active links: ${ie.length}/${re.length}`];return(0,C.jsxs)(`div`,{className:`nodeDetails`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Сводка runtime`}),(0,C.jsxs)(`div`,{className:`signalStrip compact nodeMetricGrid`,children:[(0,C.jsx)(k,{label:`Heartbeat`,value:m?F(m.observed_at):`н/д`}),(0,C.jsx)(k,{label:`Health`,value:I(m?.health_status||e.health_status)}),(0,C.jsx)(k,{label:`Listener`,value:mn(m)}),(0,C.jsx)(k,{label:`Mesh links`,value:`${ie.length}/${re.length}`}),(0,C.jsx)(k,{label:`Update`,value:Be(le,d)})]}),(0,C.jsxs)(`div`,{className:`summaryChips`,children:[(0,C.jsx)(de,{value:e.registration_status}),(0,C.jsx)(de,{value:e.membership_status}),(0,C.jsx)(de,{value:e.partition_state}),(0,C.jsx)(`span`,{className:`pill`,children:e.reported_version||m?.reported_version||`версия неизвестна`}),g?.one_way_connectivity===!0&&(0,C.jsx)(`span`,{className:`pill warn`,children:`one-way`}),g?.port_conflict===!0&&(0,C.jsx)(`span`,{className:`pill bad`,children:`port conflict`})]})]}),(0,C.jsx)(`div`,{className:`nodeTabs`,role:`tablist`,"aria-label":`Node analysis sheets`,children:[[`overview`,`Обзор`],[`network`,`Сеть и адреса`],[`mesh`,`Mesh`],[`services`,`Роли и сервисы`],[`telemetry`,`Телеметрия`],[`updates`,`Обновления`],[`raw`,`Raw`]].map(([e,t])=>(0,C.jsx)(`button`,{className:se===e?`active`:``,onClick:()=>ce(e),type:`button`,children:t},e))}),se===`overview`&&(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Идентичность и размещение`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Node ID`,value:e.id}),(0,C.jsx)(A,{label:`Node key`,value:e.node_key}),(0,C.jsx)(A,{label:`Имя`,value:e.name}),(0,C.jsx)(A,{label:`Владение`,value:I(e.ownership_type)}),(0,C.jsx)(A,{label:`Owner org`,value:P(e.owner_organization_id)}),(0,C.jsx)(A,{label:`Группа`,value:e.node_group_name||p.ungroupedNodes}),(0,C.jsx)(A,{label:`Создан`,value:F(e.created_at)}),(0,C.jsx)(A,{label:`Обновлен`,value:F(e.updated_at)})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Участие в кластерах`}),(0,C.jsx)(`div`,{className:`membershipList`,children:t.map(t=>(0,C.jsxs)(`span`,{className:t.node.id===e.id&&t.node.membership_status===`active`?`pill good`:`pill`,children:[t.cluster.name,`: `,I(t.node.membership_status)]},t.cluster.id))}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Активных ролей`,value:String(n.length)}),(0,C.jsx)(A,{label:`Desired workloads`,value:String(r.length)}),(0,C.jsx)(A,{label:`Observed workloads`,value:String(i.length)}),(0,C.jsx)(A,{label:`Последний сигнал`,value:F(e.last_seen_at||m?.observed_at)})]})]})]}),se===`network`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Локальный listener`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Статус`,value:Ce}),(0,C.jsx)(A,{label:`Режим порта`,value:M(g,`listen_port_mode`,`н/д`)}),(0,C.jsx)(A,{label:`Configured addr`,value:j}),(0,C.jsx)(A,{label:`Effective addr`,value:we}),(0,C.jsx)(A,{label:`Inbound`,value:M(g,`inbound_reachability`,ye)}),(0,C.jsx)(A,{label:`One-way`,value:M(g,`one_way_connectivity`,`н/д`)}),(0,C.jsx)(A,{label:`Port conflict`,value:M(g,`port_conflict`,`false`)}),(0,C.jsx)(A,{label:`Failure`,value:M(g,`failure_error`,M(g,`failure_reason`,`нет`))})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Desired listener`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Состояние`,value:b?.desired_state||`н/д`}),(0,C.jsx)(A,{label:`Режим порта`,value:b?.listen_port_mode||`н/д`}),(0,C.jsx)(A,{label:`Listen addr`,value:b?.listen_addr||`н/д`}),(0,C.jsx)(A,{label:`Auto range`,value:b?`${b.auto_port_start||`н/д`}-${b.auto_port_end||`н/д`}`:`н/д`}),(0,C.jsx)(A,{label:`Advertise endpoint`,value:b?.advertise_endpoint||`auto-discovery`}),(0,C.jsx)(A,{label:`Advertise transport`,value:b?.advertise_transport||`н/д`}),(0,C.jsx)(A,{label:`Connectivity`,value:b?.connectivity_mode||`н/д`}),(0,C.jsx)(A,{label:`NAT`,value:b?.nat_type||`н/д`}),(0,C.jsx)(A,{label:`Region/site`,value:b?.region||`н/д`}),(0,C.jsx)(A,{label:`Version`,value:b?.config_version||`н/д`})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Что узел сообщает кластеру`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Advertised endpoint`,value:ge||`не прислан`}),(0,C.jsx)(A,{label:`Transport`,value:ve}),(0,C.jsx)(A,{label:`Connectivity`,value:ye}),(0,C.jsx)(A,{label:`NAT`,value:be}),(0,C.jsx)(A,{label:`Region/site`,value:xe}),(0,C.jsx)(A,{label:`Observed`,value:Se})]})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Исходящий control-channel`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Status`,value:M(y,`status`,`не прислан`)}),(0,C.jsx)(A,{label:`Direction`,value:M(y,`direction`,`н/д`)}),(0,C.jsx)(A,{label:`Transport`,value:M(y,`transport`,`н/д`)}),(0,C.jsx)(A,{label:`Control Plane`,value:M(y,`control_plane_url`,`н/д`)}),(0,C.jsx)(A,{label:`Reverse usable`,value:M(y,`usable_for_inbound_control`,`н/д`)}),(0,C.jsx)(A,{label:`Inbound required`,value:M(y,`inbound_listener_required`,`н/д`)}),(0,C.jsx)(A,{label:`Relay ready`,value:M(y,`peer_connection_relay_ready`,`0`)}),(0,C.jsx)(A,{label:`Waiting rendezvous`,value:M(y,`peer_connection_waiting`,`0`)}),(0,C.jsx)(A,{label:`Rendezvous leases`,value:M(y,`rendezvous_lease_count`,`0`)}),(0,C.jsx)(A,{label:`Listener conflict`,value:M(y,`listener_port_conflict`,`false`)})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Наличие сетевых отчетов`}),(0,C.jsx)(`div`,{className:`summaryChips`,children:Ae.map(e=>(0,C.jsx)(`span`,{className:e.includes(`не прислан`)||e.includes(`не загружен`)?`pill warn`:`pill good`,children:e},e))}),!v&&!g&&(0,C.jsx)(`p`,{className:`muted`,children:`У этого узла есть heartbeat/mesh manager данные, но агент не передал адресный отчет. До обновления агента или включения endpoint/listener report панель может показать связи и config peers, но не может достоверно назвать локальный listen address.`})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Endpoint candidates узла`}),(0,C.jsx)(je,{columns:[`id`,`address`,`transport`,`reachability`,`mode`,`nat`,`priority`,`verified`],rows:Te.map(e=>[M(e,`endpoint_id`,`н/д`),M(e,`address`,`н/д`),M(e,`transport`,`н/д`),M(e,`reachability`,`н/д`),M(e,`connectivity_mode`,`н/д`),M(e,`nat_type`,`н/д`),M(e,`priority`,`н/д`),M(e,`last_verified_at`,`н/д`)])})]}),(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Рабочие peer endpoints из config`}),(0,C.jsx)(je,{columns:[`peer`,`endpoint`],rows:Ee.map(([e,t])=>[ut(l,e),t])})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Резервные кандидаты peer`}),(0,C.jsx)(je,{columns:[`peer`,`address`,`transport`,`reachability`,`mode`,`priority`],rows:ke.slice(0,20).map(({peerID:e,candidate:t})=>[ut(l,e),t.address,t.transport,t.reachability,t.connectivity_mode,String(t.priority)])})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Активные связи этого узла`}),(0,C.jsx)(je,{columns:[`peer`,`направление`,`тип`,`статус`,`latency`,`quality`,`путь`,`наблюдение`],rows:re.slice(0,20).map(t=>[ut(l,t.source_node_id===e.id?t.target_node_id:t.source_node_id),t.source_node_id===e.id?`out`:`in`,Ye(t),t.link_status,t.latency_ms==null?`н/д`:`${t.latency_ms}мс`,t.quality_score==null?`н/д`:String(t.quality_score),Xe(t,l),F(t.observed_at)])}),E.length>0&&(0,C.jsxs)(`p`,{className:`muted`,children:[`Проблемных связей: `,E.length,`. Их статус виден в таблице выше.`]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Проверка адресов peer-to-peer`}),(0,C.jsx)(je,{columns:[`peer`,`status`,`selected endpoint`,`candidate`,`latency`,`attempts`,`failure`],rows:oe.slice(0,20).map(e=>[ut(l,M(e,`node_id`,``)),M(e,`link_status`,`н/д`),M(e,`selected_endpoint`,M(e,`endpoint`,`н/д`)),M(e,`selected_candidate_id`,`н/д`),M(e,`latency_ms`,`н/д`),ot(e),M(e,`failure_reason`,`нет`)])})]})]}),se===`mesh`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Mesh control-plane`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Recovery`,value:sn(m)}),(0,C.jsx)(A,{label:`Intents`,value:cn(m)}),(0,C.jsx)(A,{label:`Manager`,value:pn(m)}),(0,C.jsx)(A,{label:`Rendezvous`,value:ln(m)}),(0,C.jsx)(A,{label:`Path decisions`,value:un(m)}),(0,C.jsx)(A,{label:`Route generation`,value:dn(m)}),(0,C.jsx)(A,{label:`Route health`,value:fn(m)}),(0,C.jsx)(A,{label:`Config version`,value:c?.config_version||`н/д`})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Scoped config counts`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Peer endpoints`,value:String(Ee.length)}),(0,C.jsx)(A,{label:`Endpoint candidates`,value:String(De.length)}),(0,C.jsx)(A,{label:`Peer directory`,value:String(c?.peer_directory?.length||0)}),(0,C.jsx)(A,{label:`Recovery seeds`,value:String(c?.recovery_seeds?.length||0)}),(0,C.jsx)(A,{label:`Rendezvous leases`,value:String(c?.rendezvous_leases?.length||0)}),(0,C.jsx)(A,{label:`Routes`,value:String(c?.routes?.length||0)})]})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Route decisions`}),(0,C.jsx)(je,{columns:[`route`,`source`,`destination`,`effective hops`,`relay`,`score`,`expires`],rows:(c?.route_path_decisions?.decisions||[]).map(e=>[P(e.route_id),ut(l,e.source_node_id),ut(l,e.destination_node_id),e.effective_hops.map(e=>_n(ut(l,e))).join(` > `),e.selected_relay_id?ut(l,e.selected_relay_id):`direct`,e.path_score==null?`н/д`:String(e.path_score),F(e.expires_at)])})]})]}),se===`services`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:p.nodeRoles}),(0,C.jsxs)(`div`,{className:`serviceTags`,children:[n.length===0&&(0,C.jsx)(`p`,{className:`muted`,children:p.noRoles}),n.map(e=>(0,C.jsxs)(`div`,{className:`serviceTag`,children:[(0,C.jsx)(`strong`,{children:Ie(e.role)}),(0,C.jsx)(`span`,{children:e.organization_id?`organization: ${P(e.organization_id)}`:`cluster-wide`}),(0,C.jsx)(`small`,{children:F(e.assigned_at)}),(0,C.jsx)(`span`,{className:`pill ${rn(e.role,m)}`,children:an(e.role,m,p)})]},e.id))]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Capabilities`}),(0,C.jsxs)(`div`,{className:`summaryChips`,children:[ae.length===0&&(0,C.jsx)(`span`,{className:`muted`,children:`Нет capability heartbeat.`}),ae.slice(0,40).map(([e,t])=>(0,C.jsx)(`span`,{className:t===!0?`pill good`:`pill`,children:e},e))]})]})]}),(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:p.desiredServices}),(0,C.jsx)(je,{columns:[`service`,`desired`,`runtime`,`version`,`updated`],rows:r.map(e=>[e.service_type,I(e.desired_state),e.runtime_mode,e.version||`не закреплена`,F(e.updated_at)])})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:p.observedServices}),(0,C.jsx)(je,{columns:[`service`,`reported`,`runtime`,`version`,`observed`],rows:i.map(e=>[e.service_type,I(e.reported_state),e.runtime_mode,e.version||`н/д`,F(e.observed_at)])})]})]})]}),se===`telemetry`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:p.nodeTelemetry}),(0,C.jsx)(he,{items:o,emptyText:p.noTelemetry}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Disk`,value:`${xn(h?.disk_used_bytes)} / ${xn(h?.disk_total_bytes)}`}),(0,C.jsx)(A,{label:`Network RX/TX`,value:`${xn(h?.network_rx_bytes)} / ${xn(h?.network_tx_bytes)}`}),(0,C.jsx)(A,{label:`Payload`,value:h?.payload?at(h.payload):`н/д`})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:p.recentHeartbeats}),(0,C.jsx)(je,{columns:[`состояние`,`версия`,`listener`,`mesh recovery`,`mesh intents`,`rv leases`,`path decisions`,`route gen`,`route health`,`наблюдение`],rows:a.slice(0,10).map(e=>[e.health_status,e.reported_version||`неизвестно`,mn(e),sn(e),cn(e),ln(e),un(e),dn(e),fn(e),F(e.observed_at)])})]})]}),se===`updates`&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:`nodeDetailGrid`,children:[(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Текущая сборка`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Node-agent version`,value:e.reported_version||m?.reported_version||`неизвестно`}),(0,C.jsx)(A,{label:`План`,value:d?`${d.action}: ${d.reason}`:`не загружен`}),(0,C.jsx)(A,{label:`Product`,value:d?.product||`rap-node-agent`}),(0,C.jsx)(A,{label:`Target`,value:d?.target_version||`н/д`}),(0,C.jsx)(A,{label:`Strategy`,value:d?.strategy||`н/д`}),(0,C.jsx)(A,{label:`Rollback`,value:d?.rollback_allowed?`разрешен`:`нет`}),(0,C.jsx)(A,{label:`Artifact`,value:d?.artifact?`${d.artifact.kind} ${d.artifact.os}/${d.artifact.arch}`:`н/д`})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{className:`primary`,disabled:!u,onClick:()=>u?.(e,`rap-node-agent`,null),children:`Node-agent latest`}),(0,C.jsx)(`button`,{className:`ghost`,disabled:!u||!d?.target_version,onClick:()=>u?.(e,`rap-node-agent`,d?.target_version||null),children:`Повторить target`}),(0,C.jsx)(`button`,{className:`ghost`,disabled:!u,onClick:()=>u?.(e,`rap-host-agent`,null),children:`Host-agent latest`})]}),(0,C.jsx)(`p`,{className:`muted`,children:`Latest означает policy без закрепленной версии: updater будет брать свежий active release своего канала при следующем цикле или heartbeat hint.`})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Последние отчеты updater`}),(0,C.jsxs)(`div`,{className:`stateList`,children:[(0,C.jsx)(A,{label:`Updater health`,value:`${ue.label}: ${ue.detail}`}),(0,C.jsx)(A,{label:`rap-node-agent`,value:Ve(D)}),(0,C.jsx)(A,{label:`rap-host-agent`,value:Ve(O)}),(0,C.jsx)(A,{label:`Всего отчетов`,value:String(f.length)}),(0,C.jsx)(A,{label:`Последний отчет`,value:F(le?.observed_at)})]}),(0,C.jsxs)(`div`,{className:`summaryChips`,children:[(0,C.jsx)(`span`,{className:`pill ${ue.tone}`,children:ue.label}),D&&(0,C.jsxs)(`span`,{className:`pill ${Ue(D)}`,children:[`node-agent: `,D.status]}),O&&(0,C.jsxs)(`span`,{className:`pill ${Ue(O)}`,children:[`host-agent: `,O.status]}),!D&&!O&&(0,C.jsx)(`span`,{className:`pill warn`,children:`updater пока не отчитался`})]})]})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`История обновлений`}),(0,C.jsx)(je,{columns:[`product`,`current`,`target`,`phase`,`status`,`attempt`,`error`,`observed`],rows:f.slice(0,40).map(e=>[e.product,e.current_version||`н/д`,e.target_version||`н/д`,e.phase,(0,C.jsx)(`span`,{className:`pill ${Ue(e)}`,children:e.status}),e.attempt_id?P(e.attempt_id):`н/д`,e.error_message||`нет`,F(e.observed_at)])})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Windows repair/update command`}),(0,C.jsx)(`p`,{className:`muted`,children:`Для существующего Windows-узла эта команда переустанавливает wrapper updater без нового join-token, сохраняет local state и запускает обновление до актуальной сборки.`}),(0,C.jsxs)(`div`,{className:`stateList compact`,children:[(0,C.jsx)(A,{label:`Когда выполнять`,value:`если updater stale, host-agent не отчитался или Windows-узел не доходит до target version`}),(0,C.jsx)(A,{label:`Control Plane`,value:Wt()}),(0,C.jsx)(A,{label:`Join-token`,value:`не нужен для repair существующего узла`})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{className:`primary`,onClick:()=>Lt(Pt(e),Nt(e,fe)),children:`Скачать repair .cmd`}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>void Rt(Nt(e,fe)),children:`Скопировать команду`})]}),(0,C.jsx)(`pre`,{className:`codePreview`,children:Nt(e,fe)})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Linux repair/update command`}),(0,C.jsx)(`p`,{className:`muted`,children:`Для существующего Ubuntu/Linux-узла эта команда восстанавливает systemd updater без нового join-token, сохраняет local state и делает одноразовую проверку обновления.`}),(0,C.jsxs)(`div`,{className:`stateList compact`,children:[(0,C.jsx)(A,{label:`Когда выполнять`,value:`если host-agent не отчитался, updater stale или Linux-узел не доходит до target version`}),(0,C.jsx)(A,{label:`Control Plane`,value:Wt()}),(0,C.jsx)(A,{label:`Join-token`,value:`не нужен для repair существующего узла`})]}),(0,C.jsxs)(`div`,{className:`actions`,children:[(0,C.jsx)(`button`,{className:`primary`,onClick:()=>Lt(It(e),Ft(e,fe)),children:`Скачать repair .sh`}),(0,C.jsx)(`button`,{className:`ghost`,onClick:()=>void Rt(Ft(e,fe)),children:`Скопировать команду`})]}),(0,C.jsx)(`pre`,{className:`codePreview`,children:Ft(e,fe)})]}),(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Payload последнего отчета`}),(0,C.jsxs)(`div`,{className:`rawDetailsGrid`,children:[(0,C.jsx)(_e,{title:`rap-node-agent update status`,value:D}),(0,C.jsx)(_e,{title:`rap-host-agent update status`,value:O}),(0,C.jsx)(_e,{title:`Update plan`,value:d})]})]})]}),se===`raw`&&(0,C.jsxs)(`section`,{className:`nodePanel`,children:[(0,C.jsx)(`h4`,{children:`Raw данные узла`}),(0,C.jsxs)(`div`,{className:`rawDetailsGrid`,children:[(0,C.jsx)(_e,{title:`Последний heartbeat metadata`,value:m?.metadata}),(0,C.jsx)(_e,{title:`Heartbeat capabilities`,value:m?.capabilities}),(0,C.jsx)(_e,{title:`Heartbeat service states`,value:m?.service_states}),(0,C.jsx)(_e,{title:`Synthetic mesh config`,value:c}),(0,C.jsx)(_e,{title:`Listener report`,value:g}),(0,C.jsx)(_e,{title:`Endpoint report`,value:v}),(0,C.jsx)(_e,{title:`Peer recovery report`,value:x}),(0,C.jsx)(_e,{title:`Connection intent report`,value:S}),(0,C.jsx)(_e,{title:`Connection manager report`,value:w}),(0,C.jsx)(_e,{title:`Rendezvous lease report`,value:ee}),(0,C.jsx)(_e,{title:`Route decision report`,value:te}),(0,C.jsx)(_e,{title:`Route generation report`,value:ne}),(0,C.jsx)(_e,{title:`Route health report`,value:T})]})]})]})}function _e({title:e,value:t}){return(0,C.jsxs)(`details`,{className:`rawBlock`,children:[(0,C.jsx)(`summary`,{children:e}),(0,C.jsx)(`pre`,{children:t==null?`н/д`:JSON.stringify(t,null,2)})]})}function ve({runtime:e}){return(0,C.jsxs)(`div`,{className:`runtimeBadges`,children:[(0,C.jsx)(`span`,{className:`pill ${e.agentTone}`,children:e.agentLabel}),(0,C.jsx)(`span`,{className:`pill ${e.clientTone}`,children:e.clientLabel}),(0,C.jsx)(`span`,{className:`pill ${e.outboundTone}`,children:e.outboundLabel}),(0,C.jsx)(`span`,{className:`pill ${e.inboundTone}`,children:e.inboundLabel})]})}function ye({node:e,fallback:t,heartbeatsByNode:n,meshLinks:r}){if(!e)return t;let i=rt(e,n[e.id]||[],r);return(0,C.jsxs)(`div`,{className:`nodeEndpointCell`,children:[(0,C.jsx)(`strong`,{children:e.name}),(0,C.jsx)(ve,{runtime:i}),(0,C.jsx)(`small`,{children:i.address})]})}function be({nodes:e,links:t,syntheticMeshConfigsByNode:n,entryPoints:r,entryPointNodesById:i,egressPools:a,egressPoolNodesById:o,rolesByNode:s,workloadsByNode:c,telemetryByNode:l,labels:u,emptyText:d}){if(e.length===0)return(0,C.jsx)(pe,{title:`Нет узлов`,text:`Одобренные node-agent появятся на карте после первого heartbeat.`});let f=qe(t).filter(e=>e.source_node_id!==e.target_node_id),p=new Map(e.map(e=>[e.id,e])),m=f.map(e=>({link:e,status:Se(e,f,p)})),h=m.filter(e=>e.status===`reachable`),g=m.filter(e=>e.status===`one_way`),_=m.filter(e=>e.status===`stale`),v=m.filter(e=>e.status!==`reachable`&&e.status!==`one_way`&&e.status!==`stale`),y=ke(e,n),b=j(e.length,r.length,a.length),x=Te(e.length),S=De(e,b.height,x),w=new Map(r.map((e,t)=>[e.id,we(170,t,r.length,150,b.height-100)])),ee=new Map(a.map((e,t)=>[e.id,we(950,t,a.length,150,b.height-100)])),te=new Set(m.filter(e=>e.status!==`stale`).map(e=>`${e.link.source_node_id}->${e.link.target_node_id}`)),ne=new Map(e.map(e=>[e.id,xe(e.id,m)])),T=y.filter(e=>!te.has(`${e.source_node_id}->${e.target_node_id}`)),re=r.flatMap(e=>(i[e.id]||[]).filter(e=>e.status!==`disabled`).map(t=>({entryPoint:e,assignment:t}))),ie=a.flatMap(e=>(o[e.id]||[]).filter(e=>e.status!==`disabled`).map(t=>({pool:e,assignment:t}))),E=re.length+ie.length;return(0,C.jsxs)(`div`,{className:`topologyShell`,children:[(0,C.jsxs)(`svg`,{className:`topologySvg`,viewBox:`0 0 ${b.width} ${b.height}`,role:`img`,"aria-label":`Карта трафика узлов Fabric`,children:[(0,C.jsx)(`defs`,{children:(0,C.jsx)(`marker`,{id:`arrow`,markerHeight:`8`,markerWidth:`8`,orient:`auto`,refX:`7`,refY:`4`,children:(0,C.jsx)(`path`,{d:`M0,0 L8,4 L0,8 Z`,fill:`currentColor`})})}),(0,C.jsx)(`rect`,{x:`36`,y:`58`,width:`268`,height:b.height-100,rx:`24`,className:`topologyZone ingress`}),(0,C.jsx)(`rect`,{x:`330`,y:`58`,width:`460`,height:b.height-100,rx:`24`,className:`topologyZone core`}),(0,C.jsx)(`rect`,{x:`816`,y:`58`,width:`268`,height:b.height-100,rx:`24`,className:`topologyZone egress`}),(0,C.jsx)(`text`,{x:`170`,y:`98`,className:`topologyLayerLabel`,children:u.fabricIngressLayer}),(0,C.jsx)(`text`,{x:`560`,y:`98`,className:`topologyLayerLabel`,children:u.fabricNodeLayer}),(0,C.jsx)(`text`,{x:`950`,y:`98`,className:`topologyLayerLabel`,children:u.fabricEgressLayer}),re.map(({entryPoint:e,assignment:t})=>{let n=w.get(e.id),r=S.get(t.node_id);return!n||!r?null:(0,C.jsx)(`line`,{x1:n.x+78,y1:n.y,x2:r.x-x-8,y2:r.y,className:`topologyPlacementLink ${t.status===`active`?`good`:`weak`}`,markerEnd:`url(#arrow)`},`entry-${e.id}-${t.node_id}`)}),ie.map(({pool:e,assignment:t})=>{let n=S.get(t.node_id),r=ee.get(e.id);return!n||!r?null:(0,C.jsx)(`line`,{x1:n.x+x+8,y1:n.y,x2:r.x-78,y2:r.y,className:`topologyPlacementLink ${t.status===`active`?`good`:`weak`}`,markerEnd:`url(#arrow)`},`egress-${e.id}-${t.node_id}`)}),T.map(e=>{let t=S.get(e.source_node_id),n=S.get(e.target_node_id);if(!t||!n)return null;let r=Oe(t,n,x+8);return(0,C.jsx)(`line`,{x1:r.x1,y1:r.y1,x2:r.x2,y2:r.y2,className:`topologyConfiguredLink`,markerEnd:`url(#arrow)`},e.id)}),m.map(({link:e,status:t})=>{let n=S.get(e.source_node_id),r=S.get(e.target_node_id);if(!n||!r)return null;let i=Oe(n,r,x+8),a=(i.x1+i.x2)/2,o=(i.y1+i.y2)/2;return(0,C.jsxs)(`g`,{children:[(0,C.jsx)(`line`,{x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2,className:`topologyLink ${gn(e,t)}`,markerEnd:`url(#arrow)`}),(0,C.jsx)(`text`,{x:a,y:o-8,className:`topologyLinkLabel`,children:Ze(e,t)})]},e.id||`${e.source_node_id}-${e.target_node_id}`)}),r.map(e=>{let t=w.get(e.id),n=(i[e.id]||[]).length;return(0,C.jsxs)(`g`,{className:`topologyEndpoint`,children:[(0,C.jsx)(`rect`,{x:t.x-86,y:t.y-36,width:`172`,height:`72`,rx:`20`,className:`topologyEndpointRect ${e.status}`}),(0,C.jsx)(`text`,{x:t.x,y:t.y-8,className:`topologyEndpointName`,children:_n(e.name)}),(0,C.jsxs)(`text`,{x:t.x,y:t.y+15,className:`topologyEndpointMeta`,children:[e.endpoint_type,` · `,n]})]},e.id)}),e.map(t=>{let n=S.get(t.id),r=Ee(e.length),i=Fe(s[t.id]||[]),a=ne.get(t.id)||`isolated`;return(0,C.jsxs)(`g`,{className:`topologyNode`,children:[(0,C.jsx)(`circle`,{cx:n.x,cy:n.y,r:x,className:`topologyNodeCircle ${t.health_status}`}),(0,C.jsx)(`text`,{x:n.x,y:n.y-r.nameOffset,className:`topologyNodeName`,style:{fontSize:r.name},children:_n(t.name,r.maxChars)}),(0,C.jsxs)(`text`,{x:n.x,y:n.y+r.metaOffset,className:`topologyNodeMeta`,style:{fontSize:r.meta},children:[i.length,` активн. ролей / `,(c[t.id]||[]).length,` серв.`]}),(0,C.jsxs)(`text`,{x:n.x,y:n.y+r.memoryOffset,className:`topologyNodeMeta`,style:{fontSize:r.meta},children:[`mesh: `,I(a)]})]},t.id)}),a.map(e=>{let t=ee.get(e.id),n=(o[e.id]||[]).length;return(0,C.jsxs)(`g`,{className:`topologyEndpoint`,children:[(0,C.jsx)(`rect`,{x:t.x-86,y:t.y-36,width:`172`,height:`72`,rx:`20`,className:`topologyEndpointRect ${e.status}`}),(0,C.jsx)(`text`,{x:t.x,y:t.y-8,className:`topologyEndpointName`,children:_n(e.name)}),(0,C.jsxs)(`text`,{x:t.x,y:t.y+15,className:`topologyEndpointMeta`,children:[`egress · `,n]})]},e.id)}),m.length===0&&T.length===0&&E===0&&(0,C.jsx)(`text`,{x:b.width/2,y:b.height-34,className:`topologyEmpty`,children:d})]}),(0,C.jsxs)(`div`,{className:`topologyLegend`,children:[(0,C.jsxs)(`span`,{children:[(0,C.jsx)(`i`,{className:`legendLine placement`}),` `,u.placementIntent,`: `,E]}),(0,C.jsxs)(`span`,{children:[(0,C.jsx)(`i`,{className:`legendLine observed`}),` реальные: `,h.length]}),(0,C.jsxs)(`span`,{children:[(0,C.jsx)(`i`,{className:`legendLine oneWay`}),` one-way: `,g.length]}),(0,C.jsxs)(`span`,{children:[(0,C.jsx)(`i`,{className:`legendLine stale`}),` stale: `,_.length]}),(0,C.jsxs)(`span`,{children:[(0,C.jsx)(`i`,{className:`legendLine problem`}),` проблемы: `,v.length]}),(0,C.jsxs)(`span`,{children:[(0,C.jsx)(`i`,{className:`legendLine configured`}),` configured: `,T.length]})]}),(0,C.jsxs)(`div`,{className:`serviceTags`,children:[r.map(t=>(0,C.jsxs)(`div`,{className:`serviceTag`,children:[(0,C.jsx)(`strong`,{children:t.name}),(0,C.jsx)(`span`,{children:t.endpoint_type}),(0,C.jsx)(`small`,{children:(i[t.id]||[]).map(t=>ut(e,t.node_id)).join(`, `)||u.assignedNodesEmpty})]},t.id)),e.map(e=>(0,C.jsxs)(`div`,{className:`serviceTag`,children:[(0,C.jsx)(`strong`,{children:e.name}),(0,C.jsxs)(`span`,{children:[I(e.health_status),` / mesh `,I(ne.get(e.id)||`isolated`)]}),(0,C.jsx)(`small`,{children:Pe(s[e.id]||[])}),(0,C.jsx)(`small`,{children:Le(c[e.id]||[])})]},e.id)),a.map(t=>(0,C.jsxs)(`div`,{className:`serviceTag`,children:[(0,C.jsx)(`strong`,{children:t.name}),(0,C.jsx)(`span`,{children:t.status}),(0,C.jsx)(`small`,{children:(o[t.id]||[]).map(t=>ut(e,t.node_id)).join(`, `)||u.assignedNodesEmpty})]},t.id))]})]})}function xe(e,t){let n=t.filter(t=>t.link.source_node_id!==t.link.target_node_id&&(t.link.source_node_id===e||t.link.target_node_id===e));return n.some(e=>e.status===`reachable`||e.status===`one_way`)?`connected`:n.some(e=>e.status!==`stale`)?`degraded`:`isolated`}function Se(e,t,n){if(Ce(e,n))return`stale`;if(e.link_status!==`reachable`)return e.link_status===`degraded`||e.link_status===`unreachable`?e.link_status:`unknown`;let r=t.find(t=>t.source_node_id===e.target_node_id&&t.target_node_id===e.source_node_id&&!Ce(t,n));return!r||r.link_status!==`reachable`?`one_way`:`reachable`}function Ce(e,t){if(e.link_status===`stale`||e.metadata?.derived_link_stale===!0)return!0;let n=new Date(e.observed_at).getTime();if(!Number.isFinite(n)||Date.now()-n>120*1e3)return!0;if(!t)return!1;let r=t.get(e.source_node_id),i=t.get(e.target_node_id);return r?.health_status!==`healthy`||i?.health_status!==`healthy`}function we(e,t,n,r,i){return n<=1?{x:e,y:Math.round((r+i)/2)}:{x:e,y:Math.round(r+(i-r)*t/(n-1))}}function j(e,t,n){let r=Math.max(e,t,n,1),i=Math.max(Math.ceil(e/3),r);return{width:1120,height:Math.max(640,220+i*104)}}function Te(e){return e>48?26:e>24?32:e>12?40:52}function Ee(e){return e>48?{name:12,meta:9,nameOffset:7,metaOffset:7,memoryOffset:20,maxChars:10}:e>24?{name:14,meta:10,nameOffset:8,metaOffset:9,memoryOffset:24,maxChars:12}:e>12?{name:16,meta:12,nameOffset:10,metaOffset:11,memoryOffset:28,maxChars:14}:{name:21,meta:15,nameOffset:12,metaOffset:10,memoryOffset:31,maxChars:18}}function De(e,t,n){let r=e.length>24?4:e.length>8?3:e.length>3?2:1,i=Math.max(1,Math.ceil(e.length/r)),a=r===1?0:300/(r-1),o=t-96,s=i===1?0:(o-142)/(i-1);return new Map(e.map((e,t)=>{let n=t%r,c=Math.floor(t/r);return[e.id,{x:Math.round(r===1?560:410+a*n),y:Math.round(i===1?(142+o)/2:142+s*c)}]}))}function Oe(e,t,n){let r=t.x-e.x,i=t.y-e.y,a=Math.max(Math.sqrt(r*r+i*i),1),o=r/a*n,s=i/a*n;return{x1:e.x+o,y1:e.y+s,x2:t.x-o,y2:t.y-s}}function ke(e,t){let n=new Set(e.map(e=>e.id)),r=new Map;for(let[e,i]of Object.entries(t))for(let t of i.routes||[]){let i=t.hops||[];for(let a=0;a${s}`,{id:`configured-${e}-${t.route_id}-${a}`,source_node_id:o,target_node_id:s})}}return[...r.values()]}function Ae({children:e}){return(0,C.jsx)(`div`,{className:`formGrid`,children:e})}function je({columns:e,rows:t}){return t.length===0?(0,C.jsx)(pe,{title:`Нет данных`,text:`В текущей области пока нечего показать.`}):(0,C.jsx)(`div`,{className:`tableWrap`,children:(0,C.jsxs)(`table`,{children:[(0,C.jsx)(`thead`,{children:(0,C.jsx)(`tr`,{children:e.map(e=>(0,C.jsx)(`th`,{children:e},e))})}),(0,C.jsx)(`tbody`,{children:t.map((e,t)=>(0,C.jsx)(`tr`,{children:e.map((e,n)=>(0,C.jsx)(`td`,{children:e},`${t}-${n}`))},t))})]})})}function Me(e,t){let n=JSON.parse(e||`{}`);if(!n||Array.isArray(n)||typeof n!=`object`)throw Error(`${t}: требуется JSON object.`);return n}function Ne(e,t){let n=JSON.parse(e||`[]`);if(!Array.isArray(n))throw Error(`${t}: требуется JSON array.`);return n}function Pe(e){let t=Fe(e);return t.length===0?`активные роли не назначены`:t.map(e=>`${Ie(e.role)}${e.organization_id?` @ ${P(e.organization_id)}`:``}`).join(`, `)}function Fe(e){return e.filter(e=>e.status===`active`)}function Ie(e){let t=T[e];return t?`${t} (${e})`:e}function Le(e){return e.length===0?`нет сервисов`:e.map(e=>`${e.service_type}:${e.reported_state}`).join(`, `)}function Re(e,t,n){let r=n.find(e=>e.product===`rap-node-agent`&&e.channel===`stable`&&e.status===`active`)||n.find(e=>e.product===`rap-node-agent`&&e.status===`active`),i=e.reported_version||``,a=t?.target_version||r?.version||``;return e.version_state&&e.version_state!==`unknown`?{status:e.version_state,targetLabel:a?`target ${a}`:`policy target unknown`}:i?t?.action===`update`?{status:`outdated`,targetLabel:`target ${t.target_version||a}`}:a&&i!==a?{status:`outdated`,targetLabel:`latest ${a}`}:a&&i===a?{status:`current`,targetLabel:`latest ${a}`}:{status:t?.reason===`no_update_policy`?`no_policy`:`unknown`,targetLabel:t?.reason||`release policy unknown`}:{status:`unknown`,targetLabel:a?`target ${a}`:`target unknown`}}function ze(e,t){return e.find(e=>e.product===t)}function Be(e,t){return e?`${e.product}: ${e.phase}/${e.status}`:t?`${t.action}: ${t.reason}`:`нет отчета`}function Ve(e){if(!e)return`нет отчета`;let t=e.target_version?` -> ${e.target_version}`:``,n=e.error_message?`, ошибка: ${e.error_message}`:``;return`${e.current_version||`н/д`}${t}, ${e.phase}/${e.status}, ${F(e.observed_at)}${n}`}function He(e){return e?`push ${e.pushed||0} / pop ${e.popped||0} / q ${e.queue_depth||0} / drop ${e.dropped||0}`:`нет данных`}function Ue(e){if(!e)return`warn`;let t=`${e.phase}:${e.status}`.toLowerCase();return t.includes(`error`)||t.includes(`failed`)||t.includes(`rollback`)?`bad`:t.includes(`success`)||t.includes(`updated`)||t.includes(`noop`)||t.includes(`already_current`)?`good`:t.includes(`download`)||t.includes(`replace`)||t.includes(`plan`)||t.includes(`apply`)?`warn`:``}function We(e){let t=ze(e,`rap-node-agent`),n=ze(e,`rap-host-agent`);if(!t&&!n)return{label:`updater: нет отчета`,detail:`repair/update task не отчитался`,tone:`bad`};let r=[t,n].some(e=>e&&Ge(e)),i=!n,a=n?.phase===`apply`&&n?.status===`staged`,o=[t,n].some(e=>e&&Ue(e)===`bad`),s=t?`${t.current_version||`?`}->${t.target_version||`?`}`:`node ?`,c=n?`${n.current_version||`?`}->${n.target_version||`?`}`:`host ?`,l=F((n||t)?.observed_at);return o?{label:`updater: ошибка`,detail:`${s}; ${c}; ${l}`,tone:`bad`}:i?{label:`repair updater`,detail:`host-agent не отчитался; ${s}; ${l}`,tone:`warn`}:a?{label:`host-agent staged`,detail:`${c}; нужен следующий запуск updater`,tone:`warn`}:r?{label:`updater: stale`,detail:`${s}; ${c}; ${l}`,tone:`warn`}:{label:`updater: ok`,detail:`${s}; ${c}; ${l}`,tone:`good`}}function Ge(e){let t=new Date(e.observed_at).getTime();return!Number.isFinite(t)||Date.now()-t>900*1e3}function Ke(e){let t=typeof e.scope?.node_name==`string`?e.scope.node_name:``,n=typeof e.scope?.purpose==`string`?e.scope.purpose:``;return t||n||P(e.id)}function qe(e){let t=new Map;for(let n of e){let e=`${n.source_node_id}->${n.target_node_id}:${Je(n)}`,r=t.get(e);(!r||new Date(n.observed_at).getTime()>new Date(r.observed_at).getTime())&&t.set(e,n)}return[...t.values()]}function Je(e){let t=Qe(e,`observation_type`)||`default`;return t===`synthetic_route_health`?`${t}:${Qe(e,`route_id`)||e.id}`:t===`peer_connection_manager`?`${t}:${Qe(e,`transport_mode`)}:${Qe(e,`relay_node_id`)}`:t}function Ye(e){let t=Qe(e,`observation_type`);if(t===`synthetic_route_health`){let t=e.metadata?.route_path_drift_detected===!0?`drift`:`ok`;return`route-health ${e.metadata?.route_path_decision_applied===!0?`decision`:`route`} ${t}`}if(t===`peer_connection_manager`){let t=Qe(e,`transport_mode`)||`manager`,n=Qe(e,`connection_state`);return n?`${t} ${n}`:t}return t||`link`}function Xe(e,t){let n=Qe(e,`route_id`),r=Qe(e,`route_path_decision_selected_relay_id`)||Qe(e,`relay_node_id`),i=$e(e,`expected_effective_hops`),a=$e(e,`observed_ack_path`),o=i.length>0?i:a,s=[];return n&&s.push(P(n)),r&&s.push(`via ${P(r)}`),o.length>0&&s.push(o.map(e=>_n(ut(t,e))).join(` > `)),s.length>0?s.join(` / `):`н/д`}function Ze(e,t=e.link_status===`reachable`?`reachable`:`unknown`){return t===`stale`?`stale`:t===`one_way`?`one-way`:Qe(e,`observation_type`)===`synthetic_route_health`?e.metadata?.route_path_drift_detected===!0?`drift`:`route`:e.latency_ms==null?`связь`:`${e.latency_ms}мс`}function Qe(e,t){let n=e.metadata?.[t];return typeof n==`string`?n:``}function $e(e,t){let n=e.metadata?.[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function et(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}function tt(e){return Array.isArray(e)?e.map(e=>et(e)).filter(e=>!!e):[]}function M(e,t,n=``){let r=e?.[t];return typeof r==`string`?r:typeof r==`number`||typeof r==`boolean`?String(r):n}function nt(e,t){for(let n of t){let t=M(e,n,``);if(t)return t}return``}function rt(e,t,n){let r=t[0],i=r?.metadata||{},a=et(i.mesh_listener_report),o=et(i.mesh_endpoint_report),s=et(i.mesh_outbound_session_report),c=et(i.mesh_peer_connection_manager_report),l=et(i.mesh_peer_recovery_report),u=tt(o?.endpoint_candidates)[0],d=nt(o,[`peer_endpoint`,`advertised_endpoint`,`endpoint`])||M(u,`address`,``)||M(a,`effective_listen_addr`,``)||`адрес не прислан`;if(!r&&!e.last_seen_at)return{agentLabel:`agent: no heartbeat`,agentTone:`bad`,clientLabel:`client: unknown`,clientTone:`warn`,outboundLabel:`outbound: no heartbeat`,outboundTone:`bad`,inboundLabel:`inbound: unknown`,inboundTone:`warn`,address:d,detail:`Узел создан/одобрен, но node-agent еще ни разу не прислал heartbeat.`};let f=it(c,`peer_connection_ready`)||it(l,`peer_connection_ready`)||qe(n).filter(t=>(t.source_node_id===e.id||t.target_node_id===e.id)&&t.link_status===`reachable`).length,p=it(c,`peer_connection_total`)||it(l,`peer_connection_total`)||qe(n).filter(t=>t.source_node_id===e.id||t.target_node_id===e.id).length,m=it(c,`failed`),h=M(a,`status`,``),g=a?.port_conflict===!0,_=a?.one_way_connectivity===!0||M(o,`connectivity_mode`,``)===`outbound_only`||it(c,`peer_connection_relay_ready`)>0,v=`inbound: no report`,y=`warn`;h===`listening`||h===`auto_rebound`?(v=h===`auto_rebound`?`inbound: auto port`:`inbound: listening`,y=`good`):h===`listen_failed`?(v=g?`inbound: port busy`:`inbound: failed`,y=`bad`):h===`disabled`?(v=`inbound: disabled`,y=_?`warn`:`bad`):o&&(v=`inbound: advertised`,y=`good`);let b=`client: no peers`,x=`warn`;f>0?(b=`client: ready ${f}/${Math.max(p,f)}`,x=`good`):(m>0||p>0)&&(b=`client: backoff ${f}/${Math.max(p,m)}`,x=`bad`);let S=M(s,`status`,``),C=s?.usable_for_inbound_control===!0,w=it(s,`peer_connection_relay_ready`),ee=it(s,`rendezvous_lease_count`),te=`outbound: no report`,ne=`warn`;S===`ready`?(te=C?`outbound: ready reverse`:`outbound: ready`,ne=`good`):S===`backoff`||S===`failed`?(te=`outbound: ${S}`,ne=`bad`):(_||w>0||ee>0)&&(te=`outbound: inferred`,ne=`warn`);let T=e.health_status===`healthy`?`good`:e.health_status===`unknown`?`warn`:`bad`;return{agentLabel:r?`agent: heartbeat`:`agent: stale`,agentTone:T,clientLabel:_&&f>0?`${b} one-way`:b,clientTone:x,outboundLabel:te,outboundTone:ne,inboundLabel:v,inboundTone:y,address:d,detail:M(a,`failure_error`,M(a,`failure_reason`,``))}}function it(e,t,n=0){let r=e?.[t];return typeof r==`number`&&Number.isFinite(r)?r:n}function at(e){if(e==null)return`н/д`;let t=JSON.stringify(e);return t.length>140?`${t.slice(0,137)}...`:t}function ot(e){let t=tt(e.candidate_results);return t.length===0?`н/д`:t.slice(0,4).map(e=>{let t=M(e,`candidate_id`,`candidate`),n=M(e,`link_status`,`unknown`),r=M(e,`latency_ms`,``);return r&&r!==`0`?`${t}:${n}:${r}мс`:`${t}:${n}`}).join(`, `)}function st(e){return Object.values(e.peer_endpoint_candidates||{}).reduce((e,t)=>e+t.length,0)}function ct(e){let t=e?.rendezvous_relay_policy;if(!t)return`none`;let n=[`stale${t.stale_relay_count}`,`wd${t.withdrawn_lease_count}`,`repl${t.replacement_lease_count}`];t.scoring_mode.includes(`synthetic_route_health_feedback`)&&n.push(`rh feedback`);let r=t.decisions?.find(e=>e.selected_relay_id);return r?.selected_relay_id&&n.push(`via ${P(r.selected_relay_id)}`),n.join(` `)}function lt(e){let t=e?.route_path_decisions;if(!t)return`none`;let n=[`path${t.decision_count}`,`repl${t.replacement_decision_count}`],r=t.decisions?.find(e=>e.selected_relay_id||e.next_hop_id);return r?.selected_relay_id?n.push(`via ${P(r.selected_relay_id)}`):r?.next_hop_id&&n.push(`next ${P(r.next_hop_id)}`),n.join(` `)}function ut(e,t){return e.find(e=>e.id===t)?.name||P(t)}function dt(e,t){let n=new Map(t.map(e=>[e.id,e])),r=[e.name],i=e.parent_group_id,a=new Set([e.id]);for(;i&&!a.has(i);){a.add(i);let e=n.get(i);if(!e)break;r.unshift(e.name),i=e.parent_group_id}return r.join(` / `)}function ft(e,t){let n=t.find(t=>t.id===e);return n?dt(n,t):e}function pt(e,t){let n=[],r=new Map;for(let e of t){let t=e.parent_group_id||``;r.set(t,[...r.get(t)||[],e])}let i=e=>{for(let t of r.get(e)||[])n.push(t.id),i(t.id)};return i(e),n}function mt(e,t,n,r,i){let a=[],o=new Map,s=[],c=[];for(let t of e){let e=t.memberships.find(e=>e.cluster.id===n);if(!e){c.push(t);continue}let r=e.node.node_group_id;if(!r){s.push(t);continue}o.set(r,[...o.get(r)||[],t])}let l=new Map;for(let e of t){let t=e.parent_group_id||``;l.set(t,[...l.get(t)||[],e])}for(let e of l.values())e.sort((e,t)=>e.sort_order-t.sort_order||e.name.localeCompare(t.name));let u=new Map,d=e=>{let t=u.get(e.id);if(t!=null)return t;let n=o.get(e.id)?.length||0;for(let t of l.get(e.id)||[])n+=d(t);return u.set(e.id,n),n},f=(e,t)=>{let n=[...o.get(e.id)||[]].sort((e,t)=>e.node.name.localeCompare(t.node.name)),r=l.get(e.id)||[],s=`group-${e.id}`,c=d(e);if(a.push({kind:`group`,key:s,label:e.name,depth:t,count:c,groupId:e.id}),!i.has(s)){for(let r of n)a.push({kind:`node`,key:`node-${e.id}-${r.node.id}`,entry:r,depth:t+1});for(let e of r)f(e,t+1)}return c};for(let e of l.get(``)||[])f(e,0);if(s.length>0){let e=`group-ungrouped`;if(a.push({kind:`group`,key:e,label:r.ungroupedNodes,depth:0,count:s.length}),!i.has(e))for(let e of s.sort((e,t)=>e.node.name.localeCompare(t.node.name)))a.push({kind:`node`,key:`node-ungrouped-${e.node.id}`,entry:e,depth:1})}if(c.length>0){let e=`group-outside-active-cluster`;if(a.push({kind:`group`,key:e,label:r.notMemberOfActiveCluster,depth:0,count:c.length}),!i.has(e))for(let e of c.sort((e,t)=>e.node.name.localeCompare(t.node.name)))a.push({kind:`node`,key:`node-outside-${e.node.id}`,entry:e,depth:1})}return a}function ht(e,t){return Object.entries(t).filter(([,t])=>t.some(t=>t.role===e&&t.status===`active`)).map(([e])=>e)}function gt(e){let t={roles:e.roles,node_name:e.nodeName.trim()||null,node_group_id:e.nodeGroupId||null,ownership_type:e.ownershipType,purpose:e.purpose.trim()||null,approval:{mode:`manual`,auto_approve:!1,role_assignment:`manual_after_approval`},source:`platform_owner_console`};if(e.installMode===`docker`){let n=(e.controlPlaneEndpoint||bt()).trim().replace(/\/$/,``);t.install_profile=`docker`,t.backend_url=n,t.control_plane_endpoints=[n],t.image=e.dockerImage||`rap-node-agent:latest`,e.dockerContainerName.trim()&&(t.container_name=e.dockerContainerName.trim()),t.artifact_endpoints=St(e.artifactEndpoints||xt()),e.dockerImageArtifactSHA256.trim()&&(t.docker_image_artifact_sha256=e.dockerImageArtifactSHA256.trim()),t.network=e.dockerNetwork||`host`,t.restart_policy=`unless-stopped`,t.pull_image=!!e.pullImage,t.replace=e.replace!==!1,t.mesh_synthetic_runtime_enabled=e.syntheticRuntime!==!1,t.mesh_production_forwarding_enabled=!1,t.mesh_listen_addr=e.meshListenAddr||`:19131`,t.mesh_listen_port_mode=e.meshListenPortMode||`auto`,t.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,t.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,e.meshAdvertiseEndpoint?.trim()&&(t.mesh_advertise_endpoint=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)),t.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_http`,t.mesh_connectivity_mode=e.meshConnectivityMode||`private_lan`,t.mesh_nat_type=e.meshNATType||`unknown`,t.mesh_region=e.meshRegion||null}if(e.installMode===`windows_service`){let n=(e.controlPlaneEndpoint||bt()).trim().replace(/\/$/,``);t.install_profile=`windows_service`,t.backend_url=n,t.control_plane_endpoints=[n],t.artifact_endpoints=St(e.artifactEndpoints||xt()),t.startup_mode=e.windowsStartupMode||`auto`,e.windowsInstallDir.trim()&&(t.install_dir=e.windowsInstallDir.trim()),e.windowsNodeAgentSHA256.trim()&&(t.node_agent_artifact_sha256=e.windowsNodeAgentSHA256.trim()),t.mesh_synthetic_runtime_enabled=e.syntheticRuntime!==!1,t.mesh_production_forwarding_enabled=!1,t.mesh_listen_addr=e.meshListenAddr||`:19131`,t.mesh_listen_port_mode=e.meshListenPortMode||`auto`,t.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,t.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,e.meshAdvertiseEndpoint?.trim()&&(t.mesh_advertise_endpoint=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)),t.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_http`,t.mesh_connectivity_mode=e.meshConnectivityMode||`outbound_only`,t.mesh_nat_type=e.meshNATType||`unknown`,t.mesh_region=e.meshRegion||`windows`}if(e.installMode===`linux_binary`){let n=(e.controlPlaneEndpoint||bt()).trim().replace(/\/$/,``);t.install_profile=`linux_binary`,t.backend_url=n,t.control_plane_endpoints=[n],t.artifact_endpoints=St(e.artifactEndpoints||xt()),t.startup_mode=`systemd`,e.linuxInstallDir.trim()&&(t.install_dir=e.linuxInstallDir.trim()),e.linuxNodeAgentSHA256.trim()&&(t.node_agent_artifact_sha256=e.linuxNodeAgentSHA256.trim()),t.replace=e.replace!==!1,t.mesh_synthetic_runtime_enabled=e.syntheticRuntime!==!1,t.mesh_production_forwarding_enabled=!1,t.mesh_listen_addr=e.meshListenAddr||`:19131`,t.mesh_listen_port_mode=e.meshListenPortMode||`auto`,t.mesh_listen_auto_port_start=e.meshListenAutoPortStart||19131,t.mesh_listen_auto_port_end=e.meshListenAutoPortEnd||19231,e.meshAdvertiseEndpoint?.trim()&&(t.mesh_advertise_endpoint=e.meshAdvertiseEndpoint.trim().replace(/\/$/,``)),t.mesh_advertise_transport=e.meshAdvertiseTransport||`direct_http`,t.mesh_connectivity_mode=e.meshConnectivityMode||`outbound_only`,t.mesh_nat_type=e.meshNATType||`unknown`,t.mesh_region=e.meshRegion||`linux`}return t}function _t(e,t){let n=vt(e.roles),r=vt(e.artifact_endpoints).join(`, `);return{...t,roles:n.length>0?n:t.roles,nodeName:M(e,`node_name`,``)||t.nodeName,nodeGroupId:M(e,`node_group_id`,``)||t.nodeGroupId,ownershipType:M(e,`ownership_type`,t.ownershipType),purpose:M(e,`purpose`,``)||t.purpose,installMode:M(e,`install_profile`,t.installMode),dockerImage:M(e,`image`,t.dockerImage),dockerContainerName:M(e,`container_name`,``)||t.dockerContainerName,dockerNetwork:M(e,`network`,t.dockerNetwork),windowsStartupMode:M(e,`startup_mode`,t.windowsStartupMode),windowsInstallDir:M(e,`install_dir`,``)||t.windowsInstallDir,windowsNodeAgentSHA256:M(e,`node_agent_artifact_sha256`,``)||t.windowsNodeAgentSHA256,linuxInstallDir:M(e,`install_dir`,``)||t.linuxInstallDir,linuxNodeAgentSHA256:M(e,`node_agent_artifact_sha256`,``)||t.linuxNodeAgentSHA256,meshListenAddr:M(e,`mesh_listen_addr`,t.meshListenAddr),meshListenPortMode:M(e,`mesh_listen_port_mode`,t.meshListenPortMode),meshListenAutoPortStart:it(e,`mesh_listen_auto_port_start`,t.meshListenAutoPortStart),meshListenAutoPortEnd:it(e,`mesh_listen_auto_port_end`,t.meshListenAutoPortEnd),meshAdvertiseEndpoint:M(e,`mesh_advertise_endpoint`,``)||t.meshAdvertiseEndpoint,meshAdvertiseTransport:M(e,`mesh_advertise_transport`,t.meshAdvertiseTransport),meshConnectivityMode:M(e,`mesh_connectivity_mode`,t.meshConnectivityMode),meshNATType:M(e,`mesh_nat_type`,t.meshNATType),meshRegion:M(e,`mesh_region`,``)||t.meshRegion,controlPlaneEndpoint:vt(e.control_plane_endpoints)[0]||M(e,`backend_url`,``)||t.controlPlaneEndpoint,artifactEndpoints:r||t.artifactEndpoints,dockerImageArtifactSHA256:M(e,`docker_image_artifact_sha256`,``)||t.dockerImageArtifactSHA256,pullImage:yt(e,`pull_image`,t.pullImage),replace:yt(e,`replace`,t.replace),syntheticRuntime:yt(e,`mesh_synthetic_runtime_enabled`,t.syntheticRuntime)}}function vt(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean):[]}function yt(e,t,n){let r=e[t];return typeof r==`boolean`?r:n}function bt(){return typeof window>`u`||!window.location?.origin?`http://:18080/api/v1`:`${window.location.origin.replace(/\/$/,``)}/api/v1`}function xt(){return typeof window>`u`||!window.location?.origin?`http://:18080/downloads`:`${window.location.origin.replace(/\/$/,``)}/downloads`}function St(e){return e.split(`,`).map(e=>e.trim().replace(/\/$/,``)).filter(Boolean)}function Ct(e){return St(e.artifactEndpoints||xt()).map(e=>`${e}/rap-node-agent-dev-enrollment-bootstrap-smoke.tar`)}function wt(e){return e.meshConnectivityMode===`outbound_only`?`outbound_only`:e.meshConnectivityMode===`private_lan`?`private_lan`:e.meshNATType!==`none`&&e.meshAdvertiseEndpoint.trim()?`nat_forward`:`direct`}function Tt(e,t){let n={...e};return t===`private_lan`?(n.meshConnectivityMode=`private_lan`,n.meshNATType=`none`):t===`direct`?(n.meshConnectivityMode=`direct`,n.meshNATType=`none`):t===`nat_forward`?(n.meshConnectivityMode=`direct`,n.meshNATType=`port_restricted`):(n.meshConnectivityMode=`outbound_only`,n.meshNATType=`symmetric`,n.meshAdvertiseEndpoint=``),n}function Et(e,t){return e.nodeName.trim()?e.nodeName.trim():`${Jt(t?.slug||t?.name||`rap-node`)}-node-1`}function Dt(e,t){return e.dockerContainerName.trim()?e.dockerContainerName.trim():`rap-node-agent-${Jt(Et(e,t))}`}function Ot(e,t,n=se){let r=t?.id||e.cluster_id,i=Et(n,t),a=Dt(n,t),o=Jt(i),s=[`rap-host-agent install`,`--backend-url ${N(Ut(n))}`,`--cluster-id ${N(r)}`,`--join-token ${N(e.token)}`,`--node-name ${N(i)}`,`--image ${N(n.dockerImage||`rap-node-agent:latest`)}`,`--container-name ${N(a)}`,`--state-dir ${N(`/var/lib/rap/nodes/${o}`)}`,`--network host`,`--replace`];for(let e of Ct(n))s.push(`--image-artifact-url ${N(e)}`);return n.dockerImageArtifactSHA256.trim()&&s.push(`--image-artifact-sha256 ${N(n.dockerImageArtifactSHA256.trim())}`),s.join(` \\ `)}function kt(e,t,n=se){let r=t?.id||e.cluster_id,i=Et(n,t),a=[`sudo "$rap_host_agent" install`,`--profile-url ${N(Ut(n))}`,`--cluster-id ${N(r)}`,`--install-token ${N(e.token)}`,`--node-name ${N(i)}`].join(` \\ `);return[`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${N(Kt(n))} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,a].join(` && \\ `)}function At(e,t,n=se){let r=t?.id||e.cluster_id,i=Et(n,t),a=[`sudo "$rap_host_agent" install-linux`,`--profile-url ${N(Ut(n))}`,`--cluster-id ${N(r)}`,`--install-token ${N(e.token)}`,`--node-name ${N(i)}`].join(` \\ `);return[`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${N(Kt(n))} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,a].join(` && \\ `)}function jt(e,t,n=se){let r=t?.id||e.cluster_id,i=Et(n,t),a=Ut(n);return[`$rapHostAgent = Join-Path $env:TEMP "rap-host-agent.exe"`,`Invoke-WebRequest -UseBasicParsing ${Yt(qt(n))} -OutFile $rapHostAgent`,`& $rapHostAgent install-windows --profile-url ${Yt(a)} --cluster-id ${Yt(r)} --install-token ${Yt(e.token)} --node-name ${Yt(i)} --startup-mode ${Yt(n.windowsStartupMode||`auto`)}`].join(`\r `)}function Mt(e,t,n=se){let r=t?.id||e.cluster_id,i=Et(n,t),a=Ut(n),o=qt(n),s=n.windowsStartupMode||`auto`;return[`powershell -NoProfile -ExecutionPolicy Bypass -Command "Invoke-WebRequest -UseBasicParsing '${o}' -OutFile $env:TEMP\\rap-host-agent.exe"`,`%TEMP%\\rap-host-agent.exe install-windows --profile-url "${a}" --cluster-id "${r}" --install-token "${e.token}" --node-name "${i}" --startup-mode "${s}"`].join(`\r `)}function Nt(e,t){let n=Wt(),r=n.replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``),i=e.name||e.node_key||e.id,a=Bt(i),o=`%ProgramFiles%\\RAP\\${a}`,s=`%ProgramData%\\RAP\\nodes\\${a}`,c=`RAP Node Agent ${a}`,l=`RAP Host Agent Updater ${a}`,u=`${o}\\rap-host-agent.exe`,d=`${u}.next`;return[`@echo off`,`echo === RAP Windows updater repair: ${Xt(i)} ===`,`echo Node ID: ${e.id}`,`echo Control Plane: ${n}`,`echo.`,`echo === Before repair: scheduled tasks ===`,`schtasks /Query /TN "${c}" /V /FO LIST`,`schtasks /Query /TN "${l}" /V /FO LIST`,`echo.`,`echo === Before repair: binaries ===`,`dir "${o}\\rap-*.exe*"`,`echo.`,`powershell -NoProfile -ExecutionPolicy Bypass -Command "Invoke-WebRequest -UseBasicParsing '${r}/downloads/rap-host-agent-windows-amd64.exe' -OutFile $env:TEMP\\rap-host-agent.exe"`,`%TEMP%\\rap-host-agent.exe install-windows --backend-url "${n}" --cluster-id "${t||``}" --node-id "${e.id}" --node-name "${Xt(i)}" --replace --startup-mode "auto" --auto-update-current-version "0.0.0" --auto-update-initial-delay-seconds 1`,`"${u}" update-loop --backend-url "${n}" --cluster-id "${t||``}" --node-id "${e.id}" --state-dir "${s}" --current-version "0.0.0" --os windows --arch amd64 --install-type windows_service --binary-path "${o}\\rap-node-agent.exe" --windows-task-name "${c}" --health-timeout-seconds 30 --interval-seconds 0 --initial-delay-seconds 0 --max-runs 1 --host-agent-update-status-enabled --host-agent-current-version "0.0.0" --host-agent-binary-path "${u}"`,`echo.`,`echo === Applying staged host-agent if present ===`,`if exist "${d}" copy /Y "${d}" "${u}"`,`if exist "${d}" del /F /Q "${d}"`,`schtasks /End /TN "${l}"`,`schtasks /Run /TN "${l}"`,`echo.`,`echo === After repair: binaries ===`,`dir "${o}\\rap-*.exe*"`,`echo.`,`echo === After repair: updater task ===`,`schtasks /Query /TN "${l}" /V /FO LIST`,`echo.`,`echo Repair command finished. Check the admin panel for rap-node-agent and rap-host-agent plan/noop reports.`].join(`\r `)}function Pt(e){return`rap-repair-updater-${zt(e.name||e.node_key||e.id||`node`)}.cmd`}function Ft(e,t){let n=Wt(),r=n.replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``),i=e.name||e.node_key||e.id,a=Vt(i),o=`/opt/rap/${a}`,s=`/var/lib/rap/nodes/${a}`,c=`rap-node-agent-${a}.service`,l=`rap-host-agent-updater-${a}.service`,u=`${o}/rap-host-agent`;return[`#!/usr/bin/env bash`,`set -euo pipefail`,`echo "=== RAP Linux updater repair: ${Ht(i)} ==="`,`echo "Node ID: ${e.id}"`,`echo "Control Plane: ${n}"`,`echo`,`echo "=== Before repair: systemd units ==="`,`systemctl status ${N(c)} --no-pager || true`,`systemctl status ${N(l)} --no-pager || true`,`echo`,`echo "=== Before repair: binaries ==="`,`ls -la ${N(o)} || true`,`echo`,`rap_host_agent="$(mktemp /tmp/rap-host-agent.XXXXXX)"`,`curl -fL --retry 3 --retry-delay 1 ${N(`${r}/downloads/rap-host-agent-linux-amd64`)} -o "$rap_host_agent"`,`chmod +x "$rap_host_agent"`,`sudo "$rap_host_agent" install-linux --backend-url ${N(n)} --cluster-id ${N(t||``)} --node-id ${N(e.id)} --node-name ${N(i)} --replace --startup-mode systemd --auto-update-current-version 0.0.0 --auto-update-initial-delay-seconds 1`,`sudo ${N(u)} update-loop --backend-url ${N(n)} --cluster-id ${N(t||``)} --node-id ${N(e.id)} --state-dir ${N(s)} --current-version 0.0.0 --os linux --arch amd64 --install-type linux_binary --binary-path ${N(`${o}/rap-node-agent`)} --systemd-unit ${N(c)} --health-timeout-seconds 30 --interval-seconds 0 --initial-delay-seconds 0 --max-runs 1 --host-agent-update-status-enabled --host-agent-current-version 0.0.0 --host-agent-binary-path ${N(u)}`,`sudo systemctl daemon-reload`,`sudo systemctl restart ${N(l)}`,`echo`,`echo "=== After repair: systemd updater ==="`,`systemctl status ${N(l)} --no-pager || true`,`echo "Repair command finished. Check the admin panel for rap-node-agent and rap-host-agent plan/noop reports."`].join(` `)}function It(e){return`rap-repair-updater-${zt(e.name||e.node_key||e.id||`node`)}.sh`}function Lt(e,t){if(typeof document>`u`)return;let n=new Blob([t.endsWith(`\r `)?t:`${t}\r\n`],{type:`text/plain;charset=utf-8`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=e,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}async function Rt(e){await navigator.clipboard.writeText(e)}function zt(e){return e.trim().replace(/[\\/:*?"<>|]+/g,`-`).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).slice(0,80)||`node`}function Bt(e){return e.trim().replace(/[\\/:*?"<>|]+/g,`-`).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`node`}function Vt(e){return Bt(e).slice(0,48)||`node`}function Ht(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\$/g,`\\$`).replace(/`/g,"\\`")}function Ut(e=se){return(e.controlPlaneEndpoint||bt()).trim().replace(/\/$/,``)}function Wt(){let e=typeof window>`u`?``:window.location?.origin||``;return/^(http:\/\/)?(192\.168\.200\.61|docker-test\.cin\.su)(:18080)?$/i.test(e.replace(/\/$/,``))?`http://vpn.cin.su:19191/api/v1`:`${e.replace(/\/$/,``)}/api/v1`}function Gt(e=se){let t=St(e.artifactEndpoints)[0];return t?t.replace(/\/downloads$/i,``).replace(/\/$/,``):Ut(e).replace(/\/api\/v1$/i,``).replace(/\/api$/i,``).replace(/\/$/,``)}function Kt(e=se){return`${typeof window>`u`&&!e.controlPlaneEndpoint?`http://:18080`:Gt(e)}/downloads/rap-host-agent-linux-amd64`}function qt(e=se){return`${typeof window>`u`&&!e.controlPlaneEndpoint?`http://:18080`:Gt(e)}/downloads/rap-host-agent-windows-amd64.exe`}function Jt(e){return e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,42)||`rap-node`}function N(e){return`'${e.replace(/'/g,`'\\''`)}'`}function Yt(e){return`'${e.replace(/'/g,`''`)}'`}function Xt(e){return e.replace(/"/g,`""`)}function Zt(e,t){return e.includes(t)?e.filter(e=>e!==t):[...e,t]}function Qt(e,t,n,r,i){let a=n.trim().toLowerCase(),o=new Map;for(let n of e){if(a&&!$t(n,a))continue;let e=en(n,t,r,i);o.set(e,[...o.get(e)||[],n])}return Array.from(o.entries()).map(([e,t])=>({label:e,items:t.sort((e,t)=>e.node.name.localeCompare(t.node.name))})).sort((e,t)=>e.label.localeCompare(t.label))}function $t(e,t){return[e.node.name,e.node.node_key,e.node.health_status,e.node.ownership_type,e.node.reported_version||``,...e.memberships.flatMap(e=>[e.cluster.name,e.cluster.slug,e.node.membership_status])].some(e=>e.toLowerCase().includes(t))}function en(e,t,n,r){if(n===`health`)return I(e.node.health_status);if(n===`ownership`)return I(e.node.ownership_type);if(n===`cluster_count`)return hn(e.memberships.length,r);let i=e.memberships.find(e=>e.cluster.id===t);return i?i.node.membership_status===`active`?r===`en`?`In active cluster`:`В активном кластере`:`${r===`en`?`Membership`:`Участие`}: ${I(i.node.membership_status)}`:r===`en`?`Not in active cluster`:`Не в активном кластере`}function tn(e,t){let n=re[e]||[];if(n.length===0||!t)return`unknown`;if(nn(t))return`stale`;let r=t.capabilities||{};return n.some(e=>!!r[e])?`confirmed`:`missing`}function nn(e){if(!e?.observed_at)return!0;let t=new Date(e.observed_at).getTime();return!Number.isFinite(t)||Date.now()-t>60*1e3}function rn(e,t){let n=tn(e,t);return n===`confirmed`?`good`:n===`missing`?`bad`:n===`stale`?`warn`:``}function an(e,t,n){let r=tn(e,t);return r===`confirmed`?n.capabilityConfirmed:r===`missing`?n.capabilityMissing:r===`stale`?`heartbeat устарел`:n.capabilityUnknown}function on(e,t,n){let r=tn(e,t);return n===`en`?r===`confirmed`?`capable`:r===`missing`?`not reported`:r===`stale`?`stale heartbeat`:`unknown`:r===`confirmed`?`подходит`:r===`missing`?`не заявлено`:r===`stale`?`heartbeat устарел`:`неизвестно`}function sn(e){let t=e?.metadata?.mesh_peer_recovery_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.mode==`string`?n.mode:`unknown`,i=typeof n.ready_peer_count==`number`?n.ready_peer_count:null,a=typeof n.target_ready_peers==`number`?n.target_ready_peers:null,o=typeof n.deficit==`number`?n.deficit:0,s=i==null||a==null?r:`${r} ${i}/${a}`;return o>0?`${s} deficit ${o}`:s}function cn(e){let t=e?.metadata?.mesh_peer_connection_intent_report;if(!t||typeof t!=`object`||Array.isArray(t))return pn(e);let n=t,r=typeof n.intent_count==`number`?n.intent_count:0,i=typeof n.maintain_count==`number`?n.maintain_count:0,a=typeof n.recover_count==`number`?n.recover_count:0,o=typeof n.rendezvous_required_count==`number`?n.rendezvous_required_count:0,s=typeof n.rendezvous_resolved_count==`number`?n.rendezvous_resolved_count:0,c=typeof n.relay_control_count==`number`?n.relay_control_count:0,l=[`rv${o}`];s>0&&l.push(`ok${s}`),c>0&&l.push(`relay${c}`);let u=o>0||s>0||c>0?`${r} intents m${i}/r${a} ${l.join(`/`)}`:`${r} intents m${i}/r${a}`,d=pn(e);return d===`н/д`?u:`${u}; ${d}`}function ln(e){let t=e?.metadata?.mesh_rendezvous_lease_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.lease_count==`number`?n.lease_count:0,i=typeof n.active_count==`number`?n.active_count:0,a=typeof n.admitted_as_relay_count==`number`?n.admitted_as_relay_count:0,o=typeof n.admitted_as_peer_count==`number`?n.admitted_as_peer_count:0,s=typeof n.renewal_needed_count==`number`?n.renewal_needed_count:0,c=typeof n.relay_control_ready_count==`number`?n.relay_control_ready_count:0,l=typeof n.stale_relay_count==`number`?n.stale_relay_count:0,u=typeof n.refresh_attempt_count==`number`?n.refresh_attempt_count:0,d=typeof n.refresh_success_count==`number`?n.refresh_success_count:0,f=[`lease ${i}/${r}`];return a>0&&f.push(`relay${a}`),o>0&&f.push(`peer${o}`),s>0&&f.push(`renew${s}`),l>0&&f.push(`stale${l}`),c>0&&f.push(`ready${c}`),u>0&&f.push(`ref${d}/${u}`),f.join(` `)}function un(e){let t=e?.metadata?.mesh_route_path_decision_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.decision_count==`number`?n.decision_count:0,i=typeof n.replacement_decision_count==`number`?n.replacement_decision_count:0,a=typeof n.local_effective_path_count==`number`?n.local_effective_path_count:0,o=typeof n.next_hop_available_count==`number`?n.next_hop_available_count:0,s=typeof n.withdrawn_local_relay_count==`number`?n.withdrawn_local_relay_count:0,c=[`path ${a}/${r}`];return i>0&&c.push(`repl${i}`),o>0&&c.push(`next${o}`),s>0&&c.push(`wd${s}`),c.join(` `)}function dn(e){let t=e?.metadata?.mesh_route_generation_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.active_decision_count==`number`?n.active_decision_count:0,i=typeof n.applied_decision_count==`number`?n.applied_decision_count:0,a=typeof n.withdrawn_decision_count==`number`?n.withdrawn_decision_count:0,o=n.generation_changed===!0,s=[`gen ${r}`];return i>0&&s.push(`ap${i}`),a>0&&s.push(`wd${a}`),o&&s.push(`chg`),s.join(` `)}function fn(e){let t=e?.metadata?.mesh_route_health_config_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=e?.metadata?.mesh_route_health_feedback_refresh_report,i=r&&typeof r==`object`&&!Array.isArray(r)?r:{},a=typeof n.route_health_route_count==`number`?n.route_health_route_count:0,o=typeof n.route_path_decision_applied_count==`number`?n.route_path_decision_applied_count:0,s=typeof n.replacement_route_health_route_count==`number`?n.replacement_route_health_route_count:0,c=typeof n.route_health_decision_drift_candidate_count==`number`?n.route_health_decision_drift_candidate_count:0,l=typeof i.feedback_refresh_attempt_count==`number`?i.feedback_refresh_attempt_count:typeof n.feedback_refresh_attempt_count==`number`?n.feedback_refresh_attempt_count:0,u=typeof i.feedback_refresh_success_count==`number`?i.feedback_refresh_success_count:typeof n.feedback_refresh_success_count==`number`?n.feedback_refresh_success_count:0,d=typeof i.feedback_refresh_suppressed_count==`number`?i.feedback_refresh_suppressed_count:typeof n.feedback_refresh_suppressed_count==`number`?n.feedback_refresh_suppressed_count:0,f=[`rh ${o}/${a}`];return s>0&&f.push(`repl${s}`),c>0&&f.push(`drift${c}`),(l>0||d>0)&&f.push(`fb${u}/${l}`),d>0&&f.push(`sup${d}`),f.join(` `)}function pn(e){let t=e?.metadata?.mesh_peer_connection_manager_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t;if(n.enabled===!1)return`manager off`;let r=typeof n.attempted==`number`?n.attempted:0,i=typeof n.succeeded==`number`?n.succeeded:0,a=typeof n.deferred==`number`?n.deferred:0,o=typeof n.relay_control_count==`number`?n.relay_control_count:0,s=o>0?`mgr ${i}/${r} relay${o}`:`mgr ${i}/${r}`;return a>0?`${s} def${a}`:s}function mn(e){let t=e?.metadata?.mesh_listener_report;if(!t||typeof t!=`object`||Array.isArray(t))return`н/д`;let n=t,r=typeof n.status==`string`?n.status:`unknown`,i=typeof n.listen_port_mode==`string`?n.listen_port_mode:`manual`,a=typeof n.effective_listen_addr==`string`?n.effective_listen_addr:``,o=typeof n.failure_reason==`string`?n.failure_reason:``;return r===`listening`?a?`listen ${a}`:`listen`:r===`auto_rebound`?a?`auto ${a}`:`auto rebound`:r===`listen_failed`?o?`${i} failed: ${o}`:`${i} failed`:r===`disabled`?i===`disabled`?`inbound off`:`inbound unavailable`:r}function hn(e,t){if(t===`en`)return e===1?`1 cluster`:`${e} clusters`;let n=e%10,r=e%100;return n===1&&r!==11?`${e} кластер`:n>=2&&n<=4&&(r<12||r>14)?`${e} кластера`:`${e} кластеров`}function gn(e,t=e.link_status===`reachable`?`reachable`:`unknown`){return t===`stale`?`stale`:t===`one_way`?`oneWay`:t!==`reachable`||e.link_status!==`reachable`?`bad`:e.quality_score!=null&&e.quality_score<70||e.latency_ms!=null&&e.latency_ms>80?`weak`:`good`}function _n(e,t=16){return e.length>t?`${e.slice(0,Math.max(1,t-2))}…`:e}function vn(e){return window.confirm(`${e}?\n\nЭто высокорисковая операция владельца платформы. Действие будет записано в аудит.`)}function yn(e){let t=(e||``).replace(/\/$/,``);return!t||t===`/api/v1`?window.location.origin:t.endsWith(`/api/v1`)?t.slice(0,-7):t}function P(e){return e?e.length>12?`${e.slice(0,8)}...${e.slice(-4)}`:e:`нет`}function F(e){return e?new Intl.DateTimeFormat(void 0,{dateStyle:`medium`,timeStyle:`short`}).format(new Date(e)):`никогда`}function bn(e){return e?new Intl.DateTimeFormat(void 0,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`}).format(new Date(e)):`н/д`}function xn(e){if(e==null||Number.isNaN(e))return`н/д`;let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=e,r=0;for(;n>=1024&&r