mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-11-09 02:52:22 +01:00
Do an imitation of protecting our butts (race conditions in message loading, websocket defensiveness, optimistic UI update rollback handling
This commit is contained in:
1 parent
bf03d76c33
commit
0138233743
12 files changed
+553
-91
No files matched your search
+41
-12
@@ -12,6 +12,10 @@ from app.config import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Timeout for individual WebSocket send operations (seconds)
|
||||
# Prevents a slow client from blocking broadcasts to other clients
|
||||
SEND_TIMEOUT_SECONDS = 5.0
|
||||
|
||||
|
||||
class WebSocketManager:
|
||||
"""Manages WebSocket connections and broadcasts events."""
|
||||
@@ -33,25 +37,50 @@ class WebSocketManager:
|
||||
logger.info("WebSocket client disconnected (%d remaining)", len(self.active_connections))
|
||||
|
||||
async def broadcast(self, event_type: str, data: Any) -> None:
|
||||
"""Broadcast an event to all connected clients."""
|
||||
"""Broadcast an event to all connected clients.
|
||||
|
||||
Uses a copy-then-send pattern to avoid holding the lock during I/O:
|
||||
1. Copy connection list while holding lock
|
||||
2. Release lock before sending
|
||||
3. Send to all clients concurrently with timeout
|
||||
4. Re-acquire lock to clean up disconnected clients
|
||||
"""
|
||||
if not self.active_connections:
|
||||
return
|
||||
|
||||
message = json.dumps({"type": event_type, "data": data})
|
||||
|
||||
# Copy connection list under lock to avoid holding lock during I/O
|
||||
async with self._lock:
|
||||
disconnected = []
|
||||
for connection in self.active_connections:
|
||||
try:
|
||||
await connection.send_text(message)
|
||||
except Exception as e:
|
||||
logger.debug("Failed to send to client: %s", e)
|
||||
disconnected.append(connection)
|
||||
connections = list(self.active_connections)
|
||||
|
||||
# Clean up disconnected clients
|
||||
for conn in disconnected:
|
||||
if conn in self.active_connections:
|
||||
self.active_connections.remove(conn)
|
||||
if not connections:
|
||||
return
|
||||
|
||||
# Send to all clients concurrently, collect failures
|
||||
disconnected: list[WebSocket] = []
|
||||
|
||||
async def send_to_client(connection: WebSocket) -> None:
|
||||
try:
|
||||
# Timeout prevents blocking on slow/unresponsive clients
|
||||
await asyncio.wait_for(connection.send_text(message), timeout=SEND_TIMEOUT_SECONDS)
|
||||
except asyncio.TimeoutError:
|
||||
logger.debug("Timeout sending to WebSocket client, marking disconnected")
|
||||
disconnected.append(connection)
|
||||
except Exception as e:
|
||||
logger.debug("Failed to send to client: %s", e)
|
||||
disconnected.append(connection)
|
||||
|
||||
# Send to all clients concurrently
|
||||
await asyncio.gather(*[send_to_client(conn) for conn in connections])
|
||||
|
||||
# Clean up disconnected clients (re-acquire lock)
|
||||
if disconnected:
|
||||
async with self._lock:
|
||||
for conn in disconnected:
|
||||
if conn in self.active_connections:
|
||||
self.active_connections.remove(conn)
|
||||
logger.debug("Removed %d disconnected WebSocket clients", len(disconnected))
|
||||
|
||||
async def send_personal(self, websocket: WebSocket, event_type: str, data: Any) -> None:
|
||||
"""Send an event to a specific client."""
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"mappings":";;;;;;;;6CASa,IAAIA,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,cAAc,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,SAAS,SAASC,EAAEC,EAAE,CAAC,OAAUA,IAAP,MAAqB,OAAOA,GAAlB,SAA2B,MAAKA,EAAEF,GAAGE,EAAEF,CAAC,GAAGE,EAAE,YAAY,EAAqB,OAAOA,GAApB,WAAsBA,EAAE,KAAI,CAC1e,IAAIC,EAAE,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,EAAE,mBAAmB,UAAU,GAAG,oBAAoB,UAAU,GAAG,gBAAgB,UAAU,EAAE,EAAEC,EAAE,OAAO,OAAOC,EAAE,GAAG,SAASC,EAAEJ,EAAEK,EAAEC,EAAE,CAAC,KAAK,MAAMN,EAAE,KAAK,QAAQK,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAGL,CAAC,CAACG,EAAE,UAAU,iBAAiB,GACnQA,EAAE,UAAU,SAAS,SAASJ,EAAEK,EAAE,CAAC,GAAc,OAAOL,GAAlB,UAAkC,OAAOA,GAApB,YAA6BA,GAAN,KAAQ,MAAM,MAAM,uHAAuH,EAAE,KAAK,QAAQ,gBAAgB,KAAKA,EAAEK,EAAE,UAAU,CAAC,EAAED,EAAE,UAAU,YAAY,SAASJ,EAAE,CAAC,KAAK,QAAQ,mBAAmB,KAAKA,EAAE,aAAa,CAAC,EAAE,SAASO,GAAG,EAAEA,EAAE,UAAUH,EAAE,UAAU,SAASI,EAAER,EAAEK,EAAEC,EAAE,CAAC,KAAK,MAAMN,EAAE,KAAK,QAAQK,EAAE,KAAK,KAAKF,EAAE,KAAK,QAAQG,GAAGL,CAAC,CAAC,IAAIQ,EAAED,EAAE,UAAU,IAAID,EACrfE,EAAE,YAAYD,EAAEN,EAAEO,EAAEL,EAAE,SAAS,EAAEK,EAAE,qBAAqB,GAAG,IAAIC,EAAE,MAAM,QAAQC,EAAE,OAAO,UAAU,eAAeC,EAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,EAAE,EACxK,SAASC,EAAEd,EAAEK,EAAEC,EAAE,CAAC,IAAIS,EAAEC,GAAE,GAAGC,GAAE,KAAKC,GAAE,KAAK,GAASb,GAAN,KAAQ,IAAIU,KAAcV,EAAE,MAAX,SAAiBa,GAAEb,EAAE,KAAcA,EAAE,MAAX,SAAiBY,GAAE,GAAGZ,EAAE,KAAKA,EAAEM,EAAE,KAAKN,EAAEU,CAAC,GAAG,CAACF,EAAE,eAAeE,CAAC,IAAIC,GAAED,CAAC,EAAEV,EAAEU,CAAC,GAAG,IAAII,GAAE,UAAU,OAAO,EAAE,GAAOA,KAAJ,EAAMH,GAAE,SAASV,UAAU,EAAEa,GAAE,CAAC,QAAQC,GAAE,MAAMD,EAAC,EAAEE,GAAE,EAAEA,GAAEF,GAAEE,KAAID,GAAEC,EAAC,EAAE,UAAUA,GAAE,CAAC,EAAEL,GAAE,SAASI,EAAC,CAAC,GAAGpB,GAAGA,EAAE,aAAa,IAAIe,KAAKI,GAAEnB,EAAE,aAAamB,GAAWH,GAAED,CAAC,IAAZ,SAAgBC,GAAED,CAAC,EAAEI,GAAEJ,CAAC,GAAG,MAAM,CAAC,SAAS5B,EAAE,KAAKa,EAAE,IAAIiB,GAAE,IAAIC,GAAE,MAAMF,GAAE,OAAOJ,EAAE,OAAO,CAAC,CAC7a,SAASU,EAAEtB,EAAEK,EAAE,CAAC,MAAM,CAAC,SAASlB,EAAE,KAAKa,EAAE,KAAK,IAAIK,EAAE,IAAIL,EAAE,IAAI,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAM,CAAC,CAAC,SAASuB,EAAEvB,EAAE,CAAC,OAAiB,OAAOA,GAAlB,UAA4BA,IAAP,MAAUA,EAAE,WAAWb,CAAC,CAAC,SAASqC,EAAOxB,EAAE,CAAC,IAAIK,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAIL,EAAE,QAAQ,QAAQ,SAASA,EAAE,CAAC,OAAOK,EAAEL,CAAC,CAAC,CAAC,CAAC,CAAC,IAAIyB,GAAE,OAAO,SAASC,EAAE1B,EAAEK,EAAE,CAAC,OAAiB,OAAOL,GAAlB,UAA4BA,IAAP,MAAgBA,EAAE,KAAR,KAAYwB,EAAO,GAAGxB,EAAE,GAAG,EAAEK,EAAE,SAAS,EAAE,CAAC,CAC/W,SAASsB,GAAE3B,EAAEK,EAAEC,EAAES,EAAEC,GAAE,CAAC,IAAIC,GAAE,OAAOjB,GAAmBiB,KAAd,aAA6BA,KAAZ,aAAcjB,EAAE,MAAK,IAAIkB,GAAE,GAAG,GAAUlB,IAAP,KAASkB,GAAE,OAAQ,QAAOD,GAAC,CAAE,IAAK,SAAS,IAAK,SAASC,GAAE,GAAG,MAAM,IAAK,SAAS,OAAOlB,EAAE,SAAQ,CAAE,KAAKb,EAAE,KAAKC,EAAE8B,GAAE,EAAE,CAAC,CAAC,GAAGA,GAAE,OAAOA,GAAElB,EAAEgB,GAAEA,GAAEE,EAAC,EAAElB,EAAOe,IAAL,GAAO,IAAIW,EAAER,GAAE,CAAC,EAAEH,EAAEL,EAAEM,EAAC,GAAGV,EAAE,GAASN,GAAN,OAAUM,EAAEN,EAAE,QAAQyB,GAAE,KAAK,EAAE,KAAKE,GAAEX,GAAEX,EAAEC,EAAE,GAAG,SAASN,GAAE,CAAC,OAAOA,EAAC,CAAC,GAASgB,IAAN,OAAUO,EAAEP,EAAC,IAAIA,GAAEM,EAAEN,GAAEV,GAAG,CAACU,GAAE,KAAKE,IAAGA,GAAE,MAAMF,GAAE,IAAI,IAAI,GAAGA,GAAE,KAAK,QAAQS,GAAE,KAAK,EAAE,KAAKzB,CAAC,GAAGK,EAAE,KAAKW,EAAC,GAAG,EAAyB,GAAvBE,GAAE,EAAEH,EAAOA,IAAL,GAAO,IAAIA,EAAE,IAAOL,EAAEV,CAAC,EAAE,QAAQmB,GAAE,EAAEA,GAAEnB,EAAE,OAAOmB,KAAI,CAACF,GACrfjB,EAAEmB,EAAC,EAAE,IAAIC,GAAEL,EAAEW,EAAET,GAAEE,EAAC,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,CAAC,SAASI,GAAErB,EAAEC,CAAC,EAAe,OAAOoB,IAApB,WAAsB,IAAIpB,EAAEoB,GAAE,KAAKpB,CAAC,EAAEmB,GAAE,EAAE,EAAEF,GAAEjB,EAAE,KAAI,GAAI,MAAMiB,GAAEA,GAAE,MAAMG,GAAEL,EAAEW,EAAET,GAAEE,IAAG,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,UAAqBC,KAAX,SAAa,MAAMZ,EAAE,OAAOL,CAAC,EAAE,MAAM,mDAAuEK,IAApB,kBAAsB,qBAAqB,OAAO,KAAKL,CAAC,EAAE,KAAK,IAAI,EAAE,IAAIK,GAAG,2EAA2E,EAAE,OAAOa,EAAC,CACzZ,SAASU,GAAE5B,EAAEK,EAAEC,EAAE,CAAC,GAASN,GAAN,KAAQ,OAAOA,EAAE,IAAIe,EAAE,GAAGC,GAAE,EAAE,OAAAW,GAAE3B,EAAEe,EAAE,GAAG,GAAG,SAASf,GAAE,CAAC,OAAOK,EAAE,KAAKC,EAAEN,GAAEgB,IAAG,CAAC,CAAC,EAASD,CAAC,CAAC,SAASc,GAAE7B,EAAE,CAAC,GAAQA,EAAE,UAAP,GAAe,CAAC,IAAIK,EAAEL,EAAE,QAAQK,EAAEA,EAAC,EAAGA,EAAE,KAAK,SAASA,EAAE,EAAQL,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAC,EAAE,SAASA,EAAE,EAAQL,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAC,CAAC,EAAOL,EAAE,UAAP,KAAiBA,EAAE,QAAQ,EAAEA,EAAE,QAAQK,EAAE,CAAC,GAAOL,EAAE,UAAN,EAAc,OAAOA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,OAAQ,CAC5Z,IAAI8B,GAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,WAAW,IAAI,EAAEC,GAAE,CAAC,uBAAuBF,GAAE,wBAAwBC,EAAE,kBAAkBnB,CAAC,EAAE,SAASqB,GAAG,CAAC,MAAM,MAAM,0DAA0D,CAAE,CACzM,OAAAC,GAAA,SAAiB,CAAC,IAAIN,GAAE,QAAQ,SAAS5B,EAAEK,EAAEC,EAAE,CAACsB,GAAE5B,EAAE,UAAU,CAACK,EAAE,MAAM,KAAK,SAAS,CAAC,EAAEC,CAAC,CAAC,EAAE,MAAM,SAASN,EAAE,CAAC,IAAIK,EAAE,EAAE,OAAAuB,GAAE5B,EAAE,UAAU,CAACK,GAAG,CAAC,EAASA,CAAC,EAAE,QAAQ,SAASL,EAAE,CAAC,OAAO4B,GAAE5B,EAAE,SAASA,EAAE,CAAC,OAAOA,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,SAASA,EAAE,CAAC,GAAG,CAACuB,EAAEvB,CAAC,EAAE,Line truncated
|
||||
+35
-35
@@ -6,7 +6,7 @@ var Dv=Object.defineProperty;var Rv=(r,a,o)=>a in r?Dv(r,a,{enumerable:!0,config
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var bp;function Nv(){if(bp)return ft;bp=1;var r=Symbol.for("react.element"),a=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),f=Symbol.for("react.provider"),p=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.iterator;function w(B){return B===null||typeof B!="object"?null:(B=y&&B[y]||B["@@iterator"],typeof B=="function"?B:null)}var P={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},D=Object.assign,C={};function k(B,V,K){this.props=B,this.context=V,this.refs=C,this.updater=K||P}k.prototype.isReactComponent={},k.prototype.setState=function(B,V){if(typeof B!="object"&&typeof B!="function"&&B!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,B,V,"setState")},k.prototype.forceUpdate=function(B){this.updater.enqueueForceUpdate(this,B,"forceUpdate")};function R(){}R.prototype=k.prototype;function T(B,V,K){this.props=B,this.context=V,this.refs=C,this.updater=K||P}var S=T.prototype=new R;S.constructor=T,D(S,k.prototype),S.isPureReactComponent=!0;var N=Array.isArray,I=Object.prototype.hasOwnProperty,H={current:null},z={key:!0,ref:!0,__self:!0,__source:!0};function j(B,V,K){var $,ce={},de=null,Se=null;if(V!=null)for($ in V.ref!==void 0&&(Se=V.ref),V.key!==void 0&&(de=""+V.key),V)I.call(V,$)&&!z.hasOwnProperty($)&&(ce[$]=V[$]);var Ae=arguments.length-2;if(Ae===1)ce.children=K;else if(1<Ae){for(var Ue=Array(Ae),Ye=0;Ye<Ae;Ye++)Ue[Ye]=arguments[Ye+2];ce.children=Ue}if(B&&B.defaultProps)for($ in Ae=B.defaultProps,Ae)ce[$]===void 0&&(ce[$]=Ae[$]);return{$$typeof:r,type:B,key:de,ref:Se,props:ce,_owner:H.current}}function J(B,V){return{$$typeof:r,type:B.type,key:V,ref:B.ref,props:B.props,_owner:B._owner}}function W(B){return typeof B=="object"&&B!==null&&B.$$typeof===r}function U(B){var V={"=":"=0",":":"=2"};return"$"+B.replace(/[=:]/g,function(K){return V[K]})}var ne=/\/+/g;function Y(B,V){return typeof B=="object"&&B!==null&&B.key!=null?U(""+B.key):V.toString(36)}function re(B,V,K,$,ce){var de=typeof B;(de==="undefined"||de==="boolean")&&(B=null);var Se=!1;if(B===null)Se=!0;else switch(de){case"string":case"number":Se=!0;break;case"object":switch(B.$$typeof){case r:case a:Se=!0}}if(Se)return Se=B,ce=ce(Se),B=$===""?"."+Y(Se,0):$,N(ce)?(K="",B!=null&&(K=B.replace(ne,"$&/")+"/"),re(ce,V,K,"",function(Ye){return Ye})):ce!=null&&(W(ce)&&(ce=J(ce,K+(!ce.key||Se&&Se.key===ce.key?"":(""+ce.key).replace(ne,"$&/")+"/")+B)),V.push(ce)),1;if(Se=0,$=$===""?".":$+":",N(B))for(var Ae=0;Ae<B.length;Ae++){de=B[Ae];var Ue=$+Y(de,Ae);Se+=re(de,V,K,Ue,ce)}else if(Ue=w(B),typeof Ue=="function")for(B=Ue.call(B),Ae=0;!(de=B.next()).done;)de=de.value,Ue=$+Y(de,Ae++),Se+=re(de,V,K,Ue,ce);else if(de==="object")throw V=String(B),Error("Objects are not valid as a React child (found: "+(V==="[object Object]"?"object with keys {"+Object.keys(B).join(", ")+"}":V)+"). If you meant to render a collection of children, use an array instead.");return Se}function fe(B,V,K){if(B==null)return B;var $=[],ce=0;return re(B,$,"","",function(de){return V.call(K,de,ce++)}),$}function ae(B){if(B._status===-1){var V=B._result;V=V(),V.then(function(K){(B._status===0||B._status===-1)&&(B._status=1,B._result=K)},function(K){(B._status===0||B._status===-1)&&(B._status=2,B._result=K)}),B._status===-1&&(B._status=0,B._result=V)}if(B._status===1)return B._result.default;throw B._result}var he={current:null},G={transition:null},me={ReactCurrentDispatcher:he,ReactCurrentBatchConfig:G,ReactCurrentOwner:H};function Z(){throw Error("act(...) is not supported in production builds of React.")}return ft.Children={map:fe,forEach:function(B,V,K){fe(B,function(){V.apply(this,arguments)},K)},count:function(B){var V=0;return fe(B,function(){V++}),V},toArray:function(B){return fe(B,function(V){return V})||[]},only:function(B){if(!W(B))throw Error("React.Children.only expected to receive a single React element child.");return B}},ft.Component=k,ft.Fragment=o,ft.Profiler=d,ft.PureComponent=T,ft.StrictMode=l,ft.Suspense=g,ft.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=me,ft.act=Z,ft.cloneElement=function(B,V,K){if(B==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+B+".");var $=D({},B.props),ce=B.key,de=B.ref,Se=B._owner;if(V!=null){if(V.ref!==void 0&&(de=V.ref,Se=H.current),V.key!==void 0&&(ce=""+V.key),B.type&&B.type.defaultProps)var Ae=B.type.defaultProps;for(Ue in V)I.call(V,Ue)&&!z.hasOwnProperty(Ue)&&($[Ue]=V[Ue]===void 0&&Ae!==void 0?Ae[Ue]:V[Ue])}var Ue=arguments.length-2;if(Ue===1)$.children=K;else if(1<Ue){Ae=Array(Ue);for(var Ye=0;Ye<Ue;Ye++)Ae[Ye]=arguments[Ye+2];$.children=Ae}return{$$typeof:r,type:B.type,key:ce,ref:de,props:$,_owner:Se}},ft.creLine truncated
|
||||
*/var bp;function Nv(){if(bp)return ft;bp=1;var r=Symbol.for("react.element"),a=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),f=Symbol.for("react.provider"),p=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.iterator;function w(P){return P===null||typeof P!="object"?null:(P=y&&P[y]||P["@@iterator"],typeof P=="function"?P:null)}var T={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},F=Object.assign,k={};function E(P,V,K){this.props=P,this.context=V,this.refs=k,this.updater=K||T}E.prototype.isReactComponent={},E.prototype.setState=function(P,V){if(typeof P!="object"&&typeof P!="function"&&P!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,P,V,"setState")},E.prototype.forceUpdate=function(P){this.updater.enqueueForceUpdate(this,P,"forceUpdate")};function D(){}D.prototype=E.prototype;function B(P,V,K){this.props=P,this.context=V,this.refs=k,this.updater=K||T}var S=B.prototype=new D;S.constructor=B,F(S,E.prototype),S.isPureReactComponent=!0;var N=Array.isArray,M=Object.prototype.hasOwnProperty,z={current:null},H={key:!0,ref:!0,__self:!0,__source:!0};function j(P,V,K){var $,ce={},de=null,Se=null;if(V!=null)for($ in V.ref!==void 0&&(Se=V.ref),V.key!==void 0&&(de=""+V.key),V)M.call(V,$)&&!H.hasOwnProperty($)&&(ce[$]=V[$]);var Ae=arguments.length-2;if(Ae===1)ce.children=K;else if(1<Ae){for(var Ue=Array(Ae),Ye=0;Ye<Ae;Ye++)Ue[Ye]=arguments[Ye+2];ce.children=Ue}if(P&&P.defaultProps)for($ in Ae=P.defaultProps,Ae)ce[$]===void 0&&(ce[$]=Ae[$]);return{$$typeof:r,type:P,key:de,ref:Se,props:ce,_owner:z.current}}function J(P,V){return{$$typeof:r,type:P.type,key:V,ref:P.ref,props:P.props,_owner:P._owner}}function W(P){return typeof P=="object"&&P!==null&&P.$$typeof===r}function U(P){var V={"=":"=0",":":"=2"};return"$"+P.replace(/[=:]/g,function(K){return V[K]})}var ne=/\/+/g;function Y(P,V){return typeof P=="object"&&P!==null&&P.key!=null?U(""+P.key):V.toString(36)}function re(P,V,K,$,ce){var de=typeof P;(de==="undefined"||de==="boolean")&&(P=null);var Se=!1;if(P===null)Se=!0;else switch(de){case"string":case"number":Se=!0;break;case"object":switch(P.$$typeof){case r:case a:Se=!0}}if(Se)return Se=P,ce=ce(Se),P=$===""?"."+Y(Se,0):$,N(ce)?(K="",P!=null&&(K=P.replace(ne,"$&/")+"/"),re(ce,V,K,"",function(Ye){return Ye})):ce!=null&&(W(ce)&&(ce=J(ce,K+(!ce.key||Se&&Se.key===ce.key?"":(""+ce.key).replace(ne,"$&/")+"/")+P)),V.push(ce)),1;if(Se=0,$=$===""?".":$+":",N(P))for(var Ae=0;Ae<P.length;Ae++){de=P[Ae];var Ue=$+Y(de,Ae);Se+=re(de,V,K,Ue,ce)}else if(Ue=w(P),typeof Ue=="function")for(P=Ue.call(P),Ae=0;!(de=P.next()).done;)de=de.value,Ue=$+Y(de,Ae++),Se+=re(de,V,K,Ue,ce);else if(de==="object")throw V=String(P),Error("Objects are not valid as a React child (found: "+(V==="[object Object]"?"object with keys {"+Object.keys(P).join(", ")+"}":V)+"). If you meant to render a collection of children, use an array instead.");return Se}function fe(P,V,K){if(P==null)return P;var $=[],ce=0;return re(P,$,"","",function(de){return V.call(K,de,ce++)}),$}function ae(P){if(P._status===-1){var V=P._result;V=V(),V.then(function(K){(P._status===0||P._status===-1)&&(P._status=1,P._result=K)},function(K){(P._status===0||P._status===-1)&&(P._status=2,P._result=K)}),P._status===-1&&(P._status=0,P._result=V)}if(P._status===1)return P._result.default;throw P._result}var he={current:null},G={transition:null},pe={ReactCurrentDispatcher:he,ReactCurrentBatchConfig:G,ReactCurrentOwner:z};function Z(){throw Error("act(...) is not supported in production builds of React.")}return ft.Children={map:fe,forEach:function(P,V,K){fe(P,function(){V.apply(this,arguments)},K)},count:function(P){var V=0;return fe(P,function(){V++}),V},toArray:function(P){return fe(P,function(V){return V})||[]},only:function(P){if(!W(P))throw Error("React.Children.only expected to receive a single React element child.");return P}},ft.Component=E,ft.Fragment=o,ft.Profiler=d,ft.PureComponent=B,ft.StrictMode=l,ft.Suspense=g,ft.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=pe,ft.act=Z,ft.cloneElement=function(P,V,K){if(P==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+P+".");var $=F({},P.props),ce=P.key,de=P.ref,Se=P._owner;if(V!=null){if(V.ref!==void 0&&(de=V.ref,Se=z.current),V.key!==void 0&&(ce=""+V.key),P.type&&P.type.defaultProps)var Ae=P.type.defaultProps;for(Ue in V)M.call(V,Ue)&&!H.hasOwnProperty(Ue)&&($[Ue]=V[Ue]===void 0&&Ae!==void 0?Ae[Ue]:V[Ue])}var Ue=arguments.length-2;if(Ue===1)$.children=K;else if(1<Ue){Ae=Array(Ue);for(var Ye=0;Ye<Ue;Ye++)Ae[Ye]=arguments[Ye+2];$.children=Ae}return{$$typeof:r,type:P.type,key:ce,ref:de,props:$,_owner:Se}},ft.creLine truncated
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
@@ -14,7 +14,7 @@ var Dv=Object.defineProperty;var Rv=(r,a,o)=>a in r?Dv(r,a,{enumerable:!0,config
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var Ep;function Lv(){if(Ep)return Za;Ep=1;var r=h0(),a=Symbol.for("react.element"),o=Symbol.for("react.fragment"),l=Object.prototype.hasOwnProperty,d=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,f={key:!0,ref:!0,__self:!0,__source:!0};function p(h,g,m){var v,y={},w=null,P=null;m!==void 0&&(w=""+m),g.key!==void 0&&(w=""+g.key),g.ref!==void 0&&(P=g.ref);for(v in g)l.call(g,v)&&!f.hasOwnProperty(v)&&(y[v]=g[v]);if(h&&h.defaultProps)for(v in g=h.defaultProps,g)y[v]===void 0&&(y[v]=g[v]);return{$$typeof:a,type:h,key:w,ref:P,props:y,_owner:d.current}}return Za.Fragment=o,Za.jsx=p,Za.jsxs=p,Za}var kp;function Mv(){return kp||(kp=1,Pf.exports=Lv()),Pf.exports}var b=Mv(),F=h0();const Ee=Ys(F),p0=Fv({__proto__:null,default:Ee},[F]);var Bu={},Df={exports:{}},Zn={},Rf={exports:{}},Ff={};/**
|
||||
*/var Ep;function Lv(){if(Ep)return Za;Ep=1;var r=h0(),a=Symbol.for("react.element"),o=Symbol.for("react.fragment"),l=Object.prototype.hasOwnProperty,d=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,f={key:!0,ref:!0,__self:!0,__source:!0};function p(h,g,m){var v,y={},w=null,T=null;m!==void 0&&(w=""+m),g.key!==void 0&&(w=""+g.key),g.ref!==void 0&&(T=g.ref);for(v in g)l.call(g,v)&&!f.hasOwnProperty(v)&&(y[v]=g[v]);if(h&&h.defaultProps)for(v in g=h.defaultProps,g)y[v]===void 0&&(y[v]=g[v]);return{$$typeof:a,type:h,key:w,ref:T,props:y,_owner:d.current}}return Za.Fragment=o,Za.jsx=p,Za.jsxs=p,Za}var kp;function Mv(){return kp||(kp=1,Pf.exports=Lv()),Pf.exports}var b=Mv(),R=h0();const Ee=Ys(R),p0=Fv({__proto__:null,default:Ee},[R]);var Bu={},Df={exports:{}},Zn={},Rf={exports:{}},Ff={};/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
@@ -22,7 +22,7 @@ var Dv=Object.defineProperty;var Rv=(r,a,o)=>a in r?Dv(r,a,{enumerable:!0,config
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var Sp;function Iv(){return Sp||(Sp=1,(function(r){function a(G,me){var Z=G.length;G.push(me);e:for(;0<Z;){var B=Z-1>>>1,V=G[B];if(0<d(V,me))G[B]=me,G[Z]=V,Z=B;else break e}}function o(G){return G.length===0?null:G[0]}function l(G){if(G.length===0)return null;var me=G[0],Z=G.pop();if(Z!==me){G[0]=Z;e:for(var B=0,V=G.length,K=V>>>1;B<K;){var $=2*(B+1)-1,ce=G[$],de=$+1,Se=G[de];if(0>d(ce,Z))de<V&&0>d(Se,ce)?(G[B]=Se,G[de]=Z,B=de):(G[B]=ce,G[$]=Z,B=$);else if(de<V&&0>d(Se,Z))G[B]=Se,G[de]=Z,B=de;else break e}}return me}function d(G,me){var Z=G.sortIndex-me.sortIndex;return Z!==0?Z:G.id-me.id}if(typeof performance=="object"&&typeof performance.now=="function"){var f=performance;r.unstable_now=function(){return f.now()}}else{var p=Date,h=p.now();r.unstable_now=function(){return p.now()-h}}var g=[],m=[],v=1,y=null,w=3,P=!1,D=!1,C=!1,k=typeof setTimeout=="function"?setTimeout:null,R=typeof clearTimeout=="function"?clearTimeout:null,T=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(G){for(var me=o(m);me!==null;){if(me.callback===null)l(m);else if(me.startTime<=G)l(m),me.sortIndex=me.expirationTime,a(g,me);else break;me=o(m)}}function N(G){if(C=!1,S(G),!D)if(o(g)!==null)D=!0,ae(I);else{var me=o(m);me!==null&&he(N,me.startTime-G)}}function I(G,me){D=!1,C&&(C=!1,R(j),j=-1),P=!0;var Z=w;try{for(S(me),y=o(g);y!==null&&(!(y.expirationTime>me)||G&&!U());){var B=y.callback;if(typeof B=="function"){y.callback=null,w=y.priorityLevel;var V=B(y.expirationTime<=me);me=r.unstable_now(),typeof V=="function"?y.callback=V:y===o(g)&&l(g),S(me)}else l(g);y=o(g)}if(y!==null)var K=!0;else{var $=o(m);$!==null&&he(N,$.startTime-me),K=!1}return K}finally{y=null,w=Z,P=!1}}var H=!1,z=null,j=-1,J=5,W=-1;function U(){return!(r.unstable_now()-W<J)}function ne(){if(z!==null){var G=r.unstable_now();W=G;var me=!0;try{me=z(!0,G)}finally{me?Y():(H=!1,z=null)}}else H=!1}var Y;if(typeof T=="function")Y=function(){T(ne)};else if(typeof MessageChannel<"u"){var re=new MessageChannel,fe=re.port2;re.port1.onmessage=ne,Y=function(){fe.postMessage(null)}}else Y=function(){k(ne,0)};function ae(G){z=G,H||(H=!0,Y())}function he(G,me){j=k(function(){G(r.unstable_now())},me)}r.unstable_IdlePriority=5,r.unstable_ImmediatePriority=1,r.unstable_LowPriority=4,r.unstable_NormalPriority=3,r.unstable_Profiling=null,r.unstable_UserBlockingPriority=2,r.unstable_cancelCallback=function(G){G.callback=null},r.unstable_continueExecution=function(){D||P||(D=!0,ae(I))},r.unstable_forceFrameRate=function(G){0>G||125<G?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):J=0<G?Math.floor(1e3/G):5},r.unstable_getCurrentPriorityLevel=function(){return w},r.unstable_getFirstCallbackNode=function(){return o(g)},r.unstable_next=function(G){switch(w){case 1:case 2:case 3:var me=3;break;default:me=w}var Z=w;w=me;try{return G()}finally{w=Z}},r.unstable_pauseExecution=function(){},r.unstable_requestPaint=function(){},r.unstable_runWithPriority=function(G,me){switch(G){case 1:case 2:case 3:case 4:case 5:break;default:G=3}var Z=w;w=G;try{return me()}finally{w=Z}},r.unstable_scheduleCallback=function(G,me,Z){var B=r.unstable_now();switch(typeof Z=="object"&&Z!==null?(Z=Z.delay,Z=typeof Z=="number"&&0<Z?B+Z:B):Z=B,G){case 1:var V=-1;break;case 2:V=250;break;case 5:V=1073741823;break;case 4:V=1e4;break;default:V=5e3}return V=Z+V,G={id:v++,callback:me,priorityLevel:G,startTime:Z,expirationTime:V,sortIndex:-1},Z>B?(G.sortIndex=Z,a(m,G),o(g)===null&&G===o(m)&&(C?(R(j),j=-1):C=!0,he(N,Z-B))):(G.sortIndex=V,a(g,G),D||P||(D=!0,ae(I))),G},r.unstable_shouldYield=U,r.unstable_wrapCallback=function(G){var me=w;return function(){var Z=w;w=me;try{return G.apply(this,arguments)}finally{w=Z}}}})(Ff)),Ff}var Bp;function Ov(){return Bp||(Bp=1,Rf.exports=Iv()),Rf.exports}/**
|
||||
*/var Sp;function Iv(){return Sp||(Sp=1,(function(r){function a(G,pe){var Z=G.length;G.push(pe);e:for(;0<Z;){var P=Z-1>>>1,V=G[P];if(0<d(V,pe))G[P]=pe,G[Z]=V,Z=P;else break e}}function o(G){return G.length===0?null:G[0]}function l(G){if(G.length===0)return null;var pe=G[0],Z=G.pop();if(Z!==pe){G[0]=Z;e:for(var P=0,V=G.length,K=V>>>1;P<K;){var $=2*(P+1)-1,ce=G[$],de=$+1,Se=G[de];if(0>d(ce,Z))de<V&&0>d(Se,ce)?(G[P]=Se,G[de]=Z,P=de):(G[P]=ce,G[$]=Z,P=$);else if(de<V&&0>d(Se,Z))G[P]=Se,G[de]=Z,P=de;else break e}}return pe}function d(G,pe){var Z=G.sortIndex-pe.sortIndex;return Z!==0?Z:G.id-pe.id}if(typeof performance=="object"&&typeof performance.now=="function"){var f=performance;r.unstable_now=function(){return f.now()}}else{var p=Date,h=p.now();r.unstable_now=function(){return p.now()-h}}var g=[],m=[],v=1,y=null,w=3,T=!1,F=!1,k=!1,E=typeof setTimeout=="function"?setTimeout:null,D=typeof clearTimeout=="function"?clearTimeout:null,B=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(G){for(var pe=o(m);pe!==null;){if(pe.callback===null)l(m);else if(pe.startTime<=G)l(m),pe.sortIndex=pe.expirationTime,a(g,pe);else break;pe=o(m)}}function N(G){if(k=!1,S(G),!F)if(o(g)!==null)F=!0,ae(M);else{var pe=o(m);pe!==null&&he(N,pe.startTime-G)}}function M(G,pe){F=!1,k&&(k=!1,D(j),j=-1),T=!0;var Z=w;try{for(S(pe),y=o(g);y!==null&&(!(y.expirationTime>pe)||G&&!U());){var P=y.callback;if(typeof P=="function"){y.callback=null,w=y.priorityLevel;var V=P(y.expirationTime<=pe);pe=r.unstable_now(),typeof V=="function"?y.callback=V:y===o(g)&&l(g),S(pe)}else l(g);y=o(g)}if(y!==null)var K=!0;else{var $=o(m);$!==null&&he(N,$.startTime-pe),K=!1}return K}finally{y=null,w=Z,T=!1}}var z=!1,H=null,j=-1,J=5,W=-1;function U(){return!(r.unstable_now()-W<J)}function ne(){if(H!==null){var G=r.unstable_now();W=G;var pe=!0;try{pe=H(!0,G)}finally{pe?Y():(z=!1,H=null)}}else z=!1}var Y;if(typeof B=="function")Y=function(){B(ne)};else if(typeof MessageChannel<"u"){var re=new MessageChannel,fe=re.port2;re.port1.onmessage=ne,Y=function(){fe.postMessage(null)}}else Y=function(){E(ne,0)};function ae(G){H=G,z||(z=!0,Y())}function he(G,pe){j=E(function(){G(r.unstable_now())},pe)}r.unstable_IdlePriority=5,r.unstable_ImmediatePriority=1,r.unstable_LowPriority=4,r.unstable_NormalPriority=3,r.unstable_Profiling=null,r.unstable_UserBlockingPriority=2,r.unstable_cancelCallback=function(G){G.callback=null},r.unstable_continueExecution=function(){F||T||(F=!0,ae(M))},r.unstable_forceFrameRate=function(G){0>G||125<G?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):J=0<G?Math.floor(1e3/G):5},r.unstable_getCurrentPriorityLevel=function(){return w},r.unstable_getFirstCallbackNode=function(){return o(g)},r.unstable_next=function(G){switch(w){case 1:case 2:case 3:var pe=3;break;default:pe=w}var Z=w;w=pe;try{return G()}finally{w=Z}},r.unstable_pauseExecution=function(){},r.unstable_requestPaint=function(){},r.unstable_runWithPriority=function(G,pe){switch(G){case 1:case 2:case 3:case 4:case 5:break;default:G=3}var Z=w;w=G;try{return pe()}finally{w=Z}},r.unstable_scheduleCallback=function(G,pe,Z){var P=r.unstable_now();switch(typeof Z=="object"&&Z!==null?(Z=Z.delay,Z=typeof Z=="number"&&0<Z?P+Z:P):Z=P,G){case 1:var V=-1;break;case 2:V=250;break;case 5:V=1073741823;break;case 4:V=1e4;break;default:V=5e3}return V=Z+V,G={id:v++,callback:pe,priorityLevel:G,startTime:Z,expirationTime:V,sortIndex:-1},Z>P?(G.sortIndex=Z,a(m,G),o(g)===null&&G===o(m)&&(k?(D(j),j=-1):k=!0,he(N,Z-P))):(G.sortIndex=V,a(g,G),F||T||(F=!0,ae(M))),G},r.unstable_shouldYield=U,r.unstable_wrapCallback=function(G){var pe=w;return function(){var Z=w;w=pe;try{return G.apply(this,arguments)}finally{w=Z}}}})(Ff)),Ff}var Bp;function Ov(){return Bp||(Bp=1,Rf.exports=Iv()),Rf.exports}/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
@@ -30,56 +30,56 @@ var Dv=Object.defineProperty;var Rv=(r,a,o)=>a in r?Dv(r,a,{enumerable:!0,config
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/var Pp;function jv(){if(Pp)return Zn;Pp=1;var r=h0(),a=Ov();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,s=1;s<arguments.length;s++)n+="&args[]="+encodeURIComponent(arguments[s]);return"Minified React error #"+e+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var l=new Set,d={};function f(e,n){p(e,n),p(e+"Capture",n)}function p(e,n){for(d[e]=n,e=0;e<n.length;e++)l.add(n[e])}var h=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),g=Object.prototype.hasOwnProperty,m=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,v={},y={};function w(e){return g.call(y,e)?!0:g.call(v,e)?!1:m.test(e)?y[e]=!0:(v[e]=!0,!1)}function P(e,n,s,c){if(s!==null&&s.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return c?!1:s!==null?!s.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function D(e,n,s,c){if(n===null||typeof n>"u"||P(e,n,s,c))return!0;if(c)return!1;if(s!==null)switch(s.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function C(e,n,s,c,x,_,M){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=c,this.attributeNamespace=x,this.mustUseProperty=s,this.propertyName=e,this.type=n,this.sanitizeURL=_,this.removeEmptyString=M}var k={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){k[e]=new C(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];k[n]=new C(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){k[e]=new C(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){k[e]=new C(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){k[e]=new C(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){k[e]=new C(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){k[e]=new C(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){k[e]=new C(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){k[e]=new C(e,5,!1,e.toLowerCase(),null,!1,!1)});var R=/[\-:]([a-z])/g;function T(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(R,T);k[n]=new C(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(R,T);k[n]=new C(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(R,T);k[n]=new C(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){k[e]=new C(e,1,!1,e.toLowerCase(),null,!1,!1)}),k.xlinkHref=new C("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){k[e]=new C(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,n,s,c){var x=k.hasOwnProperty(n)?k[n]:null;(x!==null?x.type!==0:c||!(2<n.length)||n[0]!=="o"&&n[0]!=="O"||n[1]!=="n"&&n[1]!=
Line truncated
|
||||
`+B+e}var K=!1;function $(e,n){if(!e||K)return"";K=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(n,[])}catch(ue){var c=ue}Reflect.construct(e,[],n)}else{try{n.call()}catch(ue){c=ue}e.call(n.prototype)}else{try{throw Error()}catch(ue){c=ue}e()}}catch(ue){if(ue&&c&&typeof ue.stack=="string"){for(var x=ue.stack.split(`
|
||||
*/var Pp;function jv(){if(Pp)return Zn;Pp=1;var r=h0(),a=Ov();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,s=1;s<arguments.length;s++)n+="&args[]="+encodeURIComponent(arguments[s]);return"Minified React error #"+e+"; visit "+n+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var l=new Set,d={};function f(e,n){p(e,n),p(e+"Capture",n)}function p(e,n){for(d[e]=n,e=0;e<n.length;e++)l.add(n[e])}var h=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),g=Object.prototype.hasOwnProperty,m=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,v={},y={};function w(e){return g.call(y,e)?!0:g.call(v,e)?!1:m.test(e)?y[e]=!0:(v[e]=!0,!1)}function T(e,n,s,c){if(s!==null&&s.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return c?!1:s!==null?!s.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function F(e,n,s,c){if(n===null||typeof n>"u"||T(e,n,s,c))return!0;if(c)return!1;if(s!==null)switch(s.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function k(e,n,s,c,x,_,I){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=c,this.attributeNamespace=x,this.mustUseProperty=s,this.propertyName=e,this.type=n,this.sanitizeURL=_,this.removeEmptyString=I}var E={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){E[e]=new k(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];E[n]=new k(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){E[e]=new k(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){E[e]=new k(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){E[e]=new k(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){E[e]=new k(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){E[e]=new k(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){E[e]=new k(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){E[e]=new k(e,5,!1,e.toLowerCase(),null,!1,!1)});var D=/[\-:]([a-z])/g;function B(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(D,B);E[n]=new k(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(D,B);E[n]=new k(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(D,B);E[n]=new k(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){E[e]=new k(e,1,!1,e.toLowerCase(),null,!1,!1)}),E.xlinkHref=new k("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){E[e]=new k(e,1,!1,e.toLowerCase(),null,!0,!0)});function S(e,n,s,c){var x=E.hasOwnProperty(n)?E[n]:null;(x!==null?x.type!==0:c||!(2<n.length)||n[0]!=="o"&&n[0]!=="O"||n[1]!=="n"&&n[1]!=
Line truncated
|
||||
`+P+e}var K=!1;function $(e,n){if(!e||K)return"";K=!0;var s=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(n,[])}catch(ue){var c=ue}Reflect.construct(e,[],n)}else{try{n.call()}catch(ue){c=ue}e.call(n.prototype)}else{try{throw Error()}catch(ue){c=ue}e()}}catch(ue){if(ue&&c&&typeof ue.stack=="string"){for(var x=ue.stack.split(`
|
||||
`),_=c.stack.split(`
|
||||
`),M=x.length-1,q=_.length-1;1<=M&&0<=q&&x[M]!==_[q];)q--;for(;1<=M&&0<=q;M--,q--)if(x[M]!==_[q]){if(M!==1||q!==1)do if(M--,q--,0>q||x[M]!==_[q]){var X=`
|
||||
`+x[M].replace(" at new "," at ");return e.displayName&&X.includes("<anonymous>")&&(X=X.replace("<anonymous>",e.displayName)),X}while(1<=M&&0<=q);break}}}finally{K=!1,Error.prepareStackTrace=s}return(e=e?e.displayName||e.name:"")?V(e):""}function ce(e){switch(e.tag){case 5:return V(e.type);case 16:return V("Lazy");case 13:return V("Suspense");case 19:return V("SuspenseList");case 0:case 2:case 15:return e=$(e.type,!1),e;case 11:return e=$(e.type.render,!1),e;case 1:return e=$(e.type,!0),e;default:return""}}function de(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case z:return"Fragment";case H:return"Portal";case J:return"Profiler";case j:return"StrictMode";case Y:return"Suspense";case re:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case U:return(e.displayName||"Context")+".Consumer";case W:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case fe:return n=e.displayName||null,n!==null?n:de(e.type)||"Memo";case ae:n=e._payload,e=e._init;try{return de(e(n))}catch{}}return null}function Se(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return de(n);case 8:return n===j?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Ae(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Ue(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function Ye(e){var n=Ue(e)?"checked":"value",s=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),c=""+e[n];if(!e.hasOwnProperty(n)&&typeof s<"u"&&typeof s.get=="function"&&typeof s.set=="function"){var x=s.get,_=s.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return x.call(this)},set:function(M){c=""+M,_.call(this,M)}}),Object.defineProperty(e,n,{enumerable:s.enumerable}),{getValue:function(){return c},setValue:function(M){c=""+M},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function bt(e){e._valueTracker||(e._valueTracker=Ye(e))}function ct(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var s=n.getValue(),c="";return e&&(c=Ue(e)?e.checked?"true":"false":e.value),e=c,e!==s?(n.setValue(e),!0):!1}function Be(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ze(e,n){var s=n.checked;return Z({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:s??e._wrapperState.initialChecked})}function dt(e,n){var s=n.defaultValue==null?"":n.defaultValue,c=n.checked!=null?n.checked:n.defaultChecked;s=Ae(n.value!=null?n.value:s),e._wrapperState={initialChecked:c,initialValue:s,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Mt(e,n){n=n.checked,n!=null&&S(e,"checked",n,!1)}function at(e,n){Mt(e,n);var s=Ae(n.value),c=n.type;if(s!=null)c==="number"?(s===0&&e.value===""||e.value!=s)&&(e.value=""+s):e.value!==""+s&&(e.value=""+s);else if(c==="submit"||c==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?qe(e,n.type,s):n.hasOwnProperty("defaultValue")&&qe(e,n.type,Ae(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function gt(e,n,s){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var c=n.type;if(!(c!=="submit"&&c!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,s||n===e.value||(e.value=n),e.defaultValue=n}s=e.name,s!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,s!==""&&(e.name=s)}function qe(e,n,s){(n!=="number"||Be(e.ownerDocument)!==e)&&(s==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+s&&(e.defaultValue=""+s))}var tt=Array.isArray;function nt(e,n,s,c){if(e=e.options,n){n={};for(var x=0;x<s.length;x++)n["$"+s[x]]=!0;for(s=0;s<e.length;s++)x=n.hasOwnProperty("$"+e[s].value),e[s].selected!==x&&(e[s].selected=x),x&&c&&(e[s].defaultSelected=!0)}else{for(s=""+Ae(s),n=null,x=0;x<e.length;x++){if(e[x].value===s){e[x].selected=!0,c&&(e[x].defaultSelected=!0);return}n!==null||e[x].disabled||(n=e[x])}n!==null&&(n.selected=!0)}}function He(e,n){if(n.dangerouslySetInnerHTM
Line truncated
|
||||
`).replace(Q,"")}function le(e,n,s){if(n=ie(n),ie(e)!==n&&s)throw Error(o(425))}function xe(){}var Pe=null,We=null;function it(e,n){return e==="textarea"||e==="noscript"||typeof n.children=="string"||typeof n.children=="number"||typeof n.dangerouslySetInnerHTML=="object"&&n.dangerouslySetInnerHTML!==null&&n.dangerouslySetInnerHTML.__html!=null}var sn=typeof setTimeout=="function"?setTimeout:void 0,nn=typeof clearTimeout=="function"?clearTimeout:void 0,Fn=typeof Promise=="function"?Promise:void 0,bn=typeof queueMicrotask=="function"?queueMicrotask:typeof Fn<"u"?function(e){return Fn.resolve(null).then(e).catch(qi)}:sn;function qi(e){setTimeout(function(){throw e})}function Pa(e,n){var s=n,c=0;do{var x=s.nextSibling;if(e.removeChild(s),x&&x.nodeType===8)if(s=x.data,s==="/$"){if(c===0){e.removeChild(x),Yn(n);return}c--}else s!=="$"&&s!=="$?"&&s!=="$!"||c++;s=x}while(s);Yn(n)}function Zr(e){for(;e!=null;e=e.nextSibling){var n=e.nodeType;if(n===1||n===3)break;if(n===8){if(n=e.data,n==="$"||n==="$!"||n==="$?")break;if(n==="/$")return null}}return e}function Ul(e){e=e.previousSibling;for(var n=0;e;){if(e.nodeType===8){var s=e.data;if(s==="$"||s==="$!"||s==="$?"){if(n===0)return e;n--}else s==="/$"&&n++}e=e.previousSibling}return null}var ci=Math.random().toString(36).slice(2),fr="__reactFiber$"+ci,Gi="__reactProps$"+ci,kt="__reactContainer$"+ci,Ki="__reactEvents$"+ci,wd="__reactListeners$"+ci,bd="__reactHandles$"+ci;function di(e){var n=e[fr];if(n)return n;for(var s=e.parentNode;s;){if(n=s[kt]||s[fr]){if(s=n.alternate,n.child!==null||s!==null&&s.child!==null)for(e=Ul(e);e!==null;){if(s=e[fr])return s;e=Ul(e)}return n}e=s,s=e.parentNode}return null}function fi(e){return e=e[fr]||e[kt],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function hi(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(o(33))}function Es(e){return e[Gi]||null}var Cd=[],ks=-1;function Qi(e){return{current:e}}function Ot(e){0>ks||(e.current=Cd[ks],Cd[ks]=null,ks--)}function Lt(e,n){ks++,Cd[ks]=e.current,e.current=n}var $i={},Cn=Qi($i),jn=Qi(!1),So=$i;function Ss(e,n){var s=e.type.contextTypes;if(!s)return $i;var c=e.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===n)return c.__reactInternalMemoizedMaskedChildContext;var x={},_;for(_ in s)x[_]=n[_];return c&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=x),x}function zn(e){return e=e.childContextTypes,e!=null}function Zl(){Ot(jn),Ot(Cn)}function W0(e,n,s){if(Cn.current!==$i)throw Error(o(168));Lt(Cn,n),Lt(jn,s)}function q0(e,n,s){var c=e.stateNode;if(n=n.childContextTypes,typeof c.getChildContext!="function")return s;c=c.getChildContext();for(var x in c)if(!(x in n))throw Error(o(108,Se(e)||"Unknown",x));return Z({},s,c)}function Wl(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||$i,So=Cn.current,Lt(Cn,e),Lt(jn,jn.current),!0}function G0(e,n,s){var c=e.stateNode;if(!c)throw Error(o(169));s?(e=q0(e,n,So),c.__reactInternalMemoizedMergedChildContext=e,Ot(jn),Ot(Cn),Lt(Cn,e)):Ot(jn),Lt(jn,s)}var pi=null,ql=!1,Ed=!1;function K0(e){pi===null?pi=[e]:pi.push(e)}function $x(e){ql=!0,K0(e)}function Yi(){if(!Ed&&pi!==null){Ed=!0;var e=0,n=At;try{var s=pi;for(At=1;e<s.length;e++){var c=s[e];do c=c(!0);while(c!==null)}pi=null,ql=!1}catch(x){throw pi!==null&&(pi=pi.slice(e+1)),vl(ia,Yi),x}finally{At=n,Ed=!1}}return null}var Bs=[],Ps=0,Gl=null,Kl=0,hr=[],pr=0,Bo=null,mi=1,gi="";function Po(e,n){Bs[Ps++]=Kl,Bs[Ps++]=Gl,Gl=e,Kl=n}function Q0(e,n,s){hr[pr++]=mi,hr[pr++]=gi,hr[pr++]=Bo,Bo=e;var c=mi;e=gi;var x=32-rt(c)-1;c&=~(1<<x),s+=1;var _=32-rt(n)+x;if(30<_){var M=x-x%5;_=(c&(1<<M)-1).toString(32),c>>=M,x-=M,mi=1<<32-rt(n)+x|s<<x|c,gi=_+e}else mi=1<<_|s<<x|c,gi=e}function kd(e){e.return!==null&&(Po(e,1),Q0(e,1,0))}function Sd(e){for(;e===Gl;)Gl=Bs[--Ps],Bs[Ps]=null,Kl=Bs[--Ps],Bs[Ps]=null;for(;e===Bo;)Bo=hr[--pr],hr[pr]=null,gi=hr[--pr],hr[pr]=null,mi=hr[--pr],hr[pr]=null}var nr=null,rr=null,Vt=!1,kr=null;function $0(e,n){var s=xr(5,null,null,0);s.elementType="DELETED",s.stateNode=n,s.return=e,n=e.deletions,n===null?(e.deletions=[s],e.flags|=16):n.push(s)}function Y0(e,n){switch(e.tag){case 5:var s=e.type;return n=n.nodeType!==1||s.toLowerCase()!==n.nodeName.toLowerCase()?null:n,n!==null?(e.stateNode=n,nr=e,rr=Zr(n.firstChild),!0):!1;case 6:return n=e.pendingProps===""||n.nodeType!==3?null:n,n!==null?(e.stateNode=n,nr=e,rr=null,!0):!1;case 13:return n=n.nodeType!==8?null:n,n!==null?(s=Bo!==null?{id:mi,overflow:gi}:null,e.memoizedState={dehydrated:n,treeContext:s,retryLane:1073741824},s=xr(18,null,null,0),s.stateNode=n,s.return=e,e.child=s,nr=e,rr=null,!0):!1;default:return!1}}function Bd(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Pd(e){if(Vt){var n=rr;if(n){var s=n;if(!Y0(e,n)){if(Bd(e))throw Error(o(418));n=Zr(s.nextSibling);var c=nr;n&&Y0(e,n)?$0(c,s):(e.flags=e.flags&-4097|2,Vt=!1,nr=e)}}else{if(Bd(e))throw Error(o(418));e.flags=e.flags&-4097|2,Vt=!1,nr=e}}}function X0(e){for(e=e.r
Line truncated
|
||||
`),I=x.length-1,q=_.length-1;1<=I&&0<=q&&x[I]!==_[q];)q--;for(;1<=I&&0<=q;I--,q--)if(x[I]!==_[q]){if(I!==1||q!==1)do if(I--,q--,0>q||x[I]!==_[q]){var X=`
|
||||
`+x[I].replace(" at new "," at ");return e.displayName&&X.includes("<anonymous>")&&(X=X.replace("<anonymous>",e.displayName)),X}while(1<=I&&0<=q);break}}}finally{K=!1,Error.prepareStackTrace=s}return(e=e?e.displayName||e.name:"")?V(e):""}function ce(e){switch(e.tag){case 5:return V(e.type);case 16:return V("Lazy");case 13:return V("Suspense");case 19:return V("SuspenseList");case 0:case 2:case 15:return e=$(e.type,!1),e;case 11:return e=$(e.type.render,!1),e;case 1:return e=$(e.type,!0),e;default:return""}}function de(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case H:return"Fragment";case z:return"Portal";case J:return"Profiler";case j:return"StrictMode";case Y:return"Suspense";case re:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case U:return(e.displayName||"Context")+".Consumer";case W:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case fe:return n=e.displayName||null,n!==null?n:de(e.type)||"Memo";case ae:n=e._payload,e=e._init;try{return de(e(n))}catch{}}return null}function Se(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return de(n);case 8:return n===j?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Ae(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Ue(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function Ye(e){var n=Ue(e)?"checked":"value",s=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),c=""+e[n];if(!e.hasOwnProperty(n)&&typeof s<"u"&&typeof s.get=="function"&&typeof s.set=="function"){var x=s.get,_=s.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return x.call(this)},set:function(I){c=""+I,_.call(this,I)}}),Object.defineProperty(e,n,{enumerable:s.enumerable}),{getValue:function(){return c},setValue:function(I){c=""+I},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function bt(e){e._valueTracker||(e._valueTracker=Ye(e))}function ct(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var s=n.getValue(),c="";return e&&(c=Ue(e)?e.checked?"true":"false":e.value),e=c,e!==s?(n.setValue(e),!0):!1}function Be(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ze(e,n){var s=n.checked;return Z({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:s??e._wrapperState.initialChecked})}function dt(e,n){var s=n.defaultValue==null?"":n.defaultValue,c=n.checked!=null?n.checked:n.defaultChecked;s=Ae(n.value!=null?n.value:s),e._wrapperState={initialChecked:c,initialValue:s,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Mt(e,n){n=n.checked,n!=null&&S(e,"checked",n,!1)}function at(e,n){Mt(e,n);var s=Ae(n.value),c=n.type;if(s!=null)c==="number"?(s===0&&e.value===""||e.value!=s)&&(e.value=""+s):e.value!==""+s&&(e.value=""+s);else if(c==="submit"||c==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?qe(e,n.type,s):n.hasOwnProperty("defaultValue")&&qe(e,n.type,Ae(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function gt(e,n,s){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var c=n.type;if(!(c!=="submit"&&c!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,s||n===e.value||(e.value=n),e.defaultValue=n}s=e.name,s!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,s!==""&&(e.name=s)}function qe(e,n,s){(n!=="number"||Be(e.ownerDocument)!==e)&&(s==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+s&&(e.defaultValue=""+s))}var tt=Array.isArray;function nt(e,n,s,c){if(e=e.options,n){n={};for(var x=0;x<s.length;x++)n["$"+s[x]]=!0;for(s=0;s<e.length;s++)x=n.hasOwnProperty("$"+e[s].value),e[s].selected!==x&&(e[s].selected=x),x&&c&&(e[s].defaultSelected=!0)}else{for(s=""+Ae(s),n=null,x=0;x<e.length;x++){if(e[x].value===s){e[x].selected=!0,c&&(e[x].defaultSelected=!0);return}n!==null||e[x].disabled||(n=e[x])}n!==null&&(n.selected=!0)}}function He(e,n){if(n.dangerouslySetInnerHTM
Line truncated
|
||||
`).replace(Q,"")}function le(e,n,s){if(n=ie(n),ie(e)!==n&&s)throw Error(o(425))}function xe(){}var Pe=null,We=null;function it(e,n){return e==="textarea"||e==="noscript"||typeof n.children=="string"||typeof n.children=="number"||typeof n.dangerouslySetInnerHTML=="object"&&n.dangerouslySetInnerHTML!==null&&n.dangerouslySetInnerHTML.__html!=null}var sn=typeof setTimeout=="function"?setTimeout:void 0,nn=typeof clearTimeout=="function"?clearTimeout:void 0,Fn=typeof Promise=="function"?Promise:void 0,bn=typeof queueMicrotask=="function"?queueMicrotask:typeof Fn<"u"?function(e){return Fn.resolve(null).then(e).catch(qi)}:sn;function qi(e){setTimeout(function(){throw e})}function Pa(e,n){var s=n,c=0;do{var x=s.nextSibling;if(e.removeChild(s),x&&x.nodeType===8)if(s=x.data,s==="/$"){if(c===0){e.removeChild(x),Yn(n);return}c--}else s!=="$"&&s!=="$?"&&s!=="$!"||c++;s=x}while(s);Yn(n)}function Zr(e){for(;e!=null;e=e.nextSibling){var n=e.nodeType;if(n===1||n===3)break;if(n===8){if(n=e.data,n==="$"||n==="$!"||n==="$?")break;if(n==="/$")return null}}return e}function Ul(e){e=e.previousSibling;for(var n=0;e;){if(e.nodeType===8){var s=e.data;if(s==="$"||s==="$!"||s==="$?"){if(n===0)return e;n--}else s==="/$"&&n++}e=e.previousSibling}return null}var ci=Math.random().toString(36).slice(2),fr="__reactFiber$"+ci,Gi="__reactProps$"+ci,kt="__reactContainer$"+ci,Ki="__reactEvents$"+ci,wd="__reactListeners$"+ci,bd="__reactHandles$"+ci;function di(e){var n=e[fr];if(n)return n;for(var s=e.parentNode;s;){if(n=s[kt]||s[fr]){if(s=n.alternate,n.child!==null||s!==null&&s.child!==null)for(e=Ul(e);e!==null;){if(s=e[fr])return s;e=Ul(e)}return n}e=s,s=e.parentNode}return null}function fi(e){return e=e[fr]||e[kt],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function hi(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(o(33))}function Es(e){return e[Gi]||null}var Cd=[],ks=-1;function Qi(e){return{current:e}}function Ot(e){0>ks||(e.current=Cd[ks],Cd[ks]=null,ks--)}function Lt(e,n){ks++,Cd[ks]=e.current,e.current=n}var $i={},Cn=Qi($i),jn=Qi(!1),So=$i;function Ss(e,n){var s=e.type.contextTypes;if(!s)return $i;var c=e.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===n)return c.__reactInternalMemoizedMaskedChildContext;var x={},_;for(_ in s)x[_]=n[_];return c&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=x),x}function zn(e){return e=e.childContextTypes,e!=null}function Zl(){Ot(jn),Ot(Cn)}function W0(e,n,s){if(Cn.current!==$i)throw Error(o(168));Lt(Cn,n),Lt(jn,s)}function q0(e,n,s){var c=e.stateNode;if(n=n.childContextTypes,typeof c.getChildContext!="function")return s;c=c.getChildContext();for(var x in c)if(!(x in n))throw Error(o(108,Se(e)||"Unknown",x));return Z({},s,c)}function Wl(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||$i,So=Cn.current,Lt(Cn,e),Lt(jn,jn.current),!0}function G0(e,n,s){var c=e.stateNode;if(!c)throw Error(o(169));s?(e=q0(e,n,So),c.__reactInternalMemoizedMergedChildContext=e,Ot(jn),Ot(Cn),Lt(Cn,e)):Ot(jn),Lt(jn,s)}var pi=null,ql=!1,Ed=!1;function K0(e){pi===null?pi=[e]:pi.push(e)}function $x(e){ql=!0,K0(e)}function Yi(){if(!Ed&&pi!==null){Ed=!0;var e=0,n=At;try{var s=pi;for(At=1;e<s.length;e++){var c=s[e];do c=c(!0);while(c!==null)}pi=null,ql=!1}catch(x){throw pi!==null&&(pi=pi.slice(e+1)),vl(ia,Yi),x}finally{At=n,Ed=!1}}return null}var Bs=[],Ps=0,Gl=null,Kl=0,hr=[],pr=0,Bo=null,mi=1,gi="";function Po(e,n){Bs[Ps++]=Kl,Bs[Ps++]=Gl,Gl=e,Kl=n}function Q0(e,n,s){hr[pr++]=mi,hr[pr++]=gi,hr[pr++]=Bo,Bo=e;var c=mi;e=gi;var x=32-rt(c)-1;c&=~(1<<x),s+=1;var _=32-rt(n)+x;if(30<_){var I=x-x%5;_=(c&(1<<I)-1).toString(32),c>>=I,x-=I,mi=1<<32-rt(n)+x|s<<x|c,gi=_+e}else mi=1<<_|s<<x|c,gi=e}function kd(e){e.return!==null&&(Po(e,1),Q0(e,1,0))}function Sd(e){for(;e===Gl;)Gl=Bs[--Ps],Bs[Ps]=null,Kl=Bs[--Ps],Bs[Ps]=null;for(;e===Bo;)Bo=hr[--pr],hr[pr]=null,gi=hr[--pr],hr[pr]=null,mi=hr[--pr],hr[pr]=null}var nr=null,rr=null,Vt=!1,kr=null;function $0(e,n){var s=xr(5,null,null,0);s.elementType="DELETED",s.stateNode=n,s.return=e,n=e.deletions,n===null?(e.deletions=[s],e.flags|=16):n.push(s)}function Y0(e,n){switch(e.tag){case 5:var s=e.type;return n=n.nodeType!==1||s.toLowerCase()!==n.nodeName.toLowerCase()?null:n,n!==null?(e.stateNode=n,nr=e,rr=Zr(n.firstChild),!0):!1;case 6:return n=e.pendingProps===""||n.nodeType!==3?null:n,n!==null?(e.stateNode=n,nr=e,rr=null,!0):!1;case 13:return n=n.nodeType!==8?null:n,n!==null?(s=Bo!==null?{id:mi,overflow:gi}:null,e.memoizedState={dehydrated:n,treeContext:s,retryLane:1073741824},s=xr(18,null,null,0),s.stateNode=n,s.return=e,e.child=s,nr=e,rr=null,!0):!1;default:return!1}}function Bd(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Pd(e){if(Vt){var n=rr;if(n){var s=n;if(!Y0(e,n)){if(Bd(e))throw Error(o(418));n=Zr(s.nextSibling);var c=nr;n&&Y0(e,n)?$0(c,s):(e.flags=e.flags&-4097|2,Vt=!1,nr=e)}}else{if(Bd(e))throw Error(o(418));e.flags=e.flags&-4097|2,Vt=!1,nr=e}}}function X0(e){for(e=e.r
Line truncated
|
||||
Error generating stack: `+_.message+`
|
||||
`+_.stack}return{value:e,source:n,stack:x,digest:null}}function Yd(e,n,s){return{value:e,source:null,stack:s??null,digest:n??null}}function Xd(e,n){try{console.error(n.value)}catch(s){setTimeout(function(){throw s})}}var ov=typeof WeakMap=="function"?WeakMap:Map;function Rh(e,n,s){s=xi(-1,s),s.tag=3,s.payload={element:null};var c=n.value;return s.callback=function(){pu||(pu=!0,pf=c),Xd(e,n)},s}function Fh(e,n,s){s=xi(-1,s),s.tag=3;var c=e.type.getDerivedStateFromError;if(typeof c=="function"){var x=n.value;s.payload=function(){return c(x)},s.callback=function(){Xd(e,n)}}var _=e.stateNode;return _!==null&&typeof _.componentDidCatch=="function"&&(s.callback=function(){Xd(e,n),typeof c!="function"&&(to===null?to=new Set([this]):to.add(this));var M=n.stack;this.componentDidCatch(n.value,{componentStack:M!==null?M:""})}),s}function Nh(e,n,s){var c=e.pingCache;if(c===null){c=e.pingCache=new ov;var x=new Set;c.set(n,x)}else x=c.get(n),x===void 0&&(x=new Set,c.set(n,x));x.has(s)||(x.add(s),e=vv.bind(null,e,n,s),n.then(e,e))}function Lh(e){do{var n;if((n=e.tag===13)&&(n=e.memoizedState,n=n!==null?n.dehydrated!==null:!0),n)return e;e=e.return}while(e!==null);return null}function Mh(e,n,s,c,x){return(e.mode&1)===0?(e===n?e.flags|=65536:(e.flags|=128,s.flags|=131072,s.flags&=-52805,s.tag===1&&(s.alternate===null?s.tag=17:(n=xi(-1,1),n.tag=2,Ji(s,n,1))),s.lanes|=1),e):(e.flags|=65536,e.lanes=x,e)}var sv=N.ReactCurrentOwner,Hn=!1;function Nn(e,n,s,c){n.child=e===null?nh(n,null,s,c):Ds(n,e.child,s,c)}function Ih(e,n,s,c,x){s=s.render;var _=n.ref;return Fs(n,x),c=Ud(e,n,s,c,_,x),s=Zd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,vi(e,n,x)):(Vt&&s&&kd(n),n.flags|=1,Nn(e,n,c,x),n.child)}function Oh(e,n,s,c,x){if(e===null){var _=s.type;return typeof _=="function"&&!_f(_)&&_.defaultProps===void 0&&s.compare===null&&s.defaultProps===void 0?(n.tag=15,n.type=_,jh(e,n,_,c,x)):(e=yu(s.type,null,c,n,n.mode,x),e.ref=n.ref,e.return=n,n.child=e)}if(_=e.child,(e.lanes&x)===0){var M=_.memoizedProps;if(s=s.compare,s=s!==null?s:Hr,s(M,c)&&e.ref===n.ref)return vi(e,n,x)}return n.flags|=1,e=oo(_,c),e.ref=n.ref,e.return=n,n.child=e}function jh(e,n,s,c,x){if(e!==null){var _=e.memoizedProps;if(Hr(_,c)&&e.ref===n.ref)if(Hn=!1,n.pendingProps=c=_,(e.lanes&x)!==0)(e.flags&131072)!==0&&(Hn=!0);else return n.lanes=e.lanes,vi(e,n,x)}return Jd(e,n,s,c,x)}function zh(e,n,s){var c=n.pendingProps,x=c.children,_=e!==null?e.memoizedState:null;if(c.mode==="hidden")if((n.mode&1)===0)n.memoizedState={baseLanes:0,cachePool:null,transitions:null},Lt(Is,ir),ir|=s;else{if((s&1073741824)===0)return e=_!==null?_.baseLanes|s:s,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,Lt(Is,ir),ir|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},c=_!==null?_.baseLanes:s,Lt(Is,ir),ir|=c}else _!==null?(c=_.baseLanes|s,n.memoizedState=null):c=s,Lt(Is,ir),ir|=c;return Nn(e,n,x,s),n.child}function Hh(e,n){var s=n.ref;(e===null&&s!==null||e!==null&&e.ref!==s)&&(n.flags|=512,n.flags|=2097152)}function Jd(e,n,s,c,x){var _=zn(s)?So:Cn.current;return _=Ss(n,_),Fs(n,x),s=Ud(e,n,s,c,_,x),c=Zd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,vi(e,n,x)):(Vt&&c&&kd(n),n.flags|=1,Nn(e,n,s,x),n.child)}function Vh(e,n,s,c,x){if(zn(s)){var _=!0;Wl(n)}else _=!1;if(Fs(n,x),n.stateNode===null)uu(e,n),Th(n,s,c),$d(n,s,c,x),c=!0;else if(e===null){var M=n.stateNode,q=n.memoizedProps;M.props=q;var X=M.context,ue=s.contextType;typeof ue=="object"&&ue!==null?ue=mr(ue):(ue=zn(s)?So:Cn.current,ue=Ss(n,ue));var ye=s.getDerivedStateFromProps,we=typeof ye=="function"||typeof M.getSnapshotBeforeUpdate=="function";we||typeof M.UNSAFE_componentWillReceiveProps!="function"&&typeof M.componentWillReceiveProps!="function"||(q!==c||X!==ue)&&Dh(n,M,c,ue),Xi=!1;var ve=n.memoizedState;M.state=ve,eu(n,c,M,x),X=n.memoizedState,q!==c||ve!==X||jn.current||Xi?(typeof ye=="function"&&(Qd(n,s,ye,c),X=n.memoizedState),(q=Xi||Ph(n,s,q,c,ve,X,ue))?(we||typeof M.UNSAFE_componentWillMount!="function"&&typeof M.componentWillMount!="function"||(typeof M.componentWillMount=="function"&&M.componentWillMount(),typeof M.UNSAFE_componentWillMount=="function"&&M.UNSAFE_componentWillMount()),typeof M.componentDidMount=="function"&&(n.flags|=4194308)):(typeof M.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=c,n.memoizedState=X),M.props=c,M.state=X,M.context=ue,c=q):(typeof M.componentDidMount=="function"&&(n.flags|=4194308),c=!1)}else{M=n.stateNode,ih(e,n),q=n.memoizedProps,ue=n.type===n.elementType?q:Sr(n.type,q),M.props=ue,we=n.pendingProps,ve=M.context,X=s.contextType,typeof X=="object"&&X!==null?X=mr(X):(X=zn(s)?So:Cn.current,X=Ss(n,X));var Fe=s.getDerivedStateFromProps;(ye=typeof Fe=="function"||typeof M.getSnapshotBeforeUpdate=="function")||typeof M.UNSAFE_componentWillReceiveProps!="function"&&typeof M.componentWillReceiveProps!="function"||(q!==we||ve!==X)&&Dh(n,M,c,X),Xi=!1,ve=n.m
Line truncated
|
||||
`)}function zs(r,a,o){const l=Math.floor(Date.now()/1e3);return{id:-Date.now(),type:"PRIV",conversation_key:r,text:a,sender_timestamp:l,received_at:l,paths:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Gv(r){const a=F.useRef(null),o=F.useRef(null),l=F.useCallback(()=>{o.current!==null&&(clearInterval(o.current),o.current=null),a.current=null},[]),d=F.useCallback(async()=>{const p=a.current;if(!p)return;let h=null,g=null;for(let m=0;m<2;m++)try{h=await et.requestTelemetry(p.conversationId,"");break}catch(v){g=v instanceof Error?v:new Error("Unknown error"),m===0&&await new Promise(y=>setTimeout(y,2e3))}if(h){const m=zs(p.conversationId,qv(p,h),!1);r(v=>[...v,m])}else{const m=zs(p.conversationId,`Duty cycle poll failed after retry: ${(g==null?void 0:g.message)??"Unknown error"}`,!1);r(v=>[...v,m])}},[r]),f=F.useCallback(async(p,h)=>{const g=p.trim().toLowerCase();if(g==="dutycycle_start"){l();let m=null,v=null;for(let P=0;P<2;P++)try{m=await et.requestTelemetry(h,"");break}catch(D){v=D instanceof Error?D:new Error("Unknown error"),P===0&&await new Promise(C=>setTimeout(C,2e3))}if(!m){const P=zs(h,`Failed to start duty cycle tracking after retry: ${(v==null?void 0:v.message)??"Unknown error"}`,!1);return r(D=>[...D,P]),!0}const y=Math.floor(Date.now()/1e3);a.current={startTime:y,uptime:m.uptime_seconds,txAirtime:m.airtime_seconds,rxAirtime:m.rx_airtime_seconds,sentFlood:m.sent_flood,sentDirect:m.sent_direct,recvFlood:m.recv_flood,recvDirect:m.recv_direct,conversationId:h};const w=zs(h,`Airtime/duty cycle statistics gathering begins at ${y}. Logs will follow every 5 minutes. To stop, run dutycycle_stop or navigate away from this conversation.`,!1);return r(P=>[...P,w]),o.current=window.setInterval(d,Zv),!0}if(g==="dutycycle_stop"){if(a.current&&a.current.conversationId===h){await d(),l();const m=zs(h,"Airtime/duty cycle statistics gathering stopped.",!1);r(v=>[...v,m])}else{const m=zs(h,"Duty cycle tracking is not active.",!1);r(v=>[...v,m])}return!0}return!1},[r,l,d]);return F.useEffect(()=>()=>{o.current!==null&&clearInterval(o.current)},[]),{handleAirtimeCommand:f,stopTracking:l}}function zu(r){if(r<60)return`${r}s`;const a=Math.floor(r/86400),o=Math.floor(r%86400/3600),l=Math.floor(r%3600/60);return a>0?o>0&&l>0?`${a}d${o}h${l}m`:o>0?`${a}d${o}h`:l>0?`${a}d${l}m`:`${a}d`:o>0?l>0?`${o}h${l}m`:`${o}h`:`${l}m`}function Kv(r){return["Telemetry",`Battery Voltage: ${r.battery_volts.toFixed(3)}V`,`Uptime: ${zu(r.uptime_seconds)}`,`TX Airtime: ${zu(r.airtime_seconds)}`,`RX Airtime: ${zu(r.rx_airtime_seconds)}`,"",`Noise Floor: ${r.noise_floor_dbm} dBm`,`Last RSSI: ${r.last_rssi_dbm} dBm`,`Last SNR: ${r.last_snr_db.toFixed(1)} dB`,"",`Packets: ${r.packets_received.toLocaleString()} rx / ${r.packets_sent.toLocaleString()} tx`,`Flood: ${r.recv_flood.toLocaleString()} rx / ${r.sent_flood.toLocaleString()} tx`,`Direct: ${r.recv_direct.toLocaleString()} rx / ${r.sent_direct.toLocaleString()} tx`,`Duplicates: ${r.flood_dups.toLocaleString()} flood / ${r.direct_dups.toLocaleString()} direct`,"",`TX Queue: ${r.tx_queue_len}`,`Debug Flags: ${r.full_events}`].join(`
|
||||
`)}function Qv(r){if(r.length===0)return`Neighbors
|
||||
`+_.stack}return{value:e,source:n,stack:x,digest:null}}function Yd(e,n,s){return{value:e,source:null,stack:s??null,digest:n??null}}function Xd(e,n){try{console.error(n.value)}catch(s){setTimeout(function(){throw s})}}var ov=typeof WeakMap=="function"?WeakMap:Map;function Rh(e,n,s){s=xi(-1,s),s.tag=3,s.payload={element:null};var c=n.value;return s.callback=function(){pu||(pu=!0,pf=c),Xd(e,n)},s}function Fh(e,n,s){s=xi(-1,s),s.tag=3;var c=e.type.getDerivedStateFromError;if(typeof c=="function"){var x=n.value;s.payload=function(){return c(x)},s.callback=function(){Xd(e,n)}}var _=e.stateNode;return _!==null&&typeof _.componentDidCatch=="function"&&(s.callback=function(){Xd(e,n),typeof c!="function"&&(to===null?to=new Set([this]):to.add(this));var I=n.stack;this.componentDidCatch(n.value,{componentStack:I!==null?I:""})}),s}function Nh(e,n,s){var c=e.pingCache;if(c===null){c=e.pingCache=new ov;var x=new Set;c.set(n,x)}else x=c.get(n),x===void 0&&(x=new Set,c.set(n,x));x.has(s)||(x.add(s),e=vv.bind(null,e,n,s),n.then(e,e))}function Lh(e){do{var n;if((n=e.tag===13)&&(n=e.memoizedState,n=n!==null?n.dehydrated!==null:!0),n)return e;e=e.return}while(e!==null);return null}function Mh(e,n,s,c,x){return(e.mode&1)===0?(e===n?e.flags|=65536:(e.flags|=128,s.flags|=131072,s.flags&=-52805,s.tag===1&&(s.alternate===null?s.tag=17:(n=xi(-1,1),n.tag=2,Ji(s,n,1))),s.lanes|=1),e):(e.flags|=65536,e.lanes=x,e)}var sv=N.ReactCurrentOwner,Hn=!1;function Nn(e,n,s,c){n.child=e===null?nh(n,null,s,c):Ds(n,e.child,s,c)}function Ih(e,n,s,c,x){s=s.render;var _=n.ref;return Fs(n,x),c=Ud(e,n,s,c,_,x),s=Zd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,vi(e,n,x)):(Vt&&s&&kd(n),n.flags|=1,Nn(e,n,c,x),n.child)}function Oh(e,n,s,c,x){if(e===null){var _=s.type;return typeof _=="function"&&!_f(_)&&_.defaultProps===void 0&&s.compare===null&&s.defaultProps===void 0?(n.tag=15,n.type=_,jh(e,n,_,c,x)):(e=yu(s.type,null,c,n,n.mode,x),e.ref=n.ref,e.return=n,n.child=e)}if(_=e.child,(e.lanes&x)===0){var I=_.memoizedProps;if(s=s.compare,s=s!==null?s:Hr,s(I,c)&&e.ref===n.ref)return vi(e,n,x)}return n.flags|=1,e=oo(_,c),e.ref=n.ref,e.return=n,n.child=e}function jh(e,n,s,c,x){if(e!==null){var _=e.memoizedProps;if(Hr(_,c)&&e.ref===n.ref)if(Hn=!1,n.pendingProps=c=_,(e.lanes&x)!==0)(e.flags&131072)!==0&&(Hn=!0);else return n.lanes=e.lanes,vi(e,n,x)}return Jd(e,n,s,c,x)}function zh(e,n,s){var c=n.pendingProps,x=c.children,_=e!==null?e.memoizedState:null;if(c.mode==="hidden")if((n.mode&1)===0)n.memoizedState={baseLanes:0,cachePool:null,transitions:null},Lt(Is,ir),ir|=s;else{if((s&1073741824)===0)return e=_!==null?_.baseLanes|s:s,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,Lt(Is,ir),ir|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},c=_!==null?_.baseLanes:s,Lt(Is,ir),ir|=c}else _!==null?(c=_.baseLanes|s,n.memoizedState=null):c=s,Lt(Is,ir),ir|=c;return Nn(e,n,x,s),n.child}function Hh(e,n){var s=n.ref;(e===null&&s!==null||e!==null&&e.ref!==s)&&(n.flags|=512,n.flags|=2097152)}function Jd(e,n,s,c,x){var _=zn(s)?So:Cn.current;return _=Ss(n,_),Fs(n,x),s=Ud(e,n,s,c,_,x),c=Zd(),e!==null&&!Hn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,vi(e,n,x)):(Vt&&c&&kd(n),n.flags|=1,Nn(e,n,s,x),n.child)}function Vh(e,n,s,c,x){if(zn(s)){var _=!0;Wl(n)}else _=!1;if(Fs(n,x),n.stateNode===null)uu(e,n),Th(n,s,c),$d(n,s,c,x),c=!0;else if(e===null){var I=n.stateNode,q=n.memoizedProps;I.props=q;var X=I.context,ue=s.contextType;typeof ue=="object"&&ue!==null?ue=mr(ue):(ue=zn(s)?So:Cn.current,ue=Ss(n,ue));var _e=s.getDerivedStateFromProps,we=typeof _e=="function"||typeof I.getSnapshotBeforeUpdate=="function";we||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(q!==c||X!==ue)&&Dh(n,I,c,ue),Xi=!1;var ve=n.memoizedState;I.state=ve,eu(n,c,I,x),X=n.memoizedState,q!==c||ve!==X||jn.current||Xi?(typeof _e=="function"&&(Qd(n,s,_e,c),X=n.memoizedState),(q=Xi||Ph(n,s,q,c,ve,X,ue))?(we||typeof I.UNSAFE_componentWillMount!="function"&&typeof I.componentWillMount!="function"||(typeof I.componentWillMount=="function"&&I.componentWillMount(),typeof I.UNSAFE_componentWillMount=="function"&&I.UNSAFE_componentWillMount()),typeof I.componentDidMount=="function"&&(n.flags|=4194308)):(typeof I.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=c,n.memoizedState=X),I.props=c,I.state=X,I.context=ue,c=q):(typeof I.componentDidMount=="function"&&(n.flags|=4194308),c=!1)}else{I=n.stateNode,ih(e,n),q=n.memoizedProps,ue=n.type===n.elementType?q:Sr(n.type,q),I.props=ue,we=n.pendingProps,ve=I.context,X=s.contextType,typeof X=="object"&&X!==null?X=mr(X):(X=zn(s)?So:Cn.current,X=Ss(n,X));var Ne=s.getDerivedStateFromProps;(_e=typeof Ne=="function"||typeof I.getSnapshotBeforeUpdate=="function")||typeof I.UNSAFE_componentWillReceiveProps!="function"&&typeof I.componentWillReceiveProps!="function"||(q!==we||ve!==X)&&Dh(n,I,c,X),Xi=!1,ve=n.m
Line truncated
|
||||
`)}function zs(r,a,o){const l=Math.floor(Date.now()/1e3);return{id:-Date.now(),type:"PRIV",conversation_key:r,text:a,sender_timestamp:l,received_at:l,paths:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Kv(r){const a=R.useRef(null),o=R.useRef(null),l=R.useCallback(()=>{o.current!==null&&(clearInterval(o.current),o.current=null),a.current=null},[]),d=R.useCallback(async()=>{const p=a.current;if(!p)return;let h=null,g=null;for(let m=0;m<2;m++)try{h=await et.requestTelemetry(p.conversationId,"");break}catch(v){g=v instanceof Error?v:new Error("Unknown error"),m===0&&await new Promise(y=>setTimeout(y,2e3))}if(h){const m=zs(p.conversationId,Gv(p,h),!1);r(v=>[...v,m])}else{const m=zs(p.conversationId,`Duty cycle poll failed after retry: ${(g==null?void 0:g.message)??"Unknown error"}`,!1);r(v=>[...v,m])}},[r]),f=R.useCallback(async(p,h)=>{const g=p.trim().toLowerCase();if(g==="dutycycle_start"){l();let m=null,v=null;for(let T=0;T<2;T++)try{m=await et.requestTelemetry(h,"");break}catch(F){v=F instanceof Error?F:new Error("Unknown error"),T===0&&await new Promise(k=>setTimeout(k,2e3))}if(!m){const T=zs(h,`Failed to start duty cycle tracking after retry: ${(v==null?void 0:v.message)??"Unknown error"}`,!1);return r(F=>[...F,T]),!0}const y=Math.floor(Date.now()/1e3);a.current={startTime:y,uptime:m.uptime_seconds,txAirtime:m.airtime_seconds,rxAirtime:m.rx_airtime_seconds,sentFlood:m.sent_flood,sentDirect:m.sent_direct,recvFlood:m.recv_flood,recvDirect:m.recv_direct,conversationId:h};const w=zs(h,`Airtime/duty cycle statistics gathering begins at ${y}. Logs will follow every 5 minutes. To stop, run dutycycle_stop or navigate away from this conversation.`,!1);return r(T=>[...T,w]),o.current=window.setInterval(d,Wv),!0}if(g==="dutycycle_stop"){if(a.current&&a.current.conversationId===h){await d(),l();const m=zs(h,"Airtime/duty cycle statistics gathering stopped.",!1);r(v=>[...v,m])}else{const m=zs(h,"Duty cycle tracking is not active.",!1);r(v=>[...v,m])}return!0}return!1},[r,l,d]);return R.useEffect(()=>()=>{o.current!==null&&clearInterval(o.current)},[]),{handleAirtimeCommand:f,stopTracking:l}}function zu(r){if(r<60)return`${r}s`;const a=Math.floor(r/86400),o=Math.floor(r%86400/3600),l=Math.floor(r%3600/60);return a>0?o>0&&l>0?`${a}d${o}h${l}m`:o>0?`${a}d${o}h`:l>0?`${a}d${l}m`:`${a}d`:o>0?l>0?`${o}h${l}m`:`${o}h`:`${l}m`}function Qv(r){return["Telemetry",`Battery Voltage: ${r.battery_volts.toFixed(3)}V`,`Uptime: ${zu(r.uptime_seconds)}`,`TX Airtime: ${zu(r.airtime_seconds)}`,`RX Airtime: ${zu(r.rx_airtime_seconds)}`,"",`Noise Floor: ${r.noise_floor_dbm} dBm`,`Last RSSI: ${r.last_rssi_dbm} dBm`,`Last SNR: ${r.last_snr_db.toFixed(1)} dB`,"",`Packets: ${r.packets_received.toLocaleString()} rx / ${r.packets_sent.toLocaleString()} tx`,`Flood: ${r.recv_flood.toLocaleString()} rx / ${r.sent_flood.toLocaleString()} tx`,`Direct: ${r.recv_direct.toLocaleString()} rx / ${r.sent_direct.toLocaleString()} tx`,`Duplicates: ${r.flood_dups.toLocaleString()} flood / ${r.direct_dups.toLocaleString()} direct`,"",`TX Queue: ${r.tx_queue_len}`,`Debug Flags: ${r.full_events}`].join(`
|
||||
`)}function $v(r){if(r.length===0)return`Neighbors
|
||||
No neighbors reported`;const a=[...r].sort((l,d)=>d.snr-l.snr),o=[`Neighbors (${a.length})`];for(const l of a){const d=l.name||l.pubkey_prefix,f=l.snr>=0?`+${l.snr.toFixed(1)}`:l.snr.toFixed(1);o.push(`${d}, ${f} dB [${zu(l.last_heard_seconds)} ago]`)}return o.join(`
|
||||
`)}function $v(r){if(r.length===0)return`ACL
|
||||
`)}function Yv(r){if(r.length===0)return`ACL
|
||||
No ACL entries`;const a=[`ACL (${r.length})`];for(const o of r){const l=o.name||o.pubkey_prefix;a.push(`${l}: ${o.permission_name}`)}return a.join(`
|
||||
`)}function jo(r,a,o,l=0){const d=Math.floor(Date.now()/1e3);return{id:-Date.now()-l,type:"PRIV",conversation_key:r,text:a,sender_timestamp:d,received_at:d,paths:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Yv(r,a,o){const[l,d]=F.useState(!1),{handleAirtimeCommand:f,stopTracking:p}=Gv(o);F.useEffect(()=>{d(!1),p()},[r==null?void 0:r.id,p]);const h=F.useMemo(()=>{if(!r||r.type!=="contact")return!1;const v=a.find(y=>y.public_key===r.id);return(v==null?void 0:v.type)===Oc},[r,a]),g=F.useCallback(async v=>{if(!(!r||r.type!=="contact")&&h)try{const y=await et.requestTelemetry(r.id,v),w=jo(r.id,Kv(y),!1,0),P=jo(r.id,Qv(y.neighbors),!1,1),D=jo(r.id,$v(y.acl),!1,2);o(C=>[...C,w,P,D]),d(!0)}catch(y){const w=jo(r.id,`Telemetry request failed: ${y instanceof Error?y.message:"Unknown error"}`,!1,0);o(P=>[...P,w])}},[r,h,o]),m=F.useCallback(async v=>{if(!r||r.type!=="contact"||!h||!l||await f(v,r.id))return;const w=jo(r.id,`> ${v}`,!0,0);o(P=>[...P,w]);try{const P=await et.sendRepeaterCommand(r.id,v),D=jo(r.id,P.response,!1,1);P.sender_timestamp&&(D.sender_timestamp=P.sender_timestamp),o(C=>[...C,D])}catch(P){const D=jo(r.id,`Command failed: ${P instanceof Error?P.message:"Unknown error"}`,!1,1);o(C=>[...C,D])}},[r,h,l,o,f]);return{repeaterLoggedIn:l,activeContactIsRepeater:h,handleTelemetryRequest:g,handleRepeaterCommand:m}}const Og="remoteterm-lastMessageTime",jg="remoteterm-sortOrder";let Tc={};function Fp(r){Tc={...r}}function Np(){return{...Tc}}function Nf(r,a){return Tc[r]=a,{...Tc}}function Rr(r,a){return`${r}-${a}`}function Xv(){try{const r=localStorage.getItem(Og);return r?JSON.parse(r):{}}catch{return{}}}function Jv(){try{return localStorage.getItem(jg)==="alpha"?"alpha":"recent"}catch{return"recent"}}function Lp(){try{localStorage.removeItem(Og),localStorage.removeItem(jg)}catch{}}function Mp(r,a){if(!a)return!1;const o=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`@\\[${o}\\]`,"i").test(r)}function ey(r,a,o,l=null){const[d,f]=F.useState({}),[p,h]=F.useState({}),[g,m]=F.useState(Np),v=F.useRef(l);F.useEffect(()=>{v.current=l},[l]);const y=F.useRef(new Set),w=F.useRef(new Set);F.useEffect(()=>{const R=r.filter(N=>!y.current.has(N.key)),T=a.filter(N=>N.public_key&&!w.current.has(N.public_key));if(R.length===0&&T.length===0)return;R.forEach(N=>y.current.add(N.key)),T.forEach(N=>w.current.add(N.public_key)),(async()=>{const N=[...R.map(I=>({type:"CHAN",conversation_key:I.key})),...T.map(I=>({type:"PRIV",conversation_key:I.public_key}))];if(N.length!==0)try{const I=await et.getMessagesBulk(N,m0),H={},z={},j={};for(const J of R){const W=I[`CHAN:${J.key}`]||[];if(W.length>0){const U=Rr("channel",J.key),ne=J.last_read_at||0,Y=W.filter(fe=>!fe.outgoing&&fe.received_at>ne);Y.length>0&&(H[U]=Y.length,Y.some(fe=>Mp(fe.text,v.current))&&(z[U]=!0));const re=Math.max(...W.map(fe=>fe.received_at));j[U]=re,Nf(U,re)}}for(const J of T){const W=I[`PRIV:${J.public_key}`]||[];if(W.length>0){const U=Rr("contact",J.public_key),ne=J.last_read_at||0,Y=W.filter(fe=>!fe.outgoing&&fe.received_at>ne);Y.length>0&&(H[U]=Y.length,Y.some(fe=>Mp(fe.text,v.current))&&(z[U]=!0));const re=Math.max(...W.map(fe=>fe.received_at));j[U]=re,Nf(U,re)}}Object.keys(H).length>0&&f(J=>({...J,...H})),Object.keys(z).length>0&&h(J=>({...J,...z})),m(Np())}catch(I){console.error("Failed to fetch messages bulk:",I)}})()},[r,a]),F.useEffect(()=>{if(o&&o.type!=="raw"&&o.type!=="map"){const R=Rr(o.type,o.id);f(T=>{if(T[R]){const S={...T};return delete S[R],S}return T}),h(T=>{if(T[R]){const S={...T};return delete S[R],S}return T}),o.type==="channel"?et.markChannelRead(o.id).catch(T=>{console.error("Failed to mark channel as read on server:",T)}):o.type==="contact"&&et.markContactRead(o.id).catch(T=>{console.error("Failed to mark contact as read on server:",T)})}},[o]);const P=F.useCallback((R,T)=>{f(S=>({...S,[R]:(S[R]||0)+1})),T&&h(S=>({...S,[R]:!0}))},[]),D=F.useCallback(()=>{f({}),h({}),et.markAllRead().catch(R=>{console.error("Failed to mark all as read on server:",R)})},[]),C=F.useCallback(R=>{if(R.type==="raw"||R.type==="map")return;const T=Rr(R.type,R.id);f(S=>{if(S[T]){const N={...S};return delete N[T],N}return S}),h(S=>{if(S[T]){const N={...S};return delete N[T],N}return S}),R.type==="channel"?et.markChannelRead(R.id).catch(S=>{console.error("Failed to mark channel as read on server:",S)}):R.type==="contact"&&et.markContactRead(R.id).catch(S=>{console.error("Failed to mark contact as read on server:",S)})},[]),k=F.useCallback(R=>{let T=null;if(R.type==="CHAN"&&R.conversation_key?T=Rr("channel",R.conversation_key):R.type==="PRIV"&&R.conversation_key&&(T=Rr("contact",R.conversation_key)),T){const S=R.received_at||Math.floor(Date.now()/1e3),N=Nf(T,S);m(N)}},[]);return{unreadCounts:d,mentions:p,lastMessageTimes:g,incrementUnread:P,markAllRead:D,markConversationRead:C,trackNewMessage:k}}var g0=Ig();const zg=Ys(g0);function ty(r){if(typeof document>"u")return;let a=document.head||document.getElementsByTagName("head")[0],o=document.crea
Line truncated
|
||||
`)}function jo(r,a,o,l=0){const d=Math.floor(Date.now()/1e3);return{id:-Date.now()-l,type:"PRIV",conversation_key:r,text:a,sender_timestamp:d,received_at:d,paths:null,txt_type:0,signature:null,outgoing:o,acked:1}}function Xv(r,a,o){const[l,d]=R.useState(!1),{handleAirtimeCommand:f,stopTracking:p}=Kv(o);R.useEffect(()=>{d(!1),p()},[r==null?void 0:r.id,p]);const h=R.useMemo(()=>{if(!r||r.type!=="contact")return!1;const v=a.find(y=>y.public_key===r.id);return(v==null?void 0:v.type)===Oc},[r,a]),g=R.useCallback(async v=>{if(!(!r||r.type!=="contact")&&h)try{const y=await et.requestTelemetry(r.id,v),w=jo(r.id,Qv(y),!1,0),T=jo(r.id,$v(y.neighbors),!1,1),F=jo(r.id,Yv(y.acl),!1,2);o(k=>[...k,w,T,F]),d(!0)}catch(y){const w=jo(r.id,`Telemetry request failed: ${y instanceof Error?y.message:"Unknown error"}`,!1,0);o(T=>[...T,w])}},[r,h,o]),m=R.useCallback(async v=>{if(!r||r.type!=="contact"||!h||!l||await f(v,r.id))return;const w=jo(r.id,`> ${v}`,!0,0);o(T=>[...T,w]);try{const T=await et.sendRepeaterCommand(r.id,v),F=jo(r.id,T.response,!1,1);T.sender_timestamp&&(F.sender_timestamp=T.sender_timestamp),o(k=>[...k,F])}catch(T){const F=jo(r.id,`Command failed: ${T instanceof Error?T.message:"Unknown error"}`,!1,1);o(k=>[...k,F])}},[r,h,l,o,f]);return{repeaterLoggedIn:l,activeContactIsRepeater:h,handleTelemetryRequest:g,handleRepeaterCommand:m}}const Og="remoteterm-lastMessageTime",jg="remoteterm-sortOrder";let Tc={};function Fp(r){Tc={...r}}function Np(){return{...Tc}}function Nf(r,a){return Tc[r]=a,{...Tc}}function Rr(r,a){return`${r}-${a}`}function Jv(){try{const r=localStorage.getItem(Og);return r?JSON.parse(r):{}}catch{return{}}}function ey(){try{return localStorage.getItem(jg)==="alpha"?"alpha":"recent"}catch{return"recent"}}function Lp(){try{localStorage.removeItem(Og),localStorage.removeItem(jg)}catch{}}function Mp(r,a){if(!a)return!1;const o=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return new RegExp(`@\\[${o}\\]`,"i").test(r)}function ty(r,a,o,l=null){const[d,f]=R.useState({}),[p,h]=R.useState({}),[g,m]=R.useState(Np),v=R.useRef(l);R.useEffect(()=>{v.current=l},[l]);const y=R.useRef(new Set),w=R.useRef(new Set);R.useEffect(()=>{const D=r.filter(N=>!y.current.has(N.key)),B=a.filter(N=>N.public_key&&!w.current.has(N.public_key));if(D.length===0&&B.length===0)return;D.forEach(N=>y.current.add(N.key)),B.forEach(N=>w.current.add(N.public_key)),(async()=>{const N=[...D.map(M=>({type:"CHAN",conversation_key:M.key})),...B.map(M=>({type:"PRIV",conversation_key:M.public_key}))];if(N.length!==0)try{const M=await et.getMessagesBulk(N,m0),z={},H={},j={};for(const J of D){const W=M[`CHAN:${J.key}`]||[];if(W.length>0){const U=Rr("channel",J.key),ne=J.last_read_at||0,Y=W.filter(fe=>!fe.outgoing&&fe.received_at>ne);Y.length>0&&(z[U]=Y.length,Y.some(fe=>Mp(fe.text,v.current))&&(H[U]=!0));const re=Math.max(...W.map(fe=>fe.received_at));j[U]=re,Nf(U,re)}}for(const J of B){const W=M[`PRIV:${J.public_key}`]||[];if(W.length>0){const U=Rr("contact",J.public_key),ne=J.last_read_at||0,Y=W.filter(fe=>!fe.outgoing&&fe.received_at>ne);Y.length>0&&(z[U]=Y.length,Y.some(fe=>Mp(fe.text,v.current))&&(H[U]=!0));const re=Math.max(...W.map(fe=>fe.received_at));j[U]=re,Nf(U,re)}}Object.keys(z).length>0&&f(J=>({...J,...z})),Object.keys(H).length>0&&h(J=>({...J,...H})),m(Np())}catch(M){console.error("Failed to fetch messages bulk:",M)}})()},[r,a]),R.useEffect(()=>{if(o&&o.type!=="raw"&&o.type!=="map"){const D=Rr(o.type,o.id);f(B=>{if(B[D]){const S={...B};return delete S[D],S}return B}),h(B=>{if(B[D]){const S={...B};return delete S[D],S}return B}),o.type==="channel"?et.markChannelRead(o.id).catch(B=>{console.error("Failed to mark channel as read on server:",B)}):o.type==="contact"&&et.markContactRead(o.id).catch(B=>{console.error("Failed to mark contact as read on server:",B)})}},[o]);const T=R.useCallback((D,B)=>{f(S=>({...S,[D]:(S[D]||0)+1})),B&&h(S=>({...S,[D]:!0}))},[]),F=R.useCallback(()=>{f({}),h({}),et.markAllRead().catch(D=>{console.error("Failed to mark all as read on server:",D)})},[]),k=R.useCallback(D=>{if(D.type==="raw"||D.type==="map")return;const B=Rr(D.type,D.id);f(S=>{if(S[B]){const N={...S};return delete N[B],N}return S}),h(S=>{if(S[B]){const N={...S};return delete N[B],N}return S}),D.type==="channel"?et.markChannelRead(D.id).catch(S=>{console.error("Failed to mark channel as read on server:",S)}):D.type==="contact"&&et.markContactRead(D.id).catch(S=>{console.error("Failed to mark contact as read on server:",S)})},[]),E=R.useCallback(D=>{let B=null;if(D.type==="CHAN"&&D.conversation_key?B=Rr("channel",D.conversation_key):D.type==="PRIV"&&D.conversation_key&&(B=Rr("contact",D.conversation_key)),B){const S=D.received_at||Math.floor(Date.now()/1e3),N=Nf(B,S);m(N)}},[]);return{unreadCounts:d,mentions:p,lastMessageTimes:g,incrementUnread:T,markAllRead:F,markConversationRead:k,trackNewMessage:E}}var g0=Ig();const zg=Ys(g0);function ny(r){if(typeof document>"u")return;let a=document.head||document.getElementsByTagName("head")[0],o=document.crea
Line truncated
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const Ty=r=>r.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Dy=r=>r.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,o,l)=>l?l.toUpperCase():o.toLowerCase()),jp=r=>{const a=Dy(r);return a.charAt(0).toUpperCase()+a.slice(1)},Hg=(...r)=>r.filter((a,o,l)=>!!a&&a.trim()!==""&&l.indexOf(a)===o).join(" ").trim(),Ry=r=>{for(const a in r)if(a.startsWith("aria-")||a==="role"||a==="title")return!0};/**
|
||||
*/const Dy=r=>r.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),Ry=r=>r.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,o,l)=>l?l.toUpperCase():o.toLowerCase()),jp=r=>{const a=Ry(r);return a.charAt(0).toUpperCase()+a.slice(1)},Hg=(...r)=>r.filter((a,o,l)=>!!a&&a.trim()!==""&&l.indexOf(a)===o).join(" ").trim(),Fy=r=>{for(const a in r)if(a.startsWith("aria-")||a==="role"||a==="title")return!0};/**
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/var Fy={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
|
||||
*/var Ny={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const Ny=F.forwardRef(({color:r="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:l,className:d="",children:f,iconNode:p,...h},g)=>F.createElement("svg",{ref:g,...Fy,width:a,height:a,stroke:r,strokeWidth:l?Number(o)*24/Number(a):o,className:Hg("lucide",d),...!f&&!Ry(h)&&{"aria-hidden":"true"},...h},[...p.map(([m,v])=>F.createElement(m,v)),...Array.isArray(f)?f:[f]]));/**
|
||||
*/const Ly=R.forwardRef(({color:r="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:l,className:d="",children:f,iconNode:p,...h},g)=>R.createElement("svg",{ref:g,...Ny,width:a,height:a,stroke:r,strokeWidth:l?Number(o)*24/Number(a):o,className:Hg("lucide",d),...!f&&!Fy(h)&&{"aria-hidden":"true"},...h},[...p.map(([m,v])=>R.createElement(m,v)),...Array.isArray(f)?f:[f]]));/**
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const A0=(r,a)=>{const o=F.forwardRef(({className:l,...d},f)=>F.createElement(Ny,{ref:f,iconNode:a,className:Hg(`lucide-${Ty(jp(r))}`,`lucide-${r}`,l),...d}));return o.displayName=jp(r),o};/**
|
||||
*/const A0=(r,a)=>{const o=R.forwardRef(({className:l,...d},f)=>R.createElement(Ly,{ref:f,iconNode:a,className:Hg(`lucide-${Dy(jp(r))}`,`lucide-${r}`,l),...d}));return o.displayName=jp(r),o};/**
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const Ly=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],My=A0("check",Ly);/**
|
||||
*/const My=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],Iy=A0("check",My);/**
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const Iy=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],Oy=A0("menu",Iy);/**
|
||||
*/const Oy=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],jy=A0("menu",Oy);/**
|
||||
* @license lucide-react v0.562.0 - ISC
|
||||
*
|
||||
* This source code is licensed under the ISC license.
|
||||
* See the LICENSE file in the root directory of this source tree.
|
||||
*/const jy=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Vg=A0("x",jy);function zy({health:r,config:a,onSettingsClick:o,onMenuClick:l}){const d=(r==null?void 0:r.radio_connected)??!1,[f,p]=F.useState(!1),h=async()=>{p(!0);try{const g=await et.reconnectRadio();g.connected&&xt.success("Reconnected",{description:g.message})}catch(g){xt.error("Reconnection failed",{description:g instanceof Error?g.message:"Check radio connection and power"})}finally{p(!1)}};return b.jsxs("div",{className:"flex items-center gap-4 px-4 py-2 bg-[#252525] border-b border-[#333] text-xs",children:[l&&b.jsx("button",{onClick:l,className:"md:hidden p-1 bg-transparent border-none text-[#e0e0e0] cursor-pointer","aria-label":"Open menu",children:b.jsx(Oy,{className:"h-5 w-5"})}),b.jsx("h1",{className:"text-base font-semibold mr-auto",children:"RemoteTerm"}),b.jsxs("div",{className:"flex items-center gap-1 text-[#888]",children:[b.jsx("div",{className:`w-2 h-2 rounded-full ${d?"bg-[#4caf50]":"bg-[#666]"}`}),b.jsx("span",{className:"hidden lg:inline text-[#e0e0e0]",children:d?"Connected":"Disconnected"})]}),a&&b.jsxs("div",{className:"hidden lg:flex items-center gap-2 text-[#888]",children:[b.jsx("span",{className:"text-[#e0e0e0]",children:a.name||"Unnamed"}),b.jsx("span",{className:"font-mono text-[#888] cursor-pointer hover:text-[#4a9eff]",onClick:()=>{navigator.clipboard.writeText(a.public_key),xt.success("Public key copied!")},title:"Click to copy public key",children:a.public_key.toLowerCase()})]}),!d&&b.jsx("button",{onClick:h,disabled:f,className:"px-3 py-1 bg-[#4a3000] border border-[#6b4500] text-[#ffa500] rounded text-xs cursor-pointer hover:bg-[#5a3a00] disabled:opacity-50 disabled:cursor-not-allowed",children:f?"Reconnecting...":"Reconnect"}),b.jsxs("button",{onClick:o,className:"px-3 py-1 bg-[#333] border border-[#444] text-[#e0e0e0] rounded text-xs cursor-pointer hover:bg-[#444]",children:[b.jsx("span",{role:"img","aria-label":"Settings",children:"🔧"})," ","Radio & Config"]})]})}const Hy=12;function Vy(r){return r.slice(0,Hy)}function Ei(r,a){return r||Vy(a)}const Xf=2,Uy={text:"🛜",background:"#444444",textColor:"#ffffff"};function Zy(r){let a=0;for(let o=0;o<r.length;o++){const l=r.charCodeAt(o);a=(a<<5)-a+l,a=a&a}return Math.abs(a)}const Wy=/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u;function qy(r,a){if(!r)return a.slice(0,2).toUpperCase();const o=r.match(Wy);if(o)return o[0];const l=r.match(/[a-zA-Z]/g);if(!l||l.length===0)return a.slice(0,2).toUpperCase();const d=r.indexOf(" ");if(d!==-1){const f=l[0],p=r.slice(d+1).match(/[a-zA-Z]/);if(p)return(f+p[0]).toUpperCase()}return l[0].toUpperCase()}function Gy(r){const a=Zy(r),o=a%360,l=50+(a>>8)%30,d=35+(a>>16)%20,f=`hsl(${o}, ${l}%, ${d}%)`,p=d<45?"#ffffff":"#000000";return{background:f,text:p}}function Ky(r,a,o){if(o===Xf)return Uy;const l=qy(r,a),d=Gy(a);return{text:l,background:d.background,textColor:d.text}}function Jf({name:r,publicKey:a,size:o=28,contactType:l}){const d=Ky(r,a,l);return b.jsx("div",{className:"flex items-center justify-center rounded-full font-semibold flex-shrink-0 select-none",style:{backgroundColor:d.background,color:d.textColor,width:o,height:o,fontSize:o*.45},children:d.text})}const Ug="remoteterm-favorites";function Ko(r,a,o){return r.some(l=>l.type===a&&l.id===o)}function Qy(){try{const r=localStorage.getItem(Ug);return r?JSON.parse(r):[]}catch{return[]}}function zp(){try{localStorage.removeItem(Ug)}catch{}}function Zg(r){var a,o,l="";if(typeof r=="string"||typeof r=="number")l+=r;else if(typeof r=="object")if(Array.isArray(r)){var d=r.length;for(a=0;a<d;a++)r[a]&&(o=Zg(r[a]))&&(l&&(l+=" "),l+=o)}else for(o in r)r[o]&&(l&&(l+=" "),l+=o);return l}function Wg(){for(var r,a,o=0,l="",d=arguments.length;o<d;o++)(r=arguments[o])&&(a=Zg(r))&&(l&&(l+=" "),l+=a);return l}const $y=(r,a)=>{const o=new Array(r.length+a.length);for(let l=0;l<r.length;l++)o[l]=r[l];for(let l=0;l<a.length;l++)o[r.length+l]=a[l];return o},Yy=(r,a)=>({classGroupId:r,validator:a}),qg=(r=new Map,a=null,o)=>({nextPart:r,validators:a,classGroupId:o}),Dc="-",Hp=[],Xy="arbitrary..",Jy=r=>{const a=t_(r),{conflictingClassGroups:o,conflictingClassGroupModifiers:l}=r;return{getClassGroupId:p=>{if(p.startsWith("[")&&p.endsWith("]"))return e_(p);const h=p.split(Dc),g=h[0]===""&&h.length>1?1:0;return Gg(h,g,a)},getConflictingClassGroupIds:(p,h)=>{if(h){const g=l[p],m=o[p];return g?m?$y(m,g):g:m||Hp}return o[p]||Hp}}},Gg=(r,a,o)=>{if(r.length-a===0)return o.classGroupId;const d=r[a],f=o.nextPart.get(d);if(f){const m=Gg(r,a+1,f);if(m)return m}const p=o.validators;if(p===null)return;const h=a===0?r.join(Dc):r.slice(a).join(Dc),g=p.length;for(let m=0;m<g;m++){const v=p[m];if(v.validator(h))return v.classGroupId}},e_=r=>r.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const a=r.slice(1,-1),o=a.indexOf(":"),l=a.slice(0,o);return l?Xy+l:void 0})(),t_=r=>{const{theme:a,classGroLine truncated
|
||||
.`.concat(I1,` {
|
||||
*/const zy=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Vg=A0("x",zy);function Hy({health:r,config:a,onSettingsClick:o,onMenuClick:l}){const d=(r==null?void 0:r.radio_connected)??!1,[f,p]=R.useState(!1),h=async()=>{p(!0);try{const g=await et.reconnectRadio();g.connected&&xt.success("Reconnected",{description:g.message})}catch(g){xt.error("Reconnection failed",{description:g instanceof Error?g.message:"Check radio connection and power"})}finally{p(!1)}};return b.jsxs("div",{className:"flex items-center gap-4 px-4 py-2 bg-[#252525] border-b border-[#333] text-xs",children:[l&&b.jsx("button",{onClick:l,className:"md:hidden p-1 bg-transparent border-none text-[#e0e0e0] cursor-pointer","aria-label":"Open menu",children:b.jsx(jy,{className:"h-5 w-5"})}),b.jsx("h1",{className:"text-base font-semibold mr-auto",children:"RemoteTerm"}),b.jsxs("div",{className:"flex items-center gap-1 text-[#888]",children:[b.jsx("div",{className:`w-2 h-2 rounded-full ${d?"bg-[#4caf50]":"bg-[#666]"}`}),b.jsx("span",{className:"hidden lg:inline text-[#e0e0e0]",children:d?"Connected":"Disconnected"})]}),a&&b.jsxs("div",{className:"hidden lg:flex items-center gap-2 text-[#888]",children:[b.jsx("span",{className:"text-[#e0e0e0]",children:a.name||"Unnamed"}),b.jsx("span",{className:"font-mono text-[#888] cursor-pointer hover:text-[#4a9eff]",onClick:()=>{navigator.clipboard.writeText(a.public_key),xt.success("Public key copied!")},title:"Click to copy public key",children:a.public_key.toLowerCase()})]}),!d&&b.jsx("button",{onClick:h,disabled:f,className:"px-3 py-1 bg-[#4a3000] border border-[#6b4500] text-[#ffa500] rounded text-xs cursor-pointer hover:bg-[#5a3a00] disabled:opacity-50 disabled:cursor-not-allowed",children:f?"Reconnecting...":"Reconnect"}),b.jsxs("button",{onClick:o,className:"px-3 py-1 bg-[#333] border border-[#444] text-[#e0e0e0] rounded text-xs cursor-pointer hover:bg-[#444]",children:[b.jsx("span",{role:"img","aria-label":"Settings",children:"🔧"})," ","Radio & Config"]})]})}const Vy=12;function Uy(r){return r.slice(0,Vy)}function Ei(r,a){return r||Uy(a)}const Xf=2,Zy={text:"🛜",background:"#444444",textColor:"#ffffff"};function Wy(r){let a=0;for(let o=0;o<r.length;o++){const l=r.charCodeAt(o);a=(a<<5)-a+l,a=a&a}return Math.abs(a)}const qy=/[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F600}-\u{1F64F}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]/u;function Gy(r,a){if(!r)return a.slice(0,2).toUpperCase();const o=r.match(qy);if(o)return o[0];const l=r.match(/[a-zA-Z]/g);if(!l||l.length===0)return a.slice(0,2).toUpperCase();const d=r.indexOf(" ");if(d!==-1){const f=l[0],p=r.slice(d+1).match(/[a-zA-Z]/);if(p)return(f+p[0]).toUpperCase()}return l[0].toUpperCase()}function Ky(r){const a=Wy(r),o=a%360,l=50+(a>>8)%30,d=35+(a>>16)%20,f=`hsl(${o}, ${l}%, ${d}%)`,p=d<45?"#ffffff":"#000000";return{background:f,text:p}}function Qy(r,a,o){if(o===Xf)return Zy;const l=Gy(r,a),d=Ky(a);return{text:l,background:d.background,textColor:d.text}}function Jf({name:r,publicKey:a,size:o=28,contactType:l}){const d=Qy(r,a,l);return b.jsx("div",{className:"flex items-center justify-center rounded-full font-semibold flex-shrink-0 select-none",style:{backgroundColor:d.background,color:d.textColor,width:o,height:o,fontSize:o*.45},children:d.text})}const Ug="remoteterm-favorites";function Ko(r,a,o){return r.some(l=>l.type===a&&l.id===o)}function $y(){try{const r=localStorage.getItem(Ug);return r?JSON.parse(r):[]}catch{return[]}}function zp(){try{localStorage.removeItem(Ug)}catch{}}function Zg(r){var a,o,l="";if(typeof r=="string"||typeof r=="number")l+=r;else if(typeof r=="object")if(Array.isArray(r)){var d=r.length;for(a=0;a<d;a++)r[a]&&(o=Zg(r[a]))&&(l&&(l+=" "),l+=o)}else for(o in r)r[o]&&(l&&(l+=" "),l+=o);return l}function Wg(){for(var r,a,o=0,l="",d=arguments.length;o<d;o++)(r=arguments[o])&&(a=Zg(r))&&(l&&(l+=" "),l+=a);return l}const Yy=(r,a)=>{const o=new Array(r.length+a.length);for(let l=0;l<r.length;l++)o[l]=r[l];for(let l=0;l<a.length;l++)o[r.length+l]=a[l];return o},Xy=(r,a)=>({classGroupId:r,validator:a}),qg=(r=new Map,a=null,o)=>({nextPart:r,validators:a,classGroupId:o}),Dc="-",Hp=[],Jy="arbitrary..",e_=r=>{const a=n_(r),{conflictingClassGroups:o,conflictingClassGroupModifiers:l}=r;return{getClassGroupId:p=>{if(p.startsWith("[")&&p.endsWith("]"))return t_(p);const h=p.split(Dc),g=h[0]===""&&h.length>1?1:0;return Gg(h,g,a)},getConflictingClassGroupIds:(p,h)=>{if(h){const g=l[p],m=o[p];return g?m?Yy(m,g):g:m||Hp}return o[p]||Hp}}},Gg=(r,a,o)=>{if(r.length-a===0)return o.classGroupId;const d=r[a],f=o.nextPart.get(d);if(f){const m=Gg(r,a+1,f);if(m)return m}const p=o.validators;if(p===null)return;const h=a===0?r.join(Dc):r.slice(a).join(Dc),g=p.length;for(let m=0;m<g;m++){const v=p[m];if(v.validator(h))return v.classGroupId}},t_=r=>r.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const a=r.slice(1,-1),o=a.indexOf(":"),l=a.slice(0,o);return l?Jy+l:void 0})(),n_=r=>{const{theme:a,classGroLine truncated
|
||||
.`.concat(O1,` {
|
||||
overflow: hidden `).concat(l,`;
|
||||
padding-right: `).concat(h,"px ").concat(l,`;
|
||||
}
|
||||
@@ -113,20 +113,20 @@ No ACL entries`;const a=[`ACL (${r.length})`];for(const o of r){const l=o.name||
|
||||
}
|
||||
|
||||
body[`).concat(qs,`] {
|
||||
`).concat(O1,": ").concat(h,`px;
|
||||
`).concat(j1,": ").concat(h,`px;
|
||||
}
|
||||
`)},im=function(){var r=parseInt(document.body.getAttribute(qs)||"0",10);return isFinite(r)?r:0},rw=function(){F.useEffect(function(){return document.body.setAttribute(qs,(im()+1).toString()),function(){var r=im()-1;r<=0?document.body.removeAttribute(qs):document.body.setAttribute(qs,r.toString())}},[])},iw=function(r){var a=r.noRelative,o=r.noImportant,l=r.gapMode,d=l===void 0?"margin":l;rw();var f=F.useMemo(function(){return ew(d)},[d]);return F.createElement(tw,{styles:nw(f,!a,d,o?"":"!important")})},n0=!1;if(typeof window<"u")try{var Mu=Object.defineProperty({},"passive",{get:function(){return n0=!0,!0}});window.addEventListener("test",Mu,Mu),window.removeEventListener("test",Mu,Mu)}catch{n0=!1}var Vs=n0?{passive:!1}:!1,ow=function(r){return r.tagName==="TEXTAREA"},mA=function(r,a){if(!(r instanceof Element))return!1;var o=window.getComputedStyle(r);return o[a]!=="hidden"&&!(o.overflowY===o.overflowX&&!ow(r)&&o[a]==="visible")},sw=function(r){return mA(r,"overflowY")},aw=function(r){return mA(r,"overflowX")},om=function(r,a){var o=a.ownerDocument,l=a;do{typeof ShadowRoot<"u"&&l instanceof ShadowRoot&&(l=l.host);var d=gA(r,l);if(d){var f=AA(r,l),p=f[1],h=f[2];if(p>h)return!0}l=l.parentNode}while(l&&l!==o.body);return!1},lw=function(r){var a=r.scrollTop,o=r.scrollHeight,l=r.clientHeight;return[a,o,l]},uw=function(r){var a=r.scrollLeft,o=r.scrollWidth,l=r.clientWidth;return[a,o,l]},gA=function(r,a){return r==="v"?sw(a):aw(a)},AA=function(r,a){return r==="v"?lw(a):uw(a)},cw=function(r,a){return r==="h"&&a==="rtl"?-1:1},dw=function(r,a,o,l,d){var f=cw(r,window.getComputedStyle(a).direction),p=f*l,h=o.target,g=a.contains(h),m=!1,v=p>0,y=0,w=0;do{if(!h)break;var P=AA(r,h),D=P[0],C=P[1],k=P[2],R=C-k-f*D;(D||R)&&gA(r,h)&&(y+=R,w+=D);var T=h.parentNode;h=T&&T.nodeType===Node.DOCUMENT_FRAGMENT_NODE?T.host:T}while(!g&&h!==document.body||g&&(a.contains(h)||a===h));return(v&&Math.abs(y)<1||!v&&Math.abs(w)<1)&&(m=!0),m},Iu=function(r){return"changedTouches"in r?[r.changedTouches[0].clientX,r.changedTouches[0].clientY]:[0,0]},sm=function(r){return[r.deltaX,r.deltaY]},am=function(r){return r&&"current"in r?r.current:r},fw=function(r,a){return r[0]===a[0]&&r[1]===a[1]},hw=function(r){return`
|
||||
`)},im=function(){var r=parseInt(document.body.getAttribute(qs)||"0",10);return isFinite(r)?r:0},iw=function(){R.useEffect(function(){return document.body.setAttribute(qs,(im()+1).toString()),function(){var r=im()-1;r<=0?document.body.removeAttribute(qs):document.body.setAttribute(qs,r.toString())}},[])},ow=function(r){var a=r.noRelative,o=r.noImportant,l=r.gapMode,d=l===void 0?"margin":l;iw();var f=R.useMemo(function(){return tw(d)},[d]);return R.createElement(nw,{styles:rw(f,!a,d,o?"":"!important")})},n0=!1;if(typeof window<"u")try{var Mu=Object.defineProperty({},"passive",{get:function(){return n0=!0,!0}});window.addEventListener("test",Mu,Mu),window.removeEventListener("test",Mu,Mu)}catch{n0=!1}var Vs=n0?{passive:!1}:!1,sw=function(r){return r.tagName==="TEXTAREA"},mA=function(r,a){if(!(r instanceof Element))return!1;var o=window.getComputedStyle(r);return o[a]!=="hidden"&&!(o.overflowY===o.overflowX&&!sw(r)&&o[a]==="visible")},aw=function(r){return mA(r,"overflowY")},lw=function(r){return mA(r,"overflowX")},om=function(r,a){var o=a.ownerDocument,l=a;do{typeof ShadowRoot<"u"&&l instanceof ShadowRoot&&(l=l.host);var d=gA(r,l);if(d){var f=AA(r,l),p=f[1],h=f[2];if(p>h)return!0}l=l.parentNode}while(l&&l!==o.body);return!1},uw=function(r){var a=r.scrollTop,o=r.scrollHeight,l=r.clientHeight;return[a,o,l]},cw=function(r){var a=r.scrollLeft,o=r.scrollWidth,l=r.clientWidth;return[a,o,l]},gA=function(r,a){return r==="v"?aw(a):lw(a)},AA=function(r,a){return r==="v"?uw(a):cw(a)},dw=function(r,a){return r==="h"&&a==="rtl"?-1:1},fw=function(r,a,o,l,d){var f=dw(r,window.getComputedStyle(a).direction),p=f*l,h=o.target,g=a.contains(h),m=!1,v=p>0,y=0,w=0;do{if(!h)break;var T=AA(r,h),F=T[0],k=T[1],E=T[2],D=k-E-f*F;(F||D)&&gA(r,h)&&(y+=D,w+=F);var B=h.parentNode;h=B&&B.nodeType===Node.DOCUMENT_FRAGMENT_NODE?B.host:B}while(!g&&h!==document.body||g&&(a.contains(h)||a===h));return(v&&Math.abs(y)<1||!v&&Math.abs(w)<1)&&(m=!0),m},Iu=function(r){return"changedTouches"in r?[r.changedTouches[0].clientX,r.changedTouches[0].clientY]:[0,0]},sm=function(r){return[r.deltaX,r.deltaY]},am=function(r){return r&&"current"in r?r.current:r},hw=function(r,a){return r[0]===a[0]&&r[1]===a[1]},pw=function(r){return`
|
||||
.block-interactivity-`.concat(r,` {pointer-events: none;}
|
||||
.allow-interactivity-`).concat(r,` {pointer-events: all;}
|
||||
`)},pw=0,Us=[];function mw(r){var a=F.useRef([]),o=F.useRef([0,0]),l=F.useRef(),d=F.useState(pw++)[0],f=F.useState(pA)[0],p=F.useRef(r);F.useEffect(function(){p.current=r},[r]),F.useEffect(function(){if(r.inert){document.body.classList.add("block-interactivity-".concat(d));var C=M1([r.lockRef.current],(r.shards||[]).map(am),!0).filter(Boolean);return C.forEach(function(k){return k.classList.add("allow-interactivity-".concat(d))}),function(){document.body.classList.remove("block-interactivity-".concat(d)),C.forEach(function(k){return k.classList.remove("allow-interactivity-".concat(d))})}}},[r.inert,r.lockRef.current,r.shards]);var h=F.useCallback(function(C,k){if("touches"in C&&C.touches.length===2||C.type==="wheel"&&C.ctrlKey)return!p.current.allowPinchZoom;var R=Iu(C),T=o.current,S="deltaX"in C?C.deltaX:T[0]-R[0],N="deltaY"in C?C.deltaY:T[1]-R[1],I,H=C.target,z=Math.abs(S)>Math.abs(N)?"h":"v";if("touches"in C&&z==="h"&&H.type==="range")return!1;var j=window.getSelection(),J=j&&j.anchorNode,W=J?J===H||J.contains(H):!1;if(W)return!1;var U=om(z,H);if(!U)return!0;if(U?I=z:(I=z==="v"?"h":"v",U=om(z,H)),!U)return!1;if(!l.current&&"changedTouches"in C&&(S||N)&&(l.current=I),!I)return!0;var ne=l.current||I;return dw(ne,k,C,ne==="h"?S:N)},[]),g=F.useCallback(function(C){var k=C;if(!(!Us.length||Us[Us.length-1]!==f)){var R="deltaY"in k?sm(k):Iu(k),T=a.current.filter(function(I){return I.name===k.type&&(I.target===k.target||k.target===I.shadowParent)&&fw(I.delta,R)})[0];if(T&&T.should){k.cancelable&&k.preventDefault();return}if(!T){var S=(p.current.shards||[]).map(am).filter(Boolean).filter(function(I){return I.contains(k.target)}),N=S.length>0?h(k,S[0]):!p.current.noIsolation;N&&k.cancelable&&k.preventDefault()}}},[]),m=F.useCallback(function(C,k,R,T){var S={name:C,delta:k,target:R,should:T,shadowParent:gw(R)};a.current.push(S),setTimeout(function(){a.current=a.current.filter(function(N){return N!==S})},1)},[]),v=F.useCallback(function(C){o.current=Iu(C),l.current=void 0},[]),y=F.useCallback(function(C){m(C.type,sm(C),C.target,h(C,r.lockRef.current))},[]),w=F.useCallback(function(C){m(C.type,Iu(C),C.target,h(C,r.lockRef.current))},[]);F.useEffect(function(){return Us.push(f),r.setCallbacks({onScrollCapture:y,onWheelCapture:y,onTouchMoveCapture:w}),document.addEventListener("wheel",g,Vs),document.addEventListener("touchmove",g,Vs),document.addEventListener("touchstart",v,Vs),function(){Us=Us.filter(function(C){return C!==f}),document.removeEventListener("wheel",g,Vs),document.removeEventListener("touchmove",g,Vs),document.removeEventListener("touchstart",v,Vs)}},[]);var P=r.removeScrollBar,D=r.inert;return F.createElement(F.Fragment,null,D?F.createElement(f,{styles:hw(d)}):null,P?F.createElement(iw,{noRelative:r.noRelative,gapMode:r.gapMode}):null)}function gw(r){for(var a=null;r!==null;)r instanceof ShadowRoot&&(a=r.host,r=r.host),r=r.parentNode;return a}const Aw=W1(hA,mw);var xA=F.forwardRef(function(r,a){return F.createElement(zc,Yr({},r,{ref:a,sideCar:Aw}))});xA.classNames=zc.classNames;var xw=function(r){if(typeof document>"u")return null;var a=Array.isArray(r)?r[0]:r;return a.ownerDocument.body},Zs=new WeakMap,Ou=new WeakMap,ju={},Uf=0,vA=function(r){return r&&(r.host||vA(r.parentNode))},vw=function(r,a){return a.map(function(o){if(r.contains(o))return o;var l=vA(o);return l&&r.contains(l)?l:(console.error("aria-hidden",o,"in not contained inside",r,". Doing nothing"),null)}).filter(function(o){return!!o})},yw=function(r,a,o,l){var d=vw(a,Array.isArray(r)?r:[r]);ju[o]||(ju[o]=new WeakMap);var f=ju[o],p=[],h=new Set,g=new Set(d),m=function(y){!y||h.has(y)||(h.add(y),m(y.parentNode))};d.forEach(m);var v=function(y){!y||g.has(y)||Array.prototype.forEach.call(y.children,function(w){if(h.has(w))v(w);else try{var P=w.getAttribute(l),D=P!==null&&P!=="false",C=(Zs.get(w)||0)+1,k=(f.get(w)||0)+1;Zs.set(w,C),f.set(w,k),p.push(w),C===1&&D&&Ou.set(w,!0),k===1&&w.setAttribute(o,"true"),D||w.setAttribute(l,"true")}catch(R){console.error("aria-hidden: cannot operate on ",w,R)}})};return v(a),h.clear(),Uf++,function(){p.forEach(function(y){var w=Zs.get(y)-1,P=f.get(y)-1;Zs.set(y,w),f.set(y,P),w||(Ou.has(y)||y.removeAttribute(l),Ou.delete(y)),P||y.removeAttribute(o)}),Uf--,Uf||(Zs=new WeakMap,Zs=new WeakMap,Ou=new WeakMap,ju={})}},_w=function(r,a,o){o===void 0&&(o="data-aria-hidden");var l=Array.from(Array.isArray(r)?r:[r]),d=xw(r);return d?(l.push.apply(l,Array.from(d.querySelectorAll("[aria-live], script"))),yw(l,d,o,"aria-hidden")):function(){return null}};function ww(r){const a=bw(r),o=F.forwardRef((l,d)=>{const{children:f,...p}=l,h=F.Children.toArray(f),g=h.find(Ew);if(g){const m=g.props.children,v=h.map(y=>y===g?F.Children.count(m)>1?F.Children.only(null):F.isValidElement(m)?m.props.children:null:y);return b.jsx(a,{...p,ref:d,children:F.isValidElement(m)?F.cloneElement(m,void 0,v):null})}return b.jsx(a,{...p,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function bw(r){const a=F.forwardRef((o,l)=>{const{childre
Line truncated
|
||||
`)},mw=0,Us=[];function gw(r){var a=R.useRef([]),o=R.useRef([0,0]),l=R.useRef(),d=R.useState(mw++)[0],f=R.useState(pA)[0],p=R.useRef(r);R.useEffect(function(){p.current=r},[r]),R.useEffect(function(){if(r.inert){document.body.classList.add("block-interactivity-".concat(d));var k=I1([r.lockRef.current],(r.shards||[]).map(am),!0).filter(Boolean);return k.forEach(function(E){return E.classList.add("allow-interactivity-".concat(d))}),function(){document.body.classList.remove("block-interactivity-".concat(d)),k.forEach(function(E){return E.classList.remove("allow-interactivity-".concat(d))})}}},[r.inert,r.lockRef.current,r.shards]);var h=R.useCallback(function(k,E){if("touches"in k&&k.touches.length===2||k.type==="wheel"&&k.ctrlKey)return!p.current.allowPinchZoom;var D=Iu(k),B=o.current,S="deltaX"in k?k.deltaX:B[0]-D[0],N="deltaY"in k?k.deltaY:B[1]-D[1],M,z=k.target,H=Math.abs(S)>Math.abs(N)?"h":"v";if("touches"in k&&H==="h"&&z.type==="range")return!1;var j=window.getSelection(),J=j&&j.anchorNode,W=J?J===z||J.contains(z):!1;if(W)return!1;var U=om(H,z);if(!U)return!0;if(U?M=H:(M=H==="v"?"h":"v",U=om(H,z)),!U)return!1;if(!l.current&&"changedTouches"in k&&(S||N)&&(l.current=M),!M)return!0;var ne=l.current||M;return fw(ne,E,k,ne==="h"?S:N)},[]),g=R.useCallback(function(k){var E=k;if(!(!Us.length||Us[Us.length-1]!==f)){var D="deltaY"in E?sm(E):Iu(E),B=a.current.filter(function(M){return M.name===E.type&&(M.target===E.target||E.target===M.shadowParent)&&hw(M.delta,D)})[0];if(B&&B.should){E.cancelable&&E.preventDefault();return}if(!B){var S=(p.current.shards||[]).map(am).filter(Boolean).filter(function(M){return M.contains(E.target)}),N=S.length>0?h(E,S[0]):!p.current.noIsolation;N&&E.cancelable&&E.preventDefault()}}},[]),m=R.useCallback(function(k,E,D,B){var S={name:k,delta:E,target:D,should:B,shadowParent:Aw(D)};a.current.push(S),setTimeout(function(){a.current=a.current.filter(function(N){return N!==S})},1)},[]),v=R.useCallback(function(k){o.current=Iu(k),l.current=void 0},[]),y=R.useCallback(function(k){m(k.type,sm(k),k.target,h(k,r.lockRef.current))},[]),w=R.useCallback(function(k){m(k.type,Iu(k),k.target,h(k,r.lockRef.current))},[]);R.useEffect(function(){return Us.push(f),r.setCallbacks({onScrollCapture:y,onWheelCapture:y,onTouchMoveCapture:w}),document.addEventListener("wheel",g,Vs),document.addEventListener("touchmove",g,Vs),document.addEventListener("touchstart",v,Vs),function(){Us=Us.filter(function(k){return k!==f}),document.removeEventListener("wheel",g,Vs),document.removeEventListener("touchmove",g,Vs),document.removeEventListener("touchstart",v,Vs)}},[]);var T=r.removeScrollBar,F=r.inert;return R.createElement(R.Fragment,null,F?R.createElement(f,{styles:pw(d)}):null,T?R.createElement(ow,{noRelative:r.noRelative,gapMode:r.gapMode}):null)}function Aw(r){for(var a=null;r!==null;)r instanceof ShadowRoot&&(a=r.host,r=r.host),r=r.parentNode;return a}const xw=q1(hA,gw);var xA=R.forwardRef(function(r,a){return R.createElement(zc,Yr({},r,{ref:a,sideCar:xw}))});xA.classNames=zc.classNames;var vw=function(r){if(typeof document>"u")return null;var a=Array.isArray(r)?r[0]:r;return a.ownerDocument.body},Zs=new WeakMap,Ou=new WeakMap,ju={},Uf=0,vA=function(r){return r&&(r.host||vA(r.parentNode))},yw=function(r,a){return a.map(function(o){if(r.contains(o))return o;var l=vA(o);return l&&r.contains(l)?l:(console.error("aria-hidden",o,"in not contained inside",r,". Doing nothing"),null)}).filter(function(o){return!!o})},_w=function(r,a,o,l){var d=yw(a,Array.isArray(r)?r:[r]);ju[o]||(ju[o]=new WeakMap);var f=ju[o],p=[],h=new Set,g=new Set(d),m=function(y){!y||h.has(y)||(h.add(y),m(y.parentNode))};d.forEach(m);var v=function(y){!y||g.has(y)||Array.prototype.forEach.call(y.children,function(w){if(h.has(w))v(w);else try{var T=w.getAttribute(l),F=T!==null&&T!=="false",k=(Zs.get(w)||0)+1,E=(f.get(w)||0)+1;Zs.set(w,k),f.set(w,E),p.push(w),k===1&&F&&Ou.set(w,!0),E===1&&w.setAttribute(o,"true"),F||w.setAttribute(l,"true")}catch(D){console.error("aria-hidden: cannot operate on ",w,D)}})};return v(a),h.clear(),Uf++,function(){p.forEach(function(y){var w=Zs.get(y)-1,T=f.get(y)-1;Zs.set(y,w),f.set(y,T),w||(Ou.has(y)||y.removeAttribute(l),Ou.delete(y)),T||y.removeAttribute(o)}),Uf--,Uf||(Zs=new WeakMap,Zs=new WeakMap,Ou=new WeakMap,ju={})}},ww=function(r,a,o){o===void 0&&(o="data-aria-hidden");var l=Array.from(Array.isArray(r)?r:[r]),d=vw(r);return d?(l.push.apply(l,Array.from(d.querySelectorAll("[aria-live], script"))),_w(l,d,o,"aria-hidden")):function(){return null}};function bw(r){const a=Cw(r),o=R.forwardRef((l,d)=>{const{children:f,...p}=l,h=R.Children.toArray(f),g=h.find(kw);if(g){const m=g.props.children,v=h.map(y=>y===g?R.Children.count(m)>1?R.Children.only(null):R.isValidElement(m)?m.props.children:null:y);return b.jsx(a,{...p,ref:d,children:R.isValidElement(m)?R.cloneElement(m,void 0,v):null})}return b.jsx(a,{...p,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function Cw(r){const a=R.forwardRef((o,l)=>{const{childre
Line truncated
|
||||
|
||||
If you want to hide the \`${a.titleName}\`, you can wrap it with our VisuallyHidden component.
|
||||
|
||||
For more information, see https://radix-ui.com/primitives/docs/components/${a.docsSlug}`;return F.useEffect(()=>{r&&(document.getElementById(r)||console.error(o))},[o,r]),null},Mw="DialogDescriptionWarning",Iw=({contentRef:r,descriptionId:a})=>{const l=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${NA(Mw).contentName}}.`;return F.useEffect(()=>{var f;const d=(f=r.current)==null?void 0:f.getAttribute("aria-describedby");a&&d&&(document.getElementById(a)||console.warn(l))},[l,r,a]),null},LA=_A,MA=CA,Vc=EA,Uc=kA,Zc=BA,Wc=TA,IA=RA;const C0=LA,Ow=MA,OA=F.forwardRef(({className:r,...a},o)=>b.jsx(Vc,{ref:o,className:ut("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",r),...a}));OA.displayName=Vc.displayName;const qc=F.forwardRef(({className:r,children:a,...o},l)=>b.jsxs(Ow,{children:[b.jsx(OA,{}),b.jsxs(Uc,{ref:l,className:ut("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",r),...o,children:[a,b.jsxs(IA,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[b.jsx(Vg,{className:"h-4 w-4"}),b.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));qc.displayName=Uc.displayName;const Gc=({className:r,...a})=>b.jsx("div",{className:ut("flex flex-col space-y-1.5 text-center sm:text-left",r),...a});Gc.displayName="DialogHeader";const E0=({className:r,...a})=>b.jsx("div",{className:ut("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",r),...a});E0.displayName="DialogFooter";const Kc=F.forwardRef(({className:r,...a},o)=>b.jsx(Zc,{ref:o,className:ut("text-lg font-semibold leading-none tracking-tight",r),...a}));Kc.displayName=Zc.displayName;const Qc=F.forwardRef(({className:r,...a},o)=>b.jsx(Wc,{ref:o,className:ut("text-sm text-muted-foreground",r),...a}));Qc.displayName=Wc.displayName;function jw(){const r=window.location.hash.slice(1);if(!r)return null;if(r==="raw")return{type:"raw",name:"raw"};if(r==="map")return{type:"map",name:"map"};if(r.startsWith("map/focus/")){const d=r.slice(10);return d?{type:"map",name:"map",mapFocusKey:decodeURIComponent(d)}:{type:"map",name:"map"}}const a=r.indexOf("/");if(a===-1)return null;const o=r.slice(0,a),l=decodeURIComponent(r.slice(a+1));return(o==="channel"||o==="contact")&&l?{type:o,name:l}:null}function jA(r){return`#map/focus/${encodeURIComponent(r)}`}function zw(r){if(!r)return"";if(r.type==="raw")return"#raw";if(r.type==="map")return"#map";const a=r.type==="channel"&&r.name.startsWith("#")?r.name.slice(1):r.name;return`#${r.type}/${encodeURIComponent(a)}`}function Hw(r){const a=zw(r);a!==window.location.hash&&window.history.replaceState(null,"",a||window.location.pathname)}function Vw({open:r,onClose:a,paths:o,senderInfo:l,contacts:d,config:f}){const p=o.map(g=>({...g,resolved:J_(g.path,l,d,f)})),h=o.length===1;return b.jsx(C0,{open:r,onOpenChange:g=>!g&&a(),children:b.jsxs(qc,{className:"max-w-md max-h-[80vh] flex flex-col",children:[b.jsxs(Gc,{children:[b.jsxs(Kc,{children:["Message Path",!h&&`s (${o.length})`]}),b.jsx(Qc,{children:h?b.jsxs(b.Fragment,{children:["This shows ",b.jsx("em",{children:"one route"})," that this message traveled through the mesh network. Routers may be incorrectly identified due to prefix collisions between heard and non-heard router advertisements."]}):b.jsxs(b.Fragment,{children:["This message was received via ",b.jsxs("strong",{children:[o.length," different routes"]}),". Routers may be incorrectly identified due to prefix collisions."]})})]}),b.jsxs("div",{className:"flex-1 overflow-y-auto py-2 space-y-4",children:[p.map((g,m)=>b.jsxs("div",{children:[!h&&b.jsxs("div",{className:"text-xs text-muted-foreground font-medium mb-2 pb-1 border-b border-border",children:["Path ",m+1," — received ",Ks(g.received_at)]}),b.jsx(Uw,{resolved:g.resolved,senderInfo:l,hideStraightLine:!h})]},m)),!h&&p.length>0&&(()=>{const g=p[0].resolved;return St(g.sender.lat,g.sender.lon)&&St(g.receiver.lat,g.receiver.lon)?b.jsxs("div",{className:"pt-3 mt-1 border-t border-border",children:[b.jsx("span",{className:"text-sm text-muted-foreground",children:"Straight-line distance: "}),b.jsx("span",{className:"text-sm font-medium",children:Qo(Fr(g.sender.lat,g.sender.lon,g.receiver.lat,g.receiver.lon))})]}):null})()]}),b.jsx(E0,{children:b
Line truncated
|
||||
`).map(($,ce,de)=>b.jsxs("span",{children:[qw($,h),ce<de.length-1&&b.jsx("br",{})]},ce)),!me&&b.jsxs(b.Fragment,{children:[b.jsx("span",{className:"text-[10px] text-muted-foreground/50 ml-2",children:Ks(j.sender_timestamp||j.received_at)}),!j.outgoing&&j.paths&&j.paths.length>0&&b.jsx(um,{paths:j.paths,variant:"inline",onClick:()=>C({paths:j.paths,senderInfo:I(j,W,ne)})})]}),j.outgoing&&(j.acked>0?` ✓${j.acked>1?j.acked:""}`:" ?")]})]})]},j.id)})]}),w&&b.jsx("button",{onClick:T,className:"absolute bottom-4 right-4 w-10 h-10 rounded-full bg-muted hover:bg-accent border border-border flex items-center justify-center shadow-lg transition-opacity",title:"Scroll to bottom",children:b.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:b.jsx("polyline",{points:"6 9 12 15 18 9"})})}),D&&b.jsx(Vw,{open:!0,onClose:()=>C(null),paths:D.paths,senderInfo:D.senderInfo,contacts:a,config:g??null})]})}const cm=156,Kw=140,Qw=156,$w=120,Yw=8,Xw=F.forwardRef(function({onSend:a,disabled:o,placeholder:l,isRepeaterMode:d,conversationType:f,senderName:p},h){const[g,m]=F.useState(""),[v,y]=F.useState(!1),w=F.useRef(null);F.useImperativeHandle(h,()=>({appendText:I=>{var H;m(z=>z+I),(H=w.current)==null||H.focus()}}));const P=F.useMemo(()=>{if(f==="contact")return{warningAt:Kw,dangerAt:cm,hardLimit:cm};if(f==="channel"){const I=(p==null?void 0:p.length)??10,H=Math.max(1,Qw-I-2);return{warningAt:$w,dangerAt:Math.max(1,H-Yw),hardLimit:H}}return null},[f,p]),{limitState:D,warningMessage:C}=F.useMemo(()=>{if(!P)return{limitState:"normal",warningMessage:null};const I=g.length;return I>=P.hardLimit?{limitState:"error",warningMessage:"likely truncated by radio"}:I>=P.dangerAt?{limitState:"danger",warningMessage:"may impact multi-repeater hop delivery"}:I>=P.warningAt?{limitState:"warning",warningMessage:"may impact multi-repeater hop delivery"}:{limitState:"normal",warningMessage:null}},[g.length,P]),k=P?P.hardLimit-g.length:0,R=F.useCallback(async I=>{I.preventDefault();const H=g.trim();if(d){if(v||o)return;y(!0);try{await a(H),m("")}catch(z){console.error("Failed to request telemetry:",z),xt.error("Failed to request telemetry",{description:z instanceof Error?z.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var z;return(z=w.current)==null?void 0:z.focus()},0)}else{if(!H||v||o)return;y(!0);try{await a(H),m("")}catch(z){console.error("Failed to send message:",z),xt.error("Failed to send message",{description:z instanceof Error?z.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var z;return(z=w.current)==null?void 0:z.focus()},0)}},[g,v,o,a,d]),T=F.useCallback(I=>{I.key==="Enter"&&!I.shiftKey&&(I.preventDefault(),R(I))},[R]),S=d?!0:g.trim().length>0,N=!d&&P!==null;return b.jsxs("form",{className:"px-4 py-3 border-t border-border flex flex-col gap-1",onSubmit:R,children:[b.jsxs("div",{className:"flex gap-2",children:[b.jsx(tn,{ref:w,type:d?"password":"text",autoComplete:d?"off":void 0,value:g,onChange:I=>m(I.target.value),onKeyDown:T,placeholder:l||(d?"Enter password for admin login...":"Type a message..."),disabled:o||v,className:"flex-1 min-w-0"}),b.jsx(Pn,{type:"submit",disabled:o||v||!S,className:"flex-shrink-0",children:v?d?"Logging in...":"Sending...":d?g.trim()?"Log in with password":"Log in as guest/use repeater ACLs":"Send"})]}),N&&b.jsxs("div",{className:"flex items-center justify-end gap-2 text-xs",children:[b.jsxs("span",{className:ut("tabular-nums",D==="error"||D==="danger"?"text-red-500 font-medium":D==="warning"?"text-yellow-500":"text-muted-foreground"),children:[g.length,"/",P.hardLimit,k<0&&` (${k})`]}),C&&b.jsxs("span",{className:ut(D==="error"?"text-red-500":"text-yellow-500"),children:["— ",C]})]})]})});function dm(r){const a=Jw(r),o=F.forwardRef((l,d)=>{const{children:f,...p}=l,h=F.Children.toArray(f),g=h.find(t2);if(g){const m=g.props.children,v=h.map(y=>y===g?F.Children.count(m)>1?F.Children.only(null):F.isValidElement(m)?m.props.children:null:y);return b.jsx(a,{...p,ref:d,children:F.isValidElement(m)?F.cloneElement(m,void 0,v):null})}return b.jsx(a,{...p,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function Jw(r){const a=F.forwardRef((o,l)=>{const{children:d,...f}=o;if(F.isValidElement(d)){const p=r2(d),h=n2(f,d.props);return d.type!==F.Fragment&&(h.ref=l?dl(l,p):p),F.cloneElement(d,h)}return F.Children.count(d)>1?F.Children.only(null):null});return a.displayName=`${r}.SlotClone`,a}var e2=Symbol("radix.slottable");function t2(r){return F.isValidElement(r)&&typeof r.type=="function"&&"__radixId"in r.type&&r.type.__radixId===e2}function n2(r,a){const o={...a};for(const l in a){const d=r[l],f=a[l];/^on[A-Z]/.test(l)?d&&f?o[l]=(...h)=>{const g=f(...h);return d(...h),g}:d&&(o[l]=d):l==="style"?o[l]={...d,...f}:l==="className"&&(o[l]=[d,f].filter(Boolean).join(" "))}return{...r,...o}}functio
Line truncated
|
||||
For more information, see https://radix-ui.com/primitives/docs/components/${a.docsSlug}`;return R.useEffect(()=>{r&&(document.getElementById(r)||console.error(o))},[o,r]),null},Iw="DialogDescriptionWarning",Ow=({contentRef:r,descriptionId:a})=>{const l=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${NA(Iw).contentName}}.`;return R.useEffect(()=>{var f;const d=(f=r.current)==null?void 0:f.getAttribute("aria-describedby");a&&d&&(document.getElementById(a)||console.warn(l))},[l,r,a]),null},LA=_A,MA=CA,Vc=EA,Uc=kA,Zc=BA,Wc=TA,IA=RA;const C0=LA,jw=MA,OA=R.forwardRef(({className:r,...a},o)=>b.jsx(Vc,{ref:o,className:ut("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",r),...a}));OA.displayName=Vc.displayName;const qc=R.forwardRef(({className:r,children:a,...o},l)=>b.jsxs(jw,{children:[b.jsx(OA,{}),b.jsxs(Uc,{ref:l,className:ut("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",r),...o,children:[a,b.jsxs(IA,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[b.jsx(Vg,{className:"h-4 w-4"}),b.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));qc.displayName=Uc.displayName;const Gc=({className:r,...a})=>b.jsx("div",{className:ut("flex flex-col space-y-1.5 text-center sm:text-left",r),...a});Gc.displayName="DialogHeader";const E0=({className:r,...a})=>b.jsx("div",{className:ut("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",r),...a});E0.displayName="DialogFooter";const Kc=R.forwardRef(({className:r,...a},o)=>b.jsx(Zc,{ref:o,className:ut("text-lg font-semibold leading-none tracking-tight",r),...a}));Kc.displayName=Zc.displayName;const Qc=R.forwardRef(({className:r,...a},o)=>b.jsx(Wc,{ref:o,className:ut("text-sm text-muted-foreground",r),...a}));Qc.displayName=Wc.displayName;function zw(){const r=window.location.hash.slice(1);if(!r)return null;if(r==="raw")return{type:"raw",name:"raw"};if(r==="map")return{type:"map",name:"map"};if(r.startsWith("map/focus/")){const d=r.slice(10);return d?{type:"map",name:"map",mapFocusKey:decodeURIComponent(d)}:{type:"map",name:"map"}}const a=r.indexOf("/");if(a===-1)return null;const o=r.slice(0,a),l=decodeURIComponent(r.slice(a+1));return(o==="channel"||o==="contact")&&l?{type:o,name:l}:null}function jA(r){return`#map/focus/${encodeURIComponent(r)}`}function Hw(r){if(!r)return"";if(r.type==="raw")return"#raw";if(r.type==="map")return"#map";const a=r.type==="channel"&&r.name.startsWith("#")?r.name.slice(1):r.name;return`#${r.type}/${encodeURIComponent(a)}`}function Vw(r){const a=Hw(r);a!==window.location.hash&&window.history.replaceState(null,"",a||window.location.pathname)}function Uw({open:r,onClose:a,paths:o,senderInfo:l,contacts:d,config:f}){const p=o.map(g=>({...g,resolved:e1(g.path,l,d,f)})),h=o.length===1;return b.jsx(C0,{open:r,onOpenChange:g=>!g&&a(),children:b.jsxs(qc,{className:"max-w-md max-h-[80vh] flex flex-col",children:[b.jsxs(Gc,{children:[b.jsxs(Kc,{children:["Message Path",!h&&`s (${o.length})`]}),b.jsx(Qc,{children:h?b.jsxs(b.Fragment,{children:["This shows ",b.jsx("em",{children:"one route"})," that this message traveled through the mesh network. Routers may be incorrectly identified due to prefix collisions between heard and non-heard router advertisements."]}):b.jsxs(b.Fragment,{children:["This message was received via ",b.jsxs("strong",{children:[o.length," different routes"]}),". Routers may be incorrectly identified due to prefix collisions."]})})]}),b.jsxs("div",{className:"flex-1 overflow-y-auto py-2 space-y-4",children:[p.map((g,m)=>b.jsxs("div",{children:[!h&&b.jsxs("div",{className:"text-xs text-muted-foreground font-medium mb-2 pb-1 border-b border-border",children:["Path ",m+1," — received ",Ks(g.received_at)]}),b.jsx(Zw,{resolved:g.resolved,senderInfo:l,hideStraightLine:!h})]},m)),!h&&p.length>0&&(()=>{const g=p[0].resolved;return St(g.sender.lat,g.sender.lon)&&St(g.receiver.lat,g.receiver.lon)?b.jsxs("div",{className:"pt-3 mt-1 border-t border-border",children:[b.jsx("span",{className:"text-sm text-muted-foreground",children:"Straight-line distance: "}),b.jsx("span",{className:"text-sm font-medium",children:Qo(Fr(g.sender.lat,g.sender.lon,g.receiver.lat,g.receiver.lon))})]}):null})()]}),b.jsx(E0,{children:b
Line truncated
|
||||
`).map(($,ce,de)=>b.jsxs("span",{children:[Gw($,h),ce<de.length-1&&b.jsx("br",{})]},ce)),!pe&&b.jsxs(b.Fragment,{children:[b.jsx("span",{className:"text-[10px] text-muted-foreground/50 ml-2",children:Ks(j.sender_timestamp||j.received_at)}),!j.outgoing&&j.paths&&j.paths.length>0&&b.jsx(um,{paths:j.paths,variant:"inline",onClick:()=>k({paths:j.paths,senderInfo:M(j,W,ne)})})]}),j.outgoing&&(j.acked>0?` ✓${j.acked>1?j.acked:""}`:" ?")]})]})]},j.id)})]}),w&&b.jsx("button",{onClick:B,className:"absolute bottom-4 right-4 w-10 h-10 rounded-full bg-muted hover:bg-accent border border-border flex items-center justify-center shadow-lg transition-opacity",title:"Scroll to bottom",children:b.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:b.jsx("polyline",{points:"6 9 12 15 18 9"})})}),F&&b.jsx(Uw,{open:!0,onClose:()=>k(null),paths:F.paths,senderInfo:F.senderInfo,contacts:a,config:g??null})]})}const cm=156,Qw=140,$w=156,Yw=120,Xw=8,Jw=R.forwardRef(function({onSend:a,disabled:o,placeholder:l,isRepeaterMode:d,conversationType:f,senderName:p},h){const[g,m]=R.useState(""),[v,y]=R.useState(!1),w=R.useRef(null);R.useImperativeHandle(h,()=>({appendText:M=>{var z;m(H=>H+M),(z=w.current)==null||z.focus()}}));const T=R.useMemo(()=>{if(f==="contact")return{warningAt:Qw,dangerAt:cm,hardLimit:cm};if(f==="channel"){const M=(p==null?void 0:p.length)??10,z=Math.max(1,$w-M-2);return{warningAt:Yw,dangerAt:Math.max(1,z-Xw),hardLimit:z}}return null},[f,p]),{limitState:F,warningMessage:k}=R.useMemo(()=>{if(!T)return{limitState:"normal",warningMessage:null};const M=g.length;return M>=T.hardLimit?{limitState:"error",warningMessage:"likely truncated by radio"}:M>=T.dangerAt?{limitState:"danger",warningMessage:"may impact multi-repeater hop delivery"}:M>=T.warningAt?{limitState:"warning",warningMessage:"may impact multi-repeater hop delivery"}:{limitState:"normal",warningMessage:null}},[g.length,T]),E=T?T.hardLimit-g.length:0,D=R.useCallback(async M=>{M.preventDefault();const z=g.trim();if(d){if(v||o)return;y(!0);try{await a(z),m("")}catch(H){console.error("Failed to request telemetry:",H),xt.error("Failed to request telemetry",{description:H instanceof Error?H.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var H;return(H=w.current)==null?void 0:H.focus()},0)}else{if(!z||v||o)return;y(!0);try{await a(z),m("")}catch(H){console.error("Failed to send message:",H),xt.error("Failed to send message",{description:H instanceof Error?H.message:"Check radio connection"});return}finally{y(!1)}setTimeout(()=>{var H;return(H=w.current)==null?void 0:H.focus()},0)}},[g,v,o,a,d]),B=R.useCallback(M=>{M.key==="Enter"&&!M.shiftKey&&(M.preventDefault(),D(M))},[D]),S=d?!0:g.trim().length>0,N=!d&&T!==null;return b.jsxs("form",{className:"px-4 py-3 border-t border-border flex flex-col gap-1",onSubmit:D,children:[b.jsxs("div",{className:"flex gap-2",children:[b.jsx(tn,{ref:w,type:d?"password":"text",autoComplete:d?"off":void 0,value:g,onChange:M=>m(M.target.value),onKeyDown:B,placeholder:l||(d?"Enter password for admin login...":"Type a message..."),disabled:o||v,className:"flex-1 min-w-0"}),b.jsx(Pn,{type:"submit",disabled:o||v||!S,className:"flex-shrink-0",children:v?d?"Logging in...":"Sending...":d?g.trim()?"Log in with password":"Log in as guest/use repeater ACLs":"Send"})]}),N&&b.jsxs("div",{className:"flex items-center justify-end gap-2 text-xs",children:[b.jsxs("span",{className:ut("tabular-nums",F==="error"||F==="danger"?"text-red-500 font-medium":F==="warning"?"text-yellow-500":"text-muted-foreground"),children:[g.length,"/",T.hardLimit,E<0&&` (${E})`]}),k&&b.jsxs("span",{className:ut(F==="error"?"text-red-500":"text-yellow-500"),children:["— ",k]})]})]})});function dm(r){const a=e2(r),o=R.forwardRef((l,d)=>{const{children:f,...p}=l,h=R.Children.toArray(f),g=h.find(n2);if(g){const m=g.props.children,v=h.map(y=>y===g?R.Children.count(m)>1?R.Children.only(null):R.isValidElement(m)?m.props.children:null:y);return b.jsx(a,{...p,ref:d,children:R.isValidElement(m)?R.cloneElement(m,void 0,v):null})}return b.jsx(a,{...p,ref:d,children:f})});return o.displayName=`${r}.Slot`,o}function e2(r){const a=R.forwardRef((o,l)=>{const{children:d,...f}=o;if(R.isValidElement(d)){const p=i2(d),h=r2(f,d.props);return d.type!==R.Fragment&&(h.ref=l?dl(l,p):p),R.cloneElement(d,h)}return R.Children.count(d)>1?R.Children.only(null):null});return a.displayName=`${r}.SlotClone`,a}var t2=Symbol("radix.slottable");function n2(r){return R.isValidElement(r)&&typeof r.type=="function"&&"__radixId"in r.type&&r.type.__radixId===t2}function r2(r,a){const o={...a};for(const l in a){const d=r[l],f=a[l];/^on[A-Z]/.test(l)?d&&f?o[l]=(...h)=>{const g=f(...h);return d(...h),g}:d&&(o[l]=d):l==="style"?o[l]={...d,...f}:l==="className"&&(o[l]=[d,f].filter(Boolean).join(" "))}return{...r,...o}}functio
Line truncated
|
||||
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
|
||||
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
|
||||
*/var $2=ol.exports,pm;function Y2(){return pm||(pm=1,(function(r,a){(function(o,l){l(a)})($2,(function(o){var l="1.9.4";function d(t){var i,u,A,E;for(u=1,A=arguments.length;u<A;u++){E=arguments[u];for(i in E)t[i]=E[i]}return t}var f=Object.create||(function(){function t(){}return function(i){return t.prototype=i,new t}})();function p(t,i){var u=Array.prototype.slice;if(t.bind)return t.bind.apply(t,u.call(arguments,1));var A=u.call(arguments,2);return function(){return t.apply(i,A.length?A.concat(u.call(arguments)):arguments)}}var h=0;function g(t){return"_leaflet_id"in t||(t._leaflet_id=++h),t._leaflet_id}function m(t,i,u){var A,E,O,Q;return Q=function(){A=!1,E&&(O.apply(u,E),E=!1)},O=function(){A?E=arguments:(t.apply(u,arguments),setTimeout(Q,i),A=!0)},O}function v(t,i,u){var A=i[1],E=i[0],O=A-E;return t===A&&u?t:((t-E)%O+O)%O+E}function y(){return!1}function w(t,i){if(i===!1)return t;var u=Math.pow(10,i===void 0?6:i);return Math.round(t*u)/u}function P(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function D(t){return P(t).split(/\s+/)}function C(t,i){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?f(t.options):{});for(var u in i)t.options[u]=i[u];return t.options}function k(t,i,u){var A=[];for(var E in t)A.push(encodeURIComponent(u?E.toUpperCase():E)+"="+encodeURIComponent(t[E]));return(!i||i.indexOf("?")===-1?"?":"&")+A.join("&")}var R=/\{ *([\w_ -]+) *\}/g;function T(t,i){return t.replace(R,function(u,A){var E=i[A];if(E===void 0)throw new Error("No value provided for variable "+u);return typeof E=="function"&&(E=E(i)),E})}var S=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function N(t,i){for(var u=0;u<t.length;u++)if(t[u]===i)return u;return-1}var I="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function H(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var z=0;function j(t){var i=+new Date,u=Math.max(0,16-(i-z));return z=i+u,window.setTimeout(t,u)}var J=window.requestAnimationFrame||H("RequestAnimationFrame")||j,W=window.cancelAnimationFrame||H("CancelAnimationFrame")||H("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function U(t,i,u){if(u&&J===j)t.call(i);else return J.call(window,p(t,i))}function ne(t){t&&W.call(window,t)}var Y={__proto__:null,extend:d,create:f,bind:p,get lastId(){return h},stamp:g,throttle:m,wrapNum:v,falseFn:y,formatNum:w,trim:P,splitWords:D,setOptions:C,getParamString:k,template:T,isArray:S,indexOf:N,emptyImageUrl:I,requestFn:J,cancelFn:W,requestAnimFrame:U,cancelAnimFrame:ne};function re(){}re.extend=function(t){var i=function(){C(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},u=i.__super__=this.prototype,A=f(u);A.constructor=i,i.prototype=A;for(var E in this)Object.prototype.hasOwnProperty.call(this,E)&&E!=="prototype"&&E!=="__super__"&&(i[E]=this[E]);return t.statics&&d(i,t.statics),t.includes&&(fe(t.includes),d.apply(null,[A].concat(t.includes))),d(A,t),delete A.statics,delete A.includes,A.options&&(A.options=u.options?f(u.options):{},d(A.options,t.options)),A._initHooks=[],A.callInitHooks=function(){if(!this._initHooksCalled){u.callInitHooks&&u.callInitHooks.call(this),this._initHooksCalled=!0;for(var O=0,Q=A._initHooks.length;O<Q;O++)A._initHooks[O].call(this)}},i},re.include=function(t){var i=this.prototype.options;return d(this.prototype,t),t.options&&(this.prototype.options=i,this.mergeOptions(t.options)),this},re.mergeOptions=function(t){return d(this.prototype.options,t),this},re.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),u=typeof t=="function"?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(u),this};function fe(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=S(t)?t:[t];for(var i=0;i<t.length;i++)t[i]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",new Error().stack)}}var ae={on:function(t,i,u){if(typeof t=="object")for(var A in t)this._on(A,t[A],i);else{t=D(t);for(var E=0,O=t.length;E<O;E++)this._on(t[E],i,u)}return this},off:function(t,i,u){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var A in t)this._off(A,t[A],i);else{t=D(t);for(var E=arguments.length===1,O=0,Q=t.length;O<Q;O++)E?this._off(t[O]):this._off(t[O],i,u)}return this},_on:function(t,i,u,A){if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}if(this._listens(t,i,u)===!1){u===this&&(u=void 0);var E={fn:i,ctx:u};A&&(E.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(E)}},_off:function(t,i,u){var A,E,O;if(this._events&&(A=this._events[t],!!A)){if(arguments.length===1){if(this._firingCount)for(E=0,O=A.length;E<O;E++)A[E].fn=y;delete this._events[t];return}if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}var Q=this.Line truncated
|
||||
*/var Y2=ol.exports,pm;function X2(){return pm||(pm=1,(function(r,a){(function(o,l){l(a)})(Y2,(function(o){var l="1.9.4";function d(t){var i,u,A,C;for(u=1,A=arguments.length;u<A;u++){C=arguments[u];for(i in C)t[i]=C[i]}return t}var f=Object.create||(function(){function t(){}return function(i){return t.prototype=i,new t}})();function p(t,i){var u=Array.prototype.slice;if(t.bind)return t.bind.apply(t,u.call(arguments,1));var A=u.call(arguments,2);return function(){return t.apply(i,A.length?A.concat(u.call(arguments)):arguments)}}var h=0;function g(t){return"_leaflet_id"in t||(t._leaflet_id=++h),t._leaflet_id}function m(t,i,u){var A,C,O,Q;return Q=function(){A=!1,C&&(O.apply(u,C),C=!1)},O=function(){A?C=arguments:(t.apply(u,arguments),setTimeout(Q,i),A=!0)},O}function v(t,i,u){var A=i[1],C=i[0],O=A-C;return t===A&&u?t:((t-C)%O+O)%O+C}function y(){return!1}function w(t,i){if(i===!1)return t;var u=Math.pow(10,i===void 0?6:i);return Math.round(t*u)/u}function T(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function F(t){return T(t).split(/\s+/)}function k(t,i){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?f(t.options):{});for(var u in i)t.options[u]=i[u];return t.options}function E(t,i,u){var A=[];for(var C in t)A.push(encodeURIComponent(u?C.toUpperCase():C)+"="+encodeURIComponent(t[C]));return(!i||i.indexOf("?")===-1?"?":"&")+A.join("&")}var D=/\{ *([\w_ -]+) *\}/g;function B(t,i){return t.replace(D,function(u,A){var C=i[A];if(C===void 0)throw new Error("No value provided for variable "+u);return typeof C=="function"&&(C=C(i)),C})}var S=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function N(t,i){for(var u=0;u<t.length;u++)if(t[u]===i)return u;return-1}var M="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function z(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var H=0;function j(t){var i=+new Date,u=Math.max(0,16-(i-H));return H=i+u,window.setTimeout(t,u)}var J=window.requestAnimationFrame||z("RequestAnimationFrame")||j,W=window.cancelAnimationFrame||z("CancelAnimationFrame")||z("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function U(t,i,u){if(u&&J===j)t.call(i);else return J.call(window,p(t,i))}function ne(t){t&&W.call(window,t)}var Y={__proto__:null,extend:d,create:f,bind:p,get lastId(){return h},stamp:g,throttle:m,wrapNum:v,falseFn:y,formatNum:w,trim:T,splitWords:F,setOptions:k,getParamString:E,template:B,isArray:S,indexOf:N,emptyImageUrl:M,requestFn:J,cancelFn:W,requestAnimFrame:U,cancelAnimFrame:ne};function re(){}re.extend=function(t){var i=function(){k(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},u=i.__super__=this.prototype,A=f(u);A.constructor=i,i.prototype=A;for(var C in this)Object.prototype.hasOwnProperty.call(this,C)&&C!=="prototype"&&C!=="__super__"&&(i[C]=this[C]);return t.statics&&d(i,t.statics),t.includes&&(fe(t.includes),d.apply(null,[A].concat(t.includes))),d(A,t),delete A.statics,delete A.includes,A.options&&(A.options=u.options?f(u.options):{},d(A.options,t.options)),A._initHooks=[],A.callInitHooks=function(){if(!this._initHooksCalled){u.callInitHooks&&u.callInitHooks.call(this),this._initHooksCalled=!0;for(var O=0,Q=A._initHooks.length;O<Q;O++)A._initHooks[O].call(this)}},i},re.include=function(t){var i=this.prototype.options;return d(this.prototype,t),t.options&&(this.prototype.options=i,this.mergeOptions(t.options)),this},re.mergeOptions=function(t){return d(this.prototype.options,t),this},re.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),u=typeof t=="function"?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(u),this};function fe(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=S(t)?t:[t];for(var i=0;i<t.length;i++)t[i]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",new Error().stack)}}var ae={on:function(t,i,u){if(typeof t=="object")for(var A in t)this._on(A,t[A],i);else{t=F(t);for(var C=0,O=t.length;C<O;C++)this._on(t[C],i,u)}return this},off:function(t,i,u){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var A in t)this._off(A,t[A],i);else{t=F(t);for(var C=arguments.length===1,O=0,Q=t.length;O<Q;O++)C?this._off(t[O]):this._off(t[O],i,u)}return this},_on:function(t,i,u,A){if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}if(this._listens(t,i,u)===!1){u===this&&(u=void 0);var C={fn:i,ctx:u};A&&(C.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(C)}},_off:function(t,i,u){var A,C,O;if(this._events&&(A=this._events[t],!!A)){if(arguments.length===1){if(this._firingCount)for(C=0,O=A.length;C<O;C++)A[C].fn=y;delete this._events[t];return}if(typeof i!="function"){console.warn("wrong listener type: "+typeof i);return}var Q=this.Line truncated
|
||||
(c) 2012 by Cédric Mesnil. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
@@ -135,17 +135,17 @@ For more information, see https://radix-ui.com/primitives/docs/components/${a.do
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/return(function(l){var d=o,f=d.lib,p=f.WordArray,h=f.Hasher,g=d.algo,m=p.create([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13]),v=p.create([5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]),y=p.create([11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]),w=p.create([8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]),P=p.create([0,1518500249,1859775393,2400959708,2840853838]),D=p.create([1352829926,1548603684,1836072691,2053994217,0]),C=g.RIPEMD160=h.extend({_doReset:function(){this._hash=p.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(H,z){for(var j=0;j<16;j++){var J=z+j,W=H[J];H[J]=(W<<8|W>>>24)&16711935|(W<<24|W>>>8)&4278255360}var U=this._hash.words,ne=P.words,Y=D.words,re=m.words,fe=v.words,ae=y.words,he=w.words,G,me,Z,B,V,K,$,ce,de,Se;K=G=U[0],$=me=U[1],ce=Z=U[2],de=B=U[3],Se=V=U[4];for(var Ae,j=0;j<80;j+=1)Ae=G+H[z+re[j]]|0,j<16?Ae+=k(me,Z,B)+ne[0]:j<32?Ae+=R(me,Z,B)+ne[1]:j<48?Ae+=T(me,Z,B)+ne[2]:j<64?Ae+=S(me,Z,B)+ne[3]:Ae+=N(me,Z,B)+ne[4],Ae=Ae|0,Ae=I(Ae,ae[j]),Ae=Ae+V|0,G=V,V=B,B=I(Z,10),Z=me,me=Ae,Ae=K+H[z+fe[j]]|0,j<16?Ae+=N($,ce,de)+Y[0]:j<32?Ae+=S($,ce,de)+Y[1]:j<48?Ae+=T($,ce,de)+Y[2]:j<64?Ae+=R($,ce,de)+Y[3]:Ae+=k($,ce,de)+Y[4],Ae=Ae|0,Ae=I(Ae,he[j]),Ae=Ae+Se|0,K=Se,Se=de,de=I(ce,10),ce=$,$=Ae;Ae=U[1]+Z+de|0,U[1]=U[2]+B+Se|0,U[2]=U[3]+V+K|0,U[3]=U[4]+G+$|0,U[4]=U[0]+me+ce|0,U[0]=Ae},_doFinalize:function(){var H=this._data,z=H.words,j=this._nDataBytes*8,J=H.sigBytes*8;z[J>>>5]|=128<<24-J%32,z[(J+64>>>9<<4)+14]=(j<<8|j>>>24)&16711935|(j<<24|j>>>8)&4278255360,H.sigBytes=(z.length+1)*4,this._process();for(var W=this._hash,U=W.words,ne=0;ne<5;ne++){var Y=U[ne];U[ne]=(Y<<8|Y>>>24)&16711935|(Y<<24|Y>>>8)&4278255360}return W},clone:function(){var H=h.clone.call(this);return H._hash=this._hash.clone(),H}});function k(H,z,j){return H^z^j}function R(H,z,j){return H&z|~H&j}function T(H,z,j){return(H|~z)^j}function S(H,z,j){return H&j|z&~j}function N(H,z,j){return H^(z|~j)}function I(H,z){return H<<z|H>>>32-z}d.RIPEMD160=h._createHelper(C),d.HmacRIPEMD160=h._createHmacHelper(C)})(),o.RIPEMD160})})(ic)),ic.exports}var oc={exports:{}},zb=oc.exports,Fm;function nd(){return Fm||(Fm=1,(function(r,a){(function(o,l){r.exports=l(mt())})(zb,function(o){(function(){var l=o,d=l.lib,f=d.Base,p=l.enc,h=p.Utf8,g=l.algo;g.HMAC=f.extend({init:function(m,v){m=this._hasher=new m.init,typeof v=="string"&&(v=h.parse(v));var y=m.blockSize,w=y*4;v.sigBytes>w&&(v=m.finalize(v)),v.clamp();for(var P=this._oKey=v.clone(),D=this._iKey=v.clone(),C=P.words,k=D.words,R=0;R<y;R++)C[R]^=1549556828,k[R]^=909522486;P.sigBytes=D.sigBytes=w,this.reset()},reset:function(){var m=this._hasher;m.reset(),m.update(this._iKey)},update:function(m){return this._hasher.update(m),this},finalize:function(m){var v=this._hasher,y=v.finalize(m);v.reset();var w=v.finalize(this._oKey.clone().concat(y));return w}})})()})})(oc)),oc.exports}var sc={exports:{}},Hb=sc.exports,Nm;function Vb(){return Nm||(Nm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),pl(),nd())})(Hb,function(o){return(function(){var l=o,d=l.lib,f=d.Base,p=d.WordArray,h=l.algo,g=h.SHA256,m=h.HMAC,v=h.PBKDF2=f.extend({cfg:f.extend({keySize:128/32,hasher:g,iterations:25e4}),init:function(y){this.cfg=this.cfg.extend(y)},compute:function(y,w){for(var P=this.cfg,D=m.create(P.hasher,y),C=p.create(),k=p.create([1]),R=C.words,T=k.words,S=P.keySize,N=P.iterations;R.length<S;){var I=D.update(w).finalize(k);D.reset();for(var H=I.words,z=H.length,j=I,J=1;J<N;J++){j=D.finalize(j),D.reset();for(var W=j.words,U=0;U<z;U++)H[U]^=W[U]}C.concat(I),T[0]++}return C.sigBytes=S*4,C}});l.PBKDF2=function(y,w,P){return v.create(P).compute(y,w)}})(),o.PBKDF2})})(sc)),sc.exports}var ac={exports:{}},Ub=ac.exports,Lm;function fo(){return Lm||(Lm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),bx(),nd())})(Ub,function(o){return(function(){var l=o,d=l.lib,f=d.Base,p=d.WordArray,h=l.algo,g=h.MD5,m=h.EvpKDF=f.extend({cfg:f.extend({keySize:128/32,hasher:g,iterations:1}),init:function(v){this.cfg=this.cfg.extend(v)},compute:function(v,y){for(var w,P=this.cfg,D=P.hasher.create(),C=p.create(),k=C.words,R=P.keySize,T=P.iterations;k.length<R;){w&&D.update(w),w=D.update(v).finalize(y),D.reset();for(var S=1;S<T;S++)w=D.finalize(w),D.reset();C.concat(w)}return C.sigBytes=R*4,C}});l.EvpKDF=function(v,y,w){return m.create(w).compute(v,y)}})(),o.EvpKDF})})(ac)),ac.exports}var lc={exports:{}},Zb=lc.exports,Line truncated
|
||||
*/return(function(l){var d=o,f=d.lib,p=f.WordArray,h=f.Hasher,g=d.algo,m=p.create([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13]),v=p.create([5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]),y=p.create([11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]),w=p.create([8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]),T=p.create([0,1518500249,1859775393,2400959708,2840853838]),F=p.create([1352829926,1548603684,1836072691,2053994217,0]),k=g.RIPEMD160=h.extend({_doReset:function(){this._hash=p.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(z,H){for(var j=0;j<16;j++){var J=H+j,W=z[J];z[J]=(W<<8|W>>>24)&16711935|(W<<24|W>>>8)&4278255360}var U=this._hash.words,ne=T.words,Y=F.words,re=m.words,fe=v.words,ae=y.words,he=w.words,G,pe,Z,P,V,K,$,ce,de,Se;K=G=U[0],$=pe=U[1],ce=Z=U[2],de=P=U[3],Se=V=U[4];for(var Ae,j=0;j<80;j+=1)Ae=G+z[H+re[j]]|0,j<16?Ae+=E(pe,Z,P)+ne[0]:j<32?Ae+=D(pe,Z,P)+ne[1]:j<48?Ae+=B(pe,Z,P)+ne[2]:j<64?Ae+=S(pe,Z,P)+ne[3]:Ae+=N(pe,Z,P)+ne[4],Ae=Ae|0,Ae=M(Ae,ae[j]),Ae=Ae+V|0,G=V,V=P,P=M(Z,10),Z=pe,pe=Ae,Ae=K+z[H+fe[j]]|0,j<16?Ae+=N($,ce,de)+Y[0]:j<32?Ae+=S($,ce,de)+Y[1]:j<48?Ae+=B($,ce,de)+Y[2]:j<64?Ae+=D($,ce,de)+Y[3]:Ae+=E($,ce,de)+Y[4],Ae=Ae|0,Ae=M(Ae,he[j]),Ae=Ae+Se|0,K=Se,Se=de,de=M(ce,10),ce=$,$=Ae;Ae=U[1]+Z+de|0,U[1]=U[2]+P+Se|0,U[2]=U[3]+V+K|0,U[3]=U[4]+G+$|0,U[4]=U[0]+pe+ce|0,U[0]=Ae},_doFinalize:function(){var z=this._data,H=z.words,j=this._nDataBytes*8,J=z.sigBytes*8;H[J>>>5]|=128<<24-J%32,H[(J+64>>>9<<4)+14]=(j<<8|j>>>24)&16711935|(j<<24|j>>>8)&4278255360,z.sigBytes=(H.length+1)*4,this._process();for(var W=this._hash,U=W.words,ne=0;ne<5;ne++){var Y=U[ne];U[ne]=(Y<<8|Y>>>24)&16711935|(Y<<24|Y>>>8)&4278255360}return W},clone:function(){var z=h.clone.call(this);return z._hash=this._hash.clone(),z}});function E(z,H,j){return z^H^j}function D(z,H,j){return z&H|~z&j}function B(z,H,j){return(z|~H)^j}function S(z,H,j){return z&j|H&~j}function N(z,H,j){return z^(H|~j)}function M(z,H){return z<<H|z>>>32-H}d.RIPEMD160=h._createHelper(k),d.HmacRIPEMD160=h._createHmacHelper(k)})(),o.RIPEMD160})})(ic)),ic.exports}var oc={exports:{}},Hb=oc.exports,Fm;function nd(){return Fm||(Fm=1,(function(r,a){(function(o,l){r.exports=l(mt())})(Hb,function(o){(function(){var l=o,d=l.lib,f=d.Base,p=l.enc,h=p.Utf8,g=l.algo;g.HMAC=f.extend({init:function(m,v){m=this._hasher=new m.init,typeof v=="string"&&(v=h.parse(v));var y=m.blockSize,w=y*4;v.sigBytes>w&&(v=m.finalize(v)),v.clamp();for(var T=this._oKey=v.clone(),F=this._iKey=v.clone(),k=T.words,E=F.words,D=0;D<y;D++)k[D]^=1549556828,E[D]^=909522486;T.sigBytes=F.sigBytes=w,this.reset()},reset:function(){var m=this._hasher;m.reset(),m.update(this._iKey)},update:function(m){return this._hasher.update(m),this},finalize:function(m){var v=this._hasher,y=v.finalize(m);v.reset();var w=v.finalize(this._oKey.clone().concat(y));return w}})})()})})(oc)),oc.exports}var sc={exports:{}},Vb=sc.exports,Nm;function Ub(){return Nm||(Nm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),pl(),nd())})(Vb,function(o){return(function(){var l=o,d=l.lib,f=d.Base,p=d.WordArray,h=l.algo,g=h.SHA256,m=h.HMAC,v=h.PBKDF2=f.extend({cfg:f.extend({keySize:128/32,hasher:g,iterations:25e4}),init:function(y){this.cfg=this.cfg.extend(y)},compute:function(y,w){for(var T=this.cfg,F=m.create(T.hasher,y),k=p.create(),E=p.create([1]),D=k.words,B=E.words,S=T.keySize,N=T.iterations;D.length<S;){var M=F.update(w).finalize(E);F.reset();for(var z=M.words,H=z.length,j=M,J=1;J<N;J++){j=F.finalize(j),F.reset();for(var W=j.words,U=0;U<H;U++)z[U]^=W[U]}k.concat(M),B[0]++}return k.sigBytes=S*4,k}});l.PBKDF2=function(y,w,T){return v.create(T).compute(y,w)}})(),o.PBKDF2})})(sc)),sc.exports}var ac={exports:{}},Zb=ac.exports,Lm;function fo(){return Lm||(Lm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),bx(),nd())})(Zb,function(o){return(function(){var l=o,d=l.lib,f=d.Base,p=d.WordArray,h=l.algo,g=h.MD5,m=h.EvpKDF=f.extend({cfg:f.extend({keySize:128/32,hasher:g,iterations:1}),init:function(v){this.cfg=this.cfg.extend(v)},compute:function(v,y){for(var w,T=this.cfg,F=T.hasher.create(),k=p.create(),E=k.words,D=T.keySize,B=T.iterations;E.length<D;){w&&F.update(w),w=F.update(v).finalize(y),F.reset();for(var S=1;S<B;S++)w=F.finalize(w),F.reset();k.concat(w)}return k.sigBytes=D*4,k}});l.EvpKDF=function(v,y,w){return m.create(w).compute(v,y)}})(),o.EvpKDF})})(ac)),ac.exports}var lc={exports:{}},Wb=lc.exports,Line truncated
|
||||
* Counter block mode compatible with Dr Brian Gladman fileenc.c
|
||||
* derived from CryptoJS.mode.CTR
|
||||
* Jan Hruby jhruby.web@gmail.com
|
||||
*/return o.mode.CTRGladman=(function(){var l=o.lib.BlockCipherMode.extend();function d(h){if((h>>24&255)===255){var g=h>>16&255,m=h>>8&255,v=h&255;g===255?(g=0,m===255?(m=0,v===255?v=0:++v):++m):++g,h=0,h+=g<<16,h+=m<<8,h+=v}else h+=1<<24;return h}function f(h){return(h[0]=d(h[0]))===0&&(h[1]=d(h[1])),h}var p=l.Encryptor=l.extend({processBlock:function(h,g){var m=this._cipher,v=m.blockSize,y=this._iv,w=this._counter;y&&(w=this._counter=y.slice(0),this._iv=void 0),f(w);var P=w.slice(0);m.encryptBlock(P,0);for(var D=0;D<v;D++)h[g+D]^=P[D]}});return l.Decryptor=p,l})(),o.mode.CTRGladman})})(dc)),dc.exports}var fc={exports:{}},Yb=fc.exports,zm;function Xb(){return zm||(zm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(Yb,function(o){return o.mode.OFB=(function(){var l=o.lib.BlockCipherMode.extend(),d=l.Encryptor=l.extend({processBlock:function(f,p){var h=this._cipher,g=h.blockSize,m=this._iv,v=this._keystream;m&&(v=this._keystream=m.slice(0),this._iv=void 0),h.encryptBlock(v,0);for(var y=0;y<g;y++)f[p+y]^=v[y]}});return l.Decryptor=d,l})(),o.mode.OFB})})(fc)),fc.exports}var hc={exports:{}},Jb=hc.exports,Hm;function eC(){return Hm||(Hm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(Jb,function(o){return o.mode.ECB=(function(){var l=o.lib.BlockCipherMode.extend();return l.Encryptor=l.extend({processBlock:function(d,f){this._cipher.encryptBlock(d,f)}}),l.Decryptor=l.extend({processBlock:function(d,f){this._cipher.decryptBlock(d,f)}}),l})(),o.mode.ECB})})(hc)),hc.exports}var pc={exports:{}},tC=pc.exports,Vm;function nC(){return Vm||(Vm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(tC,function(o){return o.pad.AnsiX923={pad:function(l,d){var f=l.sigBytes,p=d*4,h=p-f%p,g=f+h-1;l.clamp(),l.words[g>>>2]|=h<<24-g%4*8,l.sigBytes+=h},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Ansix923})})(pc)),pc.exports}var mc={exports:{}},rC=mc.exports,Um;function iC(){return Um||(Um=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(rC,function(o){return o.pad.Iso10126={pad:function(l,d){var f=d*4,p=f-l.sigBytes%f;l.concat(o.lib.WordArray.random(p-1)).concat(o.lib.WordArray.create([p<<24],1))},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Iso10126})})(mc)),mc.exports}var gc={exports:{}},oC=gc.exports,Zm;function sC(){return Zm||(Zm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(oC,function(o){return o.pad.Iso97971={pad:function(l,d){l.concat(o.lib.WordArray.create([2147483648],1)),o.pad.ZeroPadding.pad(l,d)},unpad:function(l){o.pad.ZeroPadding.unpad(l),l.sigBytes--}},o.pad.Iso97971})})(gc)),gc.exports}var Ac={exports:{}},aC=Ac.exports,Wm;function lC(){return Wm||(Wm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(aC,function(o){return o.pad.ZeroPadding={pad:function(l,d){var f=d*4;l.clamp(),l.sigBytes+=f-(l.sigBytes%f||f)},unpad:function(l){for(var d=l.words,f=l.sigBytes-1,f=l.sigBytes-1;f>=0;f--)if(d[f>>>2]>>>24-f%4*8&255){l.sigBytes=f+1;break}}},o.pad.ZeroPadding})})(Ac)),Ac.exports}var xc={exports:{}},uC=xc.exports,qm;function cC(){return qm||(qm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(uC,function(o){return o.pad.NoPadding={pad:function(){},unpad:function(){}},o.pad.NoPadding})})(xc)),xc.exports}var vc={exports:{}},dC=vc.exports,Gm;function fC(){return Gm||(Gm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(dC,function(o){return(function(l){var d=o,f=d.lib,p=f.CipherParams,h=d.enc,g=h.Hex,m=d.format;m.Hex={stringify:function(v){return v.ciphertext.toString(g)},parse:function(v){var y=g.parse(v);return p.create({ciphertext:y})}}})(),o.format.Hex})})(vc)),vc.exports}var yc={exports:{}},hC=yc.exports,Km;function pC(){return Km||(Km=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),Xo(),Jo(),fo(),mn())})(hC,function(o){return(function(){var l=o,d=l.lib,f=d.BlockCipher,p=l.algo,h=[],g=[],m=[],v=[],y=[],w=[],P=[],D=[],C=[],k=[];(function(){for(var S=[],N=0;N<256;N++)N<128?S[N]=N<<1:S[N]=N<<1^283;for(var I=0,H=0,N=0;N<256;N++){var z=H^H<<1^H<<2^H<<3^H<<4;z=z>>>8^z&255^99,h[I]=z,g[z]=I;var j=S[I],J=S[j],W=S[J],U=S[z]*257^z*16843008;m[I]=U<<24|U>>>8,v[I]=U<<16|U>>>16,y[I]=U<<8|U>>>24,w[I]=U;var U=W*16843009^J*65537^j*257^I*16843008;P[z]=U<<24|U>>>8,D[z]=U<<16|U>>>16,C[z]=U<<8|U>>>24,k[z]=U,I?(I=j^S[S[S[W^j]]],H^=S[S[H]]):I=H=1}})();var R=[0,1,2,4,8,16,32,64,128,27,54],T=p.AES=f.extend({_doReset:function(){var S;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var N=this._keyPriorReset=this._key,I=N.words,H=N.sigBytes/4,z=this._nRounds=H+6,j=(z+1)*4,J=this._keySchedule=[],W=0;W<j;W++)W<H?J[W]=I[W]:(S=J[W-1],W%H?H>6&&W%H==4&&(S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255]):(S=S<<8|S>>>24,S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255],S^=R[W/H|0]<<24),J[W]=J[W-H]^S);for(var U=this._invKeySchedule=[],ne=0;ne<j;ne++){var W=j-ne;if(ne%4)var S=J[W];else var S=J[W-4];ne<4||W<=4?U[ne]=S:U[ne]=P[h[S>>>24]]^D[h[S>>>16&255]]^C[h[S>>>8&255]]^k[h[S&255]]}}},encryLine truncated
|
||||
*/return o.mode.CTRGladman=(function(){var l=o.lib.BlockCipherMode.extend();function d(h){if((h>>24&255)===255){var g=h>>16&255,m=h>>8&255,v=h&255;g===255?(g=0,m===255?(m=0,v===255?v=0:++v):++m):++g,h=0,h+=g<<16,h+=m<<8,h+=v}else h+=1<<24;return h}function f(h){return(h[0]=d(h[0]))===0&&(h[1]=d(h[1])),h}var p=l.Encryptor=l.extend({processBlock:function(h,g){var m=this._cipher,v=m.blockSize,y=this._iv,w=this._counter;y&&(w=this._counter=y.slice(0),this._iv=void 0),f(w);var T=w.slice(0);m.encryptBlock(T,0);for(var F=0;F<v;F++)h[g+F]^=T[F]}});return l.Decryptor=p,l})(),o.mode.CTRGladman})})(dc)),dc.exports}var fc={exports:{}},Xb=fc.exports,zm;function Jb(){return zm||(zm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(Xb,function(o){return o.mode.OFB=(function(){var l=o.lib.BlockCipherMode.extend(),d=l.Encryptor=l.extend({processBlock:function(f,p){var h=this._cipher,g=h.blockSize,m=this._iv,v=this._keystream;m&&(v=this._keystream=m.slice(0),this._iv=void 0),h.encryptBlock(v,0);for(var y=0;y<g;y++)f[p+y]^=v[y]}});return l.Decryptor=d,l})(),o.mode.OFB})})(fc)),fc.exports}var hc={exports:{}},eC=hc.exports,Hm;function tC(){return Hm||(Hm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(eC,function(o){return o.mode.ECB=(function(){var l=o.lib.BlockCipherMode.extend();return l.Encryptor=l.extend({processBlock:function(d,f){this._cipher.encryptBlock(d,f)}}),l.Decryptor=l.extend({processBlock:function(d,f){this._cipher.decryptBlock(d,f)}}),l})(),o.mode.ECB})})(hc)),hc.exports}var pc={exports:{}},nC=pc.exports,Vm;function rC(){return Vm||(Vm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(nC,function(o){return o.pad.AnsiX923={pad:function(l,d){var f=l.sigBytes,p=d*4,h=p-f%p,g=f+h-1;l.clamp(),l.words[g>>>2]|=h<<24-g%4*8,l.sigBytes+=h},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Ansix923})})(pc)),pc.exports}var mc={exports:{}},iC=mc.exports,Um;function oC(){return Um||(Um=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(iC,function(o){return o.pad.Iso10126={pad:function(l,d){var f=d*4,p=f-l.sigBytes%f;l.concat(o.lib.WordArray.random(p-1)).concat(o.lib.WordArray.create([p<<24],1))},unpad:function(l){var d=l.words[l.sigBytes-1>>>2]&255;l.sigBytes-=d}},o.pad.Iso10126})})(mc)),mc.exports}var gc={exports:{}},sC=gc.exports,Zm;function aC(){return Zm||(Zm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(sC,function(o){return o.pad.Iso97971={pad:function(l,d){l.concat(o.lib.WordArray.create([2147483648],1)),o.pad.ZeroPadding.pad(l,d)},unpad:function(l){o.pad.ZeroPadding.unpad(l),l.sigBytes--}},o.pad.Iso97971})})(gc)),gc.exports}var Ac={exports:{}},lC=Ac.exports,Wm;function uC(){return Wm||(Wm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(lC,function(o){return o.pad.ZeroPadding={pad:function(l,d){var f=d*4;l.clamp(),l.sigBytes+=f-(l.sigBytes%f||f)},unpad:function(l){for(var d=l.words,f=l.sigBytes-1,f=l.sigBytes-1;f>=0;f--)if(d[f>>>2]>>>24-f%4*8&255){l.sigBytes=f+1;break}}},o.pad.ZeroPadding})})(Ac)),Ac.exports}var xc={exports:{}},cC=xc.exports,qm;function dC(){return qm||(qm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(cC,function(o){return o.pad.NoPadding={pad:function(){},unpad:function(){}},o.pad.NoPadding})})(xc)),xc.exports}var vc={exports:{}},fC=vc.exports,Gm;function hC(){return Gm||(Gm=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),mn())})(fC,function(o){return(function(l){var d=o,f=d.lib,p=f.CipherParams,h=d.enc,g=h.Hex,m=d.format;m.Hex={stringify:function(v){return v.ciphertext.toString(g)},parse:function(v){var y=g.parse(v);return p.create({ciphertext:y})}}})(),o.format.Hex})})(vc)),vc.exports}var yc={exports:{}},pC=yc.exports,Km;function mC(){return Km||(Km=1,(function(r,a){(function(o,l,d){r.exports=l(mt(),Xo(),Jo(),fo(),mn())})(pC,function(o){return(function(){var l=o,d=l.lib,f=d.BlockCipher,p=l.algo,h=[],g=[],m=[],v=[],y=[],w=[],T=[],F=[],k=[],E=[];(function(){for(var S=[],N=0;N<256;N++)N<128?S[N]=N<<1:S[N]=N<<1^283;for(var M=0,z=0,N=0;N<256;N++){var H=z^z<<1^z<<2^z<<3^z<<4;H=H>>>8^H&255^99,h[M]=H,g[H]=M;var j=S[M],J=S[j],W=S[J],U=S[H]*257^H*16843008;m[M]=U<<24|U>>>8,v[M]=U<<16|U>>>16,y[M]=U<<8|U>>>24,w[M]=U;var U=W*16843009^J*65537^j*257^M*16843008;T[H]=U<<24|U>>>8,F[H]=U<<16|U>>>16,k[H]=U<<8|U>>>24,E[H]=U,M?(M=j^S[S[S[W^j]]],z^=S[S[z]]):M=z=1}})();var D=[0,1,2,4,8,16,32,64,128,27,54],B=p.AES=f.extend({_doReset:function(){var S;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var N=this._keyPriorReset=this._key,M=N.words,z=N.sigBytes/4,H=this._nRounds=z+6,j=(H+1)*4,J=this._keySchedule=[],W=0;W<j;W++)W<z?J[W]=M[W]:(S=J[W-1],W%z?z>6&&W%z==4&&(S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255]):(S=S<<8|S>>>24,S=h[S>>>24]<<24|h[S>>>16&255]<<16|h[S>>>8&255]<<8|h[S&255],S^=D[W/z|0]<<24),J[W]=J[W-z]^S);for(var U=this._invKeySchedule=[],ne=0;ne<j;ne++){var W=j-ne;if(ne%4)var S=J[W];else var S=J[W-4];ne<4||W<=4?U[ne]=S:U[ne]=T[h[S>>>24]]^F[h[S>>>16&255]]^k[h[S>>>8&255]]^E[h[S&255]]}}},encryLine truncated
|
||||
• Timestamp (4 bytes) - send time as unix timestamp
|
||||
• Request Type (1 byte) - type of request (GetStats, GetTelemetryData, etc.)
|
||||
• Request Data (remaining bytes) - additional request-specific data`,startByte:h+g,endByte:h+d.length-1,value:w});const P={type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w};return f!=null&&f.includeSegments&&(P.segments=p),P}catch(p){return{type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode request payload"],timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return Xa.RequestPayloadDecoder=o,Xa}var Ja={},Ag;function $C(){if(Ag)return Ja;Ag=1,Object.defineProperty(Ja,"__esModule",{value:!0}),Ja.ResponsePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const D={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(D.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),D}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+g,endByte:h+g,value:v}),g+=1;const y=(0,a.bytesToHex)(d.subarray(g,g+2));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(g));f!=null&&f.includeSegments&&d.length>g&&p.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:h+g,endByte:h+d.length-1,value:w});const P={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(P.segments=p),P}catch(p){return{type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return Ja.ResponsePayloadDecoder=o,Ja}var el={},xg;function YC(){if(xg)return el;xg=1,Object.defineProperty(el,"__esModule",{value:!0}),el.AnonRequestPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<35){const D={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(D.segments=[{name:"Invalid AnonRequest Data",description:"AnonRequest payload too short (minimum 35 bytes required: 1 for dest hash + 32 for public key + 2 for MAC)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),D}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[0]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${m}`,startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.bytesToHex)(d.subarray(1,33));f!=null&&f.includeSegments&&p.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:h+g,endByte:h+g+31,value:v}),g+=32;const y=(0,a.bytesToHex)(d.subarray(33,35));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(35));f!=null&&f.includeSegments&&d.length>35&&p.push({name:"Ciphertext",description:`Encrypted message data (${d.length-35} bytes). Contains encrypted plaintext with this structure:
|
||||
• Request Data (remaining bytes) - additional request-specific data`,startByte:h+g,endByte:h+d.length-1,value:w});const T={type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w};return f!=null&&f.includeSegments&&(T.segments=p),T}catch(p){return{type:r.PayloadType.Request,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode request payload"],timestamp:0,requestType:r.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return Xa.RequestPayloadDecoder=o,Xa}var Ja={},Ag;function YC(){if(Ag)return Ja;Ag=1,Object.defineProperty(Ja,"__esModule",{value:!0}),Ja.ResponsePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const F={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(F.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),F}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+g,endByte:h+g,value:v}),g+=1;const y=(0,a.bytesToHex)(d.subarray(g,g+2));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(g));f!=null&&f.includeSegments&&d.length>g&&p.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:h+g,endByte:h+d.length-1,value:w});const T={type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(T.segments=p),T}catch(p){return{type:r.PayloadType.Response,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return Ja.ResponsePayloadDecoder=o,Ja}var el={},xg;function XC(){if(xg)return el;xg=1,Object.defineProperty(el,"__esModule",{value:!0}),el.AnonRequestPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<35){const F={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(F.segments=[{name:"Invalid AnonRequest Data",description:"AnonRequest payload too short (minimum 35 bytes required: 1 for dest hash + 32 for public key + 2 for MAC)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),F}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[0]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${m}`,startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.bytesToHex)(d.subarray(1,33));f!=null&&f.includeSegments&&p.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:h+g,endByte:h+g+31,value:v}),g+=32;const y=(0,a.bytesToHex)(d.subarray(33,35));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(35));f!=null&&f.includeSegments&&d.length>35&&p.push({name:"Ciphertext",description:`Encrypted message data (${d.length-35} bytes). Contains encrypted plaintext with this structure:
|
||||
• Timestamp (4 bytes) - send time as unix timestamp
|
||||
• Sync Timestamp (4 bytes) - room server only, sender's "sync messages SINCE x" timestamp
|
||||
• Password (remaining bytes) - password for repeater/room`,startByte:h+g,endByte:h+d.length-1,value:w});const P={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,senderPublicKey:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-35};return f!=null&&f.includeSegments&&(P.segments=p),P}catch(p){return{type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return el.AnonRequestPayloadDecoder=o,el}var tl={},vg;function XC(){if(vg)return tl;vg=1,Object.defineProperty(tl,"__esModule",{value:!0}),tl.AckPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const v={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return f!=null&&f.includeSegments&&(v.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),v}const p=[],h=(f==null?void 0:f.segmentOffset)||0,g=(0,a.bytesToHex)(d.subarray(0,4));f!=null&&f.includeSegments&&p.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${g}`,startByte:h,endByte:h+3,value:g}),f!=null&&f.includeSegments&&d.length>4&&p.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:h+4,endByte:h+d.length-1,value:(0,a.bytesToHex)(d.subarray(4))});const m={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!0,checksum:g};return f!=null&&f.includeSegments&&(m.segments=p),m}catch(p){return{type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode Ack payload"],checksum:""}}}}return tl.AckPayloadDecoder=o,tl}var nl={},yg;function JC(){if(yg)return nl;yg=1,Object.defineProperty(nl,"__esModule",{value:!0}),nl.PathPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d){try{if(d.length<2)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const f=d[0];if(d.length<1+f+1)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+f+1} bytes for path length + path + extra type)`],pathLength:f,pathHashes:[],extraType:0,extraData:""};const p=[];for(let m=0;m<f;m++)p.push((0,a.byteToHex)(d[1+m]));const h=d[1+f];let g="";return d.length>1+f+1&&(g=(0,a.bytesToHex)(d.subarray(1+f+1))),{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!0,pathLength:f,pathHashes:p,extraType:h,extraData:g}}catch(f){return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[f instanceof Error?f.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return nl.PathPayloadDecoder=o,nl}var rl={},_g;function eE(){if(_g)return rl;_g=1,Object.defineProperty(rl,"__esModule",{value:!0}),rl.TextMessagePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const D={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(D.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),D}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+g,endByte:h+g,value:v}),g+=1;const y=(0,a.bytesToHex)(d.subarray(g,g+2));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(g));f!=null&&f.includeSegments&&d.length>g&&p.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:h+g,endByte:h+d.length-1,value:w});const P={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(P.segments=p),P}catch(p){return{type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,i
Line truncated
|
||||
• Password (remaining bytes) - password for repeater/room`,startByte:h+g,endByte:h+d.length-1,value:w});const T={type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,senderPublicKey:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-35};return f!=null&&f.includeSegments&&(T.segments=p),T}catch(p){return{type:r.PayloadType.AnonRequest,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return el.AnonRequestPayloadDecoder=o,el}var tl={},vg;function JC(){if(vg)return tl;vg=1,Object.defineProperty(tl,"__esModule",{value:!0}),tl.AckPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const v={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return f!=null&&f.includeSegments&&(v.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),v}const p=[],h=(f==null?void 0:f.segmentOffset)||0,g=(0,a.bytesToHex)(d.subarray(0,4));f!=null&&f.includeSegments&&p.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${g}`,startByte:h,endByte:h+3,value:g}),f!=null&&f.includeSegments&&d.length>4&&p.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:h+4,endByte:h+d.length-1,value:(0,a.bytesToHex)(d.subarray(4))});const m={type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!0,checksum:g};return f!=null&&f.includeSegments&&(m.segments=p),m}catch(p){return{type:r.PayloadType.Ack,version:r.PayloadVersion.Version1,isValid:!1,errors:[p instanceof Error?p.message:"Failed to decode Ack payload"],checksum:""}}}}return tl.AckPayloadDecoder=o,tl}var nl={},yg;function eE(){if(yg)return nl;yg=1,Object.defineProperty(nl,"__esModule",{value:!0}),nl.PathPayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d){try{if(d.length<2)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const f=d[0];if(d.length<1+f+1)return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+f+1} bytes for path length + path + extra type)`],pathLength:f,pathHashes:[],extraType:0,extraData:""};const p=[];for(let m=0;m<f;m++)p.push((0,a.byteToHex)(d[1+m]));const h=d[1+f];let g="";return d.length>1+f+1&&(g=(0,a.bytesToHex)(d.subarray(1+f+1))),{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!0,pathLength:f,pathHashes:p,extraType:h,extraData:g}}catch(f){return{type:r.PayloadType.Path,version:r.PayloadVersion.Version1,isValid:!1,errors:[f instanceof Error?f.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return nl.PathPayloadDecoder=o,nl}var rl={},_g;function tE(){if(_g)return rl;_g=1,Object.defineProperty(rl,"__esModule",{value:!0}),rl.TextMessagePayloadDecoder=void 0;const r=sr(),a=vn();class o{static decode(d,f){try{if(d.length<4){const F={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return f!=null&&f.includeSegments&&(F.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:f.segmentOffset||0,endByte:(f.segmentOffset||0)+d.length-1,value:(0,a.bytesToHex)(d)}]),F}const p=[],h=(f==null?void 0:f.segmentOffset)||0;let g=0;const m=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:h+g,endByte:h+g,value:m}),g+=1;const v=(0,a.byteToHex)(d[g]);f!=null&&f.includeSegments&&p.push({name:"Source Hash",description:"First byte of source node public key",startByte:h+g,endByte:h+g,value:v}),g+=1;const y=(0,a.bytesToHex)(d.subarray(g,g+2));f!=null&&f.includeSegments&&p.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:h+g,endByte:h+g+1,value:y}),g+=2;const w=(0,a.bytesToHex)(d.subarray(g));f!=null&&f.includeSegments&&d.length>g&&p.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:h+g,endByte:h+d.length-1,value:w});const T={type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,isValid:!0,destinationHash:m,sourceHash:v,cipherMac:y,ciphertext:w,ciphertextLength:d.length-4};return f!=null&&f.includeSegments&&(T.segments=p),T}catch(p){return{type:r.PayloadType.TextMessage,version:r.PayloadVersion.Version1,i
Line truncated
|
||||
// SHA256 round constants
|
||||
const K: array<u32, 64> = array<u32, 64>(
|
||||
0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u,
|
||||
@@ -531,12 +531,12 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
|
||||
process_candidate(name_idx);
|
||||
}
|
||||
}
|
||||
`}async init(){if(!navigator.gpu)return console.warn("WebGPU not supported"),!1;try{const a=await navigator.gpu.requestAdapter();if(!a)return console.warn("No GPU adapter found"),!1;this.device=await a.requestDevice(),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}}]}),this.paramsBuffer=this.device.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.matchCountBuffer=this.device.createBuffer({size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST}),this.matchIndicesBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC});for(let d=0;d<2;d++)this.matchCountReadBuffers[d]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[d]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const o=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:o,entryPoint:"main"}}),!0}catch(a){return console.error("WebGPU initialization failed:",a),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(a,o){return Go(o,a)}countNamesForLength(a){return sl(a)}async runBatch(a,o,l,d,f,p){if(!this.device||!this.pipeline||!this.bindGroupLayout||!this.paramsBuffer||!this.matchCountBuffer||!this.matchIndicesBuffer||!this.matchCountReadBuffers[0]||!this.matchCountReadBuffers[1]||!this.matchIndicesReadBuffers[0]||!this.matchIndicesReadBuffers[1])throw new Error("GPU not initialized");const h=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const g=this.matchCountReadBuffers[h],m=this.matchIndicesReadBuffers[h],v=f&&p?1:0;let y,w=0,P=0;if(v){const I=new Uint8Array(f.length/2);for(let W=0;W<I.length;W++)I[W]=parseInt(f.substr(W*2,2),16);w=I.length*8;const H=Math.ceil(I.length/4)*4,z=new Uint8Array(H);z.set(I),y=new Uint32Array(H/4);for(let W=0;W<y.length;W++)y[W]=z[W*4]<<24|z[W*4+1]<<16|z[W*4+2]<<8|z[W*4+3];const j=parseInt(p.substr(0,2),16),J=parseInt(p.substr(2,2),16);P=j<<24|J<<16}else y=new Uint32Array([0]);const D=Math.max(y.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<D)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:D,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=D,this.bindGroupDirty=!0);const C=new Uint32Array([a,l,o,d,P,y.length,w,v]);this.device.queue.writeBuffer(this.paramsBuffer,0,C),this.device.queue.writeBuffer(this.ciphertextBuffer,0,y),this.device.queue.writeBuffer(this.matchCountBuffer,0,id.ZERO_DATA),(this.bindGroupDirty||!this.bindGroup)&&(this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.paramsBuffer}},{binding:1,resource:{buffer:this.matchCountBuffer}},{binding:2,resource:{buffer:this.matchIndicesBuffer}},{binding:3,resource:{buffer:this.ciphertextBuffer}}]}),this.bindGroupDirty=!1);const k=this.device.createCommandEncoder(),R=k.beginComputePass();R.setPipeline(this.pipeline),R.setBindGroup(0,this.bindGroup),R.dispatchWorkgroups(Math.ceil(d/(256*32))),R.end(),k.copyBufferToBuffer(this.matchCountBuffer,0,g,0,4),k.copyBufferToBuffer(this.matchIndicesBuffer,0,m,0,1024*4),this.device.queue.submit([k.finish()]),await g.mapAsync(GPUMapMode.READ);const S=new Uint32Array(g.getMappedRange())[0];g.unmap();const N=[];if(S>0){await m.mapAsync(GPUMapMode.READ);const I=new Uint32Array(m.getMappedRange());for(let H=0;H<Math.min(S,1024);H++)N.push(I[H]);m.unmap()}return N}destroy(){var a,o,l,d,f,p,h,g;(a=this.paramsBuffer)==null||a.destroy(),(o=this.matchCountBuffer)==null||o.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(d=this.ciphertextBuffer)==null||d.destroy(),(f=this.matchCountReadBuffers[0])==null||f.destroy(),(p=this.matchCountReadBuffers[1])==null||p.destroy(),(h=this.matchIndicesReadBuffers[0])==null||h.destroy(),(g=this.matchIndicesReadBuffers[1])==null||g.destroy(),this.paramsBuffer=null,this.matchCountBuffer=null,this.matchIndicesBuffer=null,this.ciphertextBuffer=null,this.ciphertextBufferSize=0,this.matchCountReadBuffers=[null,null],this.matchIndicesReadBuffers=[null,null],this.currentReadBufferIndex=0,this.bindGroup=null,this.bindGroupDirty=!0,this.device&&(this.device.destroy(),this.device=null),this.pipeline=null,this.bindGroupLayout=null}}id.ZERO_DATA=new Uint32Array([0]);function pE(){return typeof navigator<"u"&&"gpu"in navigator}class Dg{runBatch(a,o,l,d,f,p){const h=[],g=a.toString(16).padStart(2,"0")
Line truncated
|
||||
`).map(f=>f.trim().toLowerCase()).filter(f=>f.length>0);this.wordlist=d.filter(Rg)}setWordlist(a){this.wordlist=a.map(o=>o.trim().toLowerCase()).filter(Rg)}abort(){this.abortFlag=!0}isGpuAvailable(){return pE()}async decodePacket(a){var l;const o=a.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!o||!/^[0-9a-fA-F]+$/.test(o))return null;try{const f=(l=(await Bg.MeshCorePacketDecoder.decodeWithVerification(o,{})).payload)==null?void 0:l.decoded;return!(f!=null&&f.channelHash)||!(f!=null&&f.ciphertext)||!(f!=null&&f.cipherMac)?null:{channelHash:f.channelHash,ciphertext:f.ciphertext,cipherMac:f.cipherMac,isGroupText:!0}}catch{return null}}async crack(a,o,l){this.abortFlag=!1,this.useTimestampFilter=(o==null?void 0:o.useTimestampFilter)??!0,this.useUtf8Filter=(o==null?void 0:o.useUtf8Filter)??!0,this.useSenderFilter=(o==null?void 0:o.useSenderFilter)??!0,this.validSeconds=(o==null?void 0:o.validSeconds)??c0,this.useCpu=(o==null?void 0:o.forceCpu)??!1;const d=(o==null?void 0:o.maxLength)??8,f=(o==null?void 0:o.startingLength)??1,p=(o==null?void 0:o.useDictionary)??!0,h=(o==null?void 0:o.startFromType)??"bruteforce",g=a.toLowerCase(),m=await this.decodePacket(g);if(!m)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:v,ciphertext:y,cipherMac:w}=m,P=parseInt(v,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new Dg):this.gpuInstance||(this.gpuInstance=new id,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new Dg));const D=performance.now();let C=0,k=performance.now(),R=f,T=0,S=0,N=!1;if(o!=null&&o.startFrom){const Y=o.startFrom.toLowerCase();if(h==="dictionary"){const re=this.wordlist.indexOf(Y);re>=0&&(S=re+1)}else{N=!0;const re=dE(Y);re&&(R=Math.max(f,re.length),T=re.index+1,T>=sl(R)&&(R++,T=0))}}let I=0;p&&!N&&this.wordlist.length>0&&(I+=this.wordlist.length-S);for(let Y=R;Y<=d;Y++)I+=sl(Y);I-=T;const H=(Y,re,fe)=>{if(!l)return;const he=(performance.now()-D)/1e3,G=he>0?Math.round(C/he):0,me=I-C,Z=G>0?me/G:0;l({checked:C,total:I,percent:I>0?Math.min(100,C/I*100):0,rateKeysPerSec:G,etaSeconds:Z,elapsedSeconds:he,currentLength:re,currentPosition:fe,phase:Y})},z=Y=>{if(!Wx(y,w,Y))return{valid:!1};const re=Bg.ChannelCrypto.decryptGroupTextMessage(y,w,Y);return!re.success||!re.data?{valid:!1}:this.useTimestampFilter&&!fE(re.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!hE(re.data.message)?{valid:!1}:this.useSenderFilter&&!re.data.sender?{valid:!1}:{valid:!0,message:re.data.sender?`${re.data.sender}: ${re.data.message}`:re.data.message}};if(!N&&S===0&&R===f&&T===0){H("public-key",0,u0);const Y=f0(Pc);if(v===Y){const re=z(Pc);if(re.valid)return{found:!0,roomName:u0,key:Pc,decryptedMessage:re.message}}}if(p&&!N&&this.wordlist.length>0)for(let Y=S;Y<this.wordlist.length;Y++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:this.wordlist[Y],resumeType:"dictionary"};const re=this.wordlist[Y],fe=d0("#"+re),ae=f0(fe);if(parseInt(ae,16)===P){const G=z(fe);if(G.valid)return{found:!0,roomName:re,key:fe,decryptedMessage:G.message,resumeFrom:re,resumeType:"dictionary"}}C++;const he=performance.now();he-k>=200&&(H("wordlist",re.length,re),k=he,await new Promise(G=>setTimeout(G,0)))}const j=this.useCpu?1024:32768,J=(o==null?void 0:o.gpuDispatchMs)??1e3;let W=j,U=!1;for(let Y=R;Y<=d;Y++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:Go(Y,0)||void 0,resumeType:"bruteforce"};const re=sl(Y);let fe=Y===R?T:0;for(;fe<re;){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:Go(Y,fe)||void 0,resumeType:"bruteforce"};const ae=Math.min(W,re-fe),he=performance.now();let G;this.useCpu?G=this.cpuInstance.runBatch(P,Y,fe,ae,y,w):G=await this.gpuInstance.runBatch(P,Y,fe,ae,y,w);const me=performance.now()-he;if(C+=ae,!this.useCpu&&!U&&ae>=j&&me>0){const B=J/me,V=Math.round(ae*B),K=Math.pow(2,Math.round(Math.log2(Math.max(j,V))));W=Math.max(j,K),U=!0}for(const B of G){const V=Go(Y,B);if(!V)continue;const K=d0("#"+V),$=z(K);if($.valid)return{found:!0,roomName:V,key:K,decryptedMessage:$.message,resumeFrom:V,resumeType:"bruteforce"}}fe+=ae;const Z=performance.now();if(Z-k>=200){const B=Go(Y,Math.min(fe,re-1))||"";H("bruteforce",Y,B),k=Z,await new Promise(V=>setTimeout(V,0))}}}return{found:!1,resumeFrom:Go(d,sl(d)-1)||void 0,resumeType:"bruteforce"}}destroy(){this.gpuInstance&&(this.gpuInstance.destroy(),this.gpuInstance=null),this.cpuInstance&&(this.cpuInstance.destroy(),this.cpuInstance=null)}}var Qf,Fg;function vE(){return Fg||(Fg=1,Qf={webm:"data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4EEQoWBAhhTgGcBAAAAAAAVkhFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsghV17AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUq17GDD0JATYCNTGF2ZjU1LjMzLjEwMFdBjUxhdmY1NS4zMy4xMDBzpJBlrrXf3DCDVB8KcgbMpcr+RImIQJBgAAAAAAAWVK5rAQAAAAAAD++uAQAA
Line truncated
|
||||
`}async init(){if(!navigator.gpu)return console.warn("WebGPU not supported"),!1;try{const a=await navigator.gpu.requestAdapter();if(!a)return console.warn("No GPU adapter found"),!1;this.device=await a.requestDevice(),this.bindGroupLayout=this.device.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{type:"storage"}},{binding:3,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}}]}),this.paramsBuffer=this.device.createBuffer({size:32,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.matchCountBuffer=this.device.createBuffer({size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST}),this.matchIndicesBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC});for(let d=0;d<2;d++)this.matchCountReadBuffers[d]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[d]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const o=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:o,entryPoint:"main"}}),!0}catch(a){return console.error("WebGPU initialization failed:",a),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(a,o){return Go(o,a)}countNamesForLength(a){return sl(a)}async runBatch(a,o,l,d,f,p){if(!this.device||!this.pipeline||!this.bindGroupLayout||!this.paramsBuffer||!this.matchCountBuffer||!this.matchIndicesBuffer||!this.matchCountReadBuffers[0]||!this.matchCountReadBuffers[1]||!this.matchIndicesReadBuffers[0]||!this.matchIndicesReadBuffers[1])throw new Error("GPU not initialized");const h=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const g=this.matchCountReadBuffers[h],m=this.matchIndicesReadBuffers[h],v=f&&p?1:0;let y,w=0,T=0;if(v){const M=new Uint8Array(f.length/2);for(let W=0;W<M.length;W++)M[W]=parseInt(f.substr(W*2,2),16);w=M.length*8;const z=Math.ceil(M.length/4)*4,H=new Uint8Array(z);H.set(M),y=new Uint32Array(z/4);for(let W=0;W<y.length;W++)y[W]=H[W*4]<<24|H[W*4+1]<<16|H[W*4+2]<<8|H[W*4+3];const j=parseInt(p.substr(0,2),16),J=parseInt(p.substr(2,2),16);T=j<<24|J<<16}else y=new Uint32Array([0]);const F=Math.max(y.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<F)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:F,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=F,this.bindGroupDirty=!0);const k=new Uint32Array([a,l,o,d,T,y.length,w,v]);this.device.queue.writeBuffer(this.paramsBuffer,0,k),this.device.queue.writeBuffer(this.ciphertextBuffer,0,y),this.device.queue.writeBuffer(this.matchCountBuffer,0,id.ZERO_DATA),(this.bindGroupDirty||!this.bindGroup)&&(this.bindGroup=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.paramsBuffer}},{binding:1,resource:{buffer:this.matchCountBuffer}},{binding:2,resource:{buffer:this.matchIndicesBuffer}},{binding:3,resource:{buffer:this.ciphertextBuffer}}]}),this.bindGroupDirty=!1);const E=this.device.createCommandEncoder(),D=E.beginComputePass();D.setPipeline(this.pipeline),D.setBindGroup(0,this.bindGroup),D.dispatchWorkgroups(Math.ceil(d/(256*32))),D.end(),E.copyBufferToBuffer(this.matchCountBuffer,0,g,0,4),E.copyBufferToBuffer(this.matchIndicesBuffer,0,m,0,1024*4),this.device.queue.submit([E.finish()]),await g.mapAsync(GPUMapMode.READ);const S=new Uint32Array(g.getMappedRange())[0];g.unmap();const N=[];if(S>0){await m.mapAsync(GPUMapMode.READ);const M=new Uint32Array(m.getMappedRange());for(let z=0;z<Math.min(S,1024);z++)N.push(M[z]);m.unmap()}return N}destroy(){var a,o,l,d,f,p,h,g;(a=this.paramsBuffer)==null||a.destroy(),(o=this.matchCountBuffer)==null||o.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(d=this.ciphertextBuffer)==null||d.destroy(),(f=this.matchCountReadBuffers[0])==null||f.destroy(),(p=this.matchCountReadBuffers[1])==null||p.destroy(),(h=this.matchIndicesReadBuffers[0])==null||h.destroy(),(g=this.matchIndicesReadBuffers[1])==null||g.destroy(),this.paramsBuffer=null,this.matchCountBuffer=null,this.matchIndicesBuffer=null,this.ciphertextBuffer=null,this.ciphertextBufferSize=0,this.matchCountReadBuffers=[null,null],this.matchIndicesReadBuffers=[null,null],this.currentReadBufferIndex=0,this.bindGroup=null,this.bindGroupDirty=!0,this.device&&(this.device.destroy(),this.device=null),this.pipeline=null,this.bindGroupLayout=null}}id.ZERO_DATA=new Uint32Array([0]);function mE(){return typeof navigator<"u"&&"gpu"in navigator}class Dg{runBatch(a,o,l,d,f,p){const h=[],g=a.toString(16).padStart(2,"0")
Line truncated
|
||||
`).map(f=>f.trim().toLowerCase()).filter(f=>f.length>0);this.wordlist=d.filter(Rg)}setWordlist(a){this.wordlist=a.map(o=>o.trim().toLowerCase()).filter(Rg)}abort(){this.abortFlag=!0}isGpuAvailable(){return mE()}async decodePacket(a){var l;const o=a.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!o||!/^[0-9a-fA-F]+$/.test(o))return null;try{const f=(l=(await Bg.MeshCorePacketDecoder.decodeWithVerification(o,{})).payload)==null?void 0:l.decoded;return!(f!=null&&f.channelHash)||!(f!=null&&f.ciphertext)||!(f!=null&&f.cipherMac)?null:{channelHash:f.channelHash,ciphertext:f.ciphertext,cipherMac:f.cipherMac,isGroupText:!0}}catch{return null}}async crack(a,o,l){this.abortFlag=!1,this.useTimestampFilter=(o==null?void 0:o.useTimestampFilter)??!0,this.useUtf8Filter=(o==null?void 0:o.useUtf8Filter)??!0,this.useSenderFilter=(o==null?void 0:o.useSenderFilter)??!0,this.validSeconds=(o==null?void 0:o.validSeconds)??c0,this.useCpu=(o==null?void 0:o.forceCpu)??!1;const d=(o==null?void 0:o.maxLength)??8,f=(o==null?void 0:o.startingLength)??1,p=(o==null?void 0:o.useDictionary)??!0,h=(o==null?void 0:o.startFromType)??"bruteforce",g=a.toLowerCase(),m=await this.decodePacket(g);if(!m)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:v,ciphertext:y,cipherMac:w}=m,T=parseInt(v,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new Dg):this.gpuInstance||(this.gpuInstance=new id,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new Dg));const F=performance.now();let k=0,E=performance.now(),D=f,B=0,S=0,N=!1;if(o!=null&&o.startFrom){const Y=o.startFrom.toLowerCase();if(h==="dictionary"){const re=this.wordlist.indexOf(Y);re>=0&&(S=re+1)}else{N=!0;const re=fE(Y);re&&(D=Math.max(f,re.length),B=re.index+1,B>=sl(D)&&(D++,B=0))}}let M=0;p&&!N&&this.wordlist.length>0&&(M+=this.wordlist.length-S);for(let Y=D;Y<=d;Y++)M+=sl(Y);M-=B;const z=(Y,re,fe)=>{if(!l)return;const he=(performance.now()-F)/1e3,G=he>0?Math.round(k/he):0,pe=M-k,Z=G>0?pe/G:0;l({checked:k,total:M,percent:M>0?Math.min(100,k/M*100):0,rateKeysPerSec:G,etaSeconds:Z,elapsedSeconds:he,currentLength:re,currentPosition:fe,phase:Y})},H=Y=>{if(!Wx(y,w,Y))return{valid:!1};const re=Bg.ChannelCrypto.decryptGroupTextMessage(y,w,Y);return!re.success||!re.data?{valid:!1}:this.useTimestampFilter&&!hE(re.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!pE(re.data.message)?{valid:!1}:this.useSenderFilter&&!re.data.sender?{valid:!1}:{valid:!0,message:re.data.sender?`${re.data.sender}: ${re.data.message}`:re.data.message}};if(!N&&S===0&&D===f&&B===0){z("public-key",0,u0);const Y=f0(Pc);if(v===Y){const re=H(Pc);if(re.valid)return{found:!0,roomName:u0,key:Pc,decryptedMessage:re.message}}}if(p&&!N&&this.wordlist.length>0)for(let Y=S;Y<this.wordlist.length;Y++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:this.wordlist[Y],resumeType:"dictionary"};const re=this.wordlist[Y],fe=d0("#"+re),ae=f0(fe);if(parseInt(ae,16)===T){const G=H(fe);if(G.valid)return{found:!0,roomName:re,key:fe,decryptedMessage:G.message,resumeFrom:re,resumeType:"dictionary"}}k++;const he=performance.now();he-E>=200&&(z("wordlist",re.length,re),E=he,await new Promise(G=>setTimeout(G,0)))}const j=this.useCpu?1024:32768,J=(o==null?void 0:o.gpuDispatchMs)??1e3;let W=j,U=!1;for(let Y=D;Y<=d;Y++){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:Go(Y,0)||void 0,resumeType:"bruteforce"};const re=sl(Y);let fe=Y===D?B:0;for(;fe<re;){if(this.abortFlag)return{found:!1,aborted:!0,resumeFrom:Go(Y,fe)||void 0,resumeType:"bruteforce"};const ae=Math.min(W,re-fe),he=performance.now();let G;this.useCpu?G=this.cpuInstance.runBatch(T,Y,fe,ae,y,w):G=await this.gpuInstance.runBatch(T,Y,fe,ae,y,w);const pe=performance.now()-he;if(k+=ae,!this.useCpu&&!U&&ae>=j&&pe>0){const P=J/pe,V=Math.round(ae*P),K=Math.pow(2,Math.round(Math.log2(Math.max(j,V))));W=Math.max(j,K),U=!0}for(const P of G){const V=Go(Y,P);if(!V)continue;const K=d0("#"+V),$=H(K);if($.valid)return{found:!0,roomName:V,key:K,decryptedMessage:$.message,resumeFrom:V,resumeType:"bruteforce"}}fe+=ae;const Z=performance.now();if(Z-E>=200){const P=Go(Y,Math.min(fe,re-1))||"";z("bruteforce",Y,P),E=Z,await new Promise(V=>setTimeout(V,0))}}}return{found:!1,resumeFrom:Go(d,sl(d)-1)||void 0,resumeType:"bruteforce"}}destroy(){this.gpuInstance&&(this.gpuInstance.destroy(),this.gpuInstance=null),this.cpuInstance&&(this.cpuInstance.destroy(),this.cpuInstance=null)}}var Qf,Fg;function yE(){return Fg||(Fg=1,Qf={webm:"data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch4EEQoWBAhhTgGcBAAAAAAAVkhFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEwTbuMU6uEHFO7a1OsghV17AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEUq17GDD0JATYCNTGF2ZjU1LjMzLjEwMFdBjUxhdmY1NS4zMy4xMDBzpJBlrrXf3DCDVB8KcgbMpcr+RImIQJBgAAAAAAAWVK5rAQAAAAAAD++uAQAA
Line truncated
|
||||
NoSleep enabled for older iOS devices. This can interrupt
|
||||
active or long-running network requests from completing successfully.
|
||||
See https://github.com/richtr/NoSleep.js/issues/15 for more details.
|
||||
`),this.noSleepTimer=window.setInterval(()=>{document.hidden||(window.location.href=window.location.href.split("#")[0],window.setTimeout(window.stop,0))},15e3),this.enabled=!0,Promise.resolve()):this.noSleepVideo.play().then(h=>(this.enabled=!0,h)).catch(h=>{throw this.enabled=!1,h})}disable(){l()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):o()?this.noSleepTimer&&(console.warn(`
|
||||
NoSleep now disabled for older iOS devices.
|
||||
`),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}}return $f=d,$f}var _E=yE();const wE=Ys(_E);function bE(r){if(r.length<4)return null;try{const o=parseInt(r.slice(0,2),16)&3;let l=2;if(o===0||o===3){if(r.length<l+8)return null;l+=8}if(r.length<l+2)return null;const d=parseInt(r.slice(l,l+2),16);l+=2;const f=d*2;return r.length<l+f?null:(l+=f,r.slice(l))}catch{return null}}function CE({packets:r,channels:a,onChannelCreate:o,onRunningChange:l,visible:d=!1}){const[f,p]=F.useState(!1),[h,g]=F.useState(6),[m,v]=F.useState(!1),[y,w]=F.useState(!0),[P,D]=F.useState(!1),[C,k]=F.useState(null),[R,T]=F.useState(new Map),[S,N]=F.useState([]),[I,H]=F.useState(!1),[z,j]=F.useState(null),[J,W]=F.useState(null),[U,ne]=F.useState(0),Y=F.useRef(null),re=F.useRef(null),fe=F.useRef(!1),ae=F.useRef(!1),he=F.useRef(!1),G=F.useRef(new Map),me=F.useRef(!1),Z=F.useRef(6),B=F.useRef(!0),V=F.useRef(!1),K=F.useRef(new Set),$=F.useRef(new Set);F.useEffect(()=>{const Be=new xE;Y.current=Be,j(Be.isGpuAvailable());const Ze=new wE;return re.current=Ze,()=>{Be.destroy(),Y.current=null,Ze.disable(),re.current=null}},[]),F.useEffect(()=>{!d||I||gb(async()=>{const{ENGLISH_WORDLIST:Be}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:Be}},[]).then(({ENGLISH_WORDLIST:Be})=>{Y.current&&(Y.current.setWordlist(Be),H(!0))}).catch(Be=>{console.error("Failed to load wordlist:",Be),xt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[d,I]),F.useEffect(()=>{const Be=()=>{et.getUndecryptedPacketCount().then(({count:dt})=>W(dt)).catch(()=>W(null))};Be();const Ze=setInterval(Be,3e4);return()=>clearInterval(Ze)},[]);const ce=F.useMemo(()=>new Set(a.map(Be=>Be.key.toUpperCase())),[a]),de=r.filter(Be=>Be.payload_type==="GROUP_TEXT"&&!Be.decrypted);F.useEffect(()=>{let Be=0;T(Ze=>{const dt=new Map(Ze);let Mt=!1;for(const at of de)if(!dt.has(at.id)){const gt=bE(at.data);if(gt&&$.current.has(gt)){Be++;continue}gt&&$.current.add(gt),dt.set(at.id,{packet:at,attempts:0,lastAttemptLength:0,status:"pending"}),Mt=!0}return Mt?(G.current=dt,dt):Ze}),Be>0&&ne(Ze=>Ze+Be)},[de.length]),F.useEffect(()=>{G.current=R},[R]),F.useEffect(()=>{me.current=m},[m]),F.useEffect(()=>{Z.current=h},[h]),F.useEffect(()=>{B.current=y},[y]),F.useEffect(()=>{V.current=P},[P]),F.useEffect(()=>{K.current=new Set(de.map(Be=>Be.id))},[de]),F.useEffect(()=>{l==null||l(f)},[f,l]);const Se=Array.from(R.values()).filter(Be=>Be.status==="pending").length,Ae=Array.from(R.values()).filter(Be=>Be.status==="cracked").length,Ue=Array.from(R.values()).filter(Be=>Be.status==="failed").length,Ye=F.useCallback(async()=>{if(he.current||!Y.current||!fe.current)return;const Be=G.current;let Ze=null,dt=null;for(const[qe,tt]of Be.entries())if(tt.status==="pending"){Ze=tt,dt=qe;break}if(!Ze&&me.current){const qe=Array.from(Be.entries()).filter(([,tt])=>tt.status==="failed"&&tt.lastAttemptLength<10);qe.length>0&&(qe.sort((tt,nt)=>tt[1].lastAttemptLength-nt[1].lastAttemptLength),[dt,Ze]=qe[0])}if(!Ze||dt===null){fe.current&&setTimeout(()=>Ye(),1e3);return}if(!K.current.has(dt)){T(qe=>{const tt=new Map(qe);return tt.delete(dt),tt}),fe.current&&setTimeout(()=>Ye(),10);return}he.current=!0;const Mt=Z.current,at=Ze.lastAttemptLength>0,gt=at?Ze.lastAttemptLength+1:Mt;try{const qe=await Y.current.crack(Ze.packet.data,{maxLength:gt,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,...V.current&&{gpuDispatchMs:1e4},...at&&{useDictionary:!1,startingLength:gt}},tt=>{k(tt)});if(ae.current){ae.current=!1,he.current=!1,k(null);return}if(qe.found&&qe.roomName&&qe.key){T(He=>{const Ct=new Map(He),Ce=Ct.get(dt);return Ce&&Ct.set(dt,{...Ce,status:"cracked",attempts:Ce.attempts+1,lastAttemptLength:gt}),Ct});const tt={roomName:qe.roomName,key:qe.key,packetId:dt,message:qe.decryptedMessage||"",crackedAt:Date.now()};N(He=>[...He,tt]);const nt=qe.key.toUpperCase();if(!ce.has(nt))try{const He="#"+qe.roomName;await o(He,qe.key),B.current&&await et.decryptHistoricalPackets({key_type:"channel",channel_name:He})}catch(He){console.error("Failed to create channel or decrypt historical:",He),xt.error("Failed to save cracked channel",{description:He instanceof Error?He.message:"Channel discovered but could not be saved"})}}else T(tt=>{const nt=new Map(tt),He=nt.get(dt);return He&&nt.set(dt,{...He,status:"failed",attempts:He.attempts+1,lastAttemptLength:gt}),nt})}catch(qe){console.error("Cracking error:",qe),T(tt=>{const nt=new Map(tt),He=nt.get(dt);return He&&nt.set(dt,{...He,status:"failed",attempts:He.attempts+1,lastAttemptLength:gt}),nt})}he.current=!1,k(null),fe.current&&setTimeout(()=>Ye(),100)},[ce,o]),bt=()=>{var Be;if(!z){xt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}p(!0),fe.current=!0,ae.current=!1,(Be=re.current)==null||Be.enable(),Ye()},ct=()=>{var Be,Ze;p(!1),fe.current=!1,ae.current=!0,(Be=Y.current)==null||Be.abort(),(Ze=re.current)==
Line truncated
|
||||
//# sourceMappingURL=index-BGhVMB5J.js.map
|
||||
`),window.clearInterval(this.noSleepTimer),this.noSleepTimer=null):this.noSleepVideo.pause(),this.enabled=!1}}return $f=d,$f}var wE=_E();const bE=Ys(wE);function CE(r){if(r.length<4)return null;try{const o=parseInt(r.slice(0,2),16)&3;let l=2;if(o===0||o===3){if(r.length<l+8)return null;l+=8}if(r.length<l+2)return null;const d=parseInt(r.slice(l,l+2),16);l+=2;const f=d*2;return r.length<l+f?null:(l+=f,r.slice(l))}catch{return null}}function EE({packets:r,channels:a,onChannelCreate:o,onRunningChange:l,visible:d=!1}){const[f,p]=R.useState(!1),[h,g]=R.useState(6),[m,v]=R.useState(!1),[y,w]=R.useState(!0),[T,F]=R.useState(!1),[k,E]=R.useState(null),[D,B]=R.useState(new Map),[S,N]=R.useState([]),[M,z]=R.useState(!1),[H,j]=R.useState(null),[J,W]=R.useState(null),[U,ne]=R.useState(0),Y=R.useRef(null),re=R.useRef(null),fe=R.useRef(!1),ae=R.useRef(!1),he=R.useRef(!1),G=R.useRef(new Map),pe=R.useRef(!1),Z=R.useRef(6),P=R.useRef(!0),V=R.useRef(!1),K=R.useRef(new Set),$=R.useRef(new Set);R.useEffect(()=>{const Be=new vE;Y.current=Be,j(Be.isGpuAvailable());const Ze=new bE;return re.current=Ze,()=>{Be.destroy(),Y.current=null,Ze.disable(),re.current=null}},[]),R.useEffect(()=>{!d||M||Ab(async()=>{const{ENGLISH_WORDLIST:Be}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:Be}},[]).then(({ENGLISH_WORDLIST:Be})=>{Y.current&&(Y.current.setWordlist(Be),z(!0))}).catch(Be=>{console.error("Failed to load wordlist:",Be),xt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[d,M]),R.useEffect(()=>{const Be=()=>{et.getUndecryptedPacketCount().then(({count:dt})=>W(dt)).catch(()=>W(null))};Be();const Ze=setInterval(Be,3e4);return()=>clearInterval(Ze)},[]);const ce=R.useMemo(()=>new Set(a.map(Be=>Be.key.toUpperCase())),[a]),de=r.filter(Be=>Be.payload_type==="GROUP_TEXT"&&!Be.decrypted);R.useEffect(()=>{let Be=0;B(Ze=>{const dt=new Map(Ze);let Mt=!1;for(const at of de)if(!dt.has(at.id)){const gt=CE(at.data);if(gt&&$.current.has(gt)){Be++;continue}gt&&$.current.add(gt),dt.set(at.id,{packet:at,attempts:0,lastAttemptLength:0,status:"pending"}),Mt=!0}return Mt?(G.current=dt,dt):Ze}),Be>0&&ne(Ze=>Ze+Be)},[de.length]),R.useEffect(()=>{G.current=D},[D]),R.useEffect(()=>{pe.current=m},[m]),R.useEffect(()=>{Z.current=h},[h]),R.useEffect(()=>{P.current=y},[y]),R.useEffect(()=>{V.current=T},[T]),R.useEffect(()=>{K.current=new Set(de.map(Be=>Be.id))},[de]),R.useEffect(()=>{l==null||l(f)},[f,l]);const Se=Array.from(D.values()).filter(Be=>Be.status==="pending").length,Ae=Array.from(D.values()).filter(Be=>Be.status==="cracked").length,Ue=Array.from(D.values()).filter(Be=>Be.status==="failed").length,Ye=R.useCallback(async()=>{if(he.current||!Y.current||!fe.current)return;const Be=G.current;let Ze=null,dt=null;for(const[qe,tt]of Be.entries())if(tt.status==="pending"){Ze=tt,dt=qe;break}if(!Ze&&pe.current){const qe=Array.from(Be.entries()).filter(([,tt])=>tt.status==="failed"&&tt.lastAttemptLength<10);qe.length>0&&(qe.sort((tt,nt)=>tt[1].lastAttemptLength-nt[1].lastAttemptLength),[dt,Ze]=qe[0])}if(!Ze||dt===null){fe.current&&setTimeout(()=>Ye(),1e3);return}if(!K.current.has(dt)){B(qe=>{const tt=new Map(qe);return tt.delete(dt),tt}),fe.current&&setTimeout(()=>Ye(),10);return}he.current=!0;const Mt=Z.current,at=Ze.lastAttemptLength>0,gt=at?Ze.lastAttemptLength+1:Mt;try{const qe=await Y.current.crack(Ze.packet.data,{maxLength:gt,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,...V.current&&{gpuDispatchMs:1e4},...at&&{useDictionary:!1,startingLength:gt}},tt=>{E(tt)});if(ae.current){ae.current=!1,he.current=!1,E(null);return}if(qe.found&&qe.roomName&&qe.key){B(He=>{const Ct=new Map(He),Ce=Ct.get(dt);return Ce&&Ct.set(dt,{...Ce,status:"cracked",attempts:Ce.attempts+1,lastAttemptLength:gt}),Ct});const tt={roomName:qe.roomName,key:qe.key,packetId:dt,message:qe.decryptedMessage||"",crackedAt:Date.now()};N(He=>[...He,tt]);const nt=qe.key.toUpperCase();if(!ce.has(nt))try{const He="#"+qe.roomName;await o(He,qe.key),P.current&&await et.decryptHistoricalPackets({key_type:"channel",channel_name:He})}catch(He){console.error("Failed to create channel or decrypt historical:",He),xt.error("Failed to save cracked channel",{description:He instanceof Error?He.message:"Channel discovered but could not be saved"})}}else B(tt=>{const nt=new Map(tt),He=nt.get(dt);return He&&nt.set(dt,{...He,status:"failed",attempts:He.attempts+1,lastAttemptLength:gt}),nt})}catch(qe){console.error("Cracking error:",qe),B(tt=>{const nt=new Map(tt),He=nt.get(dt);return He&&nt.set(dt,{...He,status:"failed",attempts:He.attempts+1,lastAttemptLength:gt}),nt})}he.current=!1,E(null),fe.current&&setTimeout(()=>Ye(),100)},[ce,o]),bt=()=>{var Be;if(!H){xt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}p(!0),fe.current=!0,ae.current=!1,(Be=re.current)==null||Be.enable(),Ye()},ct=()=>{var Be,Ze;p(!1),fe.current=!1,ae.current=!0,(Be=Y.current)==null||Be.abort(),(Ze=re.current)==
Line truncated
|
||||
//# sourceMappingURL=index-BeiXDnDV.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"mappings":";;;;;;;;6CASa,IAAIA,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,cAAc,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,eAAe,EAAEC,EAAE,OAAO,IAAI,mBAAmB,EAAEC,EAAE,OAAO,IAAI,gBAAgB,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,IAAI,YAAY,EAAEC,EAAE,OAAO,SAAS,SAASC,EAAEC,EAAE,CAAC,OAAUA,IAAP,MAAqB,OAAOA,GAAlB,SAA2B,MAAKA,EAAEF,GAAGE,EAAEF,CAAC,GAAGE,EAAE,YAAY,EAAqB,OAAOA,GAApB,WAAsBA,EAAE,KAAI,CAC1e,IAAIC,EAAE,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,EAAE,mBAAmB,UAAU,GAAG,oBAAoB,UAAU,GAAG,gBAAgB,UAAU,EAAE,EAAEC,EAAE,OAAO,OAAOC,EAAE,GAAG,SAAS,EAAEH,EAAEI,EAAEC,EAAE,CAAC,KAAK,MAAML,EAAE,KAAK,QAAQI,EAAE,KAAK,KAAKD,EAAE,KAAK,QAAQE,GAAGJ,CAAC,CAAC,EAAE,UAAU,iBAAiB,GACnQ,EAAE,UAAU,SAAS,SAASD,EAAEI,EAAE,CAAC,GAAc,OAAOJ,GAAlB,UAAkC,OAAOA,GAApB,YAA6BA,GAAN,KAAQ,MAAM,MAAM,uHAAuH,EAAE,KAAK,QAAQ,gBAAgB,KAAKA,EAAEI,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,YAAY,SAASJ,EAAE,CAAC,KAAK,QAAQ,mBAAmB,KAAKA,EAAE,aAAa,CAAC,EAAE,SAASM,GAAG,EAAEA,EAAE,UAAU,EAAE,UAAU,SAASC,EAAEP,EAAEI,EAAEC,EAAE,CAAC,KAAK,MAAML,EAAE,KAAK,QAAQI,EAAE,KAAK,KAAKD,EAAE,KAAK,QAAQE,GAAGJ,CAAC,CAAC,IAAIO,EAAED,EAAE,UAAU,IAAID,EACrfE,EAAE,YAAYD,EAAEL,EAAEM,EAAE,EAAE,SAAS,EAAEA,EAAE,qBAAqB,GAAG,IAAIC,EAAE,MAAM,QAAQC,EAAE,OAAO,UAAU,eAAeC,EAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,EAAE,EACxK,SAASC,EAAEb,EAAEI,EAAEC,EAAE,CAAC,IAAIS,EAAEC,GAAE,GAAGC,GAAE,KAAKC,GAAE,KAAK,GAASb,GAAN,KAAQ,IAAIU,KAAcV,EAAE,MAAX,SAAiBa,GAAEb,EAAE,KAAcA,EAAE,MAAX,SAAiBY,GAAE,GAAGZ,EAAE,KAAKA,EAAEM,EAAE,KAAKN,EAAEU,CAAC,GAAG,CAACF,EAAE,eAAeE,CAAC,IAAIC,GAAED,CAAC,EAAEV,EAAEU,CAAC,GAAG,IAAII,GAAE,UAAU,OAAO,EAAE,GAAOA,KAAJ,EAAMH,GAAE,SAASV,UAAU,EAAEa,GAAE,CAAC,QAAQC,GAAE,MAAMD,EAAC,EAAEE,GAAE,EAAEA,GAAEF,GAAEE,KAAID,GAAEC,EAAC,EAAE,UAAUA,GAAE,CAAC,EAAEL,GAAE,SAASI,EAAC,CAAC,GAAGnB,GAAGA,EAAE,aAAa,IAAIc,KAAKI,GAAElB,EAAE,aAAakB,GAAWH,GAAED,CAAC,IAAZ,SAAgBC,GAAED,CAAC,EAAEI,GAAEJ,CAAC,GAAG,MAAM,CAAC,SAAS3B,EAAE,KAAKa,EAAE,IAAIgB,GAAE,IAAIC,GAAE,MAAMF,GAAE,OAAOJ,EAAE,OAAO,CAAC,CAC7a,SAASU,EAAErB,EAAEI,EAAE,CAAC,MAAM,CAAC,SAASjB,EAAE,KAAKa,EAAE,KAAK,IAAII,EAAE,IAAIJ,EAAE,IAAI,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAM,CAAC,CAAC,SAASsB,EAAEtB,EAAE,CAAC,OAAiB,OAAOA,GAAlB,UAA4BA,IAAP,MAAUA,EAAE,WAAWb,CAAC,CAAC,SAASoC,EAAOvB,EAAE,CAAC,IAAII,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAIJ,EAAE,QAAQ,QAAQ,SAASA,EAAE,CAAC,OAAOI,EAAEJ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAIwB,GAAE,OAAO,SAASC,EAAEzB,EAAEI,EAAE,CAAC,OAAiB,OAAOJ,GAAlB,UAA4BA,IAAP,MAAgBA,EAAE,KAAR,KAAYuB,EAAO,GAAGvB,EAAE,GAAG,EAAEI,EAAE,SAAS,EAAE,CAAC,CAC/W,SAASsB,GAAE1B,EAAEI,EAAEC,EAAES,EAAEC,GAAE,CAAC,IAAIC,GAAE,OAAOhB,GAAmBgB,KAAd,aAA6BA,KAAZ,aAAchB,EAAE,MAAK,IAAIiB,GAAE,GAAG,GAAUjB,IAAP,KAASiB,GAAE,OAAQ,QAAOD,GAAC,CAAE,IAAK,SAAS,IAAK,SAASC,GAAE,GAAG,MAAM,IAAK,SAAS,OAAOjB,EAAE,SAAQ,CAAE,KAAKb,EAAE,KAAKC,EAAE6B,GAAE,EAAE,CAAC,CAAC,GAAGA,GAAE,OAAOA,GAAEjB,EAAEe,GAAEA,GAAEE,EAAC,EAAEjB,EAAOc,IAAL,GAAO,IAAIW,EAAER,GAAE,CAAC,EAAEH,EAAEL,EAAEM,EAAC,GAAGV,EAAE,GAASL,GAAN,OAAUK,EAAEL,EAAE,QAAQwB,GAAE,KAAK,EAAE,KAAKE,GAAEX,GAAEX,EAAEC,EAAE,GAAG,SAASL,GAAE,CAAC,OAAOA,EAAC,CAAC,GAASe,IAAN,OAAUO,EAAEP,EAAC,IAAIA,GAAEM,EAAEN,GAAEV,GAAG,CAACU,GAAE,KAAKE,IAAGA,GAAE,MAAMF,GAAE,IAAI,IAAI,GAAGA,GAAE,KAAK,QAAQS,GAAE,KAAK,EAAE,KAAKxB,CAAC,GAAGI,EAAE,KAAKW,EAAC,GAAG,EAAyB,GAAvBE,GAAE,EAAEH,EAAOA,IAAL,GAAO,IAAIA,EAAE,IAAOL,EAAET,CAAC,EAAE,QAAQkB,GAAE,EAAEA,GAAElB,EAAE,OAAOkB,KAAI,CAACF,GACrfhB,EAAEkB,EAAC,EAAE,IAAIC,GAAEL,EAAEW,EAAET,GAAEE,EAAC,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,CAAC,SAASI,GAAEpB,EAAEC,CAAC,EAAe,OAAOmB,IAApB,WAAsB,IAAInB,EAAEmB,GAAE,KAAKnB,CAAC,EAAEkB,GAAE,EAAE,EAAEF,GAAEhB,EAAE,KAAI,GAAI,MAAMgB,GAAEA,GAAE,MAAMG,GAAEL,EAAEW,EAAET,GAAEE,IAAG,EAAED,IAAGS,GAAEV,GAAEZ,EAAEC,EAAEc,GAAEJ,EAAC,UAAqBC,KAAX,SAAa,MAAMZ,EAAE,OAAOJ,CAAC,EAAE,MAAM,mDAAuEI,IAApB,kBAAsB,qBAAqB,OAAO,KAAKJ,CAAC,EAAE,KAAK,IAAI,EAAE,IAAII,GAAG,2EAA2E,EAAE,OAAOa,EAAC,CACzZ,SAASU,GAAE3B,EAAEI,EAAEC,EAAE,CAAC,GAASL,GAAN,KAAQ,OAAOA,EAAE,IAAIc,EAAE,GAAGC,GAAE,EAAE,OAAAW,GAAE1B,EAAEc,EAAE,GAAG,GAAG,SAASd,GAAE,CAAC,OAAOI,EAAE,KAAKC,EAAEL,GAAEe,IAAG,CAAC,CAAC,EAASD,CAAC,CAAC,SAASc,GAAE5B,EAAE,CAAC,GAAQA,EAAE,UAAP,GAAe,CAAC,IAAII,EAAEJ,EAAE,QAAQI,EAAEA,EAAC,EAAGA,EAAE,KAAK,SAASA,EAAE,EAAQJ,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAC,EAAE,SAASA,EAAE,EAAQJ,EAAE,UAAN,GAAoBA,EAAE,UAAP,MAAeA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAC,CAAC,EAAOJ,EAAE,UAAP,KAAiBA,EAAE,QAAQ,EAAEA,EAAE,QAAQI,EAAE,CAAC,GAAOJ,EAAE,UAAN,EAAc,OAAOA,EAAE,QAAQ,QAAQ,MAAMA,EAAE,OAAQ,CAC5Z,IAAI6B,GAAE,CAAC,QAAQ,IAAI,EAAEC,EAAE,CAAC,WAAW,IAAI,EAAEC,GAAE,CAAC,uBAAuBF,GAAE,wBAAwBC,EAAE,kBAAkBnB,CAAC,EAAE,SAASqB,GAAG,CAAC,MAAM,MAAM,0DAA0D,CAAE,CACzM,OAAAC,GAAA,SAAiB,CAAC,IAAIN,GAAE,QAAQ,SAAS3B,EAAEI,EAAEC,EAAE,CAACsB,GAAE3B,EAAE,UAAU,CAACI,EAAE,MAAM,KAAK,SAAS,CAAC,EAAEC,CAAC,CAAC,EAAE,MAAM,SAASL,EAAE,CAAC,IAAII,EAAE,EAAE,OAAAuB,GAAE3B,EAAE,UAAU,CAACI,GAAG,CAAC,EAASA,CAAC,EAAE,QAAQ,SAASJ,EAAE,CAAC,OAAO2B,GAAE3B,EAAE,SAASA,EAAE,CAAC,OAAOA,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,SAASA,EAAE,CAAC,GAAG,CAACsB,EAAEtB,CAAC,EAAE,MAAM,MAAMLine truncated
|
||||
Vendored
+1
-1
@@ -13,7 +13,7 @@
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<script type="module" crossorigin src="/assets/index-BGhVMB5J.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BeiXDnDV.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CnRBRJ10.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
+19
-15
@@ -637,22 +637,26 @@ export function App() {
|
||||
);
|
||||
|
||||
// Handle sort order change via API with optimistic update
|
||||
const handleSortOrderChange = useCallback(async (order: 'recent' | 'alpha') => {
|
||||
// Optimistic update for responsive UI
|
||||
setAppSettings((prev) => (prev ? { ...prev, sidebar_sort_order: order } : prev));
|
||||
const handleSortOrderChange = useCallback(
|
||||
async (order: 'recent' | 'alpha') => {
|
||||
// Capture previous value for rollback on error
|
||||
const previousOrder = appSettings?.sidebar_sort_order ?? 'recent';
|
||||
|
||||
try {
|
||||
const updatedSettings = await api.updateSettings({ sidebar_sort_order: order });
|
||||
setAppSettings(updatedSettings);
|
||||
} catch (err) {
|
||||
console.error('Failed to update sort order:', err);
|
||||
// Revert on error
|
||||
setAppSettings((prev) =>
|
||||
prev ? { ...prev, sidebar_sort_order: order === 'recent' ? 'alpha' : 'recent' } : prev
|
||||
);
|
||||
toast.error('Failed to save sort preference');
|
||||
}
|
||||
}, []);
|
||||
// Optimistic update for responsive UI
|
||||
setAppSettings((prev) => (prev ? { ...prev, sidebar_sort_order: order } : prev));
|
||||
|
||||
try {
|
||||
const updatedSettings = await api.updateSettings({ sidebar_sort_order: order });
|
||||
setAppSettings(updatedSettings);
|
||||
} catch (err) {
|
||||
console.error('Failed to update sort order:', err);
|
||||
// Revert to previous value on error (not inverting the new value)
|
||||
setAppSettings((prev) => (prev ? { ...prev, sidebar_sort_order: previousOrder } : prev));
|
||||
toast.error('Failed to save sort preference');
|
||||
}
|
||||
},
|
||||
[appSettings?.sidebar_sort_order]
|
||||
);
|
||||
|
||||
// Sidebar content (shared between desktop and mobile)
|
||||
const sidebarContent = (
|
||||
|
||||
+20
-7
@@ -45,6 +45,16 @@ async function fetchJson<T>(url: string, options?: RequestInit): Promise<T> {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** Check if an error is an AbortError (request was cancelled) */
|
||||
export function isAbortError(err: unknown): boolean {
|
||||
// DOMException is thrown by fetch when aborted, and it's not an Error subclass
|
||||
if (err instanceof DOMException && err.name === 'AbortError') {
|
||||
return true;
|
||||
}
|
||||
// Also check for Error with AbortError name (for compatibility)
|
||||
return err instanceof Error && err.name === 'AbortError';
|
||||
}
|
||||
|
||||
interface DecryptResult {
|
||||
started: boolean;
|
||||
total_packets: number;
|
||||
@@ -134,19 +144,22 @@ export const api = {
|
||||
}),
|
||||
|
||||
// Messages
|
||||
getMessages: (params?: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
type?: 'PRIV' | 'CHAN';
|
||||
conversation_key?: string;
|
||||
}) => {
|
||||
getMessages: (
|
||||
params?: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
type?: 'PRIV' | 'CHAN';
|
||||
conversation_key?: string;
|
||||
},
|
||||
signal?: AbortSignal
|
||||
) => {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (params?.limit) searchParams.set('limit', params.limit.toString());
|
||||
if (params?.offset) searchParams.set('offset', params.offset.toString());
|
||||
if (params?.type) searchParams.set('type', params.type);
|
||||
if (params?.conversation_key) searchParams.set('conversation_key', params.conversation_key);
|
||||
const query = searchParams.toString();
|
||||
return fetchJson<Message[]>(`/messages${query ? `?${query}` : ''}`);
|
||||
return fetchJson<Message[]>(`/messages${query ? `?${query}` : ''}`, { signal });
|
||||
},
|
||||
getMessagesBulk: (
|
||||
conversations: Array<{ type: 'PRIV' | 'CHAN'; conversation_key: string }>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useCallback, useEffect, useRef } from 'react';
|
||||
import { toast } from '../components/ui/sonner';
|
||||
import { api } from '../api';
|
||||
import { api, isAbortError } from '../api';
|
||||
import type { Conversation, Message, MessagePath } from '../types';
|
||||
|
||||
const MESSAGE_PAGE_SIZE = 200;
|
||||
@@ -33,26 +33,49 @@ export function useConversationMessages(
|
||||
// Track seen message content for deduplication
|
||||
const seenMessageContent = useRef<Set<string>>(new Set());
|
||||
|
||||
// AbortController for cancelling in-flight requests on conversation change
|
||||
const abortControllerRef = useRef<AbortController | null>(null);
|
||||
|
||||
// Ref to track the conversation ID being fetched to prevent stale responses
|
||||
const fetchingConversationIdRef = useRef<string | null>(null);
|
||||
|
||||
// Fetch messages for active conversation
|
||||
// Note: This is called manually and from the useEffect. The useEffect handles
|
||||
// cancellation via AbortController; manual calls (e.g., after sending a message)
|
||||
// don't need cancellation.
|
||||
const fetchMessages = useCallback(
|
||||
async (showLoading = false) => {
|
||||
async (showLoading = false, signal?: AbortSignal) => {
|
||||
if (!activeConversation || activeConversation.type === 'raw') {
|
||||
setMessages([]);
|
||||
setHasOlderMessages(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Track which conversation we're fetching for
|
||||
const conversationId = activeConversation.id;
|
||||
|
||||
if (showLoading) {
|
||||
setMessagesLoading(true);
|
||||
// Clear messages first so MessageList resets scroll state for new conversation
|
||||
setMessages([]);
|
||||
}
|
||||
try {
|
||||
const data = await api.getMessages({
|
||||
type: activeConversation.type === 'channel' ? 'CHAN' : 'PRIV',
|
||||
conversation_key: activeConversation.id,
|
||||
limit: MESSAGE_PAGE_SIZE,
|
||||
});
|
||||
const data = await api.getMessages(
|
||||
{
|
||||
type: activeConversation.type === 'channel' ? 'CHAN' : 'PRIV',
|
||||
conversation_key: activeConversation.id,
|
||||
limit: MESSAGE_PAGE_SIZE,
|
||||
},
|
||||
signal
|
||||
);
|
||||
|
||||
// Check if this response is still for the current conversation
|
||||
// This handles the race where the conversation changed while awaiting
|
||||
if (fetchingConversationIdRef.current !== conversationId) {
|
||||
// Stale response - conversation changed while we were fetching
|
||||
return;
|
||||
}
|
||||
|
||||
setMessages(data);
|
||||
// Track seen content for new messages
|
||||
seenMessageContent.current.clear();
|
||||
@@ -62,6 +85,10 @@ export function useConversationMessages(
|
||||
// If we got a full page, there might be more
|
||||
setHasOlderMessages(data.length >= MESSAGE_PAGE_SIZE);
|
||||
} catch (err) {
|
||||
// Don't show error toast for aborted requests (user switched conversations)
|
||||
if (isAbortError(err)) {
|
||||
return;
|
||||
}
|
||||
console.error('Failed to fetch messages:', err);
|
||||
toast.error('Failed to load messages', {
|
||||
description: err instanceof Error ? err.message : 'Check your connection',
|
||||
@@ -114,10 +141,40 @@ export function useConversationMessages(
|
||||
}
|
||||
}, [activeConversation, loadingOlder, hasOlderMessages, messages.length]);
|
||||
|
||||
// Fetch messages when conversation changes
|
||||
// Fetch messages when conversation changes, with proper cancellation
|
||||
useEffect(() => {
|
||||
fetchMessages(true);
|
||||
}, [fetchMessages]);
|
||||
// Abort any previous in-flight request
|
||||
if (abortControllerRef.current) {
|
||||
abortControllerRef.current.abort();
|
||||
}
|
||||
|
||||
// Track which conversation we're now fetching
|
||||
fetchingConversationIdRef.current = activeConversation?.id ?? null;
|
||||
|
||||
// Clear state for new conversation
|
||||
if (!activeConversation || activeConversation.type === 'raw') {
|
||||
setMessages([]);
|
||||
setHasOlderMessages(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new AbortController for this fetch
|
||||
const controller = new AbortController();
|
||||
abortControllerRef.current = controller;
|
||||
|
||||
// Fetch messages with the abort signal
|
||||
fetchMessages(true, controller.signal);
|
||||
|
||||
// Cleanup: abort request if conversation changes or component unmounts
|
||||
return () => {
|
||||
controller.abort();
|
||||
};
|
||||
// NOTE: Intentionally omitting fetchMessages and activeConversation from deps:
|
||||
// - fetchMessages is recreated when activeConversation changes, which would cause infinite loops
|
||||
// - activeConversation object identity changes on every render; we only care about id/type
|
||||
// - We use fetchingConversationIdRef and AbortController to handle stale responses safely
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeConversation?.id, activeConversation?.type]);
|
||||
|
||||
// Add a message if it's new (deduplication)
|
||||
// Returns true if the message was added, false if it was a duplicate
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Tests for API utilities.
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { isAbortError } from '../api';
|
||||
|
||||
describe('isAbortError', () => {
|
||||
it('returns true for AbortError', () => {
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
|
||||
// Create an error that mimics fetch abort
|
||||
const error = new DOMException('The operation was aborted', 'AbortError');
|
||||
|
||||
expect(isAbortError(error)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns true for Error with name AbortError', () => {
|
||||
const error = new Error('Request cancelled');
|
||||
error.name = 'AbortError';
|
||||
|
||||
expect(isAbortError(error)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for regular Error', () => {
|
||||
const error = new Error('Something went wrong');
|
||||
|
||||
expect(isAbortError(error)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for TypeError', () => {
|
||||
const error = new TypeError('Network failure');
|
||||
|
||||
expect(isAbortError(error)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for null', () => {
|
||||
expect(isAbortError(null)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for undefined', () => {
|
||||
expect(isAbortError(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for non-Error objects', () => {
|
||||
expect(isAbortError({ message: 'error' })).toBe(false);
|
||||
expect(isAbortError('error string')).toBe(false);
|
||||
expect(isAbortError(42)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for Error subclasses with different names', () => {
|
||||
class CustomError extends Error {
|
||||
constructor() {
|
||||
super('Custom error');
|
||||
this.name = 'CustomError';
|
||||
}
|
||||
}
|
||||
|
||||
expect(isAbortError(new CustomError())).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -193,3 +193,80 @@ describe('parseWebSocketMessage', () => {
|
||||
expect(onRawPacket).toHaveBeenCalledWith(packetData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useWebSocket ref-based handler pattern', () => {
|
||||
/**
|
||||
* These tests verify the pattern used in useWebSocket to avoid stale closures.
|
||||
* The hook stores handlers in a ref and accesses them through the ref in callbacks.
|
||||
* This ensures that when handlers are updated, the WebSocket still calls the latest version.
|
||||
*/
|
||||
|
||||
it('demonstrates ref pattern prevents stale closure', () => {
|
||||
// Simulate the ref pattern used in useWebSocket
|
||||
interface Handlers {
|
||||
onMessage?: (msg: string) => void;
|
||||
}
|
||||
|
||||
// This simulates what the hook does: store handlers in a ref
|
||||
const handlersRef: { current: Handlers } = { current: {} };
|
||||
|
||||
// First handler version
|
||||
const firstHandler = vi.fn();
|
||||
handlersRef.current = { onMessage: firstHandler };
|
||||
|
||||
// Simulate what onmessage does: access handlers through ref
|
||||
const processMessage = (data: string) => {
|
||||
// This is the pattern: access through ref.current, not closed-over variable
|
||||
handlersRef.current.onMessage?.(data);
|
||||
};
|
||||
|
||||
// Send first message
|
||||
processMessage('message1');
|
||||
expect(firstHandler).toHaveBeenCalledWith('message1');
|
||||
|
||||
// Update handler (simulates React re-render with new handler)
|
||||
const secondHandler = vi.fn();
|
||||
handlersRef.current = { onMessage: secondHandler };
|
||||
|
||||
// Send second message
|
||||
processMessage('message2');
|
||||
|
||||
// First handler should NOT be called again (would happen with stale closure)
|
||||
expect(firstHandler).toHaveBeenCalledTimes(1);
|
||||
// Second handler should be called (ref pattern works)
|
||||
expect(secondHandler).toHaveBeenCalledWith('message2');
|
||||
});
|
||||
|
||||
it('demonstrates stale closure problem without ref pattern', () => {
|
||||
// This demonstrates the bug we fixed - without refs, handlers become stale
|
||||
interface Handlers {
|
||||
onMessage?: (msg: string) => void;
|
||||
}
|
||||
|
||||
// First handler version
|
||||
const firstHandler = vi.fn();
|
||||
let handlers: Handlers = { onMessage: firstHandler };
|
||||
|
||||
// BAD PATTERN: capture handlers in closure (this is what we fixed)
|
||||
const capturedHandlers = handlers;
|
||||
const processMessageBad = (data: string) => {
|
||||
// This captures `capturedHandlers` at creation time - STALE!
|
||||
capturedHandlers.onMessage?.(data);
|
||||
};
|
||||
|
||||
// Send first message
|
||||
processMessageBad('message1');
|
||||
expect(firstHandler).toHaveBeenCalledWith('message1');
|
||||
|
||||
// Update handler
|
||||
const secondHandler = vi.fn();
|
||||
handlers = { onMessage: secondHandler };
|
||||
|
||||
// Send second message - BUG: still calls first handler!
|
||||
processMessageBad('message2');
|
||||
|
||||
// This demonstrates the stale closure bug
|
||||
expect(firstHandler).toHaveBeenCalledTimes(2); // Called twice - bug!
|
||||
expect(secondHandler).not.toHaveBeenCalled(); // Never called - bug!
|
||||
});
|
||||
});
|
||||
@@ -33,6 +33,19 @@ export function useWebSocket(options: UseWebSocketOptions) {
|
||||
const reconnectTimeoutRef = useRef<number | null>(null);
|
||||
const [connected, setConnected] = useState(false);
|
||||
|
||||
// Store options in ref to avoid stale closures in WebSocket handlers.
|
||||
// The onmessage callback captures this ref, and we keep the ref updated
|
||||
// with the latest handlers. This way, even though the WebSocket connection
|
||||
// is only created once, it always calls the current handlers.
|
||||
const optionsRef = useRef<UseWebSocketOptions>(options);
|
||||
|
||||
// Keep the ref updated with latest options
|
||||
useEffect(() => {
|
||||
optionsRef.current = options;
|
||||
}, [options]);
|
||||
|
||||
// Connect function - uses ref for handlers to avoid stale closures
|
||||
// No dependencies needed since we access handlers through ref
|
||||
const connect = useCallback(() => {
|
||||
// Determine WebSocket URL based on current location
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
@@ -68,25 +81,27 @@ export function useWebSocket(options: UseWebSocketOptions) {
|
||||
ws.onmessage = (event) => {
|
||||
try {
|
||||
const msg: WebSocketMessage = JSON.parse(event.data);
|
||||
// Access handlers through ref to always use current versions
|
||||
const handlers = optionsRef.current;
|
||||
|
||||
switch (msg.type) {
|
||||
case 'health':
|
||||
options.onHealth?.(msg.data as HealthStatus);
|
||||
handlers.onHealth?.(msg.data as HealthStatus);
|
||||
break;
|
||||
case 'contacts':
|
||||
options.onContacts?.(msg.data as Contact[]);
|
||||
handlers.onContacts?.(msg.data as Contact[]);
|
||||
break;
|
||||
case 'channels':
|
||||
options.onChannels?.(msg.data as Channel[]);
|
||||
handlers.onChannels?.(msg.data as Channel[]);
|
||||
break;
|
||||
case 'message':
|
||||
options.onMessage?.(msg.data as Message);
|
||||
handlers.onMessage?.(msg.data as Message);
|
||||
break;
|
||||
case 'contact':
|
||||
options.onContact?.(msg.data as Contact);
|
||||
handlers.onContact?.(msg.data as Contact);
|
||||
break;
|
||||
case 'raw_packet':
|
||||
options.onRawPacket?.(msg.data as RawPacket);
|
||||
handlers.onRawPacket?.(msg.data as RawPacket);
|
||||
break;
|
||||
case 'message_acked': {
|
||||
const ackData = msg.data as {
|
||||
@@ -94,14 +109,14 @@ export function useWebSocket(options: UseWebSocketOptions) {
|
||||
ack_count: number;
|
||||
paths?: MessagePath[];
|
||||
};
|
||||
options.onMessageAcked?.(ackData.message_id, ackData.ack_count, ackData.paths);
|
||||
handlers.onMessageAcked?.(ackData.message_id, ackData.ack_count, ackData.paths);
|
||||
break;
|
||||
}
|
||||
case 'error':
|
||||
options.onError?.(msg.data as ErrorEvent);
|
||||
handlers.onError?.(msg.data as ErrorEvent);
|
||||
break;
|
||||
case 'success':
|
||||
options.onSuccess?.(msg.data as SuccessEvent);
|
||||
handlers.onSuccess?.(msg.data as SuccessEvent);
|
||||
break;
|
||||
case 'pong':
|
||||
// Heartbeat response, ignore
|
||||
@@ -115,7 +130,7 @@ export function useWebSocket(options: UseWebSocketOptions) {
|
||||
};
|
||||
|
||||
wsRef.current = ws;
|
||||
}, [options]);
|
||||
}, []); // No dependencies - handlers accessed through ref
|
||||
|
||||
useEffect(() => {
|
||||
connect();
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
"""Tests for WebSocket manager functionality."""
|
||||
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
from app.websocket import SEND_TIMEOUT_SECONDS, WebSocketManager
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ws_manager():
|
||||
"""Create a fresh WebSocketManager for each test."""
|
||||
return WebSocketManager()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_websocket():
|
||||
"""Create a mock WebSocket connection."""
|
||||
ws = AsyncMock()
|
||||
ws.send_text = AsyncMock()
|
||||
return ws
|
||||
|
||||
|
||||
class TestWebSocketBroadcast:
|
||||
"""Tests for the broadcast functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broadcast_sends_to_all_clients(self, ws_manager: WebSocketManager):
|
||||
"""Broadcast should send message to all connected clients."""
|
||||
ws1 = AsyncMock()
|
||||
ws2 = AsyncMock()
|
||||
ws1.accept = AsyncMock()
|
||||
ws2.accept = AsyncMock()
|
||||
|
||||
await ws_manager.connect(ws1)
|
||||
await ws_manager.connect(ws2)
|
||||
|
||||
await ws_manager.broadcast("test", {"key": "value"})
|
||||
|
||||
# Both clients should receive the message
|
||||
ws1.send_text.assert_called_once()
|
||||
ws2.send_text.assert_called_once()
|
||||
|
||||
# Verify the message format
|
||||
import json
|
||||
|
||||
expected = json.dumps({"type": "test", "data": {"key": "value"}})
|
||||
ws1.send_text.assert_called_with(expected)
|
||||
ws2.send_text.assert_called_with(expected)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broadcast_removes_failed_clients(self, ws_manager: WebSocketManager):
|
||||
"""Clients that fail to receive should be removed."""
|
||||
good_ws = AsyncMock()
|
||||
bad_ws = AsyncMock()
|
||||
good_ws.accept = AsyncMock()
|
||||
bad_ws.accept = AsyncMock()
|
||||
bad_ws.send_text.side_effect = Exception("Connection closed")
|
||||
|
||||
await ws_manager.connect(good_ws)
|
||||
await ws_manager.connect(bad_ws)
|
||||
|
||||
assert len(ws_manager.active_connections) == 2
|
||||
|
||||
await ws_manager.broadcast("test", {})
|
||||
|
||||
# Bad client should be removed
|
||||
assert len(ws_manager.active_connections) == 1
|
||||
assert good_ws in ws_manager.active_connections
|
||||
assert bad_ws not in ws_manager.active_connections
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broadcast_handles_timeout(self, ws_manager: WebSocketManager):
|
||||
"""Clients that timeout should be removed."""
|
||||
good_ws = AsyncMock()
|
||||
slow_ws = AsyncMock()
|
||||
good_ws.accept = AsyncMock()
|
||||
slow_ws.accept = AsyncMock()
|
||||
|
||||
# Make slow_ws hang indefinitely
|
||||
async def slow_send(_):
|
||||
await asyncio.sleep(SEND_TIMEOUT_SECONDS + 1)
|
||||
|
||||
slow_ws.send_text.side_effect = slow_send
|
||||
|
||||
await ws_manager.connect(good_ws)
|
||||
await ws_manager.connect(slow_ws)
|
||||
|
||||
assert len(ws_manager.active_connections) == 2
|
||||
|
||||
# Broadcast should complete despite slow client (due to timeout)
|
||||
await ws_manager.broadcast("test", {})
|
||||
|
||||
# Slow client should be removed due to timeout
|
||||
assert len(ws_manager.active_connections) == 1
|
||||
assert good_ws in ws_manager.active_connections
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broadcast_concurrent_sends(self, ws_manager: WebSocketManager):
|
||||
"""Verify that sends happen concurrently, not sequentially."""
|
||||
call_times = []
|
||||
|
||||
async def record_send_time(ws_name):
|
||||
async def _send(_):
|
||||
call_times.append((ws_name, asyncio.get_event_loop().time()))
|
||||
await asyncio.sleep(0.1) # Simulate some work
|
||||
|
||||
return _send
|
||||
|
||||
ws1 = AsyncMock()
|
||||
ws2 = AsyncMock()
|
||||
ws3 = AsyncMock()
|
||||
ws1.accept = AsyncMock()
|
||||
ws2.accept = AsyncMock()
|
||||
ws3.accept = AsyncMock()
|
||||
|
||||
ws1.send_text.side_effect = await record_send_time("ws1")
|
||||
ws2.send_text.side_effect = await record_send_time("ws2")
|
||||
ws3.send_text.side_effect = await record_send_time("ws3")
|
||||
|
||||
await ws_manager.connect(ws1)
|
||||
await ws_manager.connect(ws2)
|
||||
await ws_manager.connect(ws3)
|
||||
|
||||
start_time = asyncio.get_event_loop().time()
|
||||
await ws_manager.broadcast("test", {})
|
||||
elapsed = asyncio.get_event_loop().time() - start_time
|
||||
|
||||
# If sequential: 3 * 0.1 = 0.3s
|
||||
# If concurrent: ~0.1s
|
||||
# Allow some margin for test overhead
|
||||
assert elapsed < 0.2, f"Sends should be concurrent, took {elapsed}s"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broadcast_does_not_block_on_slow_client(self, ws_manager: WebSocketManager):
|
||||
"""A slow client should not block messages to fast clients."""
|
||||
fast_ws = AsyncMock()
|
||||
slow_ws = AsyncMock()
|
||||
fast_ws.accept = AsyncMock()
|
||||
slow_ws.accept = AsyncMock()
|
||||
|
||||
fast_received_at = None
|
||||
slow_received_at = None
|
||||
|
||||
async def fast_send(_):
|
||||
nonlocal fast_received_at
|
||||
fast_received_at = asyncio.get_event_loop().time()
|
||||
|
||||
async def slow_send(_):
|
||||
nonlocal slow_received_at
|
||||
await asyncio.sleep(0.2) # Slow client
|
||||
slow_received_at = asyncio.get_event_loop().time()
|
||||
|
||||
fast_ws.send_text.side_effect = fast_send
|
||||
slow_ws.send_text.side_effect = slow_send
|
||||
|
||||
await ws_manager.connect(slow_ws)
|
||||
await ws_manager.connect(fast_ws)
|
||||
|
||||
start_time = asyncio.get_event_loop().time()
|
||||
await ws_manager.broadcast("test", {})
|
||||
|
||||
# Fast client should receive message quickly, not waiting for slow client
|
||||
assert fast_received_at is not None
|
||||
assert fast_received_at - start_time < 0.1, "Fast client was blocked by slow client"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broadcast_empty_connections(self, ws_manager: WebSocketManager):
|
||||
"""Broadcast should handle empty connection list gracefully."""
|
||||
# Should not raise
|
||||
await ws_manager.broadcast("test", {"data": "value"})
|
||||
|
||||
|
||||
class TestWebSocketConnectionManagement:
|
||||
"""Tests for connection/disconnection."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect_adds_to_list(self, ws_manager: WebSocketManager, mock_websocket):
|
||||
"""Connect should add websocket to active connections."""
|
||||
assert len(ws_manager.active_connections) == 0
|
||||
|
||||
await ws_manager.connect(mock_websocket)
|
||||
|
||||
assert len(ws_manager.active_connections) == 1
|
||||
assert mock_websocket in ws_manager.active_connections
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disconnect_removes_from_list(self, ws_manager: WebSocketManager, mock_websocket):
|
||||
"""Disconnect should remove websocket from active connections."""
|
||||
await ws_manager.connect(mock_websocket)
|
||||
assert len(ws_manager.active_connections) == 1
|
||||
|
||||
await ws_manager.disconnect(mock_websocket)
|
||||
|
||||
assert len(ws_manager.active_connections) == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_disconnect_nonexistent_is_safe(
|
||||
self, ws_manager: WebSocketManager, mock_websocket
|
||||
):
|
||||
"""Disconnecting a non-connected websocket should not raise."""
|
||||
# Should not raise
|
||||
await ws_manager.disconnect(mock_websocket)
|
||||
assert len(ws_manager.active_connections) == 0
|
||||
Reference in new issue
Block a user