Add prebuilt frontend

This commit is contained in:
Jack Kingsman committed 2026-03-14 23:05:57 -07:00
1 parent 0881998e5b
commit cf1a55e258
48 files changed
+5292 -47

No files matched your search

+9 -14
View File
@@ -25,10 +25,11 @@ If extending, have your LLM read the three `AGENTS.md` files: `./AGENTS.md`, `./
## Requirements
- Python 3.10+
- Node.js LTS or current (20, 22, 24, 25)
- [UV](https://astral.sh/uv) package manager: `curl -LsSf https://astral.sh/uv/install.sh | sh`
- MeshCore radio connected via USB serial, TCP, or BLE
Node.js is not required to run the app when using the bundled prebuilt frontend. You only need Node>=20 + recent NPM if you want to develop the frontend or rebuild the web UI from source.
<details>
<summary>Finding your serial port</summary>
@@ -76,9 +77,6 @@ cd Remote-Terminal-for-MeshCore
# Install backend dependencies
uv sync
# Build frontend
cd frontend && npm install && npm run build && cd ..
# Run server
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000
```
@@ -101,16 +99,16 @@ $env:MESHCORE_SERIAL_PORT="COM8" # or your COM port
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000
```
Access at http://localhost:8000
Access at http://localhost:8000.
> **Note:** WebGPU cracking requires HTTPS when not on localhost. See the HTTPS section under Additional Setup.
>
> If you're running from a source checkout and want to rebuild the UI yourself, install Node.js and run `cd frontend && npm install && npm run build`. The backend prefers `frontend/dist` when present and otherwise falls back to the bundled prebuilt frontend.
## Docker Compose
> **Warning:** Docker has intermittent issues with serial event subscriptions. The native method above is more reliable.
> **Note:** BLE-in-docker is outside the scope of this README, but the env vars should all still work.
Edit `docker-compose.yaml` to set a serial device for passthrough, or uncomment your transport (serial or TCP). Then:
```bash
@@ -177,7 +175,7 @@ uv run uvicorn app.main:app --reload
cd frontend
npm install
npm run dev # Dev server at http://localhost:5173 (proxies API to :8000)
npm run build # Production build to dist/
npm run build # Production build to dist/ (used preferentially) and prebuilt/ (bundled to save low-memory friends from needing to build)
```
Run both the backend and `npm run dev` for hot-reloading frontend development.
@@ -207,7 +205,7 @@ cd frontend
npm run lint:fix # esLint + auto-fix
npm run test:run # run tests
npm run format # prettier (always writes)
npm run build # build the frontend
npm run build # build frontend/dist and frontend/prebuilt
```
</details>
@@ -298,11 +296,6 @@ cd /opt/remoteterm
sudo -u remoteterm uv venv
sudo -u remoteterm uv sync
# Build frontend (required for the backend to serve the web UI)
cd /opt/remoteterm/frontend
sudo -u remoteterm npm install
sudo -u remoteterm npm run build
# Install and start service
sudo cp /opt/remoteterm/remoteterm.service /etc/systemd/system/
sudo systemctl daemon-reload
@@ -314,6 +307,8 @@ sudo journalctl -u remoteterm -f
```
Edit `/etc/systemd/system/remoteterm.service` to set `MESHCORE_SERIAL_PORT` if needed.
If you are deploying from a source checkout that does not include the bundled prebuilt frontend, install Node.js and run `cd /opt/remoteterm/frontend && sudo -u remoteterm npm install && sudo -u remoteterm npm run build` before starting the service.
</details>
<details>
+48 -27
View File
@@ -10,6 +10,7 @@ logger = logging.getLogger(__name__)
INDEX_CACHE_CONTROL = "no-store"
ASSET_CACHE_CONTROL = "public, max-age=31536000, immutable"
STATIC_FILE_CACHE_CONTROL = "public, max-age=3600"
FRONTEND_BUILD_INSTRUCTIONS = "Run 'cd frontend && npm install && npm run build'."
class CacheControlStaticFiles(StaticFiles):
@@ -48,40 +49,38 @@ def _resolve_request_origin(request: Request) -> str:
return str(request.base_url).rstrip("/")
def register_frontend_static_routes(app: FastAPI, frontend_dir: Path) -> bool:
"""Register frontend static file routes if a built frontend is available.
Returns True when routes are registered, False when frontend files are
missing/incomplete. Missing frontend files are logged but are not fatal.
"""
def _validate_frontend_dir(frontend_dir: Path, *, log_failures: bool = True) -> tuple[bool, Path]:
"""Resolve and validate a built frontend directory."""
frontend_dir = frontend_dir.resolve()
index_file = frontend_dir / "index.html"
assets_dir = frontend_dir / "assets"
if not frontend_dir.exists():
logger.error(
"Frontend build directory not found at %s. "
"Run 'cd frontend && npm run build'. API will continue without frontend routes.",
frontend_dir,
)
return False
if log_failures:
logger.error("Frontend build directory not found at %s.", frontend_dir)
return False, frontend_dir
if not frontend_dir.is_dir():
logger.error(
"Frontend build path is not a directory: %s. "
"API will continue without frontend routes.",
frontend_dir,
)
return False
if log_failures:
logger.error("Frontend build path is not a directory: %s.", frontend_dir)
return False, frontend_dir
if not index_file.exists():
logger.error(
"Frontend index file not found at %s. "
"Run 'cd frontend && npm run build'. API will continue without frontend routes.",
index_file,
)
if log_failures:
logger.error("Frontend index file not found at %s.", index_file)
return False, frontend_dir
return True, frontend_dir
def register_frontend_static_routes(app: FastAPI, frontend_dir: Path) -> bool:
"""Register frontend static file routes if a built frontend is available."""
valid, frontend_dir = _validate_frontend_dir(frontend_dir)
if not valid:
return False
index_file = frontend_dir / "index.html"
assets_dir = frontend_dir / "assets"
if assets_dir.exists() and assets_dir.is_dir():
app.mount(
"/assets",
@@ -157,6 +156,30 @@ def register_frontend_static_routes(app: FastAPI, frontend_dir: Path) -> bool:
return True
def register_first_available_frontend_static_routes(
app: FastAPI, frontend_dirs: list[Path]
) -> Path | None:
"""Register frontend routes from the first valid build directory."""
for i, candidate in enumerate(frontend_dirs):
valid, resolved_candidate = _validate_frontend_dir(candidate, log_failures=False)
if not valid:
continue
if register_frontend_static_routes(app, resolved_candidate):
logger.info("Selected frontend build directory %s", resolved_candidate)
return resolved_candidate
if i < len(frontend_dirs) - 1:
logger.warning("Frontend build at %s was unusable; trying fallback", resolved_candidate)
logger.error(
"No usable frontend build found. Searched: %s. %s API will continue without frontend routes.",
", ".join(str(path.resolve()) for path in frontend_dirs),
FRONTEND_BUILD_INSTRUCTIONS,
)
return None
def register_frontend_missing_fallback(app: FastAPI) -> None:
"""Register a fallback route that tells the user to build the frontend."""
@@ -164,7 +187,5 @@ def register_frontend_missing_fallback(app: FastAPI) -> None:
async def frontend_not_built():
return JSONResponse(
status_code=404,
content={
"detail": "Frontend not built. Run: cd frontend && npm install && npm run build"
},
content={"detail": f"Frontend not built. {FRONTEND_BUILD_INSTRUCTIONS}"},
)
+9 -3
View File
@@ -11,7 +11,10 @@ from fastapi.responses import JSONResponse
from app.config import settings as server_settings
from app.config import setup_logging
from app.database import db
from app.frontend_static import register_frontend_missing_fallback, register_frontend_static_routes
from app.frontend_static import (
register_first_available_frontend_static_routes,
register_frontend_missing_fallback,
)
from app.radio import RadioDisconnectedError
from app.radio_sync import (
stop_message_polling,
@@ -151,6 +154,9 @@ app.include_router(statistics.router, prefix="/api")
app.include_router(ws.router, prefix="/api")
# Serve frontend static files in production
FRONTEND_DIR = Path(__file__).parent.parent / "frontend" / "dist"
if not register_frontend_static_routes(app, FRONTEND_DIR):
FRONTEND_DIST_DIR = Path(__file__).parent.parent / "frontend" / "dist"
FRONTEND_PREBUILT_DIR = Path(__file__).parent.parent / "frontend" / "prebuilt"
if not register_first_available_frontend_static_routes(
app, [FRONTEND_DIST_DIR, FRONTEND_PREBUILT_DIR]
):
register_frontend_missing_fallback(app)
+1 -1
View File
@@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"build": "tsc && vite build && vite build --outDir prebuilt",
"preview": "vite preview",
"test": "vitest",
"test:run": "vitest run",
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,15 @@
import{r as be,j as vr}from"./index-BJ3L5G2s.js";function wr(){return wr=Object.assign?Object.assign.bind():function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var i in t)({}).hasOwnProperty.call(t,i)&&(n[i]=t[i])}return n},wr.apply(null,arguments)}function Tu(n,e){if(n==null)return{};var t={};for(var i in n)if({}.hasOwnProperty.call(n,i)){if(e.indexOf(i)!==-1)continue;t[i]=n[i]}return t}let Tr=[],ph=[];(()=>{let n="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,t=0;e<n.length;e++)(e%2?ph:Tr).push(t=t+n[e])})();function Cu(n){if(n<768)return!1;for(let e=0,t=Tr.length;;){let i=e+t>>1;if(n<Tr[i])t=i;else if(n>=ph[i])e=i+1;else return!0;if(e==t)return!1}}function cl(n){return n>=127462&&n<=127487}const fl=8205;function Qu(n,e,t=!0,i=!0){return(t?mh:Au)(n,e,i)}function mh(n,e,t){if(e==n.length)return e;e&&gh(n.charCodeAt(e))&&Oh(n.charCodeAt(e-1))&&e--;let i=Ls(n,e);for(e+=ul(i);e<n.length;){let s=Ls(n,e);if(i==fl||s==fl||t&&Cu(s))e+=ul(s),i=s;else if(cl(s)){let r=0,o=e-2;for(;o>=0&&cl(Ls(n,o));)r++,o-=2;if(r%2==0)break;e+=2}else break}return e}function Au(n,e,t){for(;e>0;){let i=mh(n,e-2,t);if(i<e)return i;e--}return 0}function Ls(n,e){let t=n.charCodeAt(e);if(!Oh(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return gh(i)?(t-55296<<10)+(i-56320)+65536:t}function gh(n){return n>=56320&&n<57344}function Oh(n){return n>=55296&&n<56320}function ul(n){return n<65536?1:2}class V{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,i){[e,t]=ai(this,e,t);let s=[];return this.decompose(0,e,s,2),i.length&&i.decompose(0,i.length,s,3),this.decompose(t,this.length,s,1),Ye.from(s,this.length-(t-e)+i.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=ai(this,e,t);let i=[];return this.decompose(e,t,i,0),Ye.from(i,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),s=new Ci(this),r=new Ci(e);for(let o=t,l=t;;){if(s.next(o),r.next(o),o=0,s.lineBreak!=r.lineBreak||s.done!=r.done||s.value!=r.value)return!1;if(l+=s.value.length,s.done||l>=i)return!0}}iter(e=1){return new Ci(this,e)}iterRange(e,t=this.length){return new yh(this,e,t)}iterLines(e,t){let i;if(e==null)i=this.iter();else{t==null&&(t=this.lines+1);let s=this.line(e).from;i=this.iterRange(s,Math.max(s,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new bh(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?V.empty:e.length<=32?new J(e):Ye.from(J.split(e,[]))}}class J extends V{constructor(e,t=Pu(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.text[r],l=s+o.length;if((t?i:l)>=e)return new Mu(s,l,i,o);s=l+1,i++}}decompose(e,t,i,s){let r=e<=0&&t>=this.length?this:new J(dl(this.text,e,t),Math.min(t,this.length)-Math.max(0,e));if(s&1){let o=i.pop(),l=$n(r.text,o.text.slice(),0,r.length);if(l.length<=32)i.push(new J(l,o.length+r.length));else{let a=l.length>>1;i.push(new J(l.slice(0,a)),new J(l.slice(a)))}}else i.push(r)}replace(e,t,i){if(!(i instanceof J))return super.replace(e,t,i);[e,t]=ai(this,e,t);let s=$n(this.text,$n(i.text,dl(this.text,0,e)),t),r=this.length+i.length-(t-e);return sLine truncated
`){[e,t]=ai(this,e,t);let s="";for(let r=0,o=0;r<=t&&o<this.text.length;o++){let l=this.text[o],a=r+l.length;r>e&&o&&(s+=i),e<a&&t>r&&(s+=l.slice(Math.max(0,e-r),t-r)),r=a+1}return s}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(e,t){let i=[],s=-1;for(let r of e)i.push(r),s+=r.length+1,i.length==32&&(t.push(new J(i,s)),i=[],s=-1);return s>-1&&t.push(new J(i,s)),t}}class Ye extends V{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let i of e)this.lines+=i.lines}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.children[r],l=s+o.length,a=i+o.lines-1;if((t?a:l)>=e)return o.lineInner(e,t,i,s);s=l+1,i=a+1}}decompose(e,t,i,s){for(let r=0,o=0;o<=t&&r<this.children.length;r++){let l=this.children[r],a=o+l.length;if(e<=a&&t>=o){let h=s&((o<=e?1:0)|(a>=t?2:0));o>=e&&a<=t&&!h?i.push(l):l.decompose(e-o,t-o,i,h)}o=a+1}}replace(e,t,i){if([e,t]=ai(this,e,t),i.lines<this.lines)for(let s=0,r=0;s<this.children.length;s++){let o=this.children[s],l=r+o.length;if(e>=r&&t<=l){let a=o.replace(e-r,t-r,i),h=this.lines-o.lines+a.lines;if(a.lines<h>>4&&a.lines>h>>6){let c=this.children.slice();return c[s]=a,new Ye(c,this.length-(t-e)+i.length)}return super.replace(r,l,a)}r=l+1}return super.replace(e,t,i)}sliceString(e,t=this.length,i=`
`){[e,t]=ai(this,e,t);let s="";for(let r=0,o=0;r<this.children.length&&o<=t;r++){let l=this.children[r],a=o+l.length;o>e&&r&&(s+=i),e<a&&t>o&&(s+=l.sliceString(e-o,t-o,i)),o=a+1}return s}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(e,t){if(!(e instanceof Ye))return 0;let i=0,[s,r,o,l]=t>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=t,r+=t){if(s==o||r==l)return i;let a=this.children[s],h=e.children[r];if(a!=h)return i+a.scanIdentical(h,t);i+=a.length+1}}static from(e,t=e.reduce((i,s)=>i+s.length+1,-1)){let i=0;for(let d of e)i+=d.lines;if(i<32){let d=[];for(let p of e)p.flatten(d);return new J(d,t)}let s=Math.max(32,i>>5),r=s<<1,o=s>>1,l=[],a=0,h=-1,c=[];function f(d){let p;if(d.lines>r&&d instanceof Ye)for(let m of d.children)f(m);else d.lines>o&&(a>o||!a)?(u(),l.push(d)):d instanceof J&&a&&(p=c[c.length-1])instanceof J&&d.lines+p.lines<=32?(a+=d.lines,h+=d.length+1,c[c.length-1]=new J(p.text.concat(d.text),p.length+1+d.length)):(a+d.lines>s&&u(),a+=d.lines,h+=d.length+1,c.push(d))}function u(){a!=0&&(l.push(c.length==1?c[0]:Ye.from(c,h)),h=-1,a=c.length=0)}for(let d of e)f(d);return u(),l.length==1?l[0]:new Ye(l,t)}}V.empty=new J([""],0);function Pu(n){let e=-1;for(let t of n)e+=t.length+1;return e}function $n(n,e,t=0,i=1e9){for(let s=0,r=0,o=!0;r<n.length&&s<=i;r++){let l=n[r],a=s+l.length;a>=t&&(a>i&&(l=l.slice(0,i-s)),s<t&&(l=l.slice(t-s)),o?(e[e.length-1]+=l,o=!1):e.push(l)),s=a+1}return e}function dl(n,e,t){return $n(n,[""],e,t)}class Ci{constructor(e,t=1){this.dir=t,this.done=!1,this.lineBreak=!1,this.value="",this.nodes=[e],this.offsets=[t>0?1:(e instanceof J?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let i=this.nodes.length-1,s=this.nodes[i],r=this.offsets[i],o=r>>1,l=s instanceof J?s.text.length:s.children.length;if(o==(t>0?l:0)){if(i==0)return this.done=!0,this.value="",this;t>0&&this.offsets[i-1]++,this.nodes.pop(),this.offsets.pop()}else if((r&1)==(t>0?0:1)){if(this.offsets[i]+=t,e==0)return this.lineBreak=!0,this.value=`
`,this;e--}else if(s instanceof J){let a=s.text[o+(t<0?-1:0)];if(this.offsets[i]+=t,a.length>Math.max(0,e))return this.value=e==0?a:t>0?a.slice(e):a.slice(0,a.length-e),this;e-=a.length}else{let a=s.children[o+(t<0?-1:0)];e>a.length?(e-=a.length,this.offsets[i]+=t):(t<0&&this.offsets[i]--,this.nodes.push(a),this.offsets.push(t>0?1:(a instanceof J?a.text.length:a.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class yh{constructor(e,t,i){this.value="",this.done=!1,this.cursor=new Ci(e,t>i?-1:1),this.pos=t>i?e.length:0,this.from=Math.min(t,i),this.to=Math.max(t,i)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let i=t<0?this.pos-this.from:this.to-this.pos;e>i&&(e=i),i-=e;let{value:s}=this.cursor.next(e);return this.pos+=(s.length+e)*t,this.value=s.length<=i?s:t<0?s.slice(s.length-i):s.slice(0,i),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class bh{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:t,lineBreak:i,value:s}=this.inner.next(e);return t&&this.afterBreak?(this.value="",this.afterBreak=!1):t?(this.done=!0,this.value=""):i?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=s,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(V.prototype[Symbol.iterator]=function(){return this.iter()},Ci.prototype[Symbol.iterator]=yh.prototype[Symbol.iterator]=bh.prototype[Symbol.iterator]=function(){return this});class Mu{constructor(e,t,i,s){this.from=e,this.to=t,this.number=i,this.text=s}get length(){return this.to-this.from}}function ai(n,e,t){return e=Math.max(0,Math.min(n.length,e)),[e,Math.max(e,Math.min(n.length,t))]}function le(n,e,t=!0,i=!0){return Qu(n,e,t,i)}function Ru(n){return n>=56320&&n<57344}function Du(n){return n>=55296&&n<56320}function ke(n,e){let t=n.charCodeAt(e);if(!Du(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return Ru(i)?(t-55296<<10)+(i-56320)+65536:t}function xo(n){return n<=65535?String.fromCharCode(n):(n-=65536,String.fromCharCode((n>>10)+55296,(n&1023)+56320))}function Ke(n){return n<65536?1:2}const Cr=/\r\n?|\n/;var ue=(function(n){return n[n.Simple=0]="Simple",n[n.TrackDel=1]="TrackDel",n[n.TrackBefore=2]="TrackBefore",n[n.TrackAfter=3]="TrackAfter",n})(ue||(ue={}));class st{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;t<this.sections.length;t+=2)e+=this.sections[t];return e}get newLength(){let e=0;for(let t=0;t<this.sections.length;t+=2){let i=this.sections[t+1];e+=i<0?this.sections[t]:i}return e}get empty(){return this.sections.length==0||this.sections.length==2&&this.sections[1]<0}iterGaps(e){for(let t=0,i=0,s=0;t<this.sections.length;){let r=this.sections[t++],o=this.sections[t++];o<0?(e(i,s,r),s+=r):s+=o,i+=r}}iterChangedRanges(e,t=!1){Qr(this,e,t)}get invertedDesc(){let e=[];for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];s<0?e.push(i,s):e.push(s,i)}return new st(e)}composeDesc(e){return this.empty?e:e.empty?this:xh(this,e)}mapDesc(e,t=!1){return e.empty?this:Ar(this,e,t)}mapPos(e,t=-1,i=ue.Simple){let s=0,r=0;for(let o=0;o<this.sections.length;){let l=this.sections[o++],a=this.sections[o++],h=s+l;if(a<0){if(h>e)return r+(e-s);r+=l}else{if(i!=ue.Simple&&h>=e&&(i==ue.TrackDel&&s<e&&h>e||i==ue.TrackBefore&&s<e||i==ue.TrackAfter&&h>e))return null;if(h>e||h==e&&t<0&&!l)return e==s||t<0?r:r+a;r+=a}s=h}if(e>s)throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`);return r}touchesRange(e,t=e){for(let i=0,s=0;i<this.sections.length&&s<=t;){let r=this.sections[i++],o=this.sections[i++],l=s+r;if(o>=0&&s<=t&&l>=e)return s<e&&l>t?"cover":!0;s=l}return!1}toString(){let e="";for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];e+=(e?" ":"")+i+(s>=0?":"+s:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some(t=>typeof t!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new st(e)}static create(e){return new st(e)}}class se extends st{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return Qr(this,(t,i,s,r,o)=>e=e.replace(s,s+(i-t),o),!1),e}mapDesc(e,t=!1){return Ar(this,e,t,!0)}invert(e){let t=this.sections.slice(),i=[];for(let s=0,r=0;s<t.length;s+=2){let o=t[s],l=t[s+1];if(l>=0){t[s]=l,t[s+1]=o;let a=s>>1;for(;i.length<a;)i.push(V.empty);i.push(o?e.slice(r,r+o):V.empty)}r+=o}return new se(t,i)}compose(e){return this.empty?e:e.empty?this:xh(this,e,!0)}map(e,t=!1){return e.empty?this:Ar(this,e,t,!0)}iterChanges(e,t=!1){Qr(this,e,t)}get desc(){return st.crea Line truncated
`}get readOnly(){return this.facet(Ah)}phrase(e,...t){for(let i of this.facet(N.phrases))if(Object.prototype.hasOwnProperty.call(i,e)){e=i[e];break}return t.length&&(e=e.replace(/\$(\$|\d*)/g,(i,s)=>{if(s=="$")return"$";let r=+(s||1);return!r||r>t.length?i:t[r-1]})),e}languageDataAt(e,t,i=-1){let s=[];for(let r of this.facet(vh))for(let o of r(this,t,i))Object.prototype.hasOwnProperty.call(o,e)&&s.push(o[e]);return s}charCategorizer(e){let t=this.languageDataAt("wordChars",e);return Xu(t.length?t[0]:"")}wordAt(e){let{text:t,from:i,length:s}=this.doc.lineAt(e),r=this.charCategorizer(e),o=e-i,l=e-i;for(;o>0;){let a=le(t,o,!1);if(r(t.slice(a,o))!=G.Word)break;o=a}for(;l<s;){let a=le(t,l);if(r(t.slice(l,a))!=G.Word)break;l=a}return o==l?null:b.range(o+i,l+i)}}N.allowMultipleSelections=Rr;N.tabSize=Q.define({combine:n=>n.length?n[0]:4});N.lineSeparator=wh;N.readOnly=Ah;N.phrases=Q.define({compare(n,e){let t=Object.keys(n),i=Object.keys(e);return t.length==i.length&&t.every(s=>n[s]==e[s])}});N.languageData=vh;N.changeFilter=Th;N.transactionFilter=Ch;N.transactionExtender=Qh;ks.reconfigure=W.define();function ot(n,e,t={}){let i={};for(let s of n)for(let r of Object.keys(s)){let o=s[r],l=i[r];if(l===void 0)i[r]=o;else if(!(l===o||o===void 0))if(Object.hasOwnProperty.call(t,r))i[r]=t[r](l,o);else throw new Error("Config merge conflict for field "+r)}for(let s in e)i[s]===void 0&&(i[s]=e[s]);return i}class vt{eq(e){return this==e}range(e,t=e){return Wr.create(e,t,this)}}vt.prototype.startSide=vt.prototype.endSide=0;vt.prototype.point=!1;vt.prototype.mapMode=ue.TrackDel;function vo(n,e){return n==e||n.constructor==e.constructor&&n.eq(e)}let Wr=class Rh{constructor(e,t,i){this.from=e,this.to=t,this.value=i}static create(e,t,i){return new Rh(e,t,i)}};function qr(n,e){return n.from-e.from||n.value.startSide-e.value.startSide}class wo{constructor(e,t,i,s){this.from=e,this.to=t,this.value=i,this.maxPoint=s}get length(){return this.to[this.to.length-1]}findIndex(e,t,i,s=0){let r=i?this.to:this.from;for(let o=s,l=r.length;;){if(o==l)return o;let a=o+l>>1,h=r[a]-e||(i?this.value[a].endSide:this.value[a].startSide)-t;if(a==o)return h>=0?o:l;h>=0?l=a:o=a+1}}between(e,t,i,s){for(let r=this.findIndex(t,-1e9,!0),o=this.findIndex(i,1e9,!1,r);r<o;r++)if(s(this.from[r]+e,this.to[r]+e,this.value[r])===!1)return!1}map(e,t){let i=[],s=[],r=[],o=-1,l=-1;for(let a=0;a<this.value.length;a++){let h=this.value[a],c=this.from[a]+e,f=this.to[a]+e,u,d;if(c==f){let p=t.mapPos(c,h.startSide,h.mapMode);if(p==null||(u=d=p,h.startSide!=h.endSide&&(d=t.mapPos(c,h.endSide),d<u)))continue}else if(u=t.mapPos(c,h.startSide),d=t.mapPos(f,h.endSide),u>d||u==d&&h.startSide>0&&h.endSide<=0)continue;(d-u||h.endSide-h.startSide)<0||(o<0&&(o=u),h.point&&(l=Math.max(l,d-u)),i.push(h),s.push(u-o),r.push(d-o))}return{mapped:i.length?new wo(s,r,i,l):null,pos:o}}}class z{constructor(e,t,i,s){this.chunkPos=e,this.chunk=t,this.nextLayer=i,this.maxPoint=s}static create(e,t,i,s){return new z(e,t,i,s)}get length(){let e=this.chunk.length-1;return e<0?0:Math.max(this.chunkEnd(e),this.nextLayer.length)}get size(){if(this.isEmpty)return 0;let e=this.nextLayer.size;for(let t of this.chunk)e+=t.value.length;return e}chunkEnd(e){return this.chunkPos[e]+this.chunk[e].length}update(e){let{add:t=[],sort:i=!1,filterFrom:s=0,filterTo:r=this.length}=e,o=e.filter;if(t.length==0&&!o)return this;if(i&&(t=t.slice().sort(qr)),this.isEmpty)return t.length?z.of(t):this;let l=new Dh(this,null,-1).goto(0),a=0,h=[],c=new mt;for(;l.value||a<t.length;)if(a<t.length&&(l.from-t[a].from||l.startSide-t[a].value.startSide)>=0){let f=t[a++];c.addInner(f.from,f.to,f.value)||h.push(f)}else l.rangeIndex==1&&l.chunkIndex<this.chunk.length&&(a==t.length||this.chunkEnd(l.chunkIndex)<t[a].from)&&(!o||s>this.chunkEnd(l.chunkIndex)||r<this.chunkPos[l.chunkIndex])&&c.addChunk(this.chunkPos[l.chunkIndex],this.chunk[l.chunkIndex])?l.nextChunk():((!o||s>l.to||r<l.from||o(l.from,l.to,l.value))&&(c.addInner(l.from,l.to,l.value)||h.push(Wr.create(l.from,l.to,l.value))),l.next());return c.finishInner(this.nextLayer.isEmpty&&!h.length?z.empty:this.nextLayer.update({add:h,filter:o,filterFrom:s,filterTo:r}))}map(e){if(e.empty||this.isEmpty)return this;let t=[],i=[],s=-1;for(let o=0;o<this.chunk.length;o++){let l=this.chunkPos[o],a=this.chunk[o],h=e.touchesRange(l,l+a.length);if(h===!1)s=Math.max(s,a.maxPoint),t.push(a),i.push(e.mapPos(l));else if(h===!0){let{mapped:c,pos:f}=a.map(l,e);c&&(s=Math.max(s,c.maxPoint),t.push(c),i.push(f))}}let r=this.nextLayer.map(e);return t.length==0?r:new z(i,t,r||z.empty,s)}between(e,t,i){if(!this.isEmpty){for(let s=0;s<this.chunk.length;s++){let r=this.chunkPos[s],o=this.chunk[s];if(t>=r&&e<=r+o.length&&o.between(r,e-r,t-r,i)===!1)return}this.nextLayer.between(e,t,i)}}iter(e=0){return qi.from([this]).goto(e)}get isEmpty(){return this.nextLayer==this}static iter(e,t=0){return qi.from(e).goto(t)}static compare(e,t,i,s,r=-1){let o=e.filter(f=>f.maxPoint>0||!f.isEmpty&&f.maxPoint>=r),l=t.f Line truncated
`)}static newName(){let e=bl[yl]||1;return bl[yl]=e+1,Lr+e.toString(36)}static mount(e,t,i){let s=e[zr],r=i&&i.nonce;s?r&&s.setNonce(r):s=new _u(e,r),s.mount(Array.isArray(t)?t:[t],e)}}let xl=new Map;class _u{constructor(e,t){let i=e.ownerDocument||e,s=i.defaultView;if(!e.head&&e.adoptedStyleSheets&&s.CSSStyleSheet){let r=xl.get(i);if(r)return e[zr]=r;this.sheet=new s.CSSStyleSheet,xl.set(i,this)}else this.styleTag=i.createElement("style"),t&&this.styleTag.setAttribute("nonce",t);this.modules=[],e[zr]=this}mount(e,t){let i=this.sheet,s=0,r=0;for(let o=0;o<e.length;o++){let l=e[o],a=this.modules.indexOf(l);if(a<r&&a>-1&&(this.modules.splice(a,1),r--,a=-1),a==-1){if(this.modules.splice(r++,0,l),i)for(let h=0;h<l.rules.length;h++)i.insertRule(l.rules[h],s++)}else{for(;r<a;)s+=this.modules[r++].rules.length;s+=l.rules.length,r++}}if(i)t.adoptedStyleSheets.indexOf(this.sheet)<0&&(t.adoptedStyleSheets=[this.sheet,...t.adoptedStyleSheets]);else{let o="";for(let a=0;a<this.modules.length;a++)o+=this.modules[a].getRules()+`
`;this.styleTag.textContent=o;let l=t.head||t;this.styleTag.parentNode!=l&&l.insertBefore(this.styleTag,l.firstChild)}}setNonce(e){this.styleTag&&this.styleTag.getAttribute("nonce")!=e&&this.styleTag.setAttribute("nonce",e)}}var Tt={8:"Backspace",9:"Tab",10:"Enter",12:"NumLock",13:"Enter",16:"Shift",17:"Control",18:"Alt",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",44:"PrintScreen",45:"Insert",46:"Delete",59:";",61:"=",91:"Meta",92:"Meta",106:"*",107:"+",108:",",109:"-",110:".",111:"/",144:"NumLock",145:"ScrollLock",160:"Shift",161:"Shift",162:"Control",163:"Control",164:"Alt",165:"Alt",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},Bi={48:")",49:"!",50:"@",51:"#",52:"$",53:"%",54:"^",55:"&",56:"*",57:"(",59:":",61:"+",173:"_",186:":",187:"+",188:"<",189:"_",190:">",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},Uu=typeof navigator<"u"&&/Mac/.test(navigator.platform),Hu=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);for(var fe=0;fe<10;fe++)Tt[48+fe]=Tt[96+fe]=String(fe);for(var fe=1;fe<=24;fe++)Tt[fe+111]="F"+fe;for(var fe=65;fe<=90;fe++)Tt[fe]=String.fromCharCode(fe+32),Bi[fe]=String.fromCharCode(fe);for(var Is in Tt)Bi.hasOwnProperty(Is)||(Bi[Is]=Tt[Is]);function ju(n){var e=Uu&&n.metaKey&&n.shiftKey&&!n.ctrlKey&&!n.altKey||Hu&&n.shiftKey&&n.key&&n.key.length==1||n.key=="Unidentified",t=!e&&n.key||(n.shiftKey?Bi:Tt)[n.keyCode]||n.key||"Unidentified";return t=="Esc"&&(t="Escape"),t=="Del"&&(t="Delete"),t=="Left"&&(t="ArrowLeft"),t=="Up"&&(t="ArrowUp"),t=="Right"&&(t="ArrowRight"),t=="Down"&&(t="ArrowDown"),t}function _(){var n=arguments[0];typeof n=="string"&&(n=document.createElement(n));var e=1,t=arguments[1];if(t&&typeof t=="object"&&t.nodeType==null&&!Array.isArray(t)){for(var i in t)if(Object.prototype.hasOwnProperty.call(t,i)){var s=t[i];typeof s=="string"?n.setAttribute(i,s):s!=null&&(n[i]=s)}e++}for(;e<arguments.length;e++)Eh(n,arguments[e]);return n}function Eh(n,e){if(typeof e=="string")n.appendChild(document.createTextNode(e));else if(e!=null)if(e.nodeType!=null)n.appendChild(e);else if(Array.isArray(e))for(var t=0;t<e.length;t++)Eh(n,e[t]);else throw new RangeError("Unsupported child node: "+e)}let xe=typeof navigator<"u"?navigator:{userAgent:"",vendor:"",platform:""},Ir=typeof document<"u"?document:{documentElement:{style:{}}};const Nr=/Edge\/(\d+)/.exec(xe.userAgent),Wh=/MSIE \d/.test(xe.userAgent),Vr=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(xe.userAgent),vs=!!(Wh||Vr||Nr),Sl=!vs&&/gecko\/(\d+)/i.test(xe.userAgent),Ns=!vs&&/Chrome\/(\d+)/.exec(xe.userAgent),Gu="webkitFontSmoothing"in Ir.documentElement.style,Xr=!vs&&/Apple Computer/.test(xe.vendor),kl=Xr&&(/Mobile\/\w+/.test(xe.userAgent)||xe.maxTouchPoints>2);var P={mac:kl||/Mac/.test(xe.platform),windows:/Win/.test(xe.platform),linux:/Linux|X11/.test(xe.platform),ie:vs,ie_version:Wh?Ir.documentMode||6:Vr?+Vr[1]:Nr?+Nr[1]:0,gecko:Sl,gecko_version:Sl?+(/Firefox\/(\d+)/.exec(xe.userAgent)||[0,0])[1]:0,chrome:!!Ns,chrome_version:Ns?+Ns[1]:0,ios:kl,android:/Android\b/.test(xe.userAgent),webkit_version:Gu?+(/\bAppleWebKit\/(\d+)/.exec(xe.userAgent)||[0,0])[1]:0,safari:Xr,safari_version:Xr?+(/\bVersion\/(\d+(\.\d+)?)/.exec(xe.userAgent)||[0,0])[1]:0,tabSize:Ir.documentElement.style.tabSize!=null?"tab-size":"-moz-tab-size"};function To(n,e){for(let t in n)t=="class"&&e.class?e.class+=" "+n.class:t=="style"&&e.style?e.style+=";"+n.style:e[t]=n[t];return e}const Zn=Object.create(null);function Co(n,e,t){if(n==e)return!0;n||(n=Zn),e||(e=Zn);let i=Object.keys(n),s=Object.keys(e);if(i.length-0!=s.length-0)return!1;for(let r of i)if(r!=t&&(s.indexOf(r)==-1||n[r]!==e[r]))return!1;return!0}function Zu(n,e){for(let t=n.attributes.length-1;t>=0;t--){let i=n.attributes[t].name;e[i]==null&&n.removeAttribute(i)}for(let t in e){let i=e[t];t=="style"?n.style.cssText=i:n.getAttribute(t)!=i&&n.setAttribute(t,i)}}function vl(n,e,t){let i=!1;if(e)for(let s in e)t&&s in t||(i=!0,s=="style"?n.style.cssText="":n.removeAttribute(s));if(t)for(let s in t)e&&e[s]==t[s]||(i=!0,s=="style"?n.style.cssText=t[s]:n.setAttribute(s,t[s]));return i}function Yu(n){let e=Object.create(null);for(let t=0;t<n.attributes.length;t++){let i=n.attributes[t];e[i.name]=i.value}return e}class Xe{eq(e){return!1}updateDOM(e,t){return!1}compare(e){return this==e||this.constructor==e.constructor&&this.eq(e)}get estimatedHeight(){return-1}get lineBreaks(){return 0}ignoreEvent(e){return!0}coordsAt(e,t,i){return null}get isHidden(){return!1}get editable(){return!1}destroy(e){}}var de=(function(n){return n[n.Text=0]="Text",n[n.WidgetBefore=1]="WidgetBefore",n[n.WidgetAfter=2]="WidgetAfter",n[n.WidgetRange=3]="WidgetRange",n})(de||(de={}));class R extends vt{constructor(e,t,i,s){super(),this.startSide=e,this.endSide=t,this.widget=i,this.spec=s}get heightRelevant(){return!1}static mark(e){return new Ji(e)}staLine truncated
`,s=n.state.doc.line(s.number+(t?1:-1)),r=n.bidiSpans(s),h=n.visualLineSide(s,!t)}if(a){if(!a(c))return l}else{if(!i)return h;a=i(c)}l=h}}function Ld(n,e,t){let i=n.state.charCategorizer(e),s=i(t);return r=>{let o=i(r);return s==G.Space&&(s=o),s==o}}function zd(n,e,t,i){let s=e.head,r=t?1:-1;if(s==(t?n.state.doc.length:0))return b.cursor(s,e.assoc);let o=e.goalColumn,l,a=n.contentDOM.getBoundingClientRect(),h=n.coordsAtPos(s,(e.empty?e.assoc:0)||(t?1:-1)),c=n.documentTop;if(h)o==null&&(o=h.left-a.left),l=r<0?h.top:h.bottom;else{let p=n.viewState.lineBlockAt(s);o==null&&(o=Math.min(a.right-a.left,n.defaultCharacterWidth*(s-p.from))),l=(r<0?p.top:p.bottom)+c}let f=a.left+o,u=i??n.viewState.heightOracle.textHeight>>1,d=Yr(n,{x:f,y:l+u*r},!1,r);return b.cursor(d.pos,d.assoc,void 0,o)}function Ri(n,e,t){for(;;){let i=0;for(let s of n)s.between(e-1,e+1,(r,o,l)=>{if(e>r&&e<o){let a=i||t||(e-r<o-e?-1:1);e=a<0?r:o,i=a}});if(!i)return e}}function hc(n,e){let t=null;for(let i=0;i<e.ranges.length;i++){let s=e.ranges[i],r=null;if(s.empty){let o=Ri(n,s.from,0);o!=s.from&&(r=b.cursor(o,-1))}else{let o=Ri(n,s.from,-1),l=Ri(n,s.to,1);(o!=s.from||l!=s.to)&&(r=b.range(s.from==s.anchor?o:l,s.from==s.head?o:l))}r&&(t||(t=e.ranges.slice()),t[i]=r)}return t?b.create(t,e.mainIndex):e}function Us(n,e,t){let i=Ri(n.state.facet(tn).map(s=>s(n)),t.from,e.head>t.from?-1:1);return i==t.from?t:b.cursor(i,i<t.from?1:-1)}class Je{constructor(e,t){this.pos=e,this.assoc=t}}function Yr(n,e,t,i){let s=n.contentDOM.getBoundingClientRect(),r=s.top+n.viewState.paddingTop,{x:o,y:l}=e,a=l-r,h;for(;;){if(a<0)return new Je(0,1);if(a>n.viewState.docHeight)return new Je(n.state.doc.length,-1);if(h=n.elementAtHeight(a),i==null)break;if(h.type==de.Text){if(i<0?h.to<n.viewport.from:h.from>n.viewport.to)break;let u=n.docView.coordsAt(i<0?h.from:h.to,i>0?-1:1);if(u&&(i<0?u.top<=a+r:u.bottom>=a+r))break}let f=n.viewState.heightOracle.textHeight/2;a=i>0?h.bottom+f:h.top-f}if(n.viewport.from>=h.to||n.viewport.to<=h.from){if(t)return null;if(h.type==de.Text){let f=Bd(n,s,h,o,l);return new Je(f,f==h.from?1:-1)}}if(h.type!=de.Text)return a<(h.top+h.bottom)/2?new Je(h.from,1):new Je(h.to,-1);let c=n.docView.lineAt(h.from,2);return(!c||c.length!=h.length)&&(c=n.docView.lineAt(h.from,-2)),new Id(n,o,l,n.textDirectionAt(h.from)).scanTile(c,h.from)}class Id{constructor(e,t,i,s){this.view=e,this.x=t,this.y=i,this.baseDir=s,this.line=null,this.spans=null}bidiSpansAt(e){return(!this.line||this.line.from>e||this.line.to<e)&&(this.line=this.view.state.doc.lineAt(e),this.spans=this.view.bidiSpans(this.line)),this}baseDirAt(e,t){let{line:i,spans:s}=this.bidiSpansAt(e);return s[et.find(s,e-i.from,-1,t)].level==this.baseDir}dirAt(e,t){let{line:i,spans:s}=this.bidiSpansAt(e);return s[et.find(s,e-i.from,-1,t)].dir}bidiIn(e,t){let{spans:i,line:s}=this.bidiSpansAt(e);return i.length>1||i.length&&(i[0].level!=this.baseDir||i[0].to+s.from<t)}scan(e,t){let i=0,s=e.length-1,r=new Set,o=this.bidiIn(e[0],e[s]),l,a,h=-1,c=1e9,f;e:for(;i<s;){let d=s-i,p=i+s>>1;t:if(r.has(p)){let g=i+Math.floor(Math.random()*d);for(let y=0;y<d;y++){if(!r.has(g)){p=g;break t}g++,g==s&&(g=i)}break e}r.add(p);let m=t(p);if(m)for(let g=0;g<m.length;g++){let y=m[g],S=0;if(y.bottom<this.y)(!l||l.bottom<y.bottom)&&(l=y),S=1;else if(y.top>this.y)(!a||a.top>y.top)&&(a=y),S=-1;else{let x=y.left>this.x?this.x-y.left:y.right<this.x?this.x-y.right:0,A=Math.abs(x);A<c&&(h=p,c=A,f=y),x&&(S=x<0==(this.baseDir==H.LTR)?-1:1)}S==-1&&(!o||this.baseDirAt(e[p],1))?s=p:S==1&&(!o||this.baseDirAt(e[p+1],-1))&&(i=p+1)}}if(!f){let d=l&&(!a||this.y-l.bottom<a.top-this.y)?l:a;return this.y=(d.top+d.bottom)/2,this.scan(e,t)}let u=(o?this.dirAt(e[h],1):this.baseDir)==H.LTR;return{i:h,after:this.x>(f.left+f.right)/2==u}}scanText(e,t){let i=[];for(let r=0;r<e.length;r=le(e.text,r))i.push(t+r);i.push(t+e.length);let s=this.scan(i,r=>{let o=i[r]-t,l=i[r+1]-t;return Ii(e.dom,o,l).getClientRects()});return s.after?new Je(i[s.i+1],-1):new Je(i[s.i],1)}scanTile(e,t){if(!e.length)return new Je(t,1);if(e.children.length==1){let l=e.children[0];if(l.isText())return this.scanText(l,t);if(l.isComposite())return this.scanTile(l,t)}let i=[t];for(let l=0,a=t;l<e.children.length;l++)i.push(a+=e.children[l].length);let s=this.scan(i,l=>{let a=e.children[l];return a.flags&48?null:(a.dom.nodeType==1?a.dom:Ii(a.dom,0,a.length)).getClientRects()}),r=e.children[s.i],o=i[s.i];return r.isText()?this.scanText(r,o):r.isComposite()?this.scanTile(r,o):s.after?new Je(i[s.i+1],-1):new Je(o,1)}}const jt="￿";class Nd{constructor(e,t){this.points=e,this.view=t,this.text="",this.lineSeparator=t.state.facet(N.lineSeparator)}append(e){this.text+=e}lineBreak(){this.text+=jt}readRange(e,t){if(!e)return this;let i=e.parentNode;for(let s=e;;){this.findPointBefore(i,s);let r=this.text.length;this.readNode(s);let o=Y.get(s),l=s.nextSibling;if(l==t){o!=null&&o.breakAfter&&!l&&i!=this.view.contentDOM&&this.lineBreak();break}let a=Y.get(l);(o&&a?o.breakAfter:(o?o.breakAfter:Yn(s Line truncated
`&&n.lineWrapping&&(i&&(i=b.single(i.main.anchor-1,i.main.head-1)),t={from:r.from,to:r.to,insert:V.of([" "])}),t)return Eo(n,t,i,o);if(i&&!ts(i,r)){let l=!1,a="select";return n.inputState.lastSelectionTime>Date.now()-50&&(n.inputState.lastSelectionOrigin=="select"&&(l=!0),a=n.inputState.lastSelectionOrigin,a=="select.pointer"&&(i=hc(s.facet(tn).map(h=>h(n)),i))),n.dispatch({selection:i,scrollIntoView:l,userEvent:a}),!0}else return!1}function Eo(n,e,t,i=-1){if(P.ios&&n.inputState.flushIOSKey(e))return!0;let s=n.state.selection.main;if(P.android&&(e.to==s.to&&(e.from==s.from||e.from==s.from-1&&n.state.sliceDoc(e.from,s.from)==" ")&&e.insert.length==1&&e.insert.lines==2&&ni(n.contentDOM,"Enter",13)||(e.from==s.from-1&&e.to==s.to&&e.insert.length==0||i==8&&e.insert.length<e.to-e.from&&e.to>s.head)&&ni(n.contentDOM,"Backspace",8)||e.from==s.from&&e.to==s.to+1&&e.insert.length==0&&ni(n.contentDOM,"Delete",46)))return!0;let r=e.insert.toString();n.inputState.composing>=0&&n.inputState.composing++;let o,l=()=>o||(o=_d(n,e,t));return n.state.facet(Yh).some(a=>a(n,e.from,e.to,r,l))||n.dispatch(l()),!0}function _d(n,e,t){let i,s=n.state,r=s.selection.main,o=-1;if(e.from==e.to&&e.from<r.from||e.from>r.to){let a=e.from<r.from?-1:1,h=a<0?r.from:r.to,c=Ri(s.facet(tn).map(f=>f(n)),h,a);e.from==c&&(o=c)}if(o>-1)i={changes:e,selection:b.cursor(e.from+e.insert.length,-1)};else if(e.from>=r.from&&e.to<=r.to&&e.to-e.from>=(r.to-r.from)/3&&(!t||t.main.empty&&t.main.from==e.from+e.insert.length)&&n.inputState.composing<0){let a=r.from<e.from?s.sliceDoc(r.from,e.from):"",h=r.to>e.to?s.sliceDoc(e.to,r.to):"";i=s.replaceSelection(n.state.toText(a+e.insert.sliceString(0,void 0,n.state.lineBreak)+h))}else{let a=s.changes(e),h=t&&t.main.to<=a.newLength?t.main:void 0;if(s.selection.ranges.length>1&&(n.inputState.composing>=0||n.inputState.compositionPendingChange)&&e.to<=r.to+10&&e.to>=r.to-10){let c=n.state.sliceDoc(e.from,e.to),f,u=t&&ac(n,t.main.head);if(u){let p=e.insert.length-(e.to-e.from);f={from:u.from,to:u.to-p}}else f=n.state.doc.lineAt(r.head);let d=r.to-e.to;i=s.changeByRange(p=>{if(p.from==r.from&&p.to==r.to)return{changes:a,range:h||p.map(a)};let m=p.to-d,g=m-c.length;if(n.state.sliceDoc(g,m)!=c||m>=f.from&&g<=f.to)return{range:p};let y=s.changes({from:g,to:m,insert:e.insert}),S=p.to-r.to;return{changes:y,range:h?b.range(Math.max(0,h.anchor+S),Math.max(0,h.head+S)):p.map(y)}})}else i={changes:a,selection:h&&s.selection.replaceRange(h)}}let l="input.type";return(n.composing||n.inputState.compositionPendingChange&&n.inputState.compositionEndedAt>Date.now()-50)&&(n.inputState.compositionPendingChange=!1,l+=".compose",n.inputState.compositionFirstChange&&(l+=".start",n.inputState.compositionFirstChange=!1)),s.update(i,{userEvent:l,scrollIntoView:!0})}function uc(n,e,t,i){let s=Math.min(n.length,e.length),r=0;for(;r<s&&n.charCodeAt(r)==e.charCodeAt(r);)r++;if(r==s&&n.length==e.length)return null;let o=n.length,l=e.length;for(;o>0&&l>0&&n.charCodeAt(o-1)==e.charCodeAt(l-1);)o--,l--;if(i=="end"){let a=Math.max(0,r-Math.min(o,l));t-=o+a-r}if(o<r&&n.length<e.length){let a=t<=r&&t>=o?r-t:0;r-=a,l=r+(l-o),o=r}else if(l<r){let a=t<=r&&t>=l?r-t:0;r-=a,o=r+(o-l),l=r}return{from:r,toA:o,toB:l}}function Ud(n){let e=[];if(n.root.activeElement!=n.contentDOM)return e;let{anchorNode:t,anchorOffset:i,focusNode:s,focusOffset:r}=n.observer.selectionRange;return t&&(e.push(new Rl(t,i)),(s!=t||r!=i)&&e.push(new Rl(s,r))),e}function Hd(n,e){if(n.length==0)return null;let t=n[0].pos,i=n.length==2?n[1].pos:t;return t>-1&&i>-1?b.single(t+e,i+e):null}function ts(n,e){return e.head==n.main.head&&e.anchor==n.main.anchor}class jd{setSelectionOrigin(e){this.lastSelectionOrigin=e,this.lastSelectionTime=Date.now()}constructor(e){this.view=e,this.lastKeyCode=0,this.lastKeyTime=0,this.lastTouchTime=0,this.lastFocusTime=0,this.lastScrollTop=0,this.lastScrollLeft=0,this.lastWheelEvent=0,this.pendingIOSKey=void 0,this.tabFocusMode=-1,this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastContextMenu=0,this.scrollHandlers=[],this.handlers=Object.create(null),this.composing=-1,this.compositionFirstChange=null,this.compositionEndedAt=0,this.compositionPendingKey=!1,this.compositionPendingChange=!1,this.insertingText="",this.insertingTextAt=0,this.mouseSelection=null,this.draggedContent=null,this.handleEvent=this.handleEvent.bind(this),this.notifiedFocused=e.hasFocus,P.safari&&e.contentDOM.addEventListener("input",()=>null),P.gecko&&hp(e.contentDOM.ownerDocument)}handleEvent(e){!ip(this.view,e)||this.ignoreDuringComposition(e)||e.type=="keydown"&&this.keydown(e)||(this.view.updateState!=0?Promise.resolve().then(()=>this.runHandlers(e.type,e)):this.runHandlers(e.type,e))}runHandlers(e,t){let i=this.handlers[e];if(i){for(let s of i.observers)s(this.view,t);for(let s of i.handlers){if(t.defaultPrevented)break;if(s(this.view,t)){t.preventDefault();break}}}}ensureHandlers(e){let t=Gd(e),i=this.handlers,s=this.view.contentDOM;for(let r in t)if(r!="scroll"){let o Line truncated
`))};if((P.mac||P.android)&&f.from==o-1&&/^\. ?$/.test(i.text)&&e.contentDOM.getAttribute("autocorrect")=="off"&&(f={from:l,to:a,insert:V.of([i.text.replace("."," ")])}),this.pendingContextChange=f,!e.state.readOnly){let u=this.to-this.from+(f.to-f.from+f.insert.length);Eo(e,f,b.single(this.toEditorPos(i.selectionStart,u),this.toEditorPos(i.selectionEnd,u)))}this.pendingContextChange&&(this.revertPending(e.state),this.setSelection(e.state)),f.from<f.to&&!f.insert.length&&e.inputState.composing>=0&&!/[\\p{Alphabetic}\\p{Number}_]/.test(t.text.slice(Math.max(0,i.updateRangeStart-1),Math.min(t.text.length,i.updateRangeStart+1)))&&this.handlers.compositionend(i)},this.handlers.characterboundsupdate=i=>{let s=[],r=null;for(let o=this.toEditorPos(i.rangeStart),l=this.toEditorPos(i.rangeEnd);o<l;o++){let a=e.coordsForChar(o);r=a&&new DOMRect(a.left,a.top,a.right-a.left,a.bottom-a.top)||r||new DOMRect,s.push(r)}t.updateCharacterBounds(i.rangeStart,s)},this.handlers.textformatupdate=i=>{let s=[];for(let r of i.getTextFormats()){let o=r.underlineStyle,l=r.underlineThickness;if(!/none/i.test(o)&&!/none/i.test(l)){let a=this.toEditorPos(r.rangeStart),h=this.toEditorPos(r.rangeEnd);if(a<h){let c=`text-decoration: underline ${/^[a-z]/.test(o)?o+" ":o=="Dashed"?"dashed ":o=="Squiggle"?"wavy ":""}${/thin/i.test(l)?1:2}px`;s.push(R.mark({attributes:{style:c}}).range(a,h))}}}e.dispatch({effects:ic.of(R.set(s))})},this.handlers.compositionstart=()=>{e.inputState.composing<0&&(e.inputState.composing=0,e.inputState.compositionFirstChange=!0)},this.handlers.compositionend=()=>{if(e.inputState.composing=-1,e.inputState.compositionFirstChange=null,this.composing){let{drifted:i}=this.composing;this.composing=null,i&&this.reset(e.state)}};for(let i in this.handlers)t.addEventListener(i,this.handlers[i]);this.measureReq={read:i=>{this.editContext.updateControlBounds(i.contentDOM.getBoundingClientRect());let s=Li(i.root);s&&s.rangeCount&&this.editContext.updateSelectionBounds(s.getRangeAt(0).getBoundingClientRect())}}}applyEdits(e){let t=0,i=!1,s=this.pendingContextChange;return e.changes.iterChanges((r,o,l,a,h)=>{if(i)return;let c=h.length-(o-r);if(s&&o>=s.to)if(s.from==r&&s.to==o&&s.insert.eq(h)){s=this.pendingContextChange=null,t+=c,this.to+=c;return}else s=null,this.revertPending(e.state);if(r+=t,o+=t,o<=this.from)this.from+=c,this.to+=c;else if(r<this.to){if(r<this.from||o>this.to||this.to-this.from+h.length>3e4){i=!0;return}this.editContext.updateText(this.toContextPos(r),this.toContextPos(o),h.toString()),this.to+=c}t+=c}),s&&!i&&this.revertPending(e.state),!i}update(e){let t=this.pendingContextChange,i=e.startState.selection.main;this.composing&&(this.composing.drifted||!e.changes.touchesRange(i.from,i.to)&&e.transactions.some(s=>!s.isUserEvent("input.type")&&s.changes.touchesRange(this.from,this.to)))?(this.composing.drifted=!0,this.composing.editorBase=e.changes.mapPos(this.composing.editorBase)):!this.applyEdits(e)||!this.rangeIsValid(e.state)?(this.pendingContextChange=null,this.reset(e.state)):(e.docChanged||e.selectionSet||t)&&this.setSelection(e.state),(e.geometryChanged||e.docChanged||e.selectionSet)&&e.view.requestMeasure(this.measureReq)}resetRange(e){let{head:t}=e.selection.main;this.from=Math.max(0,t-1e4),this.to=Math.min(e.doc.length,t+1e4)}reset(e){this.resetRange(e),this.editContext.updateText(0,this.editContext.text.length,e.doc.sliceString(this.from,this.to)),this.setSelection(e)}revertPending(e){let t=this.pendingContextChange;this.pendingContextChange=null,this.editContext.updateText(this.toContextPos(t.from),this.toContextPos(t.from+t.insert.length),e.doc.sliceString(t.from,t.to))}setSelection(e){let{main:t}=e.selection,i=this.toContextPos(Math.max(this.from,Math.min(this.to,t.anchor))),s=this.toContextPos(t.head);(this.editContext.selectionStart!=i||this.editContext.selectionEnd!=s)&&this.editContext.updateSelection(i,s)}rangeIsValid(e){let{head:t}=e.selection.main;return!(this.from>0&&t-this.from<500||this.to<e.doc.length&&this.to-t<500||this.to-this.from>1e4*3)}toEditorPos(e,t=this.to-this.from){e=Math.min(e,t);let i=this.composing;return i&&i.drifted?i.editorBase+(e-i.contextBase):e+this.from}toContextPos(e){let t=this.composing;return t&&t.drifted?t.contextBase+(e-t.editorBase):e-this.from}destroy(){for(let e in this.handlers)this.editContext.removeEventListener(e,this.handlers[e])}}class C{get state(){return this.viewState.state}get viewport(){return this.viewState.viewport}get visibleRanges(){return this.viewState.visibleRanges}get inView(){return this.viewState.inView}get composing(){return!!this.inputState&&this.inputState.composing>0}get compositionStarted(){return!!this.inputState&&this.inputState.composing>=0}get root(){return this._root}get win(){return this.dom.ownerDocument.defaultView||window}constructor(e={}){var t;this.plugins=[],this.pluginMap=new Map,this.editorAttrs={},this.contentAttrs={},this.bidiCache=[],this.destroyed=!1,this.updateState=2,this.measureScheduled=-1,this.measureReque Line truncated
--Ÿ­؜​‎‏\u2028\u2029‭‮⁦⁧⁩\uFEFF-]`,no),Hp={0:"null",7:"bell",8:"backspace",10:"newline",11:"vertical tab",13:"carriage return",27:"escape",8203:"zero width space",8204:"zero width non-joiner",8205:"zero width joiner",8206:"left-to-right mark",8207:"right-to-left mark",8232:"line separator",8237:"left-to-right override",8238:"right-to-left override",8294:"left-to-right isolate",8295:"right-to-left isolate",8297:"pop directional isolate",8233:"paragraph separator",65279:"zero width no-break space",65532:"object replacement"};let Gs=null;function jp(){var n;if(Gs==null&&typeof document<"u"&&document.body){let e=document.body.style;Gs=((n=e.tabSize)!==null&&n!==void 0?n:e.MozTabSize)!=null}return Gs||!1}const Nn=Q.define({combine(n){let e=ot(n,{render:null,specialChars:Up,addSpecialChars:null});return(e.replaceTabs=!jp())&&(e.specialChars=new RegExp(" |"+e.specialChars.source,no)),e.addSpecialChars&&(e.specialChars=new RegExp(e.specialChars.source+"|"+e.addSpecialChars.source,no)),e}});function Gp(n={}){return[Nn.of(n),Zp()]}let Jl=null;function Zp(){return Jl||(Jl=K.fromClass(class{constructor(n){this.view=n,this.decorations=R.none,this.decorationCache=Object.create(null),this.decorator=this.makeDecorator(n.state.facet(Nn)),this.decorations=this.decorator.createDeco(n)}makeDecorator(n){return new _p({regexp:n.specialChars,decoration:(e,t,i)=>{let{doc:s}=t.state,r=ke(e[0],0);if(r==9){let o=s.lineAt(i),l=t.state.tabSize,a=pi(o.text,l,i-o.from);return R.replace({widget:new em((l-a%l)*this.view.defaultCharacterWidth/this.view.scaleX)})}return this.decorationCache[r]||(this.decorationCache[r]=R.replace({widget:new Jp(n,r)}))},boundary:n.replaceTabs?void 0:/[^]/})}update(n){let e=n.state.facet(Nn);n.startState.facet(Nn)!=e?(this.decorator=this.makeDecorator(e),this.decorations=this.decorator.createDeco(n.view)):this.decorations=this.decorator.updateDeco(n,this.decorations)}},{decorations:n=>n.decorations}))}const Yp="•";function Kp(n){return n>=32?Yp:n==10?"␤":String.fromCharCode(9216+n)}class Jp extends Xe{constructor(e,t){super(),this.options=e,this.code=t}eq(e){return e.code==this.code}toDOM(e){let t=Kp(this.code),i=e.state.phrase("Control character")+" "+(Hp[this.code]||"0x"+this.code.toString(16)),s=this.options.render&&this.options.render(this.code,i,t);if(s)return s;let r=document.createElement("span");return r.textContent=t,r.title=i,r.setAttribute("aria-label",i),r.className="cm-specialChar",r}ignoreEvent(){return!1}}class em extends Xe{constructor(e){super(),this.width=e}eq(e){return e.width==this.width}toDOM(){let e=document.createElement("span");return e.textContent=" ",e.className="cm-tab",e.style.width=this.width+"px",e}ignoreEvent(){return!1}}function tm(){return nm}const im=R.line({class:"cm-activeLine"}),nm=K.fromClass(class{constructor(n){this.decorations=this.getDeco(n)}update(n){(n.docChanged||n.selectionSet)&&(this.decorations=this.getDeco(n.view))}getDeco(n){let e=-1,t=[];for(let i of n.state.selection.ranges){let s=n.lineBlockAt(i.head);s.from>e&&(t.push(im.range(s.from)),e=s.from)}return R.set(t)}},{decorations:n=>n.decorations});class sm extends Xe{constructor(e){super(),this.content=e}toDOM(e){let t=document.createElement("span");return t.className="cm-placeholder",t.style.pointerEvents="none",t.appendChild(typeof this.content=="string"?document.createTextNode(this.content):typeof this.content=="function"?this.content(e):this.content.cloneNode(!0)),t.setAttribute("aria-hidden","true"),t}coordsAt(e){let t=e.firstChild?Pi(e.firstChild):[];if(!t.length)return null;let i=window.getComputedStyle(e.parentNode),s=zi(t[0],i.direction!="rtl"),r=parseInt(i.lineHeight);return s.bottom-s.top>r*1.5?{left:s.left,right:s.right,top:s.top,bottom:s.top+r}:s}ignoreEvent(){return!1}}function rm(n){let e=K.fromClass(class{constructor(t){this.view=t,this.placeholder=n?R.set([R.widget({widget:new sm(n),side:1}).range(0)]):R.none}get decorations(){return this.view.state.doc.length?R.none:this.placeholder}},{decorations:t=>t.decorations});return typeof n=="string"?[e,C.contentAttributes.of({"aria-placeholder":n})]:e}const so=2e3;function om(n,e,t){let i=Math.min(e.line,t.line),s=Math.max(e.line,t.line),r=[];if(e.off>so||t.off>so||e.col<0||t.col<0){let o=Math.min(e.off,t.off),l=Math.max(e.off,t.off);for(let a=i;a<=s;a++){let h=n.doc.line(a);h.length<=l&&r.push(b.range(h.from+o,h.to+l))}}else{let o=Math.min(e.col,t.col),l=Math.max(e.col,t.col);for(let a=i;a<=s;a++){let h=n.doc.line(a),c=$r(h.text,o,n.tabSize,!0);if(c<0)r.push(b.cursor(h.to));else{let f=$r(h.text,l,n.tabSize);r.push(b.range(h.from+c,h.from+f))}}}return r}function lm(n,e){let t=n.coordsAtPos(n.viewport.from);return t?Math.round(Math.abs((t.left-e)/n.defaultCharacterWidth)):-1}function ea(n,e){let t=n.posAtCoords({x:e.clientX,y:e.clientY},!1),i=n.state.doc.lineAt(t),s=t-i.from,r=s>so?-1:s==i.length?lm(n,e.clientX):pi(i.text,n.state.tabSize,t-i.from);return{line:i.number,col:r,off:s}}function am(n,e){let t=ea(n,e),i=n.stat Line truncated
`:i=="r"?"\r":i=="t"?" ":"\\")}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord&&this.test==e.test}create(){return this.regexp?new S0(this):new y0(this)}getCursor(e,t=0,i){let s=e.doc?e:N.create({doc:e});return i==null&&(i=s.doc.length),this.regexp?Zt(this,s,t,i):Gt(this,s,t,i)}}class Hf{constructor(e){this.spec=e}}function g0(n,e,t){return(i,s,r,o)=>{if(t&&!t(i,s,r,o))return!1;let l=i>=o&&s<=o+r.length?r.slice(i-o,s-o):e.doc.sliceString(i,s);return n(l,e,i,s)}}function Gt(n,e,t,i){let s;return n.wholeWord&&(s=O0(e.doc,e.charCategorizer(e.selection.main.head))),n.test&&(s=g0(n.test,e,s)),new di(e.doc,n.unquoted,t,i,n.caseSensitive?void 0:r=>r.toLowerCase(),s)}function O0(n,e){return(t,i,s,r)=>((r>t||r+s.length<i)&&(r=Math.max(0,t-2),s=n.sliceString(r,Math.min(n.length,i+2))),(e(ds(s,t-r))!=G.Word||e(ps(s,t-r))!=G.Word)&&(e(ps(s,i-r))!=G.Word||e(ds(s,i-r))!=G.Word))}class y0 extends Hf{constructor(e){super(e)}nextMatch(e,t,i){let s=Gt(this.spec,e,i,e.doc.length).nextOverlapping();if(s.done){let r=Math.min(e.doc.length,t+this.spec.unquoted.length);s=Gt(this.spec,e,0,r).nextOverlapping()}return s.done||s.value.from==t&&s.value.to==i?null:s.value}prevMatchInRange(e,t,i){for(let s=i;;){let r=Math.max(t,s-1e4-this.spec.unquoted.length),o=Gt(this.spec,e,r,s),l=null;for(;!o.nextOverlapping().done;)l=o.value;if(l)return l;if(r==t)return null;s-=1e4}}prevMatch(e,t,i){let s=this.prevMatchInRange(e,0,t);return s||(s=this.prevMatchInRange(e,Math.max(0,i-this.spec.unquoted.length),e.doc.length)),s&&(s.from!=t||s.to!=i)?s:null}getReplacement(e){return this.spec.unquote(this.spec.replace)}matchAll(e,t){let i=Gt(this.spec,e,0,e.doc.length),s=[];for(;!i.next().done;){if(s.length>=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=Gt(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}function b0(n,e,t){return(i,s,r)=>(!t||t(i,s,r))&&n(r[0],e,i,s)}function Zt(n,e,t,i){let s;return n.wholeWord&&(s=x0(e.charCategorizer(e.selection.main.head))),n.test&&(s=b0(n.test,e,s)),new Ff(e.doc,n.search,{ignoreCase:!n.caseSensitive,test:s},t,i)}function ds(n,e){return n.slice(le(n,e,!1),e)}function ps(n,e){return n.slice(e,le(n,e))}function x0(n){return(e,t,i)=>!i[0].length||(n(ds(i.input,i.index))!=G.Word||n(ps(i.input,i.index))!=G.Word)&&(n(ps(i.input,i.index+i[0].length))!=G.Word||n(ds(i.input,i.index+i[0].length))!=G.Word)}class S0 extends Hf{nextMatch(e,t,i){let s=Zt(this.spec,e,i,e.doc.length).next();return s.done&&(s=Zt(this.spec,e,0,t).next()),s.done?null:s.value}prevMatchInRange(e,t,i){for(let s=1;;s++){let r=Math.max(t,i-s*1e4),o=Zt(this.spec,e,r,i),l=null;for(;!o.next().done;)l=o.value;if(l&&(r==t||l.from>r+10))return l;if(r==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g,(t,i)=>{if(i=="&")return e.match[0];if(i=="$")return"$";for(let s=i.length;s>0;s--){let r=+i.slice(0,s);if(r>0&&r<e.match.length)return e.match[r]+i.slice(s)}return t})}matchAll(e,t){let i=Zt(this.spec,e,0,e.doc.length),s=[];for(;!i.next().done;){if(s.length>=t)return null;s.push(i.value)}return s}highlight(e,t,i,s){let r=Zt(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!r.next().done;)s(r.value.from,r.value.to)}}const Ui=W.define(),Go=W.define(),kt=pe.define({create(n){return new cr(Oo(n).create(),null)},update(n,e){for(let t of e.effects)t.is(Ui)?n=new cr(t.value.create(),n.panel):t.is(Go)&&(n=new cr(n.query,t.value?Zo:null));return n},provide:n=>Vi.from(n,e=>e.panel)});class cr{constructor(e,t){this.query=e,this.panel=t}}const k0=R.mark({class:"cm-searchMatch"}),v0=R.mark({class:"cm-searchMatch cm-searchMatch-selected"}),w0=K.fromClass(class{constructor(n){this.view=n,this.decorations=this.highlight(n.state.field(kt))}update(n){let e=n.state.field(kt);(e!=n.startState.field(kt)||n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=this.highlight(e))}highlight({query:n,panel:e}){if(!e||!n.spec.valid)return R.none;let{view:t}=this,i=new mt;for(let s=0,r=t.visibleRanges,o=r.length;s<o;s++){let{from:l,to:a}=r[s];for(;s<o-1&&a>r[s+1].from-500;)a=r[++s].to;n.highlight(t.state,l,a,(h,c)=>{let f=t.state.selection.ranges.some(u=>u.from==h&&u.to==c);i.add(h,c,f?v0:k0)})}return i.finish()}},{decorations:n=>n.decorations});function hn(n){return e=>{let t=e.state.field(kt,!1);return t&&t.query.spec.valid?n(e,t):Zf(e)}}const ms=hn((n,{query:e})=>{let{to:t}=n.state.selection.main,i=e.nextMatch(n.state,t,t);if(!i)return!1;let s=b.single(i.from,i.to),r=n.state.facet(gi);return n.dispatch({selection:s,effects:[Yo(n,i),r.scrollToMatch(s.main,n)],userEvent:"select.search"}),Gf(n),!0}),gs=hn((n,{query:e})=>{let{state:t}=n,{from:i}=t.selection.main,s=e.prevMatch(t,i,i);if(!s)return!1;let r= Line truncated
`,{label:"if",detail:"block",type:"keyword"}),lt("if ${}:\n ${}\nelse:\n ${}",{label:"if",detail:"/ else block",type:"keyword"}),lt("class ${name}:\n def __init__(self, ${params}):\n ${}",{label:"class",detail:"definition",type:"keyword"}),lt("import ${module}",{label:"import",detail:"statement",type:"keyword"}),lt("from ${module} import ${names}",{label:"from",detail:"import",type:"keyword"})],Rb=E0(wu,Jf(Pb.concat(Mb)));function xr(n){let{node:e,pos:t}=n,i=n.lineIndent(t,-1),s=null;for(;;){let r=e.childBefore(t);if(r)if(r.name=="Comment")t=r.from;else if(r.name=="Body"||r.name=="MatchBody")n.baseIndentFor(r)+n.unit<=i&&(s=r),e=r;else if(r.name=="MatchClause")e=r;else if(r.type.is("Statement"))e=r;else break;else break}return s}function Sr(n,e){let t=n.baseIndentFor(e),i=n.lineAt(n.pos,-1),s=i.from+i.text.length;return/^\s*($|#)/.test(i.text)&&n.node.to<s+100&&!/\S/.test(n.state.sliceDoc(s,n.node.to))&&n.lineIndent(n.pos,-1)<=t||/^\s*(else:|elif |except |finally:|case\s+[^=:]+:)/.test(n.textAfter)&&n.lineIndent(n.pos,-1)>t?null:t+n.unit}const kr=os.define({name:"python",parser:Cb.configure({props:[Hc.add({Body:n=>{var e;let t=/^\s*(#|$)/.test(n.textAfter)&&xr(n)||n.node;return(e=Sr(n,t))!==null&&e!==void 0?e:n.continue()},MatchBody:n=>{var e;let t=xr(n);return(e=Sr(n,t||n.node))!==null&&e!==void 0?e:n.continue()},IfStatement:n=>/^\s*(else:|elif )/.test(n.textAfter)?n.baseIndent:n.continue(),"ForStatement WhileStatement":n=>/^\s*else:/.test(n.textAfter)?n.baseIndent:n.continue(),TryStatement:n=>/^\s*(except[ :]|finally:|else:)/.test(n.textAfter)?n.baseIndent:n.continue(),MatchStatement:n=>/^\s*case /.test(n.textAfter)?n.baseIndent+n.unit:n.continue(),"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression":sr({closing:")"}),"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression":sr({closing:"}"}),"ArrayExpression ArrayComprehensionExpression":sr({closing:"]"}),MemberExpression:n=>n.baseIndent+n.unit,"String FormatString":()=>null,Script:n=>{var e;let t=xr(n);return(e=t&&Sr(n,t))!==null&&e!==void 0?e:n.continue()}}),Zc.add({"ArrayExpression DictionaryExpression SetExpression TupleExpression":pg,Body:(n,e)=>({from:n.from+1,to:n.to-(n.to==e.doc.length?0:1)}),"String FormatString":(n,e)=>({from:e.doc.lineAt(n.from).to,to:n.to})})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"'''",'"""'],stringPrefixes:["f","fr","rf","r","u","b","br","rb","F","FR","RF","R","U","B","BR","RB"]},commentTokens:{line:"#"},indentOnInput:/^\s*([\}\]\)]|else:|elif |except |finally:|case\s+[^:]*:?)$/}});function Db(){return new ng(kr,[kr.data.of({autocomplete:Ab}),kr.data.of({autocomplete:Rb})])}function Bb({value:n,onChange:e,id:t,height:i="256px"}){return vr.jsx("div",{className:"w-full overflow-hidden rounded-md border border-input",children:vr.jsx(pu,{value:n,onChange:e,extensions:[Db()],theme:du,height:i,basicSetup:{lineNumbers:!0,foldGutter:!1,highlightActiveLine:!0},className:"text-sm",id:t,"aria-label":"Bot code editor"})})}export{Bb as BotCodeEditor};
//# sourceMappingURL=BotCodeEditor-CBFX17Kn.js.map
@@ -0,0 +1 @@
{"version":3,"file":"BotCodeEditor-CBFX17Kn.js","sources":["../../node_modules/@babel/runtime/helpers/esm/extends.js","../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../../node_modules/@marijn/find-cluster-break/src/index.js","../../node_modules/@codemirror/state/dist/index.js","../../node_modules/style-mod/src/style-mod.js","../../node_modules/w3c-keyname/index.js","../../node_modules/crelt/index.js","../../node_modules/@codemirror/view/dist/index.js","../../node_modules/@lezer/common/dist/index.js","../../node_modules/@lezer/highlight/dist/index.js","../../node_modules/@codemirror/language/dist/index.js","../../node_modules/@codemirror/commands/dist/index.js","../../node_modules/@codemirror/search/dist/index.js","../../node_modules/@codemirror/autocomplete/dist/index.js","../../node_modules/@codemirror/lint/dist/index.js","../../node_modules/@uiw/codemirror-extensions-basic-setup/esm/index.js","../../node_modules/@codemirror/theme-one-dark/dist/index.js","../../node_modules/@uiw/react-codemirror/esm/theme/light.js","../../node_modules/@uiw/react-codemirror/esm/getDefaultExtensions.js","../../node_modules/@uiw/react-codemirror/esm/utils.js","../../node_modules/@uiw/react-codemirror/esm/timeoutLatch.js","../../node_modules/@uiw/react-codemirror/esm/useCodeMirror.js","../../node_modules/@uiw/react-codemirror/esm/index.js","../../node_modules/@lezer/lr/dist/index.js","../../node_modules/@lezer/python/dist/index.js","../../node_modules/@codemirror/lang-python/dist/index.js","../../src/components/BotCodeEditor.tsx"],"sourcesContent":["function _extends() {\n return _extends = Object.assign ? Object.assign.bind() : function (n) {\n for (var e = 1; e < arguments.length; e++) {\n var t = arguments[e];\n for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);\n }\n return n;\n }, _extends.apply(null, arguments);\n}\nexport { _extends as default };","function _objectWithoutPropertiesLoose(r, e) {\n if (null == r) return {};\n var t = {};\n for (var n in r) if ({}.hasOwnProperty.call(r, n)) {\n if (-1 !== e.indexOf(n)) continue;\n t[n] = r[n];\n }\n return t;\n}\nexport { _objectWithoutPropertiesLoose as default };","// These are filled with ranges (rangeFrom[i] up to but not including\n// rangeTo[i]) of code points that count as extending characters.\nlet rangeFrom = [], rangeTo = []\n\n;(() => {\n // Compressed representation of the Grapheme_Cluster_Break=Extend\n // information from\n // http://www.unicode.org/Public/16.0.0/ucd/auxiliary/GraphemeBreakProperty.txt.\n // Each pair of elements represents a range, as an offet from the\n // previous range and a length. Numbers are in base-36, with the empty\n // string being a shorthand for 1.\n let numbers = \"lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o\".split(\",\").map(s => s ? parseInt(s, 36) : 1)\n for (let i = 0, n = 0; i < numbers.length; i++)\n (i % 2 ? rangeTo : rangeFrom).push(n = n + numbers[i])\n})()\n\nexport function isExtendingChar(code) {\n if (code < 768) return false\n for (let from = 0, to = rangeFrom.length;;) {\n let mid = (from + to) >> 1\n if (code < rangeFrom[mid]) to = mid\n else if (code >= rangeTo[mid]) from = mid + 1\n else return true\n if (from == to) return false\n }\n}\n\nfunction isRegionalIndicator(code) {\n return code >= 0x1F1E6 && code <= 0x1F1FF\n}\n\nfunction check(code) {\n for (let i = 0; i < rangeFrom.length; i++) {\n if (rangeTo[i] > code) return rangeFrom[i] <= code\n }\n return false\n}\n\nconst ZWJ = 0x200d\n\nexport function findClusterBreak(str, pos, forward = true, includeExtending = true) {\n return (forward ? nextClusterBreak : prevClusterBreak)(strLine truncated
@@ -0,0 +1,712 @@
import{o as tr,p as yt,q as lr,u as wt,v as nt,w as rr,x as ar,y as hr,r as H,_ as fr,t as dt,z as gr,k as Ct,j as M,l as mr}from"./index-BJ3L5G2s.js";var Se={},Fe={},ie={},St;function ve(){if(St)return ie;St=1,Object.defineProperty(ie,"__esModule",{value:!0}),ie.RequestType=ie.AdvertFlags=ie.DeviceRole=ie.PayloadVersion=ie.ControlSubType=ie.PayloadType=ie.RouteType=void 0;var t;(function(e){e[e.TransportFlood=0]="TransportFlood",e[e.Flood=1]="Flood",e[e.Direct=2]="Direct",e[e.TransportDirect=3]="TransportDirect"})(t||(ie.RouteType=t={}));var o;(function(e){e[e.Request=0]="Request",e[e.Response=1]="Response",e[e.TextMessage=2]="TextMessage",e[e.Ack=3]="Ack",e[e.Advert=4]="Advert",e[e.GroupText=5]="GroupText",e[e.GroupData=6]="GroupData",e[e.AnonRequest=7]="AnonRequest",e[e.Path=8]="Path",e[e.Trace=9]="Trace",e[e.Multipart=10]="Multipart",e[e.Control=11]="Control",e[e.RawCustom=15]="RawCustom"})(o||(ie.PayloadType=o={}));var c;(function(e){e[e.NodeDiscoverReq=128]="NodeDiscoverReq",e[e.NodeDiscoverResp=144]="NodeDiscoverResp"})(c||(ie.ControlSubType=c={}));var l;(function(e){e[e.Version1=0]="Version1",e[e.Version2=1]="Version2",e[e.Version3=2]="Version3",e[e.Version4=3]="Version4"})(l||(ie.PayloadVersion=l={}));var n;(function(e){e[e.Unknown=0]="Unknown",e[e.ChatNode=1]="ChatNode",e[e.Repeater=2]="Repeater",e[e.RoomServer=3]="RoomServer",e[e.Sensor=4]="Sensor"})(n||(ie.DeviceRole=n={}));var r;(function(e){e[e.HasLocation=16]="HasLocation",e[e.HasFeature1=32]="HasFeature1",e[e.HasFeature2=64]="HasFeature2",e[e.HasName=128]="HasName"})(r||(ie.AdvertFlags=r={}));var a;return(function(e){e[e.GetStats=1]="GetStats",e[e.Keepalive=2]="Keepalive",e[e.GetTelemetryData=3]="GetTelemetryData",e[e.GetMinMaxAvgData=4]="GetMinMaxAvgData",e[e.GetAccessList=5]="GetAccessList"})(a||(ie.RequestType=a={})),ie}var Ie={},kt;function oe(){if(kt)return Ie;kt=1,Object.defineProperty(Ie,"__esModule",{value:!0}),Ie.byteToHex=t,Ie.bytesToHex=o,Ie.numberToHex=c,Ie.hexToBytes=l;function t(n){return n.toString(16).padStart(2,"0").toUpperCase()}function o(n){return Array.from(n).map(t).join("")}function c(n,r=8){return(n>>>0).toString(16).padStart(r,"0").toUpperCase()}function l(n){const r=n.replace(/\s/g,"").toUpperCase();if(!/^[0-9A-F]*$/.test(r))throw new Error("Invalid hex string: invalid characters at position 0");if(r.length%2!==0)throw new Error("Invalid hex string: odd length");const a=new Uint8Array(r.length/2);for(let e=0;e<r.length;e+=2)a[e/2]=parseInt(r.substr(e,2),16);return a}return Ie}var ke={},Tt;function $e(){if(Tt)return ke;Tt=1,Object.defineProperty(ke,"__esModule",{value:!0}),ke.getRouteTypeName=o,ke.getPayloadTypeName=c,ke.getPayloadVersionName=l,ke.getDeviceRoleName=n,ke.getRequestTypeName=r,ke.getControlSubTypeName=a;const t=ve();function o(e){switch(e){case t.RouteType.Flood:return"Flood";case t.RouteType.Direct:return"Direct";case t.RouteType.TransportFlood:return"TransportFlood";case t.RouteType.TransportDirect:return"TransportDirect";default:return`Unknown (${e})`}}function c(e){switch(e){case t.PayloadType.RawCustom:return"RawCustom";case t.PayloadType.Trace:return"Trace";case t.PayloadType.Advert:return"Advert";case t.PayloadType.GroupText:return"GroupText";case t.PayloadType.GroupData:return"GroupData";case t.PayloadType.Request:return"Request";case t.PayloadType.Response:return"Response";case t.PayloadType.TextMessage:return"TextMessage";case t.PayloadType.AnonRequest:return"AnonRequest";case t.PayloadType.Ack:return"Ack";case t.PayloadType.Path:return"Path";case t.PayloadType.Multipart:return"Multipart";case t.PayloadType.Control:return"Control";default:return`Unknown (0x${e.toString(16)})`}}function l(e){switch(e){case t.PayloadVersion.Version1:return"Version 1";case t.PayloadVersion.Version2:return"Version 2";case t.PayloadVersion.Version3:return"Version 3";case t.PayloadVersion.Version4:return"Version 4";default:return`Unknown (${e})`}}function n(e){switch(e){case t.DeviceRole.Unknown:return"Unknown";case t.DeviceRole.ChatNode:return"Chat Node";case t.DeviceRole.Repeater:return"Repeater";case t.DeviceRole.RoomServer:return"Room Server";case t.DeviceRole.Sensor:return"Sensor";default:return`Unknown (${e})`}}function r(e){switch(e){case t.RequestType.GetStats:return"Get Stats";case t.RequestType.Keepalive:return"Keepalive (deprecated)";case t.RequestType.GetTelemetryData:return"Get Telemetry Data";case t.RequestType.GetMinMaxAvgData:return"Get Min/Max/Avg Data";case t.RequestType.GetAccessList:return"Get Access List";default:return`Unknown (${e})`}}function a(e){switch(e){case t.ControlSubType.NodeDiscoverReq:return"Node Discover Request";case t.ControlSubType.NodeDiscoverResp:return"Node Discover Response";default:return`Unknown (0x${e.toString(16)})`}}return ke}var Ue={},Ge={},Pt;function xt(){if(Pt)return Ge;Pt=1,Object.defineProperty(Ge,"__esModule",{value:!0}),Ge.ChannelCrypto=void 0;const t=tr(),o=oe();class c{static decryptGroupTextMessage(n,r,a){try{const e=(0,o.hexToBytes)(a),A=(0,o.hexToBytes)(r)Line 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:e+A,endByte:e+n.length-1,value:f});const y={type:t.PayloadType.Request,version:t.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:t.RequestType.GetStats,requestData:"",destinationHash:s,sourceHash:i,cipherMac:u,ciphertext:f};return r!=null&&r.includeSegments&&(y.segments=a),y}catch(a){return{type:t.PayloadType.Request,version:t.PayloadVersion.Version1,isValid:!1,errors:[a instanceof Error?a.message:"Failed to decode request payload"],timestamp:0,requestType:t.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return Le.RequestPayloadDecoder=c,Le}var je={},Ft;function Br(){if(Ft)return je;Ft=1,Object.defineProperty(je,"__esModule",{value:!0}),je.ResponsePayloadDecoder=void 0;const t=ve(),o=oe();class c{static decode(n,r){try{if(n.length<4){const b={type:t.PayloadType.Response,version:t.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return r!=null&&r.includeSegments&&(b.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:r.segmentOffset||0,endByte:(r.segmentOffset||0)+n.length-1,value:(0,o.bytesToHex)(n)}]),b}const a=[],e=(r==null?void 0:r.segmentOffset)||0;let A=0;const s=(0,o.byteToHex)(n[A]);r!=null&&r.includeSegments&&a.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:e+A,endByte:e+A,value:s}),A+=1;const i=(0,o.byteToHex)(n[A]);r!=null&&r.includeSegments&&a.push({name:"Source Hash",description:"First byte of source node public key",startByte:e+A,endByte:e+A,value:i}),A+=1;const u=(0,o.bytesToHex)(n.subarray(A,A+2));r!=null&&r.includeSegments&&a.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:e+A,endByte:e+A+1,value:u}),A+=2;const f=(0,o.bytesToHex)(n.subarray(A));r!=null&&r.includeSegments&&n.length>A&&a.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:e+A,endByte:e+n.length-1,value:f});const y={type:t.PayloadType.Response,version:t.PayloadVersion.Version1,isValid:!0,destinationHash:s,sourceHash:i,cipherMac:u,ciphertext:f,ciphertextLength:n.length-4};return r!=null&&r.includeSegments&&(y.segments=a),y}catch(a){return{type:t.PayloadType.Response,version:t.PayloadVersion.Version1,isValid:!1,errors:[a instanceof Error?a.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return je.ResponsePayloadDecoder=c,je}var We={},Ut;function _r(){if(Ut)return We;Ut=1,Object.defineProperty(We,"__esModule",{value:!0}),We.AnonRequestPayloadDecoder=void 0;const t=ve(),o=oe();class c{static decode(n,r){try{if(n.length<35){const b={type:t.PayloadType.AnonRequest,version:t.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return r!=null&&r.includeSegments&&(b.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:r.segmentOffset||0,endByte:(r.segmentOffset||0)+n.length-1,value:(0,o.bytesToHex)(n)}]),b}const a=[],e=(r==null?void 0:r.segmentOffset)||0;let A=0;const s=(0,o.byteToHex)(n[0]);r!=null&&r.includeSegments&&a.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${s}`,startByte:e+A,endByte:e+A,value:s}),A+=1;const i=(0,o.bytesToHex)(n.subarray(1,33));r!=null&&r.includeSegments&&a.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:e+A,endByte:e+A+31,value:i}),A+=32;const u=(0,o.bytesToHex)(n.subarray(33,35));r!=null&&r.includeSegments&&a.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:e+A,endByte:e+A+1,value:u}),A+=2;const f=(0,o.bytesToHex)(n.subarray(35));r!=null&&r.includeSegments&&n.length>35&&a.push({name:"Ciphertext",description:`Encrypted message data (${n.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:e+A,endByte:e+n.length-1,value:f});const y={type:t.PayloadType.AnonRequest,version:t.PayloadVersion.Version1,isValid:!0,destinationHash:s,senderPublicKey:i,cipherMac:u,ciphertext:f,ciphertextLength:n.length-35};return r!=null&&r.includeSegments&&(y.segments=a),y}catch(a){return{type:t.PayloadType.AnonRequest,version:t.PayloadVersion.Version1,isValid:!1,errors:[a instanceof Error?a.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return We.AnonRequestPayloadDecoder=c,We}var Ze={},Gt;function wr(){if(Gt)return Ze;Gt=1,Object.defineProperty(Ze,"__esModule",{value:!0}),Ze.AckPayloadDecoder=void 0;const t=ve(),o=oe();class c{static decode(n,r){try{if(n.length<4){const i={type:t.PayloadType.Ack,version:t.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return r!=null&&r.includeSegments&&(i.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:r.segmentOffset||0,endByte:(r.segmentOffset||0)+n.length-1,value:(0,o.bytesToHex)(n)}]),i}const a=[],e=(r==null?void 0:r.segmentOffset)||0,A=(0,o.bytesToHex)(n.subarray(0,4));r!=null&&r.includeSegments&&a.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${A}`,startByte:e,endByte:e+3,value:A}),r!=null&&r.includeSegments&&n.length>4&&a.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:e+4,endByte:e+n.length-1,value:(0,o.bytesToHex)(n.subarray(4))});const s={type:t.PayloadType.Ack,version:t.PayloadVersion.Version1,isValid:!0,checksum:A};return r!=null&&r.includeSegments&&(s.segments=a),s}catch(a){return{type:t.PayloadType.Ack,version:t.PayloadVersion.Version1,isValid:!1,errors:[a instanceof Error?a.message:"Failed to decode Ack payload"],checksum:""}}}}return Ze.AckPayloadDecoder=c,Ze}var Ke={},Qt;function Cr(){if(Qt)return Ke;Qt=1,Object.defineProperty(Ke,"__esModule",{value:!0}),Ke.PathPayloadDecoder=void 0;const t=ve(),o=oe();class c{static decode(n){try{if(n.length<2)return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const r=n[0],a=(r>>6)+1,e=r&63,A=e*a;if(a===4)return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:["Invalid path length byte: reserved hash size (bits 7:6 = 11)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};if(n.length<1+A+1)return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+A+1} bytes for path length + path + extra type)`],pathLength:e,...a>1?{pathHashSize:a}:{},pathHashes:[],extraType:0,extraData:""};const s=[];for(let f=0;f<e;f++){const y=1+f*a,b=n.subarray(y,y+a);s.push((0,o.bytesToHex)(b))}const i=n[1+A];let u="";return n.length>1+A+1&&(u=(0,o.bytesToHex)(n.subarray(1+A+1))),{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!0,pathLength:e,...a>1?{pathHashSize:a}:{},pathHashes:s,extraType:i,extraData:u}}catch(r){return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:[r instanceof Error?r.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return Ke.PathPayloadDecoder=c,Ke}var Xe={},Nt;function Sr(){if(Nt)return Xe;Nt=1,Object.defineProperty(Xe,"__esModule",{value:!0}),Xe.TextMessagePayloadDecoder=void 0;const t=ve(),o=oe();class c{static decode(n,r){try{if(n.length<4){const b={type:t.PayloadType.TextMessage,version:t.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return r!=null&&r.includeSegments&&(b.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:r.segmentOffset||0,endByte:(r.segmentOffset||0)+n.length-1,value:(0,o.bytesToHex)(n)}]),b}const a=[],e=(r==null?void 0:r.segmentOffset)||0;let A=0;const s=(0,o.byteToHex)(n[A]);r!=null&&r.includeSegments&&a.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:e+A,endByte:e+A,value:s}),A+=1;const i=(0,o.byteToHex)(n[A]);r!=null&&r.includeSegments&&a.push({name:"Source Hash",description:"First byte of source node public key",startByte:e+A,endByte:e+A,value:i}),A+=1;const u=(0,o.bytesToHex)(n.subarray(A,A+2));r!=null&&r.includeSegments&&a.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:e+A,endByte:e+A+1,value:u}),A+=2;const f=(0,o.bytesToHex)(n.subarray(A));r!=null&&r.includeSegments&&n.length>A&&a.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:e+A,endByte:e+n.leng Line truncated
// SHA256 round constants
const K: array<u32, 64> = array<u32, 64>(
0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u,
0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u,
0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau,
0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u,
0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u,
0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u,
0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u
);
// Character lookup table (a-z = 0-25, 0-9 = 26-35, dash = 36)
const CHARS: array<u32, 37> = array<u32, 37>(
0x61u, 0x62u, 0x63u, 0x64u, 0x65u, 0x66u, 0x67u, 0x68u, 0x69u, 0x6au, // a-j
0x6bu, 0x6cu, 0x6du, 0x6eu, 0x6fu, 0x70u, 0x71u, 0x72u, 0x73u, 0x74u, // k-t
0x75u, 0x76u, 0x77u, 0x78u, 0x79u, 0x7au, // u-z
0x30u, 0x31u, 0x32u, 0x33u, 0x34u, 0x35u, 0x36u, 0x37u, 0x38u, 0x39u, // 0-9
0x2du // dash
);
struct Params {
target_channel_hash: u32,
batch_offset: u32,
name_length: u32,
batch_size: u32,
target_mac: u32, // First 2 bytes of target MAC (in high 16 bits)
ciphertext_words: u32, // Number of 32-bit words in ciphertext
ciphertext_len_bits: u32, // Length of ciphertext in bits
verify_mac: u32, // 1 to verify MAC, 0 to skip
}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var<storage, read_write> match_count: atomic<u32>;
@group(0) @binding(2) var<storage, read_write> match_indices: array<u32>;
@group(0) @binding(3) var<storage, read> ciphertext: array<u32>; // Ciphertext data
fn rotr(x: u32, n: u32) -> u32 {
return (x >> n) | (x << (32u - n));
}
fn ch(x: u32, y: u32, z: u32) -> u32 {
return (x & y) ^ (~x & z);
}
fn maj(x: u32, y: u32, z: u32) -> u32 {
return (x & y) ^ (x & z) ^ (y & z);
}
fn sigma0(x: u32) -> u32 {
return rotr(x, 2u) ^ rotr(x, 13u) ^ rotr(x, 22u);
}
fn sigma1(x: u32) -> u32 {
return rotr(x, 6u) ^ rotr(x, 11u) ^ rotr(x, 25u);
}
fn gamma0(x: u32) -> u32 {
return rotr(x, 7u) ^ rotr(x, 18u) ^ (x >> 3u);
}
fn gamma1(x: u32) -> u32 {
return rotr(x, 17u) ^ rotr(x, 19u) ^ (x >> 10u);
}
// Convert index to room name bytes, returns the hash as a u32 for the first byte check
fn index_to_room_name(idx: u32, length: u32, msg: ptr<function, array<u32, 16>>) -> bool {
// Message starts with '#' (0x23)
var byte_pos = 0u;
var word_idx = 0u;
var current_word = 0x23000000u; // '#' in big-endian position 0
byte_pos = 1u;
var remaining = idx;
var prev_was_dash = false;
// Generate room name from index
for (var i = 0u; i < length; i++) {
let char_count = select(37u, 36u, i == 0u || i == length - 1u); // no dash at start/end
var char_idx = remaining % char_count;
remaining = remaining / char_count;
// Check for consecutive dashes (invalid)
let is_dash = char_idx == 36u && i > 0u && i < length - 1u;
if (is_dash && prev_was_dash) {
return false; // Invalid: consecutive dashes
}
prev_was_dash = is_dash;
// Map char index to actual character
let c = CHARS[char_idx];
// Pack byte into current word (big-endian)
let shift = (3u - byte_pos % 4u) * 8u;
if (byte_pos % 4u == 0u && byte_pos > 0u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
current_word = 0u;
}
current_word = current_word | (c << shift);
byte_pos = byte_pos + 1u;
}
// Add padding: 0x80 followed by zeros, then length in bits
let msg_len_bits = (length + 1u) * 8u; // +1 for '#'
// Add 0x80 padding byte
let shift = (3u - byte_pos % 4u) * 8u;
if (byte_pos % 4u == 0u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
current_word = 0x80000000u;
} else {
current_word = current_word | (0x80u << shift);
}
byte_pos = byte_pos + 1u;
// Store current word
if (byte_pos % 4u == 0u || word_idx < 14u) {
(*msg)[word_idx] = current_word;
word_idx = word_idx + 1u;
}
// Zero-fill until word 14
for (var i = word_idx; i < 14u; i++) {
(*msg)[i] = 0u;
}
// Length in bits (64-bit, but we only use lower 32 bits for short messages)
(*msg)[14u] = 0u;
(*msg)[15u] = msg_len_bits;
return true;
}
fn sha256_block(msg: ptr<function, array<u32, 16>>) -> array<u32, 8> {
// Initialize hash values
var h: array<u32, 8> = array<u32, 8>(
0x6a09e667u, 0xbb67ae85u, 0x3c6ef372u, 0xa54ff53au,
0x510e527fu, 0x9b05688cu, 0x1f83d9abu, 0x5be0cd19u
);
// Message schedule
var w: array<u32, 64>;
for (var i = 0u; i < 16u; i++) {
w[i] = (*msg)[i];
}
for (var i = 16u; i < 64u; i++) {
w[i] = gamma1(w[i-2u]) + w[i-7u] + gamma0(w[i-15u]) + w[i-16u];
}
// Compression
var a = h[0]; var b = h[1]; var c = h[2]; var d = h[3];
var e = h[4]; var f = h[5]; var g = h[6]; var hh = h[7];
for (var i = 0u; i < 64u; i++) {
let t1 = hh + sigma1(e) + ch(e, f, g) + K[i] + w[i];
let t2 = sigma0(a) + maj(a, b, c);
hh = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
h[0] = h[0] + a; h[1] = h[1] + b; h[2] = h[2] + c; h[3] = h[3] + d;
h[4] = h[4] + e; h[5] = h[5] + f; h[6] = h[6] + g; h[7] = h[7] + hh;
return h;
}
// Compute SHA256 of the key (16 bytes) to get channel hash
fn sha256_key(key: array<u32, 4>) -> u32 {
var msg: array<u32, 16>;
// Key bytes (16 bytes = 4 words)
msg[0] = key[0];
msg[1] = key[1];
msg[2] = key[2];
msg[3] = key[3];
// Padding: 0x80 followed by zeros
msg[4] = 0x80000000u;
for (var i = 5u; i < 14u; i++) {
msg[i] = 0u;
}
// Length: 128 bits
msg[14] = 0u;
msg[15] = 128u;
let hash = sha256_block(&msg);
// Return first byte of hash (big-endian)
return hash[0] >> 24u;
}
// HMAC-SHA256 for MAC verification
// Key is 16 bytes (4 words), padded to 32 bytes with zeros for MeshCore
// Returns first 2 bytes of HMAC (as u32 in high 16 bits)
fn hmac_sha256_mac(key: array<u32, 4>, ciphertext_len: u32) -> u32 {
// HMAC: H((K' ^ opad) || H((K' ^ ipad) || message))
// K' is 64 bytes (32 bytes key + 32 bytes zero padding for MeshCore, then padded to 64)
// ipad = 0x36 repeated, opad = 0x5c repeated
// Build padded key (64 bytes = 16 words)
// MeshCore uses 32-byte secret: 16-byte key + 16 zero bytes
var k_pad: array<u32, 16>;
k_pad[0] = key[0];
k_pad[1] = key[1];
k_pad[2] = key[2];
k_pad[3] = key[3];
for (var i = 4u; i < 16u; i++) {
k_pad[i] = 0u;
}
// Inner hash: SHA256((K' ^ ipad) || message)
// First block: K' ^ ipad (64 bytes)
var inner_block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
inner_block[i] = k_pad[i] ^ 0x36363636u;
}
// Initialize hash state with first block
var h: array<u32, 8> = sha256_block(&inner_block);
// Process ciphertext blocks (continuing from h state)
let ciphertext_words = params.ciphertext_words;
var word_idx = 0u;
// Process full 64-byte blocks of ciphertext
while (word_idx + 16u <= ciphertext_words) {
var block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
block[i] = ciphertext[word_idx + i];
}
h = sha256_block_continue(&block, h);
word_idx = word_idx + 16u;
}
// Final block with remaining ciphertext + padding
var final_block: array<u32, 16>;
var remaining = ciphertext_words - word_idx;
for (var i = 0u; i < 16u; i++) {
if (i < remaining) {
final_block[i] = ciphertext[word_idx + i];
} else if (i == remaining) {
// Add 0x80 padding
final_block[i] = 0x80000000u;
} else {
final_block[i] = 0u;
}
}
// Add length (64 bytes of ipad + ciphertext length)
let total_bits = 512u + params.ciphertext_len_bits;
if (remaining < 14u) {
final_block[14] = 0u;
final_block[15] = total_bits;
h = sha256_block_continue(&final_block, h);
} else {
// Need extra block for length
h = sha256_block_continue(&final_block, h);
var len_block: array<u32, 16>;
for (var i = 0u; i < 14u; i++) {
len_block[i] = 0u;
}
len_block[14] = 0u;
len_block[15] = total_bits;
h = sha256_block_continue(&len_block, h);
}
let inner_hash = h;
// Outer hash: SHA256((K' ^ opad) || inner_hash)
var outer_block: array<u32, 16>;
for (var i = 0u; i < 16u; i++) {
outer_block[i] = k_pad[i] ^ 0x5c5c5c5cu;
}
h = sha256_block(&outer_block);
// Second block: inner_hash (32 bytes) + padding
var hash_block: array<u32, 16>;
for (var i = 0u; i < 8u; i++) {
hash_block[i] = inner_hash[i];
}
hash_block[8] = 0x80000000u;
for (var i = 9u; i < 14u; i++) {
hash_block[i] = 0u;
}
hash_block[14] = 0u;
hash_block[15] = 512u + 256u; // 64 bytes opad + 32 bytes inner hash
h = sha256_block_continue(&hash_block, h);
// Return first 2 bytes (high 16 bits of first word)
return h[0] & 0xFFFF0000u;
}
// SHA256 block computation continuing from existing state
fn sha256_block_continue(msg: ptr<function, array<u32, 16>>, h_in: array<u32, 8>) -> array<u32, 8> {
var h = h_in;
// Message schedule
var w: array<u32, 64>;
for (var i = 0u; i < 16u; i++) {
w[i] = (*msg)[i];
}
for (var i = 16u; i < 64u; i++) {
w[i] = gamma1(w[i-2u]) + w[i-7u] + gamma0(w[i-15u]) + w[i-16u];
}
// Compression
var a = h[0]; var b = h[1]; var c = h[2]; var d = h[3];
var e = h[4]; var f = h[5]; var g = h[6]; var hh = h[7];
for (var i = 0u; i < 64u; i++) {
let t1 = hh + sigma1(e) + ch(e, f, g) + K[i] + w[i];
let t2 = sigma0(a) + maj(a, b, c);
hh = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
h[0] = h[0] + a; h[1] = h[1] + b; h[2] = h[2] + c; h[3] = h[3] + d;
h[4] = h[4] + e; h[5] = h[5] + f; h[6] = h[6] + g; h[7] = h[7] + hh;
return h;
}
// Process a single candidate and record match if found
fn process_candidate(name_idx: u32) {
// Generate message for this room name
var msg: array<u32, 16>;
let valid = index_to_room_name(name_idx, params.name_length, &msg);
if (!valid) {
return;
}
// Compute SHA256("#roomname") - this gives us the key
let key_hash = sha256_block(&msg);
// Take first 16 bytes (4 words) as the key
var key: array<u32, 4>;
key[0] = key_hash[0];
key[1] = key_hash[1];
key[2] = key_hash[2];
key[3] = key_hash[3];
// Compute SHA256(key) to get channel hash
let channel_hash = sha256_key(key);
// Check if channel hash matches target
if (channel_hash != params.target_channel_hash) {
return;
}
// Channel hash matches - verify MAC if enabled
if (params.verify_mac == 1u) {
let computed_mac = hmac_sha256_mac(key, params.ciphertext_len_bits);
if (computed_mac != params.target_mac) {
return;
}
}
// Found a match - record the index
let match_idx = atomicAdd(&match_count, 1u);
if (match_idx < 1024u) { // Limit stored matches
match_indices[match_idx] = name_idx;
}
}
// Each thread processes 32 candidates to amortize thread overhead
const CANDIDATES_PER_THREAD: u32 = 32u;
@compute @workgroup_size(256)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let base_idx = global_id.x * CANDIDATES_PER_THREAD;
for (var i = 0u; i < CANDIDATES_PER_THREAD; i++) {
let idx = base_idx + i;
if (idx >= params.batch_size) {
return;
}
let name_idx = params.batch_offset + idx;
process_candidate(name_idx);
}
}
`}async init(){if(!navigator.gpu)return console.warn("WebGPU not supported"),!1;try{const o=await navigator.gpu.requestAdapter();if(!o)return console.warn("No GPU adapter found"),!1;this.device=await o.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 n=0;n<2;n++)this.matchCountReadBuffers[n]=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIndicesReadBuffers[n]=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const c=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:c,entryPoint:"main"}}),!0}catch(o){return console.error("WebGPU initialization failed:",o),!1}}isAvailable(){return this.device!==null&&this.pipeline!==null}indexToRoomName(o,c){return ze(c,o)}countNamesForLength(o){return Fr(o)}async runBatch(o,c,l,n,r,a){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 e=this.currentReadBufferIndex;this.currentReadBufferIndex=1-this.currentReadBufferIndex;const A=this.matchCountReadBuffers[e],s=this.matchIndicesReadBuffers[e],i=r&&a?1:0;let u,f=0,y=0;if(i){const m=new Uint8Array(r.length/2);for(let F=0;F<m.length;F++)m[F]=parseInt(r.substr(F*2,2),16);f=m.length*8;const E=Math.ceil(m.length/4)*4,T=new Uint8Array(E);T.set(m),u=new Uint32Array(E/4);for(let F=0;F<u.length;F++)u[F]=T[F*4]<<24|T[F*4+1]<<16|T[F*4+2]<<8|T[F*4+3];const C=parseInt(a.substr(0,2),16),I=parseInt(a.substr(2,2),16);y=C<<24|I<<16}else u=new Uint32Array([0]);const b=Math.max(u.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<b)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:b,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=b,this.bindGroupDirty=!0);const S=new Uint32Array([o,l,c,n,y,u.length,f,i]);this.device.queue.writeBuffer(this.paramsBuffer,0,S),this.device.queue.writeBuffer(this.ciphertextBuffer,0,u),this.device.queue.writeBuffer(this.matchCountBuffer,0,it.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 h=this.device.createCommandEncoder(),d=h.beginComputePass();d.setPipeline(this.pipeline),d.setBindGroup(0,this.bindGroup),d.dispatchWorkgroups(Math.ceil(n/(256*32))),d.end(),h.copyBufferToBuffer(this.matchCountBuffer,0,A,0,4),h.copyBufferToBuffer(this.matchIndicesBuffer,0,s,0,1024*4),this.device.queue.submit([h.finish()]),await A.mapAsync(GPUMapMode.READ);const g=new Uint32Array(A.getMappedRange())[0];A.unmap();const w=[];if(g>0){await s.mapAsync(GPUMapMode.READ);const m=new Uint32Array(s.getMappedRange());for(let E=0;E<Math.min(g,1024);E++)w.push(m[E]);s.unmap()}return w}destroy(){var o,c,l,n,r,a,e,A;(o=this.paramsBuffer)==null||o.destroy(),(c=this.matchCountBuffer)==null||c.destroy(),(l=this.matchIndicesBuffer)==null||l.destroy(),(n=this.ciphertextBuffer)==null||n.destroy(),(r=this.matchCountReadBuffers[0])==null||r.destroy(),(a=this.matchCountReadBuffers[1])==null||a.destroy(),(e=this.matchIndicesReadBuffers[0])==null||e.destroy(),(A=this.matchIndicesReadBuffers[1])==null||A.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}}it.ZERO_DATA=new Uint32Array([0]);function Qr(){return typeof navigator<"u"&&"gpu"in navigator}class ot{constructor(){this.device=null,this.pipeline=null,this.bindGroupL Line truncated
// SHA256 round constants
const K: array<u32, 64> = array<u32, 64>(
0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u,
0xd807aa98u, 0x12835b01u, 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, 0xc19bf174u,
0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau,
0x983e5152u, 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u, 0x06ca6351u, 0x14292967u,
0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u,
0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, 0xd6990624u, 0xf40e3585u, 0x106aa070u,
0x19a4c116u, 0x1e376c08u, 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, 0x682e6ff3u,
0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u
);
// Pre-computed HMAC ipad/opad XOR states for common key padding (0x36/0x5c repeated)
const IPAD_XOR: u32 = 0x36363636u;
const OPAD_XOR: u32 = 0x5c5c5c5cu;
struct Params {
target_channel_hash: u32,
word_count: u32,
i_start: u32, // Starting i index (row) - computed on CPU from 64-bit offset
j_start: u32, // Starting j index (col) - computed on CPU from 64-bit offset
batch_size: u32,
target_mac: u32,
ciphertext_words: u32,
ciphertext_len_bits: u32,
max_combined_len: u32,
_padding: u32,
}
@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var<storage, read_write> match_count: atomic<u32>;
@group(0) @binding(2) var<storage, read_write> match_i: array<u32>; // Separate array for i indices
@group(0) @binding(3) var<storage, read_write> match_j: array<u32>; // Separate array for j indices
@group(0) @binding(4) var<storage, read> ciphertext: array<u32>;
@group(0) @binding(5) var<storage, read> word_data: array<u32>;
@group(0) @binding(6) var<storage, read> word_offsets: array<u32>;
// Inline bit rotation for better performance
fn rotr(x: u32, n: u32) -> u32 {
return (x >> n) | (x << (32u - n));
}
// SHA256 compression function - processes one 64-byte block
// Takes mutable state h and message block msg
fn sha256_compress(h: ptr<function, array<u32, 8>>, msg: ptr<function, array<u32, 16>>) {
var w: array<u32, 64>;
// Load message into first 16 words
w[0] = (*msg)[0]; w[1] = (*msg)[1]; w[2] = (*msg)[2]; w[3] = (*msg)[3];
w[4] = (*msg)[4]; w[5] = (*msg)[5]; w[6] = (*msg)[6]; w[7] = (*msg)[7];
w[8] = (*msg)[8]; w[9] = (*msg)[9]; w[10] = (*msg)[10]; w[11] = (*msg)[11];
w[12] = (*msg)[12]; w[13] = (*msg)[13]; w[14] = (*msg)[14]; w[15] = (*msg)[15];
// Extend message schedule
for (var i = 16u; i < 64u; i++) {
let s0 = rotr(w[i-15u], 7u) ^ rotr(w[i-15u], 18u) ^ (w[i-15u] >> 3u);
let s1 = rotr(w[i-2u], 17u) ^ rotr(w[i-2u], 19u) ^ (w[i-2u] >> 10u);
w[i] = w[i-16u] + s0 + w[i-7u] + s1;
}
var a = (*h)[0]; var b = (*h)[1]; var c = (*h)[2]; var d = (*h)[3];
var e = (*h)[4]; var f = (*h)[5]; var g = (*h)[6]; var hv = (*h)[7];
// Main compression loop
for (var i = 0u; i < 64u; i++) {
let S1 = rotr(e, 6u) ^ rotr(e, 11u) ^ rotr(e, 25u);
let ch = (e & f) ^ (~e & g);
let t1 = hv + S1 + ch + K[i] + w[i];
let S0 = rotr(a, 2u) ^ rotr(a, 13u) ^ rotr(a, 22u);
let maj = (a & b) ^ (a & c) ^ (b & c);
let t2 = S0 + maj;
hv = g; g = f; f = e; e = d + t1;
d = c; c = b; b = a; a = t1 + t2;
}
(*h)[0] += a; (*h)[1] += b; (*h)[2] += c; (*h)[3] += d;
(*h)[4] += e; (*h)[5] += f; (*h)[6] += g; (*h)[7] += hv;
}
// Initialize SHA256 state
fn sha256_init() -> array<u32, 8> {
return array<u32, 8>(
0x6a09e667u, 0xbb67ae85u, 0x3c6ef372u, 0xa54ff53au,
0x510e527fu, 0x9b05688cu, 0x1f83d9abu, 0x5be0cd19u
);
}
// Compute channel hash from 16-byte key
fn compute_channel_hash(key: array<u32, 4>) -> u32 {
var h = sha256_init();
var msg: array<u32, 16>;
msg[0] = key[0]; msg[1] = key[1]; msg[2] = key[2]; msg[3] = key[3];
msg[4] = 0x80000000u;
msg[5] = 0u; msg[6] = 0u; msg[7] = 0u; msg[8] = 0u; msg[9] = 0u;
msg[10] = 0u; msg[11] = 0u; msg[12] = 0u; msg[13] = 0u; msg[14] = 0u;
msg[15] = 128u;
sha256_compress(&h, &msg);
return h[0] >> 24u;
}
// HMAC-SHA256 with precomputed ipad/opad states (optimization from OpenCL version)
// Returns first 2 bytes of HMAC as u32 (in high 16 bits)
fn hmac_sha256_optimized(key: array<u32, 4>) -> u32 {
// Precompute ipad state: SHA256 state after processing (key XOR ipad)
var h_ipad = sha256_init();
var ipad_block: array<u32, 16>;
ipad_block[0] = key[0] ^ IPAD_XOR;
ipad_block[1] = key[1] ^ IPAD_XOR;
ipad_block[2] = key[2] ^ IPAD_XOR;
ipad_block[3] = key[3] ^ IPAD_XOR;
ipad_block[4] = IPAD_XOR; ipad_block[5] = IPAD_XOR; ipad_block[6] = IPAD_XOR; ipad_block[7] = IPAD_XOR;
ipad_block[8] = IPAD_XOR; ipad_block[9] = IPAD_XOR; ipad_block[10] = IPAD_XOR; ipad_block[11] = IPAD_XOR;
ipad_block[12] = IPAD_XOR; ipad_block[13] = IPAD_XOR; ipad_block[14] = IPAD_XOR; ipad_block[15] = IPAD_XOR;
sha256_compress(&h_ipad, &ipad_block);
// Process ciphertext with ipad state
var h = h_ipad;
let ct_words = params.ciphertext_words;
var word_idx = 0u;
// Process full blocks
while (word_idx + 16u <= ct_words) {
var block: array<u32, 16>;
block[0] = ciphertext[word_idx]; block[1] = ciphertext[word_idx+1u];
block[2] = ciphertext[word_idx+2u]; block[3] = ciphertext[word_idx+3u];
block[4] = ciphertext[word_idx+4u]; block[5] = ciphertext[word_idx+5u];
block[6] = ciphertext[word_idx+6u]; block[7] = ciphertext[word_idx+7u];
block[8] = ciphertext[word_idx+8u]; block[9] = ciphertext[word_idx+9u];
block[10] = ciphertext[word_idx+10u]; block[11] = ciphertext[word_idx+11u];
block[12] = ciphertext[word_idx+12u]; block[13] = ciphertext[word_idx+13u];
block[14] = ciphertext[word_idx+14u]; block[15] = ciphertext[word_idx+15u];
sha256_compress(&h, &block);
word_idx += 16u;
}
// Final block with remaining ciphertext + padding
var final_block: array<u32, 16>;
let remaining = ct_words - word_idx;
for (var i = 0u; i < 16u; i++) {
if (i < remaining) {
final_block[i] = ciphertext[word_idx + i];
} else if (i == remaining) {
final_block[i] = 0x80000000u;
} else {
final_block[i] = 0u;
}
}
let total_bits = 512u + params.ciphertext_len_bits;
if (remaining < 14u) {
final_block[14] = 0u;
final_block[15] = total_bits;
sha256_compress(&h, &final_block);
} else {
sha256_compress(&h, &final_block);
var len_block: array<u32, 16>;
for (var i = 0u; i < 14u; i++) { len_block[i] = 0u; }
len_block[14] = 0u;
len_block[15] = total_bits;
sha256_compress(&h, &len_block);
}
// Inner hash complete, now outer hash
// Precompute opad state
var h_opad = sha256_init();
var opad_block: array<u32, 16>;
opad_block[0] = key[0] ^ OPAD_XOR;
opad_block[1] = key[1] ^ OPAD_XOR;
opad_block[2] = key[2] ^ OPAD_XOR;
opad_block[3] = key[3] ^ OPAD_XOR;
opad_block[4] = OPAD_XOR; opad_block[5] = OPAD_XOR; opad_block[6] = OPAD_XOR; opad_block[7] = OPAD_XOR;
opad_block[8] = OPAD_XOR; opad_block[9] = OPAD_XOR; opad_block[10] = OPAD_XOR; opad_block[11] = OPAD_XOR;
opad_block[12] = OPAD_XOR; opad_block[13] = OPAD_XOR; opad_block[14] = OPAD_XOR; opad_block[15] = OPAD_XOR;
sha256_compress(&h_opad, &opad_block);
// Final HMAC block: inner_hash + padding
var hash_block: array<u32, 16>;
hash_block[0] = h[0]; hash_block[1] = h[1]; hash_block[2] = h[2]; hash_block[3] = h[3];
hash_block[4] = h[4]; hash_block[5] = h[5]; hash_block[6] = h[6]; hash_block[7] = h[7];
hash_block[8] = 0x80000000u;
hash_block[9] = 0u; hash_block[10] = 0u; hash_block[11] = 0u;
hash_block[12] = 0u; hash_block[13] = 0u; hash_block[14] = 0u;
hash_block[15] = 512u + 256u;
sha256_compress(&h_opad, &hash_block);
return h_opad[0] & 0xFFFF0000u;
}
// Read a byte from packed word data (big-endian within u32)
fn read_byte(byte_offset: u32) -> u32 {
let word_idx = byte_offset >> 2u;
let byte_in_word = byte_offset & 3u;
let word = word_data[word_idx];
return (word >> ((3u - byte_in_word) << 3u)) & 0xFFu;
}
// Process a single word pair
fn process_word_pair(word1_idx: u32, word2_idx: u32) -> bool {
let offset_len1 = word_offsets[word1_idx];
let offset1 = offset_len1 >> 8u; // 24 bits for offset (up to 16M bytes)
let len1 = offset_len1 & 0xFFu; // 8 bits for length (up to 255 chars)
let offset_len2 = word_offsets[word2_idx];
let offset2 = offset_len2 >> 8u;
let len2 = offset_len2 & 0xFFu;
let combined_len = len1 + len2;
if (combined_len > params.max_combined_len) {
return false;
}
// Check for consecutive dashes at join point
if (len1 > 0u && len2 > 0u) {
let last1 = read_byte(offset1 + len1 - 1u);
let first2 = read_byte(offset2);
if (last1 == 0x2du && first2 == 0x2du) {
return false;
}
}
// Build message: "#" + word1 + word2
var msg: array<u32, 16>;
for (var i = 0u; i < 16u; i++) { msg[i] = 0u; }
let total_len = 1u + combined_len;
var byte_pos = 0u;
var current_word = 0x23000000u; // '#' at position 0
byte_pos = 1u;
// Copy word1
for (var i = 0u; i < len1; i++) {
let c = read_byte(offset1 + i);
let shift = (3u - (byte_pos & 3u)) << 3u;
current_word |= c << shift;
byte_pos++;
if ((byte_pos & 3u) == 0u) {
msg[(byte_pos >> 2u) - 1u] = current_word;
current_word = 0u;
}
}
// Copy word2
for (var i = 0u; i < len2; i++) {
let c = read_byte(offset2 + i);
let shift = (3u - (byte_pos & 3u)) << 3u;
current_word |= c << shift;
byte_pos++;
if ((byte_pos & 3u) == 0u) {
msg[(byte_pos >> 2u) - 1u] = current_word;
current_word = 0u;
}
}
// Add 0x80 padding
let shift = (3u - (byte_pos & 3u)) << 3u;
current_word |= 0x80u << shift;
msg[(byte_pos) >> 2u] = current_word;
msg[15] = total_len << 3u;
// Compute key = SHA256("#" + word1 + word2)
var h = sha256_init();
sha256_compress(&h, &msg);
let key = array<u32, 4>(h[0], h[1], h[2], h[3]);
// Check channel hash first (fast rejection)
if (compute_channel_hash(key) != params.target_channel_hash) {
return false;
}
// Verify MAC (expensive, only if channel hash matches)
return hmac_sha256_optimized(key) == params.target_mac;
}
// Process multiple pairs per thread for better throughput
const PAIRS_PER_THREAD: u32 = 32u;
@compute @workgroup_size(256)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let base_idx = global_id.x * PAIRS_PER_THREAD;
let word_count = params.word_count;
let batch_size = params.batch_size;
// i_start and j_start are computed on CPU from 64-bit batch_offset
// This avoids needing 64-bit math in WGSL
let i_start = params.i_start;
let j_start = params.j_start;
for (var p = 0u; p < PAIRS_PER_THREAD; p++) {
let offset = base_idx + p;
if (offset >= batch_size) { return; }
// Compute actual (i, j) from starting position + offset
// offset = local_i * word_count + local_j where local_j < word_count
let total_j = j_start + offset;
let extra_i = total_j / word_count;
let i = i_start + extra_i;
let j = total_j % word_count;
if (i >= word_count) { return; }
if (process_word_pair(i, j)) {
let idx = atomicAdd(&match_count, 1u);
if (idx < 1024u) {
match_i[idx] = i;
match_j[idx] = j;
}
}
}
}
`}async init(){if(!navigator.gpu)return!1;try{const o=await navigator.gpu.requestAdapter();if(!o)return!1;this.device=await o.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:"storage"}},{binding:4,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"read-only-storage"}}]}),this.paramsBuffer=this.device.createBuffer({size:40,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),this.matchCountBuffer=this.device.createBuffer({size:4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST}),this.matchIBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC}),this.matchJBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC}),this.matchCountReadBuffer=this.device.createBuffer({size:4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchIReadBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST}),this.matchJReadBuffer=this.device.createBuffer({size:1024*4,usage:GPUBufferUsage.MAP_READ|GPUBufferUsage.COPY_DST});const c=this.device.createShaderModule({code:this.shaderCode}),l=this.device.createPipelineLayout({bindGroupLayouts:[this.bindGroupLayout]});return this.pipeline=this.device.createComputePipeline({layout:l,compute:{module:c,entryPoint:"main"}}),!0}catch(o){return console.error("WebGPU word pairs initialization failed:",o),!1}}uploadWords(o){if(!this.device)throw new Error("GPU not initialized");this.wordCount=o.length;let c=0;for(const e of o)c+=e.length;const l=new Uint8Array(Math.ceil(c/4)*4),n=new Uint32Array(o.length);let r=0;for(let e=0;e<o.length;e++){const A=o[e];n[e]=r<<8|A.length;for(let s=0;s<A.length;s++)l[r++]=A.charCodeAt(s)}const a=new Uint32Array(Math.ceil(c/4));for(let e=0;e<a.length;e++)a[e]=l[e*4]<<24|l[e*4+1]<<16|l[e*4+2]<<8|l[e*4+3];this.wordDataBuffer&&this.wordDataBuffer.destroy(),this.wordOffsetsBuffer&&this.wordOffsetsBuffer.destroy(),this.wordDataBuffer=this.device.createBuffer({size:Math.max(a.byteLength,4),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.device.queue.writeBuffer(this.wordDataBuffer,0,a),this.wordOffsetsBuffer=this.device.createBuffer({size:n.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.device.queue.writeBuffer(this.wordOffsetsBuffer,0,n)}async runBatch(o,c,l,n,r){if(!this.device||!this.pipeline||!this.bindGroupLayout||!this.paramsBuffer||!this.matchCountBuffer||!this.matchIBuffer||!this.matchJBuffer||!this.matchCountReadBuffer||!this.matchIReadBuffer||!this.matchJReadBuffer||!this.wordDataBuffer||!this.wordOffsetsBuffer)throw new Error("GPU not initialized or words not uploaded");const a=new Uint8Array(n.length/2);for(let C=0;C<a.length;C++)a[C]=parseInt(n.substr(C*2,2),16);const e=a.length*8,A=Math.ceil(a.length/4)*4,s=new Uint8Array(A);s.set(a);const i=new Uint32Array(A/4);for(let C=0;C<i.length;C++)i[C]=s[C*4]<<24|s[C*4+1]<<16|s[C*4+2]<<8|s[C*4+3];const u=parseInt(r.substr(0,2),16),f=parseInt(r.substr(2,2),16),y=u<<24|f<<16,b=Math.max(i.length*4,4);(!this.ciphertextBuffer||this.ciphertextBufferSize<b)&&(this.ciphertextBuffer&&this.ciphertextBuffer.destroy(),this.ciphertextBuffer=this.device.createBuffer({size:b,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),this.ciphertextBufferSize=b);const S=Math.floor(c/this.wordCount),h=c%this.wordCount,d=new Uint32Array([o,this.wordCount,S,h,l,y,i.length,e,30,0]);this.device.queue.writeBuffer(this.paramsBuffer,0,d),this.device.queue.writeBuffer(this.ciphertextBuffer,0,i),this.device.queue.writeBuffer(this.matchCountBuffer,0,ot.ZERO_DATA);const x=this.device.createBindGroup({layout:this.bindGroupLayout,entries:[{binding:0,resource:{buffer:this.paramsBuffer}},{binding:1,resource:{buffer:this.matchCountBuffer}},{binding:2,resource:{buffer:this.matchIBuffer}},{binding:3,resource:{buffer:this.matchJBuffer}},{binding:4,resource:{buffer:this.ciphertextBuffer}},{binding:5,resource:{buffer:this.wordDataBuffer}},{binding:6,resource:{buffer:this.wordOffsetsBuffer}}]}),g=this.device.createCommandEncoder(),w=g.beginComputePass();w.setPipeline(this.pipeline),w.setBindGroup(0,x),w.dispatchWorkgroups(Math.ceil(l/(256*32))),w.end(),g.copyBufferToBuffer(this.matchCountBuffer,0,this.matchCountReadBuffer,0,4),g.copyBufferToBuffer(this.matchIBuffer,0,this.matchIReadBuffer,0,1024*4),g.copyBufferToBuffer(this.matchJBuffer,0,this.matchJReadBuffer,0,1024*4),this.device.queue.submit([g.finish()]),await this.matchCountReadBuffer.mapAsync(GPUMapMode.READ);const E=new Uint32Array(this.matchCountR Line truncated
`).map(r=>r.trim().toLowerCase()).filter(r=>r.length>0);this.wordlist=n.filter(ft)}setWordlist(o){this.wordlist=o.map(c=>c.trim().toLowerCase()).filter(ft)}abort(){this.abortFlag=!0}isGpuAvailable(){return Qr()}async decodePacket(o){var l;const c=o.trim().replace(/\s+/g,"").replace(/^0x/i,"");if(!c||!/^[0-9a-fA-F]+$/.test(c))return null;try{const r=(l=(await Xt.MeshCorePacketDecoder.decodeWithVerification(c,{})).payload)==null?void 0:l.decoded;return!(r!=null&&r.channelHash)||!(r!=null&&r.ciphertext)||!(r!=null&&r.cipherMac)?null:{channelHash:r.channelHash.toLowerCase(),ciphertext:r.ciphertext.toLowerCase(),cipherMac:r.cipherMac.toLowerCase(),isGroupText:!0}}catch{return null}}async crack(o,c,l){this.abortFlag=!1,this.useTimestampFilter=(c==null?void 0:c.useTimestampFilter)??!0,this.useUtf8Filter=(c==null?void 0:c.useUtf8Filter)??!0,this.useSenderFilter=(c==null?void 0:c.useSenderFilter)??!0,this.validSeconds=(c==null?void 0:c.validSeconds)??bt,this.useCpu=(c==null?void 0:c.forceCpu)??!1;const n=(c==null?void 0:c.maxLength)??8,r=(c==null?void 0:c.startingLength)??1,a=(c==null?void 0:c.useDictionary)??!0,e=(c==null?void 0:c.useTwoWordCombinations)??!1,A=(c==null?void 0:c.startFromType)??"bruteforce",s=o.toLowerCase(),i=await this.decodePacket(s);if(!i)return{found:!1,error:"Invalid packet or not a GroupText packet"};const{channelHash:u,ciphertext:f,cipherMac:y}=i,b=parseInt(u,16);this.useCpu?this.cpuInstance||(this.cpuInstance=new zt):this.gpuInstance||(this.gpuInstance=new it,await this.gpuInstance.init()||(this.useCpu=!0,this.cpuInstance=new zt));const S=performance.now();let h=0,d=performance.now(),x=r,g=0,w=0,m=!1,E=!1,T=0,C=0;if(c!=null&&c.startFrom){const R=c.startFrom.toLowerCase();if(A==="dictionary"){const P=this.wordlist.indexOf(R);P>=0&&(w=P+1)}else if(A==="dictionary-pair"){m=!0;const P=R.indexOf("+");P>0&&(c._pairResumeWord1=R.substring(0,P),c._pairResumeWord2=R.substring(P+1))}else{m=!0,E=!0;const P=Vr(R);P&&(x=Math.max(r,P.length),g=P.index+1,g>=ht(x)&&(x++,g=0))}}let I=0;a&&!m&&this.wordlist.length>0&&(I+=this.wordlist.length-w);const F=30,ce=15;let D=[],$=[],J=0,ae=[],le=[];if(a&&e&&!E&&this.wordlist.length>0){D=this.wordlist.filter(O=>O.length<=ce),$=D.map(O=>O.length);const R=c;if(R._pairResumeWord1&&R._pairResumeWord2){const O=D.indexOf(R._pairResumeWord1),G=D.indexOf(R._pairResumeWord2);O>=0&&G>=0&&(T=O,C=G+1,C>=D.length&&(T++,C=0))}ae=new Array(ce+1).fill(0);for(const O of $)ae[O]++;le=new Array(F+1).fill(0);let P=0;for(let O=0;O<=F;O++)O<=ce&&(P+=ae[O]),le[O]=P;for(let O=T;O<D.length;O++){const G=$[O],re=F-G,X=le[Math.min(re,ce)];O===T&&C>0?J+=Math.max(0,X-C):J+=X}I+=J}for(let R=x;R<=n;R++)I+=ht(R);I-=g;const Q=(R,P,O)=>{if(!l)return;const re=(performance.now()-S)/1e3,X=re>0?Math.round(h/re):0,pe=I-h,ue=X>0?pe/X:0;l({checked:h,total:I,percent:I>0?Math.min(100,h/I*100):0,rateKeysPerSec:X,etaSeconds:ue,elapsedSeconds:re,currentLength:P,currentPosition:O,phase:R})},he=R=>{if(!cr(f,y,R))return{valid:!1};const P=Xt.ChannelCrypto.decryptGroupTextMessage(f,y,R);return!P.success||!P.data?{valid:!1}:this.useTimestampFilter&&!Ur(P.data.timestamp,this.validSeconds)?{valid:!1}:this.useUtf8Filter&&!Gr(P.data.message)?{valid:!1}:this.useSenderFilter&&!P.data.sender?{valid:!1}:{valid:!0,message:P.data.sender?`${P.data.sender}: ${P.data.message}`:P.data.message}};if(!m&&w===0&&x===r&&g===0){Q("public-key",0,pt);const R=st(At);if(u===R){const P=he(At);if(P.valid)return{found:!0,roomName:pt,key:At,decryptedMessage:P.message}}}let L,Z;const ye=()=>({found:!1,aborted:!0,resumeFrom:L,resumeType:Z});if(a&&!m&&this.wordlist.length>0)for(let R=w;R<this.wordlist.length;R++){if(this.abortFlag)return ye();const P=this.wordlist[R],O=Je("#"+P),G=st(O);if(parseInt(G,16)===b){const X=he(O);if(X.valid)return{found:!0,roomName:P,key:O,decryptedMessage:X.message,resumeFrom:P,resumeType:"dictionary"}}h++,L=P,Z="dictionary";const re=performance.now();re-d>=200&&(Q("wordlist",P.length,P),d=re,await new Promise(X=>setTimeout(X,0)))}if(a&&e&&!E&&D.length>0){const R=D.length*D.length,P=T*D.length+C;let O=!this.useCpu;if(O&&(this.gpuWordPairs||(this.gpuWordPairs=new ot,await this.gpuWordPairs.init()||(O=!1,this.gpuWordPairs=null)),this.gpuWordPairs&&this.gpuWordPairs.uploadWords(D)),O&&this.gpuWordPairs){const X=(c==null?void 0:c.gpuDispatchMs)??1e3;let pe=1048576,ue=!1,Ae=P;for(;Ae<R;){if(this.abortFlag)return ye();const fe=Math.min(pe,R-Ae),_=performance.now(),V=await this.gpuWordPairs.runBatch(b,Ae,fe,f,y),U=performance.now()-_;if(h+=fe,!ue&&fe>=1048576&&U>0){const j=X/U,ne=Math.round(fe*j),q=Math.pow(2,Math.round(Math.log2(Math.max(1048576,ne))));pe=Math.min(Math.max(1048576,q),536862720),ue=!0}for(const[j,ne]of V){const q=D[j],we=D[ne],Ce=q+we,et=Je("#"+Ce),tt=he(et);if(tt.valid)return{found:!0,roomName:Ce,key:et,decryptedMessage:tt.message,resumeFrom:`${q}+${we}`,resumeType:"dictionary-pair"}}Ae+=fe;const me=Ae-1,de=Math.floor(me/D.length),se=me%D.length;de<D.length&&(L=`${D[de]}+${D[se]}`,Z="dictionary-pair");const Y= 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(e=>(this.enabled=!0,e)).catch(e=>{throw this.enabled=!1,e})}disable(){l()?(this._wakeLock&&this._wakeLock.release(),this._wakeLock=null):c()?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 mt=n,mt}var Kr=Zr();const Xr=nt(Kr);function Jr({packets:t,channels:o,onChannelCreate:c,onRunningChange:l,visible:n=!1}){const[r,a]=H.useState(!1),[e,A]=H.useState(6),[s,i]=H.useState(!1),[u,f]=H.useState(!0),[y,b]=H.useState(!1),[S,h]=H.useState(!1),[d,x]=H.useState(null),[g,w]=H.useState(new Map),[m,E]=H.useState([]),[T,C]=H.useState(!1),[I,F]=H.useState(null),[ce,D]=H.useState(null),[$,J]=H.useState(0),ae=H.useRef(null),le=H.useRef(null),Q=H.useRef(!1),he=H.useRef(!1),L=H.useRef(!1),Z=H.useRef(new Map),ye=H.useRef(!1),Be=H.useRef(6),Te=H.useRef(!0),v=H.useRef(!1),ee=H.useRef(!1),ge=H.useRef(new Set),R=H.useRef(new Set),P=H.useRef(new Set);H.useEffect(()=>{const _=new jr;ae.current=_,F(_.isGpuAvailable());const V=new Xr;return le.current=V,()=>{_.destroy(),ae.current=null,V.disable(),le.current=null}},[]),H.useEffect(()=>{!n||T||fr(async()=>{const{ENGLISH_WORDLIST:_}=await import("./wordlist-BtmChKSf.js");return{ENGLISH_WORDLIST:_}},[]).then(({ENGLISH_WORDLIST:_})=>{ae.current&&(ae.current.setWordlist(_),C(!0))}).catch(_=>{console.error("Failed to load wordlist:",_),dt.error("Failed to load wordlist",{description:"Cracking will not be available"})})},[n,T]),H.useEffect(()=>{const _=()=>{Ct.getUndecryptedPacketCount().then(({count:U})=>D(U)).catch(()=>D(null))};_();const V=setInterval(_,36e5);return()=>clearInterval(V)},[]);const O=H.useMemo(()=>new Set(o.map(_=>_.key.toUpperCase())),[o]);H.useEffect(()=>{P.current=O},[O]);const G=t.filter(_=>_.payload_type==="GROUP_TEXT"&&!_.decrypted);H.useEffect(()=>{let _=0;w(V=>{const U=new Map(V);let me=!1;for(const de of G)if(!U.has(de.id)){const se=gr(de.data);if(se&&R.current.has(se)){_++;continue}se&&R.current.add(se),U.set(de.id,{packet:de,attempts:0,lastAttemptLength:0,status:"pending"}),me=!0}return me?(Z.current=U,U):V}),_>0&&J(V=>V+_)},[G.length]),H.useEffect(()=>{Z.current=g},[g]),H.useEffect(()=>{ye.current=s},[s]),H.useEffect(()=>{Be.current=e},[e]),H.useEffect(()=>{Te.current=u},[u]),H.useEffect(()=>{v.current=y},[y]),H.useEffect(()=>{ee.current=S},[S]),H.useEffect(()=>{ge.current=new Set(G.map(_=>_.id))},[G]),H.useEffect(()=>{l==null||l(r)},[r,l]);const re=Array.from(g.values()).filter(_=>_.status==="pending").length,X=Array.from(g.values()).filter(_=>_.status==="cracked").length,pe=Array.from(g.values()).filter(_=>_.status==="failed").length,ue=H.useCallback(async()=>{if(L.current||!ae.current||!Q.current)return;const _=Z.current;let V=null,U=null;for(const[Y,j]of _.entries())if(j.status==="pending"){V=j,U=Y;break}if(!V&&ye.current){const Y=Array.from(_.entries()).filter(([,j])=>j.status==="failed"&&j.lastAttemptLength<10);Y.length>0&&(Y.sort((j,ne)=>j[1].lastAttemptLength-ne[1].lastAttemptLength),[U,V]=Y[0])}if(!V||U===null){Q.current&&setTimeout(()=>ue(),1e3);return}if(!ge.current.has(U)){w(Y=>{const j=new Map(Y);return j.delete(U),j}),Q.current&&setTimeout(()=>ue(),10);return}L.current=!0;const me=Be.current,de=V.lastAttemptLength>0,se=de?V.lastAttemptLength+1:me;try{const Y=await ae.current.crack(V.packet.data,{maxLength:se,useSenderFilter:!0,useTimestampFilter:!0,useUtf8Filter:!0,useTwoWordCombinations:ee.current,...v.current&&{gpuDispatchMs:1e4},...de&&{useDictionary:!1,useTwoWordCombinations:!1,startingLength:se}},j=>{x(j)});if(he.current){he.current=!1,L.current=!1,x(null);return}if(Y.found&&Y.roomName&&Y.key){w(q=>{const we=new Map(q),Ce=we.get(U);return Ce&&we.set(U,{...Ce,status:"cracked",attempts:Ce.attempts+1,lastAttemptLength:se}),we});const j={roomName:Y.roomName,key:Y.key,packetId:U,message:Y.decryptedMessage||"",crackedAt:Date.now()};E(q=>[...q,j]);const ne=Y.key.toUpperCase();if(!P.current.has(ne))try{const q="#"+Y.roomName;await c(q,Y.key),Te.current&&await Ct.decryptHistoricalPackets({key_type:"channel",channel_name:q})}catch(q){console.error("Failed to create channel or decrypt historical:",q),dt.error("Failed to save cracked channel",{description:q instanceof Error?q.message:"Channel discovered but could not be saved"})}}else w(j=>{const ne=new Map(j),q=ne.get(U);return q&&ne.set(U,{...q,status:"failed",attempts:q.attempts+1,lastAttemptLength:se}),ne})}catch(Y){console.error("Cracking error:",Y),w(j=>{const ne=new Map(j),q=ne.get(U);return q&&ne.set(U,{...q,status:"failed",attempts:q.attempts+1,lastAttemptLength:se}),ne})}L.current=!1,x(null),Q.current&&setTimeout(()=>ue(),100)},[c]),Ae=()=>{var _;if(!I){dt.error("WebGPU not available",{description:"Cracking requires Chrome 113+ or Edge 113+ with WebGPU support."});return}a(!0),Q.current=!0,he.current=!1,(_=le.current)==null||_.enable(),ue()},fe=()=>{var _,V;a(!1),Q.current=!1,he.current=!0,(_=ae.current)==null||_.abort(),(V=le.current)==null||V.disable()};return M.jsxs("div",{className:"flex flex-col h-full p-3 gap-3 bg-background border-t border-border overflow-auto",children:[M.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[M.jsxs("d Line truncated
//# sourceMappingURL=CrackerPanel-RTfofPO9.js.map
@@ -0,0 +1 @@
{"version":3,"mappings":"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 truncated
@@ -0,0 +1,2 @@
import{r as d,D as j,j as e,U as y,m as N}from"./index-BJ3L5G2s.js";import{M as w,T as _}from"./leaflet-TNk2YzRY.js";import{C as k,P as C}from"./Popup-JtfOLvZE.js";import{u as M}from"./hooks-NBTgSuxX.js";const i={recent:"#06b6d4",today:"#2563eb",stale:"#f59e0b",old:"#64748b"},R="#0f172a",p="#f8fafc";function E(a){if(a==null)return i.old;const r=Date.now()/1e3-a,n=3600,l=86400;return r<n?i.recent:r<l?i.today:r<3*l?i.stale:i.old}function v({contacts:a,focusedContact:t}){const r=M(),[n,l]=d.useState(!1);return d.useEffect(()=>{if(t&&t.lat!=null&&t.lon!=null){r.setView([t.lat,t.lon],12),l(!0);return}if(n)return;const c=()=>{if(a.length===0){r.setView([20,0],2),l(!0);return}if(a.length===1){r.setView([a[0].lat,a[0].lon],10),l(!0);return}const u=a.map(m=>[m.lat,m.lon]);r.fitBounds(u,{padding:[50,50],maxZoom:12}),l(!0)};"geolocation"in navigator?navigator.geolocation.getCurrentPosition(u=>{r.setView([u.coords.latitude,u.coords.longitude],8),l(!0)},()=>{c()},{timeout:5e3,maximumAge:3e5}):c()},[r,a,n,t]),null}function V({contacts:a,focusedKey:t}){const r=Date.now()/1e3-604800,n=d.useMemo(()=>a.filter(s=>j(s.lat,s.lon)&&(s.public_key===t||s.last_seen!=null&&s.last_seen>r)),[a,t,r]),l=d.useMemo(()=>t&&n.find(s=>s.public_key===t)||null,[t,n]),c=l!=null&&(l.last_seen==null||l.last_seen<=r),u=d.useRef({}),m=d.useCallback((s,o)=>{u.current[s]=o},[]);return d.useEffect(()=>{if(l&&u.current[l.public_key]){const s=setTimeout(()=>{var o;(o=u.current[l.public_key])==null||o.openPopup()},100);return()=>clearTimeout(s)}},[l]),e.jsxs("div",{className:"flex flex-col h-full",children:[e.jsxs("div",{className:"px-4 py-2 bg-muted/50 text-xs text-muted-foreground flex items-center justify-between",children:[e.jsxs("span",{children:["Showing ",n.length," contact",n.length!==1?"s":""," heard in the last 7 days",c?" plus the focused contact":""]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 rounded-full",style:{backgroundColor:i.recent},"aria-hidden":"true"})," ","<1h"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 rounded-full",style:{backgroundColor:i.today},"aria-hidden":"true"})," ","<1d"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 rounded-full",style:{backgroundColor:i.stale},"aria-hidden":"true"})," ","<3d"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 rounded-full",style:{backgroundColor:i.old},"aria-hidden":"true"})," ","older"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-3 h-3 rounded-full border-2",style:{borderColor:p,backgroundColor:i.today},"aria-hidden":"true"})," ","repeater"]})]})]}),e.jsx("div",{className:"flex-1 relative",style:{zIndex:0},role:"img","aria-label":"Map showing mesh node locations",children:e.jsxs(w,{center:[20,0],zoom:2,className:"h-full w-full",style:{background:"#1a1a2e"},children:[e.jsx(_,{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"}),e.jsx(v,{contacts:n,focusedContact:l}),n.map(s=>{const o=s.type===y,x=E(s.last_seen),f=s.name||s.public_key.slice(0,12),h=s.last_seen!=null?N(s.last_seen):"Never heard by this server",g=o?10:7;return e.jsx(d.Fragment,{children:e.jsx(k,{ref:b=>m(s.public_key,b),center:[s.lat,s.lon],radius:g,pathOptions:{color:o?p:R,fillColor:x,fillOpacity:.9,weight:o?3:2},children:e.jsx(C,{children:e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"font-medium flex items-center gap-1",children:[o&&e.jsx("span",{title:"Repeater","aria-hidden":"true",children:"🛜"}),f]}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1",children:["Last heard: ",h]}),e.jsxs("div",{className:"text-xs text-gray-400 mt-1 font-mono",children:[s.lat.toFixed(5),", ",s.lon.toFixed(5)]})]})})},s.public_key)},s.public_key)})]})})]})}export{V as MapView};
//# sourceMappingURL=MapView-DG71Do9A.js.map
@@ -0,0 +1 @@
{"version":3,"file":"MapView-DG71Do9A.js","sources":["../../src/components/MapView.tsx"],"sourcesContent":["import { Fragment, useEffect, useState, useMemo, useRef, useCallback } from 'react';\nimport { MapContainer, TileLayer, CircleMarker, Popup, useMap } from 'react-leaflet';\nimport type { LatLngBoundsExpression, CircleMarker as LeafletCircleMarker } from 'leaflet';\nimport 'leaflet/dist/leaflet.css';\nimport type { Contact } from '../types';\nimport { formatTime } from '../utils/messageParser';\nimport { isValidLocation } from '../utils/pathUtils';\nimport { CONTACT_TYPE_REPEATER } from '../types';\n\ninterface MapViewProps {\n contacts: Contact[];\n /** Public key of contact to focus on and open popup */\n focusedKey?: string | null;\n}\n\nconst MAP_RECENCY_COLORS = {\n recent: '#06b6d4',\n today: '#2563eb',\n stale: '#f59e0b',\n old: '#64748b',\n} as const;\nconst MAP_MARKER_STROKE = '#0f172a';\nconst MAP_REPEATER_RING = '#f8fafc';\n\n// Calculate marker color based on how recently the contact was heard\nfunction getMarkerColor(lastSeen: number | null | undefined): string {\n if (lastSeen == null) return MAP_RECENCY_COLORS.old;\n const now = Date.now() / 1000;\n const age = now - lastSeen;\n const hour = 3600;\n const day = 86400;\n\n if (age < hour) return MAP_RECENCY_COLORS.recent;\n if (age < day) return MAP_RECENCY_COLORS.today;\n if (age < 3 * day) return MAP_RECENCY_COLORS.stale;\n return MAP_RECENCY_COLORS.old;\n}\n\n// Component to handle map bounds fitting\nfunction MapBoundsHandler({\n contacts,\n focusedContact,\n}: {\n contacts: Contact[];\n focusedContact: Contact | null;\n}) {\n const map = useMap();\n const [hasInitialized, setHasInitialized] = useState(false);\n\n useEffect(() => {\n // If we have a focused contact, center on it immediately (even if already initialized)\n if (focusedContact && focusedContact.lat != null && focusedContact.lon != null) {\n map.setView([focusedContact.lat, focusedContact.lon], 12);\n setHasInitialized(true);\n return;\n }\n\n if (hasInitialized) return;\n\n const fitToContacts = () => {\n if (contacts.length === 0) {\n // No contacts with location - show world view\n map.setView([20, 0], 2);\n setHasInitialized(true);\n return;\n }\n\n if (contacts.length === 1) {\n // Single contact - center on it\n map.setView([contacts[0].lat!, contacts[0].lon!], 10);\n setHasInitialized(true);\n return;\n }\n\n // Multiple contacts - fit bounds\n const bounds: LatLngBoundsExpression = contacts.map(\n (c) => [c.lat!, c.lon!] as [number, number]\n );\n map.fitBounds(bounds, { padding: [50, 50], maxZoom: 12 });\n setHasInitialized(true);\n };\n\n // Try geolocation first\n if ('geolocation' in navigator) {\n navigator.geolocation.getCurrentPosition(\n (position) => {\n // Success - center on user location with reasonable zoom\n map.setView([position.coords.latitude, position.coords.longitude], 8);\n setHasInitialized(true);\n },\n () => {\n // Geolocation denied/failed - fit to contacts\n fitToContacts();\n },\n { timeout: 5000, maximumAge: 300000 }\n );\n } else {\n // No geolocation support - fit to contacts\n fitToContacts();\n }\n }, [map, contacts, hasInitialized, focusedContact]);\n\n return null;\n}\n\nexport function MapView({ contacts, focusedKey }: MapViewProps) {\n const sevenDaysAgo = Date.now() / 1000 - 7 * 24 * 60 * 60;\n\n // Filter to contacts with GPS coordinates, heard within the last 7 days.\n // Always include the focused contact so \"view on map\" links work for older nodes.\n const mappableContacts = useMemo(() => {\n return contacts.filter(\n (c) =>\n isValidLocation(c.lat, c.lon) &&\n (c.public_key === focusedKey || (c.last_seen != null && c.last_seen > sevenDaysAgo))\n );\n }, [contacts, focusedKey, sevenDaysAgo]);\n\n // Find the focused contact by key\n const focusedContact = useMemo(() => {\n if (!focusedKey) return null;\n return mappableContacts.find((c) => c.public_key === focusedKey) || null;\n }, [focusedKey, mappableContacts]);\n\n const includesFocusedOutsideWindow =\n focusedContact != null &&\n (focusedContact.last_seen == null || focusedContact.last_seen <= sevenDaysAgo);\n\n // Track marker refs to open popup programmatically\n const markerRefs = useRef<Record<string, LeafletCircleMarker | null>>({});\n\n // Store ref for a marker\n const setMarkerRef = useCallback((key: string, ref: LeafletCircleMarker | null) => {\n markerRefs.current[key] = ref;\n }, []);\n\n // Open popup for focused contact after map is ready\n useEffect(() => {\n if (focusedContact && markerRefs.current[focusedContact.public_key]) {\n // Small delay to ensure map has finished rendering\n const timer = setTimeout(() =>Line truncated
@@ -0,0 +1,2 @@
import{j as l}from"./index-BJ3L5G2s.js";import{d as m,l as u,a as f,e as d,M as x,T as y}from"./leaflet-TNk2YzRY.js";import{C as p,P as c}from"./Popup-JtfOLvZE.js";const g=m(function({positions:n,...t},o){const s=new u.Polyline(n,t);return f(s,d(o,{overlayContainer:s}))},function(n,t,o){t.positions!==o.positions&&n.setLatLngs(t.positions)});function C({neighbors:i,radioLat:n,radioLon:t,radioName:o}){const s=i.filter(e=>e.lat!=null&&e.lon!=null),r=n!=null&&t!=null&&!(n===0&&t===0);if(s.length===0&&!r)return null;const h=r?[n,t]:[s[0].lat,s[0].lon];return l.jsx("div",{className:"min-h-48 flex-1 rounded border border-border overflow-hidden",role:"img","aria-label":"Map showing repeater neighbor locations",children:l.jsxs(x,{center:h,zoom:10,className:"h-full w-full",style:{background:"#1a1a2e"},children:[l.jsx(y,{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"}),r&&s.map((e,a)=>l.jsx(g,{positions:[[n,t],[e.lat,e.lon]],pathOptions:{color:"#3b82f6",weight:1.5,opacity:.5,dashArray:"6 4"}},`line-${a}`)),r&&l.jsx(p,{center:[n,t],radius:8,pathOptions:{color:"#1d4ed8",fillColor:"#3b82f6",fillOpacity:1,weight:2},children:l.jsx(c,{children:l.jsx("span",{className:"text-sm font-medium",children:o||"Our Radio"})})}),s.map((e,a)=>l.jsx(p,{center:[e.lat,e.lon],radius:6,pathOptions:{color:"#000",fillColor:e.snr>=6?"#22c55e":e.snr>=0?"#eab308":"#ef4444",fillOpacity:.8,weight:1},children:l.jsx(c,{children:l.jsx("span",{className:"text-sm",children:e.name||e.pubkey_prefix})})},a))]})})}export{C as NeighborsMiniMap};
//# sourceMappingURL=NeighborsMiniMap-D6bvxuvI.js.map
@@ -0,0 +1 @@
{"version":3,"file":"NeighborsMiniMap-D6bvxuvI.js","sources":["../../node_modules/react-leaflet/lib/Polyline.js","../../src/components/NeighborsMiniMap.tsx"],"sourcesContent":["import { createElementObject, createPathComponent, extendContext } from '@react-leaflet/core';\nimport { Polyline as LeafletPolyline } from 'leaflet';\nexport const Polyline = createPathComponent(function createPolyline({ positions , ...options }, ctx) {\n const polyline = new LeafletPolyline(positions, options);\n return createElementObject(polyline, extendContext(ctx, {\n overlayContainer: polyline\n }));\n}, function updatePolyline(layer, props, prevProps) {\n if (props.positions !== prevProps.positions) {\n layer.setLatLngs(props.positions);\n }\n});\n","import { MapContainer, TileLayer, CircleMarker, Popup, Polyline } from 'react-leaflet';\nimport 'leaflet/dist/leaflet.css';\n\ninterface Neighbor {\n lat: number | null;\n lon: number | null;\n name: string | null;\n pubkey_prefix: string;\n snr: number;\n}\n\ninterface Props {\n neighbors: Neighbor[];\n radioLat?: number | null;\n radioLon?: number | null;\n radioName?: string | null;\n}\n\nexport function NeighborsMiniMap({ neighbors, radioLat, radioLon, radioName }: Props) {\n const valid = neighbors.filter(\n (n): n is Neighbor & { lat: number; lon: number } => n.lat != null && n.lon != null\n );\n\n const hasRadio = radioLat != null && radioLon != null && !(radioLat === 0 && radioLon === 0);\n\n if (valid.length === 0 && !hasRadio) return null;\n\n // Center on radio if available, otherwise first neighbor\n const center: [number, number] = hasRadio ? [radioLat!, radioLon!] : [valid[0].lat, valid[0].lon];\n\n return (\n <div\n className=\"min-h-48 flex-1 rounded border border-border overflow-hidden\"\n role=\"img\"\n aria-label=\"Map showing repeater neighbor locations\"\n >\n <MapContainer\n center={center}\n zoom={10}\n className=\"h-full w-full\"\n style={{ background: '#1a1a2e' }}\n >\n <TileLayer\n attribution='&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a>'\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\n />\n {/* Dotted lines from radio to each neighbor */}\n {hasRadio &&\n valid.map((n, i) => (\n <Polyline\n key={`line-${i}`}\n positions={[\n [radioLat!, radioLon!],\n [n.lat, n.lon],\n ]}\n pathOptions={{\n color: '#3b82f6',\n weight: 1.5,\n opacity: 0.5,\n dashArray: '6 4',\n }}\n />\n ))}\n {/* Radio node (bright blue) */}\n {hasRadio && (\n <CircleMarker\n center={[radioLat!, radioLon!]}\n radius={8}\n pathOptions={{\n color: '#1d4ed8',\n fillColor: '#3b82f6',\n fillOpacity: 1,\n weight: 2,\n }}\n >\n <Popup>\n <span className=\"text-sm font-medium\">{radioName || 'Our Radio'}</span>\n </Popup>\n </CircleMarker>\n )}\n {/* Neighbor nodes (SNR-colored) */}\n {valid.map((n, i) => (\n <CircleMarker\n key={i}\n center={[n.lat, n.lon]}\n radius={6}\n pathOptions={{\n color: '#000',\n fillColor: n.snr >= 6 ? '#22c55e' : n.snr >= 0 ? '#eab308' : '#ef4444',\n fillOpacity: 0.8,\n weight: 1,\n }}\n >\n <Popup>\n <span className=\"text-sm\">{n.name || n.pubkey_prefix}</span>\n </Popup>\n </CircleMarker>\n ))}\n </MapContainer>\n </div>\n );\n}\n"],"names":["Polyline","createPathComponent","positions","options","ctx","polyline","LeafletPolyline","createElementObject","extendContext","layer","props","prevProps","NeighborsMiniMap","neighbors","radioLat","radioLon","radioName","valid","n","hasRadio","center","jsx","jsxs","MapContainer","TileLayer","i","CircleMarker","Popup"],"mappings":"oKAEO,MAAMA,EAAWC,EAAoB,SAAwB,CAAE,UAAAC,EAAY,GAAGC,CAAO,EAAIC,EAAK,CACjG,MAAMC,EAAW,IAAIC,WAAgBJ,EAAWC,CAAO,EACvD,OAAOI,EAAoBF,EAAUG,EAAcJ,EAAK,CACpD,iBAAkBC,CAC1B,CAAK,CAAC,CACN,EAAG,SAAwBI,EAAOC,EAAOC,EAAW,CAC5CD,EAAM,YAAcC,EAAU,WAC9BF,EAAM,WAAWC,EAAM,SAAS,CAExC,CAAC,ECOM,SAASE,EAAiB,CAAE,UAAAC,EAAW,SAAAC,EAAU,SAAAC,EAAU,UAAAC,GAAoB,CACpF,MAAMC,EAAQJ,EAAU,OACrBK,GAAoDA,EAAE,KAAO,MAAQA,EAAE,KAAO,IAAA,EAG3EC,EAAWL,GAAY,MAAQC,GAAY,MAAQ,EAAED,IAAa,GAAKC,IAAa,GAE1F,GAAIE,EAAM,SAAW,GAAK,CAACE,EAAU,OAAO,KAG5C,MAAMC,EAA2BD,EAAW,CAACL,EAAWC,CAAS,EAAI,CAACE,EAAM,CAAC,EAAE,IAAKA,EAAM,CAAC,EAAE,GAAG,EAEhG,OACEI,EAAAA,IAAC,MAAA,CACC,UAAU,+DACV,KAAK,MACL,aAAW,0CAEX,SAAAC,EAAAA,KAACC,EAAA,CACC,OAAAH,EACA,KAAM,GACN,UAAU,gBACV,MAAO,CAAE,WAAY,SAAA,EAErB,SALine truncated
@@ -0,0 +1,9 @@
import{r as x,D as l,j as i}from"./index-BJ3L5G2s.js";import{c as O,l as b,a as y,e as w,b as C,M as L,T as M,L as R}from"./leaflet-TNk2YzRY.js";import{u as T}from"./hooks-NBTgSuxX.js";const h=O(function({position:n,...t},o){const r=new b.Marker(n,t);return y(r,w(o,{overlayContainer:r}))},function(n,t,o){t.position!==o.position&&n.setLatLng(t.position),t.icon!=null&&t.icon!==o.icon&&n.setIcon(t.icon),t.zIndexOffset!=null&&t.zIndexOffset!==o.zIndexOffset&&n.setZIndexOffset(t.zIndexOffset),t.opacity!=null&&t.opacity!==o.opacity&&n.setOpacity(t.opacity),n.dragging!=null&&t.draggable!==o.draggable&&(t.draggable===!0?n.dragging.enable():n.dragging.disable())}),p=C(function(n,t){const o=new b.Tooltip(n,t.overlayContainer);return y(o,t)},function(n,t,{position:o},r){x.useEffect(function(){const s=t.overlayContainer;if(s==null)return;const{instance:u}=n,f=a=>{a.tooltip===u&&(o!=null&&u.setLatLng(o),u.update(),r(!0))},c=a=>{a.tooltip===u&&r(!1)};return s.on({tooltipopen:f,tooltipclose:c}),s.bindTooltip(u),function(){s.off({tooltipopen:f,tooltipclose:c}),s._map!=null&&s.unbindTooltip()}},[n,t,r,o])}),m=["#f97316","#eab308","#22c55e","#06b6d4","#ec4899","#f43f5e","#a855f7","#64748b"],E="#3b82f6",S="#8b5cf6";function g(e,n){return R.divIcon({className:"",iconSize:[24,24],iconAnchor:[12,12],html:`<div style="
width:24px;height:24px;border-radius:50%;
background:${n};color:#fff;
display:flex;align-items:center;justify-content:center;
font-size:11px;font-weight:700;
border:2px solid rgba(255,255,255,0.8);
box-shadow:0 1px 4px rgba(0,0,0,0.4);
">${e}</div>`})}function z(e){return m[e%m.length]}function N(e){const n=[];l(e.sender.lat,e.sender.lon)&&n.push([e.sender.lat,e.sender.lon]);for(const t of e.hops)for(const o of t.matches)l(o.lat,o.lon)&&n.push([o.lat,o.lon]);return l(e.receiver.lat,e.receiver.lon)&&n.push([e.receiver.lat,e.receiver.lon]),n}function I({points:e}){const n=T(),t=x.useRef(!1);return x.useEffect(()=>{t.current||e.length===0||(t.current=!0,e.length===1?n.setView(e[0],12):n.fitBounds(e,{padding:[30,30],maxZoom:14}))},[n,e]),null}function k({resolved:e,senderInfo:n}){const t=N(e),o=t.length>0;let r=2,d=0;l(e.sender.lat,e.sender.lon)&&d++,l(e.receiver.lat,e.receiver.lon)&&d++;for(const f of e.hops)f.matches.length===0?r++:(r+=f.matches.length,d+=f.matches.filter(c=>l(c.lat,c.lon)).length);const s=o&&d<r;if(!o)return i.jsx("div",{className:"h-14 rounded border border-border bg-muted/30 flex items-center justify-center text-sm text-muted-foreground",children:"No nodes in this route have GPS coordinates"});const u=t[0];return i.jsxs("div",{children:[i.jsx("div",{className:"rounded border border-border overflow-hidden",role:"img","aria-label":"Map showing message route between nodes",style:{height:220},children:i.jsxs(L,{center:u,zoom:10,className:"h-full w-full",style:{background:"#1a1a2e"},children:[i.jsx(M,{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"}),i.jsx(I,{points:t}),l(e.sender.lat,e.sender.lon)&&i.jsx(h,{position:[e.sender.lat,e.sender.lon],icon:g("S",E),children:i.jsx(p,{direction:"top",offset:[0,-14],children:n.name||"Sender"})}),e.hops.map((f,c)=>f.matches.filter(a=>l(a.lat,a.lon)).map((a,j)=>i.jsx(h,{position:[a.lat,a.lon],icon:g(String(c+1),z(c)),children:i.jsx(p,{direction:"top",offset:[0,-14],children:a.name||a.public_key.slice(0,12)})},`hop-${c}-${j}`))),l(e.receiver.lat,e.receiver.lon)&&i.jsx(h,{position:[e.receiver.lat,e.receiver.lon],icon:g("R",S),children:i.jsx(p,{direction:"top",offset:[0,-14],children:e.receiver.name||"Receiver"})})]})}),s&&i.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Some nodes in this route have no GPS and are not shown"})]})}export{k as PathRouteMap};
//# sourceMappingURL=PathRouteMap-DiGw6Qka.js.map
@@ -0,0 +1 @@
{"version":3,"file":"PathRouteMap-DiGw6Qka.js","sources":["../../node_modules/react-leaflet/lib/Marker.js","../../node_modules/react-leaflet/lib/Tooltip.js","../../src/components/PathRouteMap.tsx"],"sourcesContent":["import { createElementObject, createLayerComponent, extendContext } from '@react-leaflet/core';\nimport { Marker as LeafletMarker } from 'leaflet';\nexport const Marker = createLayerComponent(function createMarker({ position , ...options }, ctx) {\n const marker = new LeafletMarker(position, options);\n return createElementObject(marker, extendContext(ctx, {\n overlayContainer: marker\n }));\n}, function updateMarker(marker, props, prevProps) {\n if (props.position !== prevProps.position) {\n marker.setLatLng(props.position);\n }\n if (props.icon != null && props.icon !== prevProps.icon) {\n marker.setIcon(props.icon);\n }\n if (props.zIndexOffset != null && props.zIndexOffset !== prevProps.zIndexOffset) {\n marker.setZIndexOffset(props.zIndexOffset);\n }\n if (props.opacity != null && props.opacity !== prevProps.opacity) {\n marker.setOpacity(props.opacity);\n }\n if (marker.dragging != null && props.draggable !== prevProps.draggable) {\n if (props.draggable === true) {\n marker.dragging.enable();\n } else {\n marker.dragging.disable();\n }\n }\n});\n","import { createElementObject, createOverlayComponent } from '@react-leaflet/core';\nimport { Tooltip as LeafletTooltip } from 'leaflet';\nimport { useEffect } from 'react';\nexport const Tooltip = createOverlayComponent(function createTooltip(props, context) {\n const tooltip = new LeafletTooltip(props, context.overlayContainer);\n return createElementObject(tooltip, context);\n}, function useTooltipLifecycle(element, context, { position }, setOpen) {\n useEffect(function addTooltip() {\n const container = context.overlayContainer;\n if (container == null) {\n return;\n }\n const { instance } = element;\n const onTooltipOpen = (event)=>{\n if (event.tooltip === instance) {\n if (position != null) {\n instance.setLatLng(position);\n }\n instance.update();\n setOpen(true);\n }\n };\n const onTooltipClose = (event)=>{\n if (event.tooltip === instance) {\n setOpen(false);\n }\n };\n container.on({\n tooltipopen: onTooltipOpen,\n tooltipclose: onTooltipClose\n });\n container.bindTooltip(instance);\n return function removeTooltip() {\n container.off({\n tooltipopen: onTooltipOpen,\n tooltipclose: onTooltipClose\n });\n // @ts-ignore protected property\n if (container._map != null) {\n container.unbindTooltip();\n }\n };\n }, [\n element,\n context,\n setOpen,\n position\n ]);\n});\n","import { useEffect, useRef } from 'react';\nimport { MapContainer, TileLayer, Marker, Tooltip, useMap } from 'react-leaflet';\nimport L from 'leaflet';\nimport 'leaflet/dist/leaflet.css';\nimport { isValidLocation } from '../utils/pathUtils';\nimport type { ResolvedPath, SenderInfo } from '../utils/pathUtils';\n\ninterface PathRouteMapProps {\n resolved: ResolvedPath;\n senderInfo: SenderInfo;\n}\n\n// Colors for hop markers (indexed by hop number - 1)\nconst HOP_COLORS = [\n '#f97316', // Hop 1: orange\n '#eab308', // Hop 2: yellow\n '#22c55e', // Hop 3: green\n '#06b6d4', // Hop 4: cyan\n '#ec4899', // Hop 5: pink\n '#f43f5e', // Hop 6: rose\n '#a855f7', // Hop 7: purple\n '#64748b', // Hop 8: slate\n];\n\nconst SENDER_COLOR = '#3b82f6'; // blue\nconst RECEIVER_COLOR = '#8b5cf6'; // violet\n\nfunction makeIcon(label: string, color: string): L.DivIcon {\n return L.divIcon({\n className: '',\n iconSize: [24, 24],\n iconAnchor: [12, 12],\n html: `<div style=\"\n width:24px;height:24px;border-radius:50%;\n background:${color};color:#fff;\n display:flex;align-items:center;justify-content:center;\n font-size:11px;font-weight:700;\n border:2px solid rgba(255,255,255,0.8);\n box-shadow:0 1px 4px rgba(0,0,0,0.4);\n \">${label}</div>`,\n });\n}\n\nfunction getHopColor(hopIndex: number): string {\n return HOP_COLORS[hopIndex % HOP_COLORS.length];\n}\n\n/** Collect all valid [lat, lon] points for bounds fitting */\nfunction collectPoints(resolved: ResolvedPath): [number, number][] {\n const pts: [number, number][] = [];\n if (isValidLocation(resolved.sender.lat, resolved.sender.lon)) {\n pts.push([resolved.sender.lat!, resolved.sender.lon!]);\n }\n for (const hop of resolved.hops) {\n for (const m of hop.matches) {\n if (isValidLocation(m.lat, m.lon)) {\n pts.push([m.lat!, m.lon!]);\n Line truncated
@@ -0,0 +1,2 @@
import{d,l as f,a as s,e as C,b as m}from"./leaflet-TNk2YzRY.js";import{r as P}from"./index-BJ3L5G2s.js";function v(o,n,e){n.center!==e.center&&o.setLatLng(n.center),n.radius!=null&&n.radius!==e.radius&&o.setRadius(n.radius)}const b=d(function({center:n,children:e,...r},p){const t=new f.CircleMarker(n,r);return s(t,C(p,{overlayContainer:t}))},v),k=m(function(n,e){const r=new f.Popup(n,e.overlayContainer);return s(r,e)},function(n,e,{position:r},p){P.useEffect(function(){const{instance:a}=n;function i(u){u.popup===a&&(a.update(),p(!0))}function c(u){u.popup===a&&p(!1)}return e.map.on({popupopen:i,popupclose:c}),e.overlayContainer==null?(r!=null&&a.setLatLng(r),a.openOn(e.map)):e.overlayContainer.bindPopup(a),function(){var l;e.map.off({popupopen:i,popupclose:c}),(l=e.overlayContainer)==null||l.unbindPopup(),e.map.removeLayer(a)}},[n,e,p,r])});export{b as C,k as P};
//# sourceMappingURL=Popup-JtfOLvZE.js.map
@@ -0,0 +1 @@
{"version":3,"file":"Popup-JtfOLvZE.js","sources":["../../node_modules/@react-leaflet/core/lib/circle.js","../../node_modules/react-leaflet/lib/CircleMarker.js","../../node_modules/react-leaflet/lib/Popup.js"],"sourcesContent":["export function updateCircle(layer, props, prevProps) {\n if (props.center !== prevProps.center) {\n layer.setLatLng(props.center);\n }\n if (props.radius != null && props.radius !== prevProps.radius) {\n layer.setRadius(props.radius);\n }\n}\n","import { createElementObject, createPathComponent, extendContext, updateCircle } from '@react-leaflet/core';\nimport { CircleMarker as LeafletCircleMarker } from 'leaflet';\nexport const CircleMarker = createPathComponent(function createCircleMarker({ center , children: _c , ...options }, ctx) {\n const marker = new LeafletCircleMarker(center, options);\n return createElementObject(marker, extendContext(ctx, {\n overlayContainer: marker\n }));\n}, updateCircle);\n","import { createElementObject, createOverlayComponent } from '@react-leaflet/core';\nimport { Popup as LeafletPopup } from 'leaflet';\nimport { useEffect } from 'react';\nexport const Popup = createOverlayComponent(function createPopup(props, context) {\n const popup = new LeafletPopup(props, context.overlayContainer);\n return createElementObject(popup, context);\n}, function usePopupLifecycle(element, context, { position }, setOpen) {\n useEffect(function addPopup() {\n const { instance } = element;\n function onPopupOpen(event) {\n if (event.popup === instance) {\n instance.update();\n setOpen(true);\n }\n }\n function onPopupClose(event) {\n if (event.popup === instance) {\n setOpen(false);\n }\n }\n context.map.on({\n popupopen: onPopupOpen,\n popupclose: onPopupClose\n });\n if (context.overlayContainer == null) {\n // Attach to a Map\n if (position != null) {\n instance.setLatLng(position);\n }\n instance.openOn(context.map);\n } else {\n // Attach to container component\n context.overlayContainer.bindPopup(instance);\n }\n return function removePopup() {\n context.map.off({\n popupopen: onPopupOpen,\n popupclose: onPopupClose\n });\n context.overlayContainer?.unbindPopup();\n context.map.removeLayer(instance);\n };\n }, [\n element,\n context,\n setOpen,\n position\n ]);\n});\n"],"names":["updateCircle","layer","props","prevProps","CircleMarker","createPathComponent","center","_c","options","ctx","marker","LeafletCircleMarker","createElementObject","extendContext","Popup","createOverlayComponent","context","popup","LeafletPopup","element","position","setOpen","useEffect","instance","onPopupOpen","event","onPopupClose","_a"],"mappings":"yGAAO,SAASA,EAAaC,EAAOC,EAAOC,EAAW,CAC9CD,EAAM,SAAWC,EAAU,QAC3BF,EAAM,UAAUC,EAAM,MAAM,EAE5BA,EAAM,QAAU,MAAQA,EAAM,SAAWC,EAAU,QACnDF,EAAM,UAAUC,EAAM,MAAM,CAEpC,CCLY,MAACE,EAAeC,EAAoB,SAA4B,CAAE,OAAAC,EAAS,SAAUC,EAAK,GAAGC,CAAO,EAAIC,EAAK,CACrH,MAAMC,EAAS,IAAIC,eAAoBL,EAAQE,CAAO,EACtD,OAAOI,EAAoBF,EAAQG,EAAcJ,EAAK,CAClD,iBAAkBC,CAC1B,CAAK,CAAC,CACN,EAAGV,CAAY,ECJFc,EAAQC,EAAuB,SAAqBb,EAAOc,EAAS,CAC7E,MAAMC,EAAQ,IAAIC,EAAAA,MAAahB,EAAOc,EAAQ,gBAAgB,EAC9D,OAAOJ,EAAoBK,EAAOD,CAAO,CAC7C,EAAG,SAA2BG,EAASH,EAAS,CAAE,SAAAI,CAAQ,EAAKC,EAAS,CACpEC,EAAAA,UAAU,UAAoB,CAC1B,KAAM,CAAE,SAAAC,CAAQ,EAAMJ,EACtB,SAASK,EAAYC,EAAO,CACpBA,EAAM,QAAUF,IAChBA,EAAS,OAAM,EACfF,EAAQ,EAAI,EAEpB,CACA,SAASK,EAAaD,EAAO,CACrBA,EAAM,QAAUF,GAChBF,EAAQ,EAAK,CAErB,CACA,OAAAL,EAAQ,IAAI,GAAG,CACX,UAAWQ,EACX,WAAYE,CACxB,CAAS,EACGV,EAAQ,kBAAoB,MAExBI,GAAY,MACZG,EAAS,UAAUH,CAAQ,EAE/BG,EAAS,OAAOP,EAAQ,GAAG,GAG3BA,EAAQ,iBAAiB,UAAUO,CAAQ,EAExC,UAAuB,OAC1BP,EAAQ,IAAI,IAAI,CACZ,UAAWQ,EACX,WAAYE,CAC5B,CAAa,GACDC,EAAAX,EAAQ,mBAAR,MAAAW,EAA0B,cAC1BX,EAAQ,IAAI,YAAYO,CAAQ,CACpC,CACJ,EAAG,CACCJ,EACAH,EACAK,EACAD,CACR,CAAK,CACL,CAAC","x_google_ignoreList":[0,1,2]}
@@ -0,0 +1,3 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/NeighborsMiniMap-D6bvxuvI.js","assets/index-BJ3L5G2s.js","assets/index-Kkb-Bio9.css","assets/leaflet-TNk2YzRY.js","assets/leaflet-Dgihpmma.css","assets/Popup-JtfOLvZE.js"])))=>i.map(i=>d[i]);
import{r as a,k as $,t as q,j as e,I as ne,B as z,l as F,D as K,E as de,F as ue,_ as me,G as fe,H as xe,J as he,R as pe,K as ge,M as be,N as Q,O as je,P as ve}from"./index-BJ3L5G2s.js";import{S as X}from"./separator-ChUIbJIJ.js";const ee=3,Ne=2e3,ye=20,E={loading:!1,attempt:0,error:null,fetched_at:null};function te(){return{status:{...E},nodeInfo:{...E},neighbors:{...E},acl:{...E},radioSettings:{...E},advertIntervals:{...E},ownerInfo:{...E},lppTelemetry:{...E}}}function se(){return{status:null,nodeInfo:null,neighbors:null,acl:null,radioSettings:null,advertIntervals:null,ownerInfo:null,lppTelemetry:null}}const H=new Map;function we(t){switch(t){case"timeout":return"Login confirmation not heard";case"error":return"Login not confirmed";default:return"Repeater login not confirmed"}}function oe(t){return{...t}}function le(t){return{status:{...t.status,loading:!1},nodeInfo:{...t.nodeInfo,loading:!1},neighbors:{...t.neighbors,loading:!1},acl:{...t.acl,loading:!1},radioSettings:{...t.radioSettings,loading:!1},advertIntervals:{...t.advertIntervals,loading:!1},ownerInfo:{...t.ownerInfo,loading:!1},lppTelemetry:{...t.lppTelemetry,loading:!1}}}function ae(t){return t.map(s=>({...s}))}function _e(t){if(!t)return null;const s=H.get(t);return s?(H.delete(t),H.set(t,s),{loggedIn:s.loggedIn,loginError:s.loginError,paneData:oe(s.paneData),paneStates:le(s.paneStates),consoleHistory:ae(s.consoleHistory)}):null}function Ce(t,s){if(H.delete(t),H.set(t,{loggedIn:s.loggedIn,loginError:s.loginError,paneData:oe(s.paneData),paneStates:le(s.paneStates),consoleHistory:ae(s.consoleHistory)}),H.size>ye){const r=H.keys().next().value;r&&H.delete(r)}}function Re(t,s){switch(s){case"status":return $.repeaterStatus(t);case"nodeInfo":return $.repeaterNodeInfo(t);case"neighbors":return $.repeaterNeighbors(t);case"acl":return $.repeaterAcl(t);case"radioSettings":return $.repeaterRadioSettings(t);case"advertIntervals":return $.repeaterAdvertIntervals(t);case"ownerInfo":return $.repeaterOwnerInfo(t);case"lppTelemetry":return $.repeaterLppTelemetry(t)}}function Le(t){const s=t&&t.type==="contact"?t.id:null,r=_e(s),[o,l]=a.useState((r==null?void 0:r.loggedIn)??!1),[n,h]=a.useState(!1),[i,c]=a.useState((r==null?void 0:r.loginError)??null),[j,D]=a.useState((r==null?void 0:r.paneData)??se),[v,R]=a.useState((r==null?void 0:r.paneStates)??te),w=a.useRef((r==null?void 0:r.paneData)??se()),N=a.useRef((r==null?void 0:r.paneStates)??te()),[A,f]=a.useState((r==null?void 0:r.consoleHistory)??[]),[T,P]=a.useState(!1),u=a.useRef((t==null?void 0:t.id)??null),m=a.useRef(!0);a.useEffect(()=>{u.current=s},[s]),a.useEffect(()=>(m.current=!0,()=>{m.current=!1}),[]),a.useEffect(()=>{s&&Ce(s,{loggedIn:o,loginError:i,paneData:j,paneStates:v,consoleHistory:A})},[A,s,o,i,j,v]),a.useEffect(()=>{w.current=j},[j]),a.useEffect(()=>{N.current=v},[v]);const _=a.useCallback(()=>!t||t.type!=="contact"?null:t.id,[t]),L=a.useCallback(async p=>{const b=_();if(!b)return;const y=b;h(!0),c(null);try{const d=await $.repeaterLogin(b,p);if(u.current!==y)return;if(l(!0),!d.authenticated){const g=d.message??"Repeater login was not confirmed";c(g),q.error(we(d.status),{description:g})}}catch(d){if(u.current!==y)return;const g=d instanceof Error?d.message:"Login failed";l(!0),c(g),q.error("Login request failed",{description:`${g}. The dashboard is still available, but repeater operations may fail until a login succeeds.`})}finally{u.current===y&&h(!1)}},[_]),W=a.useCallback(async()=>{await L("")},[L]),S=a.useCallback(async p=>{const b=_();if(!b)return;const y=b;if(p==="neighbors"){const d=N.current.nodeInfo,g=w.current.nodeInfo;if((d.error!==null||d.fetched_at==null&&g==null)&&(await S("nodeInfo"),!m.current||u.current!==y))return}for(let d=1;d<=ee;d++){if(!m.current||u.current!==y)return;const g={loading:!0,attempt:d,error:null,fetched_at:N.current[p].fetched_at??null};N.current={...N.current,[p]:g},R(C=>({...C,[p]:g}));try{const C=await Re(b,p);if(!m.current||u.current!==y)return;w.current={...w.current,[p]:C};const O={loading:!1,attempt:d,error:null,fetched_at:Date.now()};N.current={...N.current,[p]:O},D(M=>({...M,[p]:C})),R(M=>({...M,[p]:O}));return}catch(C){if(!m.current||u.current!==y)return;const O=C instanceof Error?C.message:"Request failed";if(d===ee){const M={loading:!1,attempt:d,error:O,fetched_at:N.current[p].fetched_at??null};N.current={...N.current,[p]:M},R(ce=>({...ce,[p]:M})),q.error(`Failed to fetch ${p}`,{description:O})}else await new Promise(M=>setTimeout(M,Ne))}}},[_]),I=a.useCallback(async()=>{const p=["status","nodeInfo","neighbors","radioSettings","acl","advertIntervals","ownerInfo","lppTelemetry"];for(const b of p)await S(b)},[S]),k=a.useCallback(async p=>{const b=_();if(!b)return;const y=b,d=Math.floor(Date.now()/1e3);f(g=>[...g,{command:p,response:"",timestamp:d,outgoing:!0}]),P(!0);try{const g=await $.sendRepeaterCommand(b,p);if(u.current!==y)return;f(C=>[...C,{command:p,response:g.response,timestamp:g.sender_timestamp??d,outgoing:!1}])}catch(g){if(u.current!==y)Line truncated
//# sourceMappingURL=RepeaterDashboard-bua8zxo_.js.map
@@ -0,0 +1 @@
{"version":3,"mappings":"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 truncated
@@ -0,0 +1,2 @@
import{r as n,k as _,A as w,j as t,I as H,l as I,m as Q,B}from"./index-BJ3L5G2s.js";const b=50,D=300,O=new RegExp('(?<!\\S)(user|channel):(?:"((?:[^"\\\\]|\\\\.)*)"|(\\S+))',"gi");function T(c,d){if(!d)return[c];const i=[],m=new RegExp(`(${d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")})`,"gi"),r=c.split(m);for(let l=0;l<r.length;l++)m.test(r[l])?i.push(t.jsx("mark",{className:"bg-primary/30 text-foreground rounded-sm px-0.5",children:r[l]},l)):i.push(r[l]),m.lastIndex=0;return i}function L(c){const d=[];let i=0,m=!1;for(const r of c.matchAll(O))m=!0,d.push(c.slice(i,r.index)),i=(r.index??0)+r[0].length;return m?(d.push(c.slice(i)),d.map(r=>r.trim()).filter(Boolean).join(" ")):c}function $({contacts:c,channels:d,visibilityVersion:i=0,onNavigateToMessage:m,prefillRequest:r=null}){const[l,v]=n.useState(""),[a,k]=n.useState(""),[C,h]=n.useState([]),[f,p]=n.useState(!1),[A,g]=n.useState(!1),[E,y]=n.useState(0),x=n.useRef(null),j=n.useRef(null),R=L(a);n.useEffect(()=>{const e=setTimeout(()=>{k(l.trim())},D);return()=>clearTimeout(e)},[l]),n.useEffect(()=>{h([]),y(0),g(!1)},[a,i]),n.useEffect(()=>{var o;if(!r)return;const e=r.query.trim();v(e),k(e),(o=j.current)==null||o.focus()},[r]),n.useEffect(()=>()=>{var e;(e=x.current)==null||e.abort()},[]),n.useEffect(()=>{var o;if(!a){h([]),g(!1);return}(o=x.current)==null||o.abort();const e=new AbortController;return x.current=e,p(!0),_.getMessages({q:a,limit:b,offset:0},e.signal).then(s=>{h(s),g(s.length>=b),y(s.length)}).catch(s=>{w(s)||console.error("Search failed:",s)}).finally(()=>{p(!1)}),()=>e.abort()},[a,i]);const M=n.useCallback(()=>{var o;if(!a||f)return;(o=x.current)==null||o.abort();const e=new AbortController;x.current=e,p(!0),_.getMessages({q:a,limit:b,offset:E},e.signal).then(s=>{h(u=>[...u,...s]),g(s.length>=b),y(u=>u+s.length)}).catch(s=>{w(s)||console.error("Search load more failed:",s)}).finally(()=>{p(!1)})},[a,f,E]),N=n.useCallback(e=>{if(e.type==="CHAN"){const s=d.find(u=>u.key.toUpperCase()===e.conversation_key.toUpperCase());return(s==null?void 0:s.name)||e.conversation_key.slice(0,8)}const o=c.find(s=>s.public_key.toLowerCase()===e.conversation_key.toLowerCase());return(o==null?void 0:o.name)||e.conversation_key.slice(0,12)},[c,d]),S=n.useCallback(e=>{m({id:e.id,type:e.type,conversation_key:e.conversation_key,conversation_name:N(e)})},[m,N]);return n.useEffect(()=>{var e;(e=j.current)==null||e.focus()},[]),t.jsxs("div",{className:"flex flex-col h-full",children:[t.jsx("h2",{className:"flex justify-between items-center px-4 py-2.5 border-b border-border font-semibold text-base",children:"Message Search"}),t.jsx("div",{className:"px-4 py-3 border-b border-border",children:t.jsx(H,{ref:j,type:"text",placeholder:"Search all messages...",value:l,onChange:e=>v(e.target.value),className:"h-9 text-sm","aria-label":"Search messages"})}),t.jsxs("div",{className:"flex-1 overflow-y-auto",children:[!a&&t.jsxs("div",{className:"p-8 text-center text-muted-foreground text-sm",children:[t.jsx("p",{children:"Type to search across all messages"}),t.jsxs("p",{className:"mt-2 text-xs",children:["Tip: use ",t.jsx("code",{children:"user:"})," or ",t.jsx("code",{children:"channel:"})," for keys or names, and wrap names with spaces in them in quotes."]}),t.jsx("p",{className:"mt-2 text-xs",children:"Warning: User-key linkage for group messages is best-effort and based on correlation at advertise time. It does not account for multiple users with the same name, and should be considered unreliable."})]}),a&&C.length===0&&!f&&t.jsxs("div",{className:"p-8 text-center text-muted-foreground text-sm",children:["No messages found for “",a,"”"]}),C.map(e=>{const o=N(e),s=e.type==="CHAN"?"Channel":"DM";return t.jsxs("div",{className:"px-4 py-3 border-b border-border/50 cursor-pointer hover:bg-accent/50 transition-colors",role:"button",tabIndex:0,onClick:()=>S(e),onKeyDown:u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),S(e))},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[t.jsx("span",{className:I("text-[10px] font-medium px-1.5 py-0.5 rounded",e.type==="CHAN"?"bg-primary/20 text-primary":"bg-secondary text-secondary-foreground"),children:s}),t.jsx("span",{className:"text-[12px] font-medium text-foreground truncate",children:o}),t.jsx("span",{className:"text-[11px] text-muted-foreground ml-auto flex-shrink-0",children:Q(e.received_at)})]}),t.jsxs("div",{className:"text-[13px] text-foreground/80 line-clamp-2 break-words",children:[e.sender_name&&!e.outgoing&&t.jsxs("span",{className:"text-muted-foreground",children:[e.sender_name,": "]}),e.outgoing&&t.jsx("span",{className:"text-muted-foreground",children:"You: "}),T(e.sender_name&&e.text.startsWith(`${e.sender_name}: `)?e.text.slice(e.sender_name.length+2):e.text,R)]})]},e.id)}),f&&t.jsx("div",{className:"p-4 text-center text-muted-foreground text-sm",role:"status",children:"Searching..."}),A&&!f&&t.jsx("div",{className:"p-4 text-center",children:t.jsx(B,{variant:"outline",size:"sm",onClick:M,childLine truncated
//# sourceMappingURL=SearchView-Cs7v3m6K.js.map
@@ -0,0 +1 @@
{"version":3,"file":"SearchView-Cs7v3m6K.js","sources":["../../src/components/SearchView.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback } from 'react';\nimport { api, isAbortError } from '../api';\nimport type { Contact, Channel } from '../types';\nimport { formatTime } from '../utils/messageParser';\nimport { Input } from './ui/input';\nimport { Button } from './ui/button';\nimport { cn } from '@/lib/utils';\n\nconst SEARCH_PAGE_SIZE = 50;\nconst DEBOUNCE_MS = 300;\n\ninterface SearchResult {\n id: number;\n type: 'PRIV' | 'CHAN';\n conversation_key: string;\n text: string;\n received_at: number;\n outgoing: boolean;\n sender_name: string | null;\n}\n\nconst SEARCH_OPERATOR_RE = /(?<!\\S)(user|channel):(?:\"((?:[^\"\\\\]|\\\\.)*)\"|(\\S+))/gi;\n\nexport interface SearchNavigateTarget {\n id: number;\n type: 'PRIV' | 'CHAN';\n conversation_key: string;\n conversation_name: string;\n}\n\nexport interface SearchViewProps {\n contacts: Contact[];\n channels: Channel[];\n visibilityVersion?: number;\n onNavigateToMessage: (target: SearchNavigateTarget) => void;\n prefillRequest?: {\n query: string;\n nonce: number;\n } | null;\n}\n\nfunction highlightMatch(text: string, query: string): React.ReactNode[] {\n if (!query) return [text];\n const parts: React.ReactNode[] = [];\n const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})`, 'gi');\n const segments = text.split(regex);\n for (let i = 0; i < segments.length; i++) {\n if (regex.test(segments[i])) {\n parts.push(\n <mark key={i} className=\"bg-primary/30 text-foreground rounded-sm px-0.5\">\n {segments[i]}\n </mark>\n );\n } else {\n parts.push(segments[i]);\n }\n // Reset lastIndex since we're using test() in a loop\n regex.lastIndex = 0;\n }\n return parts;\n}\n\nfunction getHighlightQuery(query: string): string {\n const fragments: string[] = [];\n let lastIndex = 0;\n let foundOperator = false;\n\n for (const match of query.matchAll(SEARCH_OPERATOR_RE)) {\n foundOperator = true;\n fragments.push(query.slice(lastIndex, match.index));\n lastIndex = (match.index ?? 0) + match[0].length;\n }\n\n if (!foundOperator) {\n return query;\n }\n\n fragments.push(query.slice(lastIndex));\n return fragments\n .map((fragment) => fragment.trim())\n .filter(Boolean)\n .join(' ');\n}\n\nexport function SearchView({\n contacts,\n channels,\n visibilityVersion = 0,\n onNavigateToMessage,\n prefillRequest = null,\n}: SearchViewProps) {\n const [query, setQuery] = useState('');\n const [debouncedQuery, setDebouncedQuery] = useState('');\n const [results, setResults] = useState<SearchResult[]>([]);\n const [loading, setLoading] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const [offset, setOffset] = useState(0);\n const abortRef = useRef<AbortController | null>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const highlightQuery = getHighlightQuery(debouncedQuery);\n\n // Debounce query\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedQuery(query.trim());\n }, DEBOUNCE_MS);\n return () => clearTimeout(timer);\n }, [query]);\n\n // Reset results when query changes\n useEffect(() => {\n setResults([]);\n setOffset(0);\n setHasMore(false);\n }, [debouncedQuery, visibilityVersion]);\n\n useEffect(() => {\n if (!prefillRequest) {\n return;\n }\n\n const nextQuery = prefillRequest.query.trim();\n setQuery(nextQuery);\n setDebouncedQuery(nextQuery);\n inputRef.current?.focus();\n }, [prefillRequest]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n // Fetch search results\n useEffect(() => {\n if (!debouncedQuery) {\n setResults([]);\n setHasMore(false);\n return;\n }\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setLoading(true);\n api\n .getMessages({ q: debouncedQuery, limit: SEARCH_PAGE_SIZE, offset: 0 }, controller.signal)\n .then((data) => {\n setResults(data as SearchResult[]);\n setHasMore(data.length >= SEARCH_PAGE_SIZE);\n setOffset(data.length);\n })\n .catch((err) => {\n if (!isAbortError(err)) {\n console.error('Search failed:', err);\n }\n })\n .finally(() => {\n setLoading(false);\n });\n\n return () => controller.abort();\n }, [debouncedQuery, visibilityVersion]);\n\n const loadMore = useCallback(() => {\n if (!debouncedQuery || loading) return;\n\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setLoading(true);\n api\n .getMessages({ q: debouncedQuery, limit: SEARCH_PAGE_SIZE, offset }, controller.signal)\n .then((data) => {\n setResults((preLine truncated
@@ -0,0 +1,50 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/BotCodeEditor-CBFX17Kn.js","assets/index-BJ3L5G2s.js","assets/index-Kkb-Bio9.css"])))=>i.map(i=>d[i]);
import{c as Xe,r as o,s as ze,j as e,L as c,B as F,I as x,t as N,g as hs,T as gs,a as fs,b as js,d as $e,e as Ke,f as bs,C as We,h as vs,i as ys,k as V,l as xe,_ as Ns,m as ws,S as _s,n as ks}from"./index-BJ3L5G2s.js";import{S as b}from"./separator-ChUIbJIJ.js";/**
* @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 Ss=[["path",{d:"M18 8c0 3.613-3.869 7.429-5.393 8.795a1 1 0 0 1-1.214 0C9.87 15.429 6 11.613 6 8a6 6 0 0 1 12 0",key:"11u0oz"}],["circle",{cx:"12",cy:"8",r:"2",key:"1822b1"}],["path",{d:"M8.714 14h-3.71a1 1 0 0 0-.948.683l-2.004 6A1 1 0 0 0 3 22h18a1 1 0 0 0 .948-1.316l-2-6a1 1 0 0 0-.949-.684h-3.712",key:"q8zwxj"}]],Cs=Xe("map-pinned",Ss);/**
* @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 Ts=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]],Es=Xe("message-square",Ts),pe=[{name:"USA/Canada",freq:910.525,bw:62.5,sf:7,cr:5},{name:"Australia",freq:915.8,bw:250,sf:10,cr:5},{name:"Australia (narrow)",freq:916.575,bw:62.5,sf:7,cr:8},{name:"Australia SA, WA",freq:923.125,bw:62.5,sf:8,cr:8},{name:"Australia QLD",freq:923.125,bw:62.5,sf:8,cr:5},{name:"New Zealand",freq:917.375,bw:250,sf:11,cr:5},{name:"New Zealand (narrow)",freq:917.375,bw:62.5,sf:7,cr:5},{name:"EU/UK/Switzerland Long Range",freq:869.525,bw:250,sf:11,cr:5},{name:"EU/UK/Switzerland Medium Range",freq:869.525,bw:250,sf:10,cr:5},{name:"EU/UK/Switzerland Narrow",freq:869.618,bw:62.5,sf:8,cr:8},{name:"Czech Republic (Narrow)",freq:869.432,bw:62.5,sf:7,cr:5},{name:"EU 433MHz Long Range",freq:433.65,bw:250,sf:11,cr:5},{name:"Portugal 433MHz",freq:433.375,bw:62.5,sf:9,cr:6},{name:"Portugal 868MHz",freq:869.618,bw:62.5,sf:7,cr:6},{name:"Vietnam",freq:920.25,bw:250,sf:11,cr:5}];function Fs({config:s,health:t,appSettings:n,pageMode:a,onSave:d,onSaveAppSettings:w,onSetPrivateKey:S,onReboot:j,onDisconnect:_,onReconnect:h,onAdvertise:p,meshDiscovery:v,meshDiscoveryLoadingTarget:C,onDiscoverMesh:M,onClose:I,className:K}){const[U,L]=o.useState(""),[R,q]=o.useState(""),[B,O]=o.useState(""),[W,G]=o.useState(""),[m,A]=o.useState(""),[X,u]=o.useState(""),[y,T]=o.useState(""),[H,se]=o.useState(""),[re,Y]=o.useState("0"),[Q,E]=o.useState("current"),[J,z]=o.useState(!1),[i,l]=o.useState(!1),[f,g]=o.useState(!1),[D,Z]=o.useState(null),[P,je]=o.useState(""),[be,ve]=o.useState(!1),[ye,Ne]=o.useState(!1),[we,le]=o.useState(null),[_e,ke]=o.useState("0"),[ue,Se]=o.useState(""),[Ce,Te]=o.useState(""),[Ee,Fe]=o.useState(!1),[Ae,Me]=o.useState(null),[Le,qe]=o.useState(!1),[Pe,Re]=o.useState(null),[De,Ie]=o.useState(!1);o.useEffect(()=>{L(s.name),q(String(s.lat)),O(String(s.lon)),G(String(s.tx_power)),A(String(s.radio.freq)),u(String(s.radio.bw)),T(String(s.radio.sf)),se(String(s.radio.cr)),Y(String(s.path_hash_mode)),E(s.advert_location_source??"current")},[s]),o.useEffect(()=>{ke(String(Math.round(n.advert_interval/3600))),Se(ze(n.flood_scope)),Te(String(n.max_radio_contacts))},[n]);const as=o.useMemo(()=>{const r=parseFloat(m),k=parseFloat(X),ee=parseInt(y,10),te=parseInt(H,10);for(const ae of pe)if(ae.freq===r&&ae.bw===k&&ae.sf===ee&&ae.cr===te)return ae.name;return"custom"},[m,X,y,H]),rs=r=>{if(r==="custom")return;const k=pe.find(ee=>ee.name===r);k&&(A(String(k.freq)),u(String(k.bw)),T(String(k.sf)),se(String(k.cr)))},ns=()=>{if(!navigator.geolocation){N.error("Geolocation not supported",{description:"Your browser does not support geolocation"});return}z(!0),navigator.geolocation.getCurrentPosition(r=>{q(r.coords.latitude.toFixed(6)),O(r.coords.longitude.toFixed(6)),z(!1),N.success("Location updated")},r=>{z(!1),N.error("Failed to get location",{description:r.message})},{enableHighAccuracy:!0,timeout:1e4})},Be=()=>{const r=parseFloat(R),k=parseFloat(B),ee=parseInt(W,10),te=parseFloat(m),ae=parseFloat(X),Ue=parseInt(y,10),He=parseInt(H,10);if([r,k,ee,te,ae,Ue,He].some(ps=>isNaN(ps)))return Z("All numeric fields must have valid values"),null;const me=parseInt(re,10);return{name:U,lat:r,lon:k,tx_power:ee,...Q!==(s.advert_location_source??"current")?{advert_location_source:Q}:{},radio:{freq:te,bw:ae,sf:Ue,cr:He},...s.path_hash_mode_supported&&!isNaN(me)&&me!==s.path_hash_mode?{path_hash_mode:me}:{}}},os=async()=>{Z(null);const r=Be();if(r){l(!0);try{await d(r),N.success("Radio config saved")}catch(k){Z(k instanceof Error?k.message:"Failed to save")}finally{l(!1)}}},is=async()=>{Z(null);const r=Be();if(r){l(!0);try{await d(r),N.success("Radio config saved, rebooting..."),g(!0),await j(),a||I()}catch(k){Z(k instanceof Error?k.message:"Failed to save")}finally{g(!1),l(!1)}}},cs=async()=>{if(!P.trim()){le("Private key is required");return}le(null),ve(!0);try{await S(P.trim()),je(""),N.success("Private key set, rebooting..."),Ne(!0),await j(),a||I()}catch(r){le(r instanceof Error?r.message:"Failed to set private key")}finally{Ne(!1),ve(!1)}},ds=async()=>{Me(null),Fe(!0);try{const r={},k=parseInt(_e,10),ee=isNaN(k)?0:k*3600;ee!==n.advert_interval&&(r.advert_interval=ee),ue!==ze(n.flood_scope)&&(r.flood_scope=ue);const te=parseInt(Ce,10);!isNaN(te)&&te!==n.max_radio_contacts&&(r.max_radio_contacts=te),Object.keys(r).length>0&&await w(r),N.success("Settings saved")}catch(r){Me(r instanceof Error?r.message:"Failed to save")}finally{Fe(!1)}},ls=async()=>{qe(!0);try{await p()}finally{qe(!1)}},us=async r=>{Re(null);try{await M(r)}catch(k){Re(k instanceof Error?k.message:"Failed to run mesh discovery")}},$=(t==null?void 0:t.radio_state)??(t!=null&&t.radio_initializing?"initializing":"disconnected"),Oe=$==="paused"?"Reconnect":$==="connected"||$==="initializing"?"Disconnect":"Stop Trying",ms=$==="connected"?(t==null?void 0:t.connection_info)||"Connected":$==="initializing"?`ILine truncated
`).map(d=>d.trim()).filter(Boolean);if(n.length===0)return"No targets configured";const a=n.join(", ");return a.length<=t?a:`${a.slice(0,t-3)}...`}function Is(s){const t=(s.queue_url||"").trim();return t||"No queue configured"}function Bs(s,t){const n=Ze[s]||s,a=t.filter(d=>d.type===s).length+1;return`${n} #${a}`}const ts=`def bot(**kwargs) -> str | list[str] | None:
"""
Process messages and optionally return a reply.
Args:
kwargs keys currently provided:
sender_name: Display name of sender (may be None)
sender_key: 64-char hex public key (None for channel msgs)
message_text: The message content
is_dm: True for direct messages, False for channel
channel_key: 32-char hex key for channels, None for DMs
channel_name: Channel name with hash (e.g. "#bot"), None for DMs
sender_timestamp: Sender's timestamp (unix seconds, may be None)
path: Hex-encoded routing path (may be None)
is_outgoing: True if this is our own outgoing message
path_bytes_per_hop: Bytes per hop in path (1, 2, or 3) when known
Returns:
None for no reply, a string for a single reply,
or a list of strings to send multiple messages in order
"""
sender_name = kwargs.get("sender_name")
message_text = kwargs.get("message_text", "")
channel_name = kwargs.get("channel_name")
is_outgoing = kwargs.get("is_outgoing", False)
path_bytes_per_hop = kwargs.get("path_bytes_per_hop")
# Don't reply to our own outgoing messages
if is_outgoing:
return None
# Example: Only respond in #bot channel to "!pling" command
if channel_name == "#bot" and "!pling" in message_text.lower():
return "[BOT] Plong!"
return None`;function Je(s,t){return s==="connected"?t==="bot"||t==="webhook"||t==="apprise"?"Active":"Connected":s==="error"?"Error":s==="disconnected"?"Disconnected":"Inactive"}function Os(s,t){return t===!1?"bg-muted-foreground":s==="connected"?"bg-status-connected shadow-[0_0_6px_hsl(var(--status-connected)/0.5)]":s==="error"||s==="disconnected"?"bg-destructive shadow-[0_0_6px_hsl(var(--destructive)/0.5)]":"bg-muted-foreground"}function Us({config:s,scope:t,onChange:n,onScopeChange:a}){return e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Forward mesh data to your own MQTT broker for home automation, logging, or alerting."}),e.jsx("div",{className:"rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-xs text-warning",children:"Outgoing messages (DMs and group messages) will be reported to private MQTT brokers in decrypted/plaintext form."}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-mqtt-host",children:"Broker Host"}),e.jsx(x,{id:"fanout-mqtt-host",type:"text",placeholder:"e.g. 192.168.1.100",value:s.broker_host||"",onChange:d=>n({...s,broker_host:d.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-mqtt-port",children:"Broker Port"}),e.jsx(x,{id:"fanout-mqtt-port",type:"number",min:"1",max:"65535",value:s.broker_port||1883,onChange:d=>n({...s,broker_port:parseInt(d.target.value,10)||1883})})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-mqtt-user",children:"Username"}),e.jsx(x,{id:"fanout-mqtt-user",type:"text",placeholder:"Optional",value:s.username||"",onChange:d=>n({...s,username:d.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-mqtt-pass",children:"Password"}),e.jsx(x,{id:"fanout-mqtt-pass",type:"password",placeholder:"Optional",value:s.password||"",onChange:d=>n({...s,password:d.target.value})})]})]}),e.jsxs("label",{className:"flex items-center gap-3 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:!!s.use_tls,onChange:d=>n({...s,use_tls:d.target.checked}),className:"h-4 w-4 rounded border-border"}),e.jsx("span",{className:"text-sm",children:"Use TLS"})]}),!!s.use_tls&&e.jsxs("label",{className:"flex items-center gap-3 cursor-pointer ml-7",children:[e.jsx("input",{type:"checkbox",checked:!!s.tls_insecure,onChange:d=>n({...s,tls_insecure:d.target.checked}),className:"h-4 w-4 rounded border-border"}),e.jsx("span",{className:"text-sm",children:"Skip certificate verification"})]}),e.jsx(b,{}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-mqtt-prefix",children:"Topic Prefix"}),e.jsx(x,{id:"fanout-mqtt-prefix",type:"text",value:s.topic_prefix||"meshcore",onChange:d=>n({...s,topic_prefix:d.target.value})})]}),e.jsx(b,{}),e.jsx(de,{scope:t,onChange:a,showRawPackets:!0})]})}function Hs({config:s,onChange:t}){const n=s.auth_mode||ss;return e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Share raw packet data with the MeshCore community for coverage mapping and network analysis. Only raw RF packets are shared — never decrypted messages."}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-comm-host",children:"Broker Host"}),e.jsx(x,{id:"fanout-comm-host",type:"text",placeholder:oe,value:s.broker_host||oe,onChange:a=>t({...s,broker_host:a.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-comm-port",children:"Broker Port"}),e.jsx(x,{id:"fanout-comm-port",type:"number",min:"1",max:"65535",value:s.broker_port||ce,onChange:a=>t({...s,broker_port:parseInt(a.target.value,10)||ce})})]})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-comm-transport",children:"Transport"}),e.jsxs("select",{id:"fanout-comm-transport",value:s.transport||es,onChange:a=>t({...s,transport:a.target.value}),className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm",children:[e.jsx("option",{value:"websockets",children:"WebSockets"}),e.jsx("option",{value:"tcp",children:"TCP"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-comm-auth-mode",children:"Authentication"}),e.jsxs("select",{id:"fanout-comm-auth-mode",value:n,onChange:a=>t({...s,auth_mode:a.target.value}),className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm",children:[e.jsx("option",{value:"token",children:"Token"}),e.jsx("option",{value:"none",children:"None"}),e.jsx("option",{value:"password",children:"Username / Password"})]})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["LetsMes Line truncated
slack://token_a/token_b/token_c
tgram://bot_token/chat_id`,value:s.urls||"",onChange:d=>n({...s,urls:d.target.value}),rows:4}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"One URL per line. All URLs receive every matched notification."})]}),e.jsxs("label",{className:"flex items-center gap-3 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:s.preserve_identity!==!1,onChange:d=>n({...s,preserve_identity:d.target.checked}),className:"h-4 w-4 rounded border-border"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm",children:"Preserve identity on Discord"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"When enabled, Discord webhooks will use their configured name/avatar instead of overriding with MeshCore sender info."})]})]}),e.jsxs("label",{className:"flex items-center gap-3 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:s.include_path!==!1,onChange:d=>n({...s,include_path:d.target.checked}),className:"h-4 w-4 rounded border-border"}),e.jsx("span",{className:"text-sm",children:"Include routing path in notifications"})]}),e.jsx(b,{}),e.jsx(de,{scope:t,onChange:a})]})}function Ws({config:s,scope:t,onChange:n,onScopeChange:a}){const d=JSON.stringify(s.headers??{},null,2),[w,S]=o.useState(d),[j,_]=o.useState(null),h=p=>{S(p);try{const v=JSON.parse(p);if(typeof v!="object"||Array.isArray(v)){_("Must be a JSON object");return}_(null),n({...s,headers:v})}catch{_("Invalid JSON")}};return e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Send message data as JSON to an HTTP endpoint when messages are received."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-webhook-url",children:"URL"}),e.jsx(x,{id:"fanout-webhook-url",type:"url",placeholder:"https://example.com/webhook",value:s.url||"",onChange:p=>n({...s,url:p.target.value})})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-webhook-method",children:"HTTP Method"}),e.jsxs("select",{id:"fanout-webhook-method",value:s.method||"POST",onChange:p=>n({...s,method:p.target.value}),className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm",children:[e.jsx("option",{value:"POST",children:"POST"}),e.jsx("option",{value:"PUT",children:"PUT"}),e.jsx("option",{value:"PATCH",children:"PATCH"})]})]})}),e.jsx(b,{}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(c,{children:"HMAC Signing"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["When a secret is set, each request includes an HMAC-SHA256 signature of the JSON body in the specified header (e.g. ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"sha256=ab12cd..."}),")."]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-webhook-hmac-secret",children:"HMAC Secret"}),e.jsx(x,{id:"fanout-webhook-hmac-secret",type:"password",placeholder:"Leave empty to disable signing",value:s.hmac_secret||"",onChange:p=>n({...s,hmac_secret:p.target.value})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-webhook-hmac-header",children:"Signature Header Name"}),e.jsx(x,{id:"fanout-webhook-hmac-header",type:"text",placeholder:"X-Webhook-Signature",value:s.hmac_header||"",onChange:p=>n({...s,hmac_header:p.target.value})})]})]})]}),e.jsx(b,{}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-webhook-headers",children:"Extra Headers (JSON)"}),e.jsx("textarea",{id:"fanout-webhook-headers",className:"w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono min-h-[60px]",value:w,onChange:p=>h(p.target.value),placeholder:'{"Authorization": "Bearer ..."}'}),j&&e.jsx("p",{className:"text-xs text-destructive",children:j})]}),e.jsx(b,{}),e.jsx(de,{scope:t,onChange:a})]})}function Gs({config:s,scope:t,onChange:n,onScopeChange:a}){return e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Send matched mesh events to an Amazon SQS queue for durable processing by workers, Lambdas, or downstream automation."}),e.jsx("div",{className:"rounded-md border border-warning/50 bg-warning/10 px-3 py-2 text-xs text-warning",children:"Outgoing messages and any selected raw packets will be delivered exactly as forwarded by the fanout scope, including decrypted/plaintext message content."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-sqs-queue-url",children:"Queue URL"}),e.jsx(x,{id:"fanout-sqs-queue-url",type:"url",placeholder:"https://sqs.us-east-1.amazonaws.com/123456789012/mesh-events",value:s.queue_url||"",onChange:d=>n({...s,queue_url:d.target.value})})]}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(c,{htmlFor:"fanout-sqs-region",children:"Region (optional)"}),e.jsx(x Line truncated
//# sourceMappingURL=SettingsModal-C-alEUMR.js.map
@@ -0,0 +1 @@
{"version":3,"mappings":"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 truncated
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
{"version":3,"file":"VisualizerView-BBRdi0S-.js","sources":["../../node_modules/lucide-react/dist/esm/icons/maximize-2.js","../../node_modules/lucide-react/dist/esm/icons/minimize-2.js","../../src/utils/visualizerSettings.ts","../../src/utils/visualizerUtils.ts","../../src/components/visualizer/shared.ts","../../src/components/visualizer/VisualizerControls.tsx","../../src/components/visualizer/VisualizerTooltip.tsx","../../node_modules/d3-force-3d/src/center.js","../../node_modules/d3-binarytree/src/add.js","../../node_modules/d3-binarytree/src/cover.js","../../node_modules/d3-binarytree/src/data.js","../../node_modules/d3-binarytree/src/extent.js","../../node_modules/d3-binarytree/src/half.js","../../node_modules/d3-binarytree/src/find.js","../../node_modules/d3-binarytree/src/remove.js","../../node_modules/d3-binarytree/src/root.js","../../node_modules/d3-binarytree/src/size.js","../../node_modules/d3-binarytree/src/visit.js","../../node_modules/d3-binarytree/src/visitAfter.js","../../node_modules/d3-binarytree/src/x.js","../../node_modules/d3-binarytree/src/binarytree.js","../../node_modules/d3-quadtree/src/add.js","../../node_modules/d3-quadtree/src/cover.js","../../node_modules/d3-quadtree/src/data.js","../../node_modules/d3-quadtree/src/extent.js","../../node_modules/d3-quadtree/src/quad.js","../../node_modules/d3-quadtree/src/find.js","../../node_modules/d3-quadtree/src/remove.js","../../node_modules/d3-quadtree/src/root.js","../../node_modules/d3-quadtree/src/size.js","../../node_modules/d3-quadtree/src/visit.js","../../node_modules/d3-quadtree/src/visitAfter.js","../../node_modules/d3-quadtree/src/x.js","../../node_modules/d3-quadtree/src/y.js","../../node_modules/d3-quadtree/src/quadtree.js","../../node_modules/d3-octree/src/add.js","../../node_modules/d3-octree/src/cover.js","../../node_modules/d3-octree/src/data.js","../../node_modules/d3-octree/src/extent.js","../../node_modules/d3-octree/src/octant.js","../../node_modules/d3-octree/src/find.js","../../node_modules/d3-octree/src/findAll.js","../../node_modules/d3-octree/src/remove.js","../../node_modules/d3-octree/src/root.js","../../node_modules/d3-octree/src/size.js","../../node_modules/d3-octree/src/visit.js","../../node_modules/d3-octree/src/visitAfter.js","../../node_modules/d3-octree/src/x.js","../../node_modules/d3-octree/src/y.js","../../node_modules/d3-octree/src/z.js","../../node_modules/d3-octree/src/octree.js","../../node_modules/d3-force-3d/src/constant.js","../../node_modules/d3-force-3d/src/jiggle.js","../../node_modules/d3-force-3d/src/link.js","../../node_modules/d3-dispatch/src/dispatch.js","../../node_modules/d3-timer/src/timer.js","../../node_modules/d3-force-3d/src/lcg.js","../../node_modules/d3-force-3d/src/simulation.js","../../node_modules/d3-force-3d/src/manyBody.js","../../node_modules/d3-force-3d/src/x.js","../../node_modules/d3-force-3d/src/y.js","../../node_modules/d3-force-3d/src/z.js","../../src/networkGraph/packetNetworkGraph.ts","../../src/components/visualizer/useVisualizerData3D.ts","../../node_modules/three/build/three.core.js","../../node_modules/three/build/three.module.js","../../node_modules/three/examples/jsm/controls/OrbitControls.js","../../node_modules/three/examples/jsm/renderers/CSS2DRenderer.js","../../src/components/visualizer/useVisualizer3DScene.ts","../../src/components/PacketVisualizer3D.tsx","../../src/components/VisualizerView.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"m21 3-7 7\", key: \"1l2asr\" }],\n [\"path\", { d: \"m3 21 7-7\", key: \"tjx5ai\" }],\n [\"path\", { d: \"M9 21H3v-6\", key: \"wtvkvv\" }]\n];\nconst Maximize2 = createLucideIcon(\"maximize-2\", __iconNode);\n\nexport { __iconNode, Maximize2 as default };\n//# sourceMappingURL=maximize-2.js.map\n","/**\n * @license lucide-react v0.562.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m14 10 7-7\", key: \"oa77jy\" }],\n [\"path\", { d: \"M20 10h-6V4\", key: \"mjg0md\" }],\n [\"path\", { d: \"m3 21 7-7\", key: \"tjx5ai\" }],\n [\"path\", { d: \"M4 14h6v6\", key: \"rmj7iw\" }]\n];\nconst Minimize2 = createLucideIcon(\"minimize-2\", __iconNode);\n\nexport { __iconNode, Minimize2 as default };\n//# sourceMappingURL=minimize-2.js.map\n","const VISUALIZER_SETTINGS_KEY = 'remoteterm-visualizer-settings';\n\nexport interface VisualizerSettings {\n showAmbiguousPaths: boolean;\n showAmbiguousNodes: boolean;\n useAdvertPathHints: boolean;\n collapseLikelyKnownSiblingRepeaters: boolean;\n splitAmbiguousByTraffic: boolean;\n cLine truncated
@@ -0,0 +1,2 @@
import"./index-BJ3L5G2s.js";import{u as t}from"./leaflet-TNk2YzRY.js";function r(){return t().map}export{r as u};
//# sourceMappingURL=hooks-NBTgSuxX.js.map
@@ -0,0 +1 @@
{"version":3,"file":"hooks-NBTgSuxX.js","sources":["../../node_modules/react-leaflet/lib/hooks.js"],"sourcesContent":["import { useLeafletContext } from '@react-leaflet/core';\nimport { useEffect } from 'react';\nexport function useMap() {\n return useLeafletContext().map;\n}\nexport function useMapEvent(type, handler) {\n const map = useMap();\n useEffect(function addMapEventHandler() {\n // @ts-ignore event type\n map.on(type, handler);\n return function removeMapEventHandler() {\n // @ts-ignore event type\n map.off(type, handler);\n };\n }, [\n map,\n type,\n handler\n ]);\n return map;\n}\nexport function useMapEvents(handlers) {\n const map = useMap();\n useEffect(function addMapEventHandlers() {\n map.on(handlers);\n return function removeMapEventHandlers() {\n map.off(handlers);\n };\n }, [\n map,\n handlers\n ]);\n return map;\n}\n"],"names":["useMap","useLeafletContext"],"mappings":"sEAEO,SAASA,GAAS,CACrB,OAAOC,EAAiB,EAAG,GAC/B","x_google_ignoreList":[0]}
+261
View File
@@ -0,0 +1,261 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/PathRouteMap-DiGw6Qka.js","assets/leaflet-TNk2YzRY.js","assets/leaflet-Dgihpmma.css","assets/hooks-NBTgSuxX.js","assets/RepeaterDashboard-bua8zxo_.js","assets/separator-ChUIbJIJ.js","assets/MapView-DG71Do9A.js","assets/Popup-JtfOLvZE.js","assets/SettingsModal-C-alEUMR.js"])))=>i.map(i=>d[i]);
var Zy=Object.defineProperty;var Jy=(t,o,s)=>o in t?Zy(t,o,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[o]=s;var mo=(t,o,s)=>Jy(t,typeof o!="symbol"?o+"":o,s);function eg(t,o){for(var s=0;s<o.length;s++){const a=o[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in t)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(t,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}(function(){const o=document.createElement("link").relList;if(o&&o.supports&&o.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))a(i);new MutationObserver(i=>{for(const l of i)if(l.type==="childList")for(const d of l.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&a(d)}).observe(document,{childList:!0,subtree:!0});function s(i){const l={};return i.integrity&&(l.integrity=i.integrity),i.referrerPolicy&&(l.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?l.credentials="include":i.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function a(i){if(i.ep)return;i.ep=!0;const l=s(i);fetch(i.href,l)}})();var Zu=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function ax(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}function ix(t){if(Object.prototype.hasOwnProperty.call(t,"__esModule"))return t;var o=t.default;if(typeof o=="function"){var s=function a(){return this instanceof a?Reflect.construct(o,arguments,this.constructor):o.apply(this,arguments)};s.prototype=o.prototype}else s={};return Object.defineProperty(s,"__esModule",{value:!0}),Object.keys(t).forEach(function(a){var i=Object.getOwnPropertyDescriptor(t,a);Object.defineProperty(s,a,i.get?i:{enumerable:!0,get:function(){return t[a]}})}),s}var Ju={exports:{}},ca={},e0={exports:{}},Ye={};/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Mh;function tg(){if(Mh)return Ye;Mh=1;var t=Symbol.for("react.element"),o=Symbol.for("react.portal"),s=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.provider"),d=Symbol.for("react.context"),u=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),f=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),m=Symbol.iterator;function y(P){return P===null||typeof P!="object"?null:(P=m&&P[m]||P["@@iterator"],typeof P=="function"?P:null)}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,_={};function g(P,O,H){this.props=P,this.context=O,this.refs=_,this.updater=H||b}g.prototype.isReactComponent={},g.prototype.setState=function(P,O){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,O,"setState")},g.prototype.forceUpdate=function(P){this.updater.enqueueForceUpdate(this,P,"forceUpdate")};function N(){}N.prototype=g.prototype;function A(P,O,H){this.props=P,this.context=O,this.refs=_,this.updater=H||b}var k=A.prototype=new N;k.constructor=A,C(k,g.prototype),k.isPureReactComponent=!0;var B=Array.isArray,S=Object.prototype.hasOwnProperty,R={current:null},T={key:!0,ref:!0,__self:!0,__source:!0};function D(P,O,H){var j,K={},ee=null,le=null;if(O!=null)for(j in O.ref!==void 0&&(le=O.ref),O.key!==void 0&&(ee=""+O.key),O)S.call(O,j)&&!T.hasOwnProperty(j)&&(K[j]=O[j]);var te=arguments.length-2;if(te===1)K.children=H;else if(1<te){for(var he=Array(te),Pe=0;Pe<te;Pe++)he[Pe]=arguments[Pe+2];K.children=he}if(P&&P.defaultProps)for(j in te=P.defaultProps,te)K[j]===void 0&&(K[j]=te[j]);return{$$typeof:t,type:P,key:ee,ref:le,props:K,_owner:R.current}}function L(P,O){return{$$typeof:t,type:P.type,key:O,ref:P.ref,props:P.props,_owner:P._owner}}function M(P){return typeof P=="object"&&P!==null&&P.$$typeof===t}function I(P){var O={"=":"=0",":":"=2"};return"$"+P.replace(/[=:]/g,function(H){return O[H]})}var $=/\/+/g;function q(P,O){return typeof P=="object"&&P!==null&&P.key!=null?I(""+P.key):O.toString(36)}function G(P,O,H,j,K){var ee=typeof P;(ee==="undefined"||ee==="boolean")&&(P=null);var le=!1;if(P===null)le=!0;else switch(ee){case"string":case"number":le=!0;break;case"object":switch(P.$$typeof){case t:case o:le=!0}}if(le)return le=P,K=K(le),P=j===""?"."+q(le,0):j,B(K)?(H="",P!=null&&(H=P.replace($,"$&/")+"/"),G(K,O,H,"",function(Pe){return Pe})):K!=null&&(M(K)&&(K=L(K,H+(!K.key||le&&le.key===K.key?"":(""+K.key).replace($,"$&/")+"/")+P)),O.push(K)),1;if(le=0,j=j===""?".":j+":",B(P))for(var te=0;te<P.length;te++){ee=P[te];var he=j+q(ee,te);le+=G(ee,O,H,he,K)}else if(he=y(P),typeof he=="function")for(P=he.call(P),te=0;!(ee=P.next()).done;)ee=ee.value,he=j+q(ee,te++),le+=G(ee,O,H,he,K);else if(ee==="object")throw O=String(P),Error("Objects are not valid as a React child (found: "+(O==="[object Object]"?"object with keys {"+Object.keys(P).join(", ")+"}":O)+"). If you meant to render a collection of children, use an array instead.");return le}function ie(P,O,H){if(P==null)return P;var j=[],K=0;return G(P,j,"","",function(ee){return O.call(H,ee,K++)}),j}function re(P){if(P._status===-1){var O=P._result;O=O(),O.then(function(H){(P._status===0||P._status===-1)&&(P._status=1,P._result=H)},function(H){(P._status===0||P._status===-1)&&(P._status=2,P._result=H)}),P._status===-1&&(P._status=0,P._result=O)}if(P._status===1)return P._result.default;throw P._result}var ce={current:null},oe={transition:null},se={ReactCurrentDispatcher:ce,ReactCurrentBatchConfig:oe,ReactCurrentOwner:R};function U(){throw Error("act(...) is not supported in production builds of React.")}return Ye.Children={map:ie,forEach:function(P,O,H){ie(P,function(){O.apply(this,arguments)},H)},count:function(P){var O=0;return ie(P,function(){O++}),O},toArray:function(P){return ie(P,function(O){return O})||[]},only:function(P){if(!M(P))throw Error("React.Children.only expected to receive a single React element child.");return P}},Ye.Component=g,Ye.Fragment=s,Ye.Profiler=i,Ye.PureComponent=A,Ye.StrictMode=a,Ye.Suspense=p,Ye.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=se,Ye.act=U,Ye.cloneElement=function(P,O,H){if(P==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+P+".");var j=C({},P.props),K=P.key,ee=P.ref,le=P._owner;if(O!=null){if(O.ref!==void 0&&(ee=O.ref,le=R.current),O.key!==void 0&&(K=""+O.key),P.type&&P.type.defaultProps)var te=P.type.defaultProps;for(he in O)S.call(O,he)&&!T.hasOwnProperty(he)&&(j[he]=O[he]===void 0&&te!==void 0?te[he]:O[he])}var he=arguments.length-2;if(he===1)j.children=H;else if(1<he){te=Array(he);for(var Pe=0;Pe<he;Pe++)te[Pe]=arguments[Pe+2];j.children=te}return{$$typeof:t,type:P.type,key:K,ref:ee,props:j,_owner:le}},Ye.createContext=function(P){return P={Line truncated
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Oh;function ng(){if(Oh)return ca;Oh=1;var t=L0(),o=Symbol.for("react.element"),s=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,i=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function d(u,p,f){var v,m={},y=null,b=null;f!==void 0&&(y=""+f),p.key!==void 0&&(y=""+p.key),p.ref!==void 0&&(b=p.ref);for(v in p)a.call(p,v)&&!l.hasOwnProperty(v)&&(m[v]=p[v]);if(u&&u.defaultProps)for(v in p=u.defaultProps,p)m[v]===void 0&&(m[v]=p[v]);return{$$typeof:o,type:u,key:y,ref:b,props:m,_owner:i.current}}return ca.Fragment=s,ca.jsx=d,ca.jsxs=d,ca}var Hh;function rg(){return Hh||(Hh=1,Ju.exports=ng()),Ju.exports}var h=rg(),E=L0();const xe=ax(E),I0=eg({__proto__:null,default:xe},[E]);var Ki={},t0={exports:{}},fn={},n0={exports:{}},r0={};/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var Lh;function og(){return Lh||(Lh=1,(function(t){function o(oe,se){var U=oe.length;oe.push(se);e:for(;0<U;){var P=U-1>>>1,O=oe[P];if(0<i(O,se))oe[P]=se,oe[U]=O,U=P;else break e}}function s(oe){return oe.length===0?null:oe[0]}function a(oe){if(oe.length===0)return null;var se=oe[0],U=oe.pop();if(U!==se){oe[0]=U;e:for(var P=0,O=oe.length,H=O>>>1;P<H;){var j=2*(P+1)-1,K=oe[j],ee=j+1,le=oe[ee];if(0>i(K,U))ee<O&&0>i(le,K)?(oe[P]=le,oe[ee]=U,P=ee):(oe[P]=K,oe[j]=U,P=j);else if(ee<O&&0>i(le,U))oe[P]=le,oe[ee]=U,P=ee;else break e}}return se}function i(oe,se){var U=oe.sortIndex-se.sortIndex;return U!==0?U:oe.id-se.id}if(typeof performance=="object"&&typeof performance.now=="function"){var l=performance;t.unstable_now=function(){return l.now()}}else{var d=Date,u=d.now();t.unstable_now=function(){return d.now()-u}}var p=[],f=[],v=1,m=null,y=3,b=!1,C=!1,_=!1,g=typeof setTimeout=="function"?setTimeout:null,N=typeof clearTimeout=="function"?clearTimeout:null,A=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function k(oe){for(var se=s(f);se!==null;){if(se.callback===null)a(f);else if(se.startTime<=oe)a(f),se.sortIndex=se.expirationTime,o(p,se);else break;se=s(f)}}function B(oe){if(_=!1,k(oe),!C)if(s(p)!==null)C=!0,re(S);else{var se=s(f);se!==null&&ce(B,se.startTime-oe)}}function S(oe,se){C=!1,_&&(_=!1,N(D),D=-1),b=!0;var U=y;try{for(k(se),m=s(p);m!==null&&(!(m.expirationTime>se)||oe&&!I());){var P=m.callback;if(typeof P=="function"){m.callback=null,y=m.priorityLevel;var O=P(m.expirationTime<=se);se=t.unstable_now(),typeof O=="function"?m.callback=O:m===s(p)&&a(p),k(se)}else a(p);m=s(p)}if(m!==null)var H=!0;else{var j=s(f);j!==null&&ce(B,j.startTime-se),H=!1}return H}finally{m=null,y=U,b=!1}}var R=!1,T=null,D=-1,L=5,M=-1;function I(){return!(t.unstable_now()-M<L)}function $(){if(T!==null){var oe=t.unstable_now();M=oe;var se=!0;try{se=T(!0,oe)}finally{se?q():(R=!1,T=null)}}else R=!1}var q;if(typeof A=="function")q=function(){A($)};else if(typeof MessageChannel<"u"){var G=new MessageChannel,ie=G.port2;G.port1.onmessage=$,q=function(){ie.postMessage(null)}}else q=function(){g($,0)};function re(oe){T=oe,R||(R=!0,q())}function ce(oe,se){D=g(function(){oe(t.unstable_now())},se)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(oe){oe.callback=null},t.unstable_continueExecution=function(){C||b||(C=!0,re(S))},t.unstable_forceFrameRate=function(oe){0>oe||125<oe?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):L=0<oe?Math.floor(1e3/oe):5},t.unstable_getCurrentPriorityLevel=function(){return y},t.unstable_getFirstCallbackNode=function(){return s(p)},t.unstable_next=function(oe){switch(y){case 1:case 2:case 3:var se=3;break;default:se=y}var U=y;y=se;try{return oe()}finally{y=U}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(oe,se){switch(oe){case 1:case 2:case 3:case 4:case 5:break;default:oe=3}var U=y;y=oe;try{return se()}finally{y=U}},t.unstable_scheduleCallback=function(oe,se,U){var P=t.unstable_now();switch(typeof U=="object"&&U!==null?(U=U.delay,U=typeof U=="number"&&0<U?P+U:P):U=P,oe){case 1:var O=-1;break;case 2:O=250;break;case 5:O=1073741823;break;case 4:O=1e4;break;default:O=5e3}return O=U+O,oe={id:v++,callback:se,priorityLevel:oe,startTime:U,expirationTime:O,sortIndex:-1},U>P?(oe.sortIndex=U,o(f,oe),s(p)===null&&oe===s(f)&&(_?(N(D),D=-1):_=!0,ce(B,U-P))):(oe.sortIndex=O,o(p,oe),C||b||(C=!0,re(S))),oe},t.unstable_shouldYield=I,t.unstable_wrapCallback=function(oe){var se=y;return function(){var U=y;y=se;try{return oe.apply(this,arguments)}finally{y=U}}}})(r0)),r0}var Ih;function sg(){return Ih||(Ih=1,n0.exports=og()),n0.exports}/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var $h;function ag(){if($h)return fn;$h=1;var t=L0(),o=sg();function s(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=1;r<arguments.length;r++)n+="&args[]="+encodeURIComponent(arguments[r]);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 a=new Set,i={};function l(e,n){d(e,n),d(e+"Capture",n)}function d(e,n){for(i[e]=n,e=0;e<n.length;e++)a.add(n[e])}var u=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),p=Object.prototype.hasOwnProperty,f=/^[: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={},m={};function y(e){return p.call(m,e)?!0:p.call(v,e)?!1:f.test(e)?m[e]=!0:(v[e]=!0,!1)}function b(e,n,r,c){if(r!==null&&r.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return c?!1:r!==null?!r.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function C(e,n,r,c){if(n===null||typeof n>"u"||b(e,n,r,c))return!0;if(c)return!1;if(r!==null)switch(r.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 _(e,n,r,c,x,w,F){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=c,this.attributeNamespace=x,this.mustUseProperty=r,this.propertyName=e,this.type=n,this.sanitizeURL=w,this.removeEmptyString=F}var g={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){g[e]=new _(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];g[n]=new _(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){g[e]=new _(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){g[e]=new _(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){g[e]=new _(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){g[e]=new _(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){g[e]=new _(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){g[e]=new _(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){g[e]=new _(e,5,!1,e.toLowerCase(),null,!1,!1)});var N=/[\-:]([a-z])/g;function A(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(N,A);g[n]=new _(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(N,A);g[n]=new _(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(N,A);g[n]=new _(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){g[e]=new _(e,1,!1,e.toLowerCase(),null,!1,!1)}),g.xlinkHref=new _("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){g[e]=new _(e,1,!1,e.toLowerCase(),null,!0,!0)});function k(e,n,r,c){var x=g.hasOwnProperty(n)?g[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 H=!1;function j(e,n){if(!e||H)return"";H=!0;var r=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(ne){var c=ne}Reflect.construct(e,[],n)}else{try{n.call()}catch(ne){c=ne}e.call(n.prototype)}else{try{throw Error()}catch(ne){c=ne}e()}}catch(ne){if(ne&&c&&typeof ne.stack=="string"){for(var x=ne.stack.split(`
`),w=c.stack.split(`
`),F=x.length-1,z=w.length-1;1<=F&&0<=z&&x[F]!==w[z];)z--;for(;1<=F&&0<=z;F--,z--)if(x[F]!==w[z]){if(F!==1||z!==1)do if(F--,z--,0>z||x[F]!==w[z]){var V=`
`+x[F].replace(" at new "," at ");return e.displayName&&V.includes("<anonymous>")&&(V=V.replace("<anonymous>",e.displayName)),V}while(1<=F&&0<=z);break}}}finally{H=!1,Error.prepareStackTrace=r}return(e=e?e.displayName||e.name:"")?O(e):""}function K(e){switch(e.tag){case 5:return O(e.type);case 16:return O("Lazy");case 13:return O("Suspense");case 19:return O("SuspenseList");case 0:case 2:case 15:return e=j(e.type,!1),e;case 11:return e=j(e.type.render,!1),e;case 1:return e=j(e.type,!0),e;default:return""}}function ee(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 T:return"Fragment";case R:return"Portal";case L:return"Profiler";case D:return"StrictMode";case q:return"Suspense";case G:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case I:return(e.displayName||"Context")+".Consumer";case M:return(e._context.displayName||"Context")+".Provider";case $:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ie:return n=e.displayName||null,n!==null?n:ee(e.type)||"Memo";case re:n=e._payload,e=e._init;try{return ee(e(n))}catch{}}return null}function le(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 ee(n);case 8:return n===D?"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 te(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function he(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function Pe(e){var n=he(e)?"checked":"value",r=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),c=""+e[n];if(!e.hasOwnProperty(n)&&typeof r<"u"&&typeof r.get=="function"&&typeof r.set=="function"){var x=r.get,w=r.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return x.call(this)},set:function(F){c=""+F,w.call(this,F)}}),Object.defineProperty(e,n,{enumerable:r.enumerable}),{getValue:function(){return c},setValue:function(F){c=""+F},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function Je(e){e._valueTracker||(e._valueTracker=Pe(e))}function De(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var r=n.getValue(),c="";return e&&(c=he(e)?e.checked?"true":"false":e.value),e=c,e!==r?(n.setValue(e),!0):!1}function Ge(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 We(e,n){var r=n.checked;return U({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:r??e._wrapperState.initialChecked})}function Ft(e,n){var r=n.defaultValue==null?"":n.defaultValue,c=n.checked!=null?n.checked:n.defaultChecked;r=te(n.value!=null?n.value:r),e._wrapperState={initialChecked:c,initialValue:r,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Rt(e,n){n=n.checked,n!=null&&k(e,"checked",n,!1)}function ht(e,n){Rt(e,n);var r=te(n.value),c=n.type;if(r!=null)c==="number"?(r===0&&e.value===""||e.value!=r)&&(e.value=""+r):e.value!==""+r&&(e.value=""+r);else if(c==="submit"||c==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?nt(e,n.type,r):n.hasOwnProperty("defaultValue")&&nt(e,n.type,te(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function vt(e,n,r){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,r||n===e.value||(e.value=n),e.defaultValue=n}r=e.name,r!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,r!==""&&(e.name=r)}function nt(e,n,r){(n!=="number"||Ge(e.ownerDocument)!==e)&&(r==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+r&&(e.defaultValue=""+r))}var pt=Array.isArray;function rt(e,n,r,c){if(e=e.options,n){n={};for(var x=0;x<r.length;x++)n["$"+r[x]]=!0;for(r=0;r<e.length;r++)x=n.hasOwnProperty("$"+e[r].value),e[r].selected!==x&&(e[r].selected=x),x&&c&&(e[r].defaultSelected=!0)}else{for(r=""+te(r),n=null,x=0;x<e.length;x++){if(e[x].value===r){e[x].selected=!0,c&&(e[x].defaultSelected=!0);return}n!==null||e[x].disabled||(n=e[x])}n!==null&&(n.selected=!0)}}function Q(e,n){if(n.dangerouslySetInnerHTML!=n Line truncated
`).replace(dy,"")}function ai(e,n,r){if(n=ef(n),ef(e)!==n&&r)throw Error(s(425))}function ii(){}var Vc=null,Uc=null;function Wc(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 qc=typeof setTimeout=="function"?setTimeout:void 0,fy=typeof clearTimeout=="function"?clearTimeout:void 0,tf=typeof Promise=="function"?Promise:void 0,hy=typeof queueMicrotask=="function"?queueMicrotask:typeof tf<"u"?function(e){return tf.resolve(null).then(e).catch(py)}:qc;function py(e){setTimeout(function(){throw e})}function Kc(e,n){var r=n,c=0;do{var x=r.nextSibling;if(e.removeChild(r),x&&x.nodeType===8)if(r=x.data,r==="/$"){if(c===0){e.removeChild(x),Ms(n);return}c--}else r!=="$"&&r!=="$?"&&r!=="$!"||c++;r=x}while(r);Ms(n)}function Nr(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 nf(e){e=e.previousSibling;for(var n=0;e;){if(e.nodeType===8){var r=e.data;if(r==="$"||r==="$!"||r==="$?"){if(n===0)return e;n--}else r==="/$"&&n++}e=e.previousSibling}return null}var $o=Math.random().toString(36).slice(2),Wn="__reactFiber$"+$o,Ks="__reactProps$"+$o,ar="__reactContainer$"+$o,Gc="__reactEvents$"+$o,my="__reactListeners$"+$o,xy="__reactHandles$"+$o;function no(e){var n=e[Wn];if(n)return n;for(var r=e.parentNode;r;){if(n=r[ar]||r[Wn]){if(r=n.alternate,n.child!==null||r!==null&&r.child!==null)for(e=nf(e);e!==null;){if(r=e[Wn])return r;e=nf(e)}return n}e=r,r=e.parentNode}return null}function Gs(e){return e=e[Wn]||e[ar],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function Vo(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(s(33))}function li(e){return e[Ks]||null}var Yc=[],Uo=-1;function Br(e){return{current:e}}function gt(e){0>Uo||(e.current=Yc[Uo],Yc[Uo]=null,Uo--)}function xt(e,n){Uo++,Yc[Uo]=e.current,e.current=n}var Dr={},Xt=Br(Dr),an=Br(!1),ro=Dr;function Wo(e,n){var r=e.type.contextTypes;if(!r)return Dr;var c=e.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===n)return c.__reactInternalMemoizedMaskedChildContext;var x={},w;for(w in r)x[w]=n[w];return c&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=x),x}function ln(e){return e=e.childContextTypes,e!=null}function ci(){gt(an),gt(Xt)}function rf(e,n,r){if(Xt.current!==Dr)throw Error(s(168));xt(Xt,n),xt(an,r)}function of(e,n,r){var c=e.stateNode;if(n=n.childContextTypes,typeof c.getChildContext!="function")return r;c=c.getChildContext();for(var x in c)if(!(x in n))throw Error(s(108,le(e)||"Unknown",x));return U({},r,c)}function ui(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Dr,ro=Xt.current,xt(Xt,e),xt(an,an.current),!0}function sf(e,n,r){var c=e.stateNode;if(!c)throw Error(s(169));r?(e=of(e,n,ro),c.__reactInternalMemoizedMergedChildContext=e,gt(an),gt(Xt),xt(Xt,e)):gt(an),xt(an,r)}var ir=null,di=!1,Xc=!1;function af(e){ir===null?ir=[e]:ir.push(e)}function vy(e){di=!0,af(e)}function Fr(){if(!Xc&&ir!==null){Xc=!0;var e=0,n=st;try{var r=ir;for(st=1;e<r.length;e++){var c=r[e];do c=c(!0);while(c!==null)}ir=null,di=!1}catch(x){throw ir!==null&&(ir=ir.slice(e+1)),As(Do,Fr),x}finally{st=n,Xc=!1}}return null}var qo=[],Ko=0,fi=null,hi=0,_n=[],Sn=0,oo=null,lr=1,cr="";function so(e,n){qo[Ko++]=hi,qo[Ko++]=fi,fi=e,hi=n}function lf(e,n,r){_n[Sn++]=lr,_n[Sn++]=cr,_n[Sn++]=oo,oo=e;var c=lr;e=cr;var x=32-sn(c)-1;c&=~(1<<x),r+=1;var w=32-sn(n)+x;if(30<w){var F=x-x%5;w=(c&(1<<F)-1).toString(32),c>>=F,x-=F,lr=1<<32-sn(n)+x|r<<x|c,cr=w+e}else lr=1<<w|r<<x|c,cr=e}function Qc(e){e.return!==null&&(so(e,1),lf(e,1,0))}function Zc(e){for(;e===fi;)fi=qo[--Ko],qo[Ko]=null,hi=qo[--Ko],qo[Ko]=null;for(;e===oo;)oo=_n[--Sn],_n[Sn]=null,cr=_n[--Sn],_n[Sn]=null,lr=_n[--Sn],_n[Sn]=null}var yn=null,gn=null,Et=!1,jn=null;function cf(e,n){var r=Dn(5,null,null,0);r.elementType="DELETED",r.stateNode=n,r.return=e,n=e.deletions,n===null?(e.deletions=[r],e.flags|=16):n.push(r)}function uf(e,n){switch(e.tag){case 5:var r=e.type;return n=n.nodeType!==1||r.toLowerCase()!==n.nodeName.toLowerCase()?null:n,n!==null?(e.stateNode=n,yn=e,gn=Nr(n.firstChild),!0):!1;case 6:return n=e.pendingProps===""||n.nodeType!==3?null:n,n!==null?(e.stateNode=n,yn=e,gn=null,!0):!1;case 13:return n=n.nodeType!==8?null:n,n!==null?(r=oo!==null?{id:lr,overflow:cr}:null,e.memoizedState={dehydrated:n,treeContext:r,retryLane:1073741824},r=Dn(18,null,null,0),r.stateNode=n,r.return=e,e.child=r,yn=e,gn=null,!0):!1;default:return!1}}function Jc(e){return(e.mode&1)!==0&&(e.flags&128)===0}function eu(e){if(Et){var n=gn;if(n){var r=n;if(!uf(e,n)){if(Jc(e))throw Error(s(418));n=Nr(r.nextSibling);var c=yn;n&&uf(e,n)?cf(c,r):(e.flags=e.flags&-4097|2,Et=!1,yn=e)}}else{if(Jc(e))throw Error(s(418));e.flags=e.flags&-4097|2,Et=!1,yn=e}}}function df(e){for(e=e. Line truncated
Error generating stack: `+w.message+`
`+w.stack}return{value:e,source:n,stack:x,digest:null}}function Cu(e,n,r){return{value:e,source:null,stack:r??null,digest:n??null}}function ku(e,n){try{console.error(n.value)}catch(r){setTimeout(function(){throw r})}}var Sy=typeof WeakMap=="function"?WeakMap:Map;function Wf(e,n,r){r=dr(-1,r),r.tag=3,r.payload={element:null};var c=n.value;return r.callback=function(){Ti||(Ti=!0,Ou=c),ku(e,n)},r}function qf(e,n,r){r=dr(-1,r),r.tag=3;var c=e.type.getDerivedStateFromError;if(typeof c=="function"){var x=n.value;r.payload=function(){return c(x)},r.callback=function(){ku(e,n)}}var w=e.stateNode;return w!==null&&typeof w.componentDidCatch=="function"&&(r.callback=function(){ku(e,n),typeof c!="function"&&(jr===null?jr=new Set([this]):jr.add(this));var F=n.stack;this.componentDidCatch(n.value,{componentStack:F!==null?F:""})}),r}function Kf(e,n,r){var c=e.pingCache;if(c===null){c=e.pingCache=new Sy;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(r)||(x.add(r),e=Ly.bind(null,e,n,r),n.then(e,e))}function Gf(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 Yf(e,n,r,c,x){return(e.mode&1)===0?(e===n?e.flags|=65536:(e.flags|=128,r.flags|=131072,r.flags&=-52805,r.tag===1&&(r.alternate===null?r.tag=17:(n=dr(-1,1),n.tag=2,Tr(r,n,1))),r.lanes|=1),e):(e.flags|=65536,e.lanes=x,e)}var Ay=B.ReactCurrentOwner,cn=!1;function tn(e,n,r,c){n.child=e===null?mf(n,null,r,c):Yo(n,e.child,r,c)}function Xf(e,n,r,c,x){r=r.render;var w=n.ref;return Qo(n,x),c=pu(e,n,r,c,w,x),r=mu(),e!==null&&!cn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,fr(e,n,x)):(Et&&r&&Qc(n),n.flags|=1,tn(e,n,c,x),n.child)}function Qf(e,n,r,c,x){if(e===null){var w=r.type;return typeof w=="function"&&!Wu(w)&&w.defaultProps===void 0&&r.compare===null&&r.defaultProps===void 0?(n.tag=15,n.type=w,Zf(e,n,w,c,x)):(e=Hi(r.type,null,c,n,n.mode,x),e.ref=n.ref,e.return=n,n.child=e)}if(w=e.child,(e.lanes&x)===0){var F=w.memoizedProps;if(r=r.compare,r=r!==null?r:$s,r(F,c)&&e.ref===n.ref)return fr(e,n,x)}return n.flags|=1,e=Hr(w,c),e.ref=n.ref,e.return=n,n.child=e}function Zf(e,n,r,c,x){if(e!==null){var w=e.memoizedProps;if($s(w,c)&&e.ref===n.ref)if(cn=!1,n.pendingProps=c=w,(e.lanes&x)!==0)(e.flags&131072)!==0&&(cn=!0);else return n.lanes=e.lanes,fr(e,n,x)}return Eu(e,n,r,c,x)}function Jf(e,n,r){var c=n.pendingProps,x=c.children,w=e!==null?e.memoizedState:null;if(c.mode==="hidden")if((n.mode&1)===0)n.memoizedState={baseLanes:0,cachePool:null,transitions:null},xt(ts,bn),bn|=r;else{if((r&1073741824)===0)return e=w!==null?w.baseLanes|r:r,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e,cachePool:null,transitions:null},n.updateQueue=null,xt(ts,bn),bn|=e,null;n.memoizedState={baseLanes:0,cachePool:null,transitions:null},c=w!==null?w.baseLanes:r,xt(ts,bn),bn|=c}else w!==null?(c=w.baseLanes|r,n.memoizedState=null):c=r,xt(ts,bn),bn|=c;return tn(e,n,x,r),n.child}function eh(e,n){var r=n.ref;(e===null&&r!==null||e!==null&&e.ref!==r)&&(n.flags|=512,n.flags|=2097152)}function Eu(e,n,r,c,x){var w=ln(r)?ro:Xt.current;return w=Wo(n,w),Qo(n,x),r=pu(e,n,r,c,w,x),c=mu(),e!==null&&!cn?(n.updateQueue=e.updateQueue,n.flags&=-2053,e.lanes&=~x,fr(e,n,x)):(Et&&c&&Qc(n),n.flags|=1,tn(e,n,r,x),n.child)}function th(e,n,r,c,x){if(ln(r)){var w=!0;ui(n)}else w=!1;if(Qo(n,x),n.stateNode===null)Ni(e,n),Vf(n,r,c),wu(n,r,c,x),c=!0;else if(e===null){var F=n.stateNode,z=n.memoizedProps;F.props=z;var V=F.context,ne=r.contextType;typeof ne=="object"&&ne!==null?ne=An(ne):(ne=ln(r)?ro:Xt.current,ne=Wo(n,ne));var de=r.getDerivedStateFromProps,fe=typeof de=="function"||typeof F.getSnapshotBeforeUpdate=="function";fe||typeof F.UNSAFE_componentWillReceiveProps!="function"&&typeof F.componentWillReceiveProps!="function"||(z!==c||V!==ne)&&Uf(n,F,c,ne),Rr=!1;var ue=n.memoizedState;F.state=ue,gi(n,c,F,x),V=n.memoizedState,z!==c||ue!==V||an.current||Rr?(typeof de=="function"&&(bu(n,r,de,c),V=n.memoizedState),(z=Rr||$f(n,r,z,c,ue,V,ne))?(fe||typeof F.UNSAFE_componentWillMount!="function"&&typeof F.componentWillMount!="function"||(typeof F.componentWillMount=="function"&&F.componentWillMount(),typeof F.UNSAFE_componentWillMount=="function"&&F.UNSAFE_componentWillMount()),typeof F.componentDidMount=="function"&&(n.flags|=4194308)):(typeof F.componentDidMount=="function"&&(n.flags|=4194308),n.memoizedProps=c,n.memoizedState=V),F.props=c,F.state=V,F.context=ne,c=z):(typeof F.componentDidMount=="function"&&(n.flags|=4194308),c=!1)}else{F=n.stateNode,vf(e,n),z=n.memoizedProps,ne=n.type===n.elementType?z:Mn(n.type,z),F.props=ne,fe=n.pendingProps,ue=F.context,V=r.contextType,typeof V=="object"&&V!==null?V=An(V):(V=ln(r)?ro:Xt.current,V=Wo(n,V));var be=r.getDerivedStateFromProps;(de=typeof be=="function"||typeof F.getSnapshotBeforeUpdate=="function")||typeof F.UNSAFE_componentWillReceiveProps!="function"&&typeof F.componentWillReceiveProps!="function"||(z!==fe||ue!==V)&&Uf(n,F,c,V),Rr=!1,ue=n.m 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 F2=t=>t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),R2=t=>t.replace(/^([A-Z])|[\s-_]+(\w)/g,(o,s,a)=>a?a.toUpperCase():s.toLowerCase()),ip=t=>{const o=R2(t);return o.charAt(0).toUpperCase()+o.slice(1)},vx=(...t)=>t.filter((o,s,a)=>!!o&&o.trim()!==""&&a.indexOf(o)===s).join(" ").trim(),T2=t=>{for(const o in t)if(o.startsWith("aria-")||o==="role"||o==="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 P2={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 j2=E.forwardRef(({color:t="currentColor",size:o=24,strokeWidth:s=2,absoluteStrokeWidth:a,className:i="",children:l,iconNode:d,...u},p)=>E.createElement("svg",{ref:p,...P2,width:o,height:o,stroke:t,strokeWidth:a?Number(s)*24/Number(o):s,className:vx("lucide",i),...!l&&!T2(u)&&{"aria-hidden":"true"},...u},[...d.map(([f,v])=>E.createElement(f,v)),...Array.isArray(l)?l:[l]]));/**
* @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 ft=(t,o)=>{const s=E.forwardRef(({className:a,...i},l)=>E.createElement(j2,{ref:l,iconNode:o,className:vx(`lucide-${F2(ip(t))}`,`lucide-${t}`,a),...i}));return s.displayName=ip(t),s};/**
* @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 M2=[["path",{d:"M4.929 4.929 19.07 19.071",key:"196cmz"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],ss=ft("ban",M2);/**
* @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 z2=[["path",{d:"M10.268 21a2 2 0 0 0 3.464 0",key:"vwvbt9"}],["path",{d:"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",key:"11g9vi"}]],yx=ft("bell",z2);/**
* @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 O2=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]],H2=ft("chart-column",O2);/**
* @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 L2=[["path",{d:"M18 6 7 17l-5-5",key:"116fxf"}],["path",{d:"m22 10-7.5 7.5L13 16",key:"ke71qq"}]],I2=ft("check-check",L2);/**
* @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 $2=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],V2=ft("check",$2);/**
* @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 U2=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],W2=ft("chevron-down",U2);/**
* @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 q2=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],K2=ft("chevron-right",q2);/**
* @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 G2=[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]],Y2=ft("database",G2);/**
* @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 X2=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2",key:"1m3agn"}],["path",{d:"M16 8h.01",key:"cr5u4v"}],["path",{d:"M8 8h.01",key:"1e4136"}],["path",{d:"M8 16h.01",key:"18s6g9"}],["path",{d:"M16 16h.01",key:"1f9h7w"}],["path",{d:"M12 12h.01",key:"1mp3jc"}]],Q2=ft("dice-5",X2);/**
* @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 Z2=[["path",{d:"M21.54 15H17a2 2 0 0 0-2 2v4.54",key:"1djwo0"}],["path",{d:"M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17",key:"1tzkfa"}],["path",{d:"M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05",key:"14pb5j"}],["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]],lp=ft("earth",Z2);/**
* @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 J2=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],gx=ft("info",J2);/**
* @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 eb=[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 9.9-1",key:"1mm8w8"}]],tb=ft("lock-open",eb);/**
* @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 nb=[["path",{d:"M3 5h1",key:"1mv5vm"}],["path",{d:"M3 12h1",key:"lp3yf2"}],["path",{d:"M3 19h1",key:"w6f3n9"}],["path",{d:"M8 5h1",key:"1nxr5w"}],["path",{d:"M8 12h1",key:"1con00"}],["path",{d:"M8 19h1",key:"k7p10e"}],["path",{d:"M13 5h8",key:"a7qcls"}],["path",{d:"M13 12h8",key:"h98zly"}],["path",{d:"M13 19h8",key:"c3s6r1"}]],rb=ft("logs",nb);/**
* @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 ob=[["path",{d:"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z",key:"169xi5"}],["path",{d:"M15 5.764v15",key:"1pn4in"}],["path",{d:"M9 3.236v15",key:"1uimfh"}]],sb=ft("map",ob);/**
* @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 ab=[["path",{d:"M4 5h16",key:"1tepv9"}],["path",{d:"M4 12h16",key:"1lakjw"}],["path",{d:"M4 19h16",key:"1djgab"}]],ib=ft("menu",ab);/**
* @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 lb=[["path",{d:"M12 17v4",key:"1riwvh"}],["path",{d:"m14.305 7.53.923-.382",key:"1mlnsw"}],["path",{d:"m15.228 4.852-.923-.383",key:"82mpwg"}],["path",{d:"m16.852 3.228-.383-.924",key:"ln4sir"}],["path",{d:"m16.852 8.772-.383.923",key:"1dejw0"}],["path",{d:"m19.148 3.228.383-.924",key:"192kgf"}],["path",{d:"m19.53 9.696-.382-.924",key:"fiavlr"}],["path",{d:"m20.772 4.852.924-.383",key:"1j8mgp"}],["path",{d:"m20.772 7.148.924.383",key:"zix9be"}],["path",{d:"M22 13v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7",key:"1tnzv8"}],["path",{d:"M8 21h8",key:"1ev6f3"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}]],cb=ft("monitor-cog",lb);/**
* @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 ub=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],db=ft("moon",ub);/**
* @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 fb=[["path",{d:"M4.9 16.1C1 12.2 1 5.8 4.9 1.9",key:"s0qx1y"}],["path",{d:"M7.8 4.7a6.14 6.14 0 0 0-.8 7.5",key:"1idnkw"}],["circle",{cx:"12",cy:"9",r:"2",key:"1092wv"}],["path",{d:"M16.2 4.8c2 2 2.26 5.11.8 7.47",key:"ojru2q"}],["path",{d:"M19.1 1.9a9.96 9.96 0 0 1 0 14.1",key:"rhi7fg"}],["path",{d:"M9.5 18h5",key:"mfy3pd"}],["path",{d:"m8 22 4-11 4 11",key:"25yftu"}]],hb=ft("radio-tower",fb);/**
* @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 pb=[["circle",{cx:"6",cy:"19",r:"3",key:"1kj8tv"}],["path",{d:"M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15",key:"1d8sl"}],["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}]],mb=ft("route",pb);/**
* @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 xb=[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]],A0=ft("search",xb);/**
* @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 vb=[["circle",{cx:"18",cy:"5",r:"3",key:"gq8acd"}],["circle",{cx:"6",cy:"12",r:"3",key:"w7nqdw"}],["circle",{cx:"18",cy:"19",r:"3",key:"1xt0gg"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49",key:"47mynk"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49",key:"1n3mei"}]],yb=ft("share-2",vb);/**
* @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 gb=[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]],bb=ft("square-pen",gb);/**
* @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 wb=[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]],ps=ft("star",wb);/**
* @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 Cb=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],kb=ft("sun",Cb);/**
* @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 Eb=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],_b=ft("trash-2",Eb);/**
* @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 Sb=[["circle",{cx:"12",cy:"4.5",r:"2.5",key:"r5ysbb"}],["path",{d:"m10.2 6.3-3.9 3.9",key:"1nzqf6"}],["circle",{cx:"4.5",cy:"12",r:"2.5",key:"jydg6v"}],["path",{d:"M7 12h10",key:"b7w52i"}],["circle",{cx:"19.5",cy:"12",r:"2.5",key:"1piiel"}],["path",{d:"m13.8 17.7 3.9-3.9",key:"1wyg1y"}],["circle",{cx:"12",cy:"19.5",r:"2.5",key:"13o1pw"}]],Ab=ft("waypoints",Sb);/**
* @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 Nb=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],q0=ft("x",Nb);function rn(t){(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),t.currentTarget.click())}const N0="remoteterm-theme-change",Bb=[{id:"original",name:"Original",swatches:["#111419","#181b21","#27a05c","#282c33","#f59e0b","#3b82f6"],metaThemeColor:"#111419"},{id:"light",name:"Light",swatches:["#F8F7F4","#FFFFFF","#1B7D4E","#EDEBE7","#D97706","#3B82F6"],metaThemeColor:"#F8F7F4"},{id:"ios",name:"iPhone",swatches:["#F2F2F7","#FFFFFF","#007AFF","#E5E5EA","#FF9F0A","#34C759"],metaThemeColor:"#F2F2F7"},{id:"paper-grove",name:"Paper Grove",swatches:["#F7F1E4","#FFF9EE","#2F9E74","#E7DEC8","#E76F51","#5C7CFA"],metaThemeColor:"#F7F1E4"},{id:"cyberpunk",name:"Cyberpunk",swatches:["#07080A","#0D1112","#00FF41","#141E17","#FAFF00","#FF2E6C"],metaThemeColor:"#07080A"},{id:"obsidian-glass",name:"Obsidian Glass",swatches:["#0C0E12","#151821","#D4A070","#1E2230","#D4924A","#5B82B4"],metaThemeColor:"#0C0E12"},{id:"solar-flare",name:"Solar Flare",swatches:["#0D0607","#151012","#FF0066","#2D1D22","#FF8C1A","#30ACD4"],metaThemeColor:"#0D0607"},{id:"lagoon-pop",name:"Lagoon Pop",swatches:["#081A22","#0F2630","#23D7C6","#173844","#FF7A66","#7C83FF"],metaThemeColor:"#081A22"},{id:"candy-dusk",name:"Candy Dusk",swatches:["#140F24","#201736","#FF79C9","#2A2144","#FFC857","#8BE9FD"],metaThemeColor:"#140F24"},{id:"high-contrast",name:"High Contrast",swatches:["#000000","#141414","#3B9EFF","#1E1E1E","#FFB800","#FF4757"],metaThemeColor:"#000000"},{id:"monochrome",name:"Monochrome",swatches:["#FAFAFA","#FFFFFF","#111111","#EAEAEA","#8A8A8A","#4A4A4A"],metaThemeColor:"#FAFAFA"},{id:"windows-95",name:"Windows 95",swatches:["#008080","#C0C0C0","#000080","#DFDFDF","#FFDE59","#000000"],metaThemeColor:"#008080"}],bx="remoteterm-theme";function B0(){try{return localStorage.getItem(bx)??"original"}catch{return"original"}}function wx(t){try{localStorage.setItem(bx,t)}catch{}t==="original"?delete document.documentElement.dataset.theme:document.documentElement.dataset.theme=t;const o=Bb.find(s=>s.id===t);if(o){const s=document.querySelector('meta[name="theme-color"]');s&&s.setAttribute("content",o.metaThemeColor)}typeof window<"u"&&window.dispatchEvent(new CustomEvent(N0,{detail:t}))}function Cx(t){var o,s,a="";if(typeof t=="string"||typeof t=="number")a+=t;else if(typeof t=="object")if(Array.isArray(t)){var i=t.length;for(o=0;o<i;o++)t[o]&&(s=Cx(t[o]))&&(a&&(a+=" "),a+=s)}else for(s in t)t[s]&&(a&&(a+=" "),a+=s);return a}function kx(){for(var t,o,s=0,a="",i=arguments.length;s<i;s++)(t=arguments[s])&&(o=Cx(t))&&(a&&(a+=" "),a+=o);return a}const Db=(t,o)=>{const s=new Array(t.length+o.length);for(let a=0;a<t.length;a++)s[a]=t[a];for(let a=0;a<o.length;a++)s[t.length+a]=o[a];return s},Fb=(t,o)=>({classGroupId:t,validator:o}),Ex=(t=new Map,o=null,s)=>({nextPart:t,validators:o,classGroupId:s}),Wl="-",cp=[],Rb="arbitrary..",Tb=t=>{const o=jb(t),{conflictingClassGroups:s,conflictingClassGroupModifiers:a}=t;return{getClassGroupId:d=>{if(d.startsWith("[")&&d.endsWith("]"))return Pb(d);const u=d.split(Wl),p=u[0]===""&&u.length>1?1:0;return _x(u,p,o)},getConflictingClassGroupIds:(d,u)=>{if(u){const p=a[d],f=s[d];return p?f?Db(f,p):p:f||cp}return s[d]||cp}}},_x=(t,o,s)=>{if(t.length-o===0)return s.classGroupId;const i=t[o],l=s.nextPart.get(i);if(l){const f=_x(t,o+1,l);if(f)return f}const d=s.validators;if(d===null)return;const u=o===0?t.join(Wl):t.slice(o).join(Wl),p=d.length;for(let f=0;f<p;f++){const v=d[f];if(v.validator(u))return v.classGroupId}},Pb=t=>t.slice(1,-1).indexOf(":")===-1?void 0:(()=>{const o=t.slice(1,-1),s=o.indexOf(":"),a=o.slice(0,s);return a?Rb+a:void 0})(),jb=t=>{const{theme:o,classGroups:s}=t;return Mb(s,o)},Mb=(t,o)=>{const s=Ex();for(const a in t){const i=t[a];K0(i,s,a,o)}return s},K0=(t,o,s,a)=>{const i=t.length;for(let l=0;l<i;l++){const d=t[l];zb(d,o,s,a)}},zb=(t,o,s,a)=>{if(typeof t=="string"){Ob(t,o,s);return}if(typeof t=="function"){Hb(t,o,s,a);return}Lb(t,o,s,a)},Ob=(t,o,s)=>{const a=t===""?o:Sx(o,t);a.classGroupId=s},Hb=(t,o,s,a)=>{if(Ib(t)){K0(t(a),o,s,a);return}o.validators===null&&(o.validators=[]),o.validators.push(Fb(s,t))},Lb=(t,o,s,a)=>{const i=Object.entries(t),l=i.length;for(let d=0;d<l;d++){const[u,p]=i[d];K0(p,Sx(o,u),s,a)}},Sx=(t,o)=>{let s=t;const a=o.split(Wl),i=a.length;for(let l=0;l<i;l++){const d=a[l];let u=s.nextPart.get(d);u||(u=Ex(),s.nextPart.set(d,u)),s=u}return s},Ib=t=>"isThemeGetter"in t&&t.isThemeGetter===!0,$b=t=>{if(t<1)return{get:()=>{},set:()=>{}};let o=0,s=Object.create(null),a=Object.create(null);const i=(l,d)=>{s[l]=d,o++,o>t&&(o=0,a=s,s=Object.create(null))};return{get(l){let d=s[l];if(d!==void 0)return d;if((d=a[l])!==void 0)return i(l,d),d},set(l,d){l in s?s[l]=d:i(l,d)}}},D0="!",up=":",Vb=[],dp=(t,o,s,a,i)=>({modifiers:t,hasImportantModifier:o,baseClassName:s,maybePostfixModifierPosition:a,isExternal:i}),Ub=t=>{const{prefix:o,experimentalParseClassName:s}=t;let a=i=>{const l=[];let d=Line truncated
.`.concat(N4,` {
overflow: hidden `).concat(a,`;
padding-right: `).concat(u,"px ").concat(a,`;
}
body[`).concat(ds,`] {
overflow: hidden `).concat(a,`;
overscroll-behavior: contain;
`).concat([o&&"position: relative ".concat(a,";"),s==="margin"&&`
padding-left: `.concat(i,`px;
padding-top: `).concat(l,`px;
padding-right: `).concat(d,`px;
margin-left:0;
margin-top:0;
margin-right: `).concat(u,"px ").concat(a,`;
`),s==="padding"&&"padding-right: ".concat(u,"px ").concat(a,";")].filter(Boolean).join(""),`
}
.`).concat(ol,` {
right: `).concat(u,"px ").concat(a,`;
}
.`).concat(sl,` {
margin-right: `).concat(u,"px ").concat(a,`;
}
.`).concat(ol," .").concat(ol,` {
right: 0 `).concat(a,`;
}
.`).concat(sl," .").concat(sl,` {
margin-right: 0 `).concat(a,`;
}
body[`).concat(ds,`] {
`).concat(B4,": ").concat(u,`px;
}
`)},Ap=function(){var t=parseInt(document.body.getAttribute(ds)||"0",10);return isFinite(t)?t:0},G4=function(){E.useEffect(function(){return document.body.setAttribute(ds,(Ap()+1).toString()),function(){var t=Ap()-1;t<=0?document.body.removeAttribute(ds):document.body.setAttribute(ds,t.toString())}},[])},Y4=function(t){var o=t.noRelative,s=t.noImportant,a=t.gapMode,i=a===void 0?"margin":a;G4();var l=E.useMemo(function(){return W4(i)},[i]);return E.createElement(q4,{styles:K4(l,!o,i,s?"":"!important")})},T0=!1;if(typeof window<"u")try{var el=Object.defineProperty({},"passive",{get:function(){return T0=!0,!0}});window.addEventListener("test",el,el),window.removeEventListener("test",el,el)}catch{T0=!1}var as=T0?{passive:!1}:!1,X4=function(t){return t.tagName==="TEXTAREA"},Jx=function(t,o){if(!(t instanceof Element))return!1;var s=window.getComputedStyle(t);return s[o]!=="hidden"&&!(s.overflowY===s.overflowX&&!X4(t)&&s[o]==="visible")},Q4=function(t){return Jx(t,"overflowY")},Z4=function(t){return Jx(t,"overflowX")},Np=function(t,o){var s=o.ownerDocument,a=o;do{typeof ShadowRoot<"u"&&a instanceof ShadowRoot&&(a=a.host);var i=e1(t,a);if(i){var l=t1(t,a),d=l[1],u=l[2];if(d>u)return!0}a=a.parentNode}while(a&&a!==s.body);return!1},J4=function(t){var o=t.scrollTop,s=t.scrollHeight,a=t.clientHeight;return[o,s,a]},eC=function(t){var o=t.scrollLeft,s=t.scrollWidth,a=t.clientWidth;return[o,s,a]},e1=function(t,o){return t==="v"?Q4(o):Z4(o)},t1=function(t,o){return t==="v"?J4(o):eC(o)},tC=function(t,o){return t==="h"&&o==="rtl"?-1:1},nC=function(t,o,s,a,i){var l=tC(t,window.getComputedStyle(o).direction),d=l*a,u=s.target,p=o.contains(u),f=!1,v=d>0,m=0,y=0;do{if(!u)break;var b=t1(t,u),C=b[0],_=b[1],g=b[2],N=_-g-l*C;(C||N)&&e1(t,u)&&(m+=N,y+=C);var A=u.parentNode;u=A&&A.nodeType===Node.DOCUMENT_FRAGMENT_NODE?A.host:A}while(!p&&u!==document.body||p&&(o.contains(u)||o===u));return(v&&Math.abs(m)<1||!v&&Math.abs(y)<1)&&(f=!0),f},tl=function(t){return"changedTouches"in t?[t.changedTouches[0].clientX,t.changedTouches[0].clientY]:[0,0]},Bp=function(t){return[t.deltaX,t.deltaY]},Dp=function(t){return t&&"current"in t?t.current:t},rC=function(t,o){return t[0]===o[0]&&t[1]===o[1]},oC=function(t){return`
.block-interactivity-`.concat(t,` {pointer-events: none;}
.allow-interactivity-`).concat(t,` {pointer-events: all;}
`)},sC=0,is=[];function aC(t){var o=E.useRef([]),s=E.useRef([0,0]),a=E.useRef(),i=E.useState(sC++)[0],l=E.useState(Zx)[0],d=E.useRef(t);E.useEffect(function(){d.current=t},[t]),E.useEffect(function(){if(t.inert){document.body.classList.add("block-interactivity-".concat(i));var _=A4([t.lockRef.current],(t.shards||[]).map(Dp),!0).filter(Boolean);return _.forEach(function(g){return g.classList.add("allow-interactivity-".concat(i))}),function(){document.body.classList.remove("block-interactivity-".concat(i)),_.forEach(function(g){return g.classList.remove("allow-interactivity-".concat(i))})}}},[t.inert,t.lockRef.current,t.shards]);var u=E.useCallback(function(_,g){if("touches"in _&&_.touches.length===2||_.type==="wheel"&&_.ctrlKey)return!d.current.allowPinchZoom;var N=tl(_),A=s.current,k="deltaX"in _?_.deltaX:A[0]-N[0],B="deltaY"in _?_.deltaY:A[1]-N[1],S,R=_.target,T=Math.abs(k)>Math.abs(B)?"h":"v";if("touches"in _&&T==="h"&&R.type==="range")return!1;var D=window.getSelection(),L=D&&D.anchorNode,M=L?L===R||L.contains(R):!1;if(M)return!1;var I=Np(T,R);if(!I)return!0;if(I?S=T:(S=T==="v"?"h":"v",I=Np(T,R)),!I)return!1;if(!a.current&&"changedTouches"in _&&(k||B)&&(a.current=S),!S)return!0;var $=a.current||S;return nC($,g,_,$==="h"?k:B)},[]),p=E.useCallback(function(_){var g=_;if(!(!is.length||is[is.length-1]!==l)){var N="deltaY"in g?Bp(g):tl(g),A=o.current.filter(function(S){return S.name===g.type&&(S.target===g.target||g.target===S.shadowParent)&&rC(S.delta,N)})[0];if(A&&A.should){g.cancelable&&g.preventDefault();return}if(!A){var k=(d.current.shards||[]).map(Dp).filter(Boolean).filter(function(S){return S.contains(g.target)}),B=k.length>0?u(g,k[0]):!d.current.noIsolation;B&&g.cancelable&&g.preventDefault()}}},[]),f=E.useCallback(function(_,g,N,A){var k={name:_,delta:g,target:N,should:A,shadowParent:iC(N)};o.current.push(k),setTimeout(function(){o.current=o.current.filter(function(B){return B!==k})},1)},[]),v=E.useCallback(function(_){s.current=tl(_),a.current=void 0},[]),m=E.useCallback(function(_){f(_.type,Bp(_),_.target,u(_,t.lockRef.current))},[]),y=E.useCallback(function(_){f(_.type,tl(_),_.target,u(_,t.lockRef.current))},[]);E.useEffect(function(){return is.push(l),t.setCallbacks({onScrollCapture:m,onWheelCapture:m,onTouchMoveCapture:y}),document.addEventListener("wheel",p,as),document.addEventListener("touchmove",p,as),document.addEventListener("touchstart",v,as),function(){is=is.filter(function(_){return _!==l}),document.removeEventListener("wheel",p,as),document.removeEventListener("touchmove",p,as),document.removeEventListener("touchstart",v,as)}},[]);var b=t.removeScrollBar,C=t.inert;return E.createElement(E.Fragment,null,C?E.createElement(l,{styles:oC(i)}):null,b?E.createElement(Y4,{noRelative:t.noRelative,gapMode:t.gapMode}):null)}function iC(t){for(var o=null;t!==null;)t instanceof ShadowRoot&&(o=t.host,t=t.host),t=t.parentNode;return o}const lC=M4(Qx,aC);var n1=E.forwardRef(function(t,o){return E.createElement(Jl,tr({},t,{ref:o,sideCar:lC}))});n1.classNames=Jl.classNames;var cC=function(t){if(typeof document>"u")return null;var o=Array.isArray(t)?t[0]:t;return o.ownerDocument.body},ls=new WeakMap,nl=new WeakMap,rl={},p0=0,r1=function(t){return t&&(t.host||r1(t.parentNode))},uC=function(t,o){return o.map(function(s){if(t.contains(s))return s;var a=r1(s);return a&&t.contains(a)?a:(console.error("aria-hidden",s,"in not contained inside",t,". Doing nothing"),null)}).filter(function(s){return!!s})},dC=function(t,o,s,a){var i=uC(o,Array.isArray(t)?t:[t]);rl[s]||(rl[s]=new WeakMap);var l=rl[s],d=[],u=new Set,p=new Set(i),f=function(m){!m||u.has(m)||(u.add(m),f(m.parentNode))};i.forEach(f);var v=function(m){!m||p.has(m)||Array.prototype.forEach.call(m.children,function(y){if(u.has(y))v(y);else try{var b=y.getAttribute(a),C=b!==null&&b!=="false",_=(ls.get(y)||0)+1,g=(l.get(y)||0)+1;ls.set(y,_),l.set(y,g),d.push(y),_===1&&C&&nl.set(y,!0),g===1&&y.setAttribute(s,"true"),C||y.setAttribute(a,"true")}catch(N){console.error("aria-hidden: cannot operate on ",y,N)}})};return v(o),u.clear(),p0++,function(){d.forEach(function(m){var y=ls.get(m)-1,b=l.get(m)-1;ls.set(m,y),l.set(m,b),y||(nl.has(m)||m.removeAttribute(a),nl.delete(m)),b||m.removeAttribute(s)}),p0--,p0||(ls=new WeakMap,ls=new WeakMap,nl=new WeakMap,rl={})}},fC=function(t,o,s){s===void 0&&(s="data-aria-hidden");var a=Array.from(Array.isArray(t)?t:[t]),i=cC(t);return i?(a.push.apply(a,Array.from(i.querySelectorAll("[aria-live], script"))),dC(a,i,s,"aria-hidden")):function(){return null}};function hC(t){const o=pC(t),s=E.forwardRef((a,i)=>{const{children:l,...d}=a,u=E.Children.toArray(l),p=u.find(xC);if(p){const f=p.props.children,v=u.map(m=>m===p?E.Children.count(f)>1?E.Children.only(null):E.isValidElement(f)?f.props.children:null:m);return h.jsx(o,{...d,ref:i,children:E.isValidElement(f)?E.cloneElement(f,void 0,v):null})}return h.jsx(o,{...d,ref:i,children:l})});return s.displayName=`${t}.Slot`,s}function pC(t){const o=E.forwardRef((s,a)=>{const{children:i Line truncated
If you want to hide the \`${o.titleName}\`, you can wrap it with our VisuallyHidden component.
For more information, see https://radix-ui.com/primitives/docs/components/${o.docsSlug}`;return E.useEffect(()=>{t&&(document.getElementById(t)||console.error(s))},[s,t]),null},AC="DialogDescriptionWarning",NC=({contentRef:t,descriptionId:o})=>{const a=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${y1(AC).contentName}}.`;return E.useEffect(()=>{var l;const i=(l=t.current)==null?void 0:l.getAttribute("aria-describedby");o&&i&&(document.getElementById(o)||console.warn(a))},[a,t,o]),null},g1=s1,b1=l1,tc=c1,nc=u1,rc=f1,oc=p1,w1=x1;const Pa=g1,BC=b1,C1=E.forwardRef(({className:t,...o},s)=>h.jsx(tc,{ref:s,className:Ue("fixed inset-0 z-50 bg-overlay/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...o}));C1.displayName=tc.displayName;const bs=E.forwardRef(({className:t,children:o,...s},a)=>h.jsxs(BC,{children:[h.jsx(C1,{}),h.jsxs(nc,{ref:a,className:Ue("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",t),...s,children:[o,h.jsxs(w1,{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:[h.jsx(q0,{className:"h-4 w-4"}),h.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));bs.displayName=nc.displayName;const ws=({className:t,...o})=>h.jsx("div",{className:Ue("flex flex-col space-y-1.5 text-center sm:text-left",t),...o});ws.displayName="DialogHeader";const ja=({className:t,...o})=>h.jsx("div",{className:Ue("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...o});ja.displayName="DialogFooter";const Cs=E.forwardRef(({className:t,...o},s)=>h.jsx(rc,{ref:s,className:Ue("text-lg font-semibold leading-none tracking-tight",t),...o}));Cs.displayName=rc.displayName;const ks=E.forwardRef(({className:t,...o},s)=>h.jsx(oc,{ref:s,className:Ue("text-sm text-muted-foreground",t),...o}));ks.displayName=oc.displayName;function DC(t){return t===0?"1-byte hops":t===1?"2-byte hops":t===2?"3-byte hops":"Unknown hop width"}function Fp(t,o,s,a){if(t.path_len<=0||!t.path)return`${o} -> ${s}`;const i=Yr(t.path,t.path_len).map(l=>{const d=$x(l,a,!0);return d.length===1?d[0].name||`${d[0].public_key.slice(0,l.length)}…`:d.length>1?`${l}…?`:`${l}…`});return[o,...i,s].join(" -> ")}function Rp({label:t,route:o,chain:s}){const a=Yr(o.path,o.path_len).join(" -> ")||"direct";return h.jsxs("div",{className:"rounded-md border border-border bg-muted/20 p-3",children:[h.jsxs("div",{className:"flex items-center justify-between gap-3",children:[h.jsx("h4",{className:"text-sm font-semibold",children:t}),h.jsx("span",{className:"text-[11px] text-muted-foreground",children:In(o.path_len,!0)})]}),h.jsx("p",{className:"mt-2 text-sm",children:s}),h.jsxs("div",{className:"mt-2 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground",children:[h.jsxs("span",{children:["Raw: ",a]}),h.jsx("span",{children:DC(o.path_hash_mode)})]})]})}function FC({open:t,onClose:o,contact:s,contacts:a,radioName:i,onDiscover:l}){const[d,u]=E.useState(!1),[p,f]=E.useState(null),[v,m]=E.useState(null),y=E.useMemo(()=>X0(s),[s]),b=Ra(s),C=E.useMemo(()=>{if(s.last_path_len===-1)return"Flood";const k=Yr(s.last_path,s.last_path_len);return k.length>0?`${In(s.last_path_len,!0)} (${k.join(" -> ")})`:In(s.last_path_len,!0)},[s.last_path,s.last_path_len]),_=E.useMemo(()=>{if(!b)return null;if(y.pathLen===-1)return"Flood";const k=Yr(y.path,y.pathLen);return k.length>0?`${In(y.pathLen,!0)} (${k.join(" -> ")})`:In(y.pathLen,!0)},[y,b]),g=v?Fp(v.forward_path,i||"Local radio",s.name||s.public_key.slice(0,12),a):null,N=v?Fp(v.return_path,s.name||s.public_key.slice(0,12),i||"Local radio",a):null,A=async()=>{u(!0),f(null);try{const k=await l(s.public_key);m(k)}catch(k){f(k instanceof Error?k.message:"Unknown error")}finally{u(!1)}};return h.jsx(Pa,{open:t,onOpenChange:k=>!k&&o(),children:h.jsxs(bs,{className:"sm:max-w-[560px]",children:[h.jsxs(ws,{children:[h.jsx(Cs,{children:"Path Discovery"}),h.jsx(ks,{children:"Send a routed probe to this contact and wait for the round-trip path response. The learned forward route will be saved back onto the contact if a response comes back."})]}),h.jsxs("div",{className:"space-y-4",children:[h.jsxs("div",{className:"rounded-md border border-border bg-muted/20 p-3 text-sm",children:[h.jsx("div",{className:"font-medium",children:s.name Line truncated
`).map((Ve,it,mt)=>h.jsxs("span",{children:[JC(Ve,v),it<mt.length-1&&h.jsx("br",{})]},it)),!pe&&h.jsxs(h.Fragment,{children:[h.jsx("span",{className:"text-[10px] text-muted-foreground ml-2",children:Fn(Q.sender_timestamp||Q.received_at)}),!Q.outgoing&&Q.paths&&Q.paths.length>0&&h.jsx(Lp,{paths:Q.paths,variant:"inline",onClick:()=>L({paths:Q.paths,senderInfo:pt(Q,Ce,He)})})]}),Q.outgoing&&(Q.acked>0?Q.paths&&Q.paths.length>0?h.jsx("span",{className:"text-muted-foreground cursor-pointer hover:text-primary",role:"button",tabIndex:0,onKeyDown:rn,onClick:Ve=>{Ve.stopPropagation(),L({paths:Q.paths,senderInfo:Ft,messageId:Q.id,isOutgoingChan:Q.type==="CHAN"&&!!f})},title:"View echo paths","aria-label":`Acknowledged, ${Q.acked} echo${Q.acked!==1?"s":""} — view paths`,children:` ✓${Q.acked>1?Q.acked:""}`}):h.jsx("span",{className:"text-muted-foreground",children:` ✓${Q.acked>1?Q.acked:""}`}):f&&Q.type==="CHAN"?h.jsxs("span",{className:"text-muted-foreground cursor-pointer hover:text-primary",role:"button",tabIndex:0,onKeyDown:rn,onClick:Ve=>{Ve.stopPropagation(),L({paths:[],senderInfo:Ft,messageId:Q.id,isOutgoingChan:!0})},title:"Message status","aria-label":"No echoes yet — view message status",children:[" ","?"]}):h.jsxs("span",{className:"text-muted-foreground",title:"No repeats heard yet",children:[" ","?"]}))]})]})]})]},Q.id)}),g&&h.jsx("div",{className:"text-center py-2 text-muted-foreground text-sm",role:"status",children:"Loading newer messages..."}),!g&&_&&h.jsx("div",{className:"text-center py-2 text-muted-foreground text-xs",children:"Scroll down for newer messages"})]}),ie&&h.jsx("div",{className:"pointer-events-none absolute bottom-4 left-1/2 -translate-x-1/2",children:h.jsxs("div",{className:"pointer-events-auto flex h-9 items-center overflow-hidden rounded-full border border-border bg-card shadow-lg transition-all hover:scale-105",children:[h.jsx("button",{type:"button",onClick:()=>{var Q,ge;(ge=(Q=U.current)==null?void 0:Q.scrollIntoView)==null||ge.call(Q,{block:"center"}),oe(!0),re(!1)},className:"h-full px-3 text-sm font-medium hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",children:"Jump to unread"}),h.jsx("button",{type:"button",onClick:()=>{oe(!0),re(!1)},className:"flex h-full w-9 items-center justify-center border-l border-border text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring","aria-label":"Dismiss jump to unread",title:"Dismiss jump to unread",children:"×"})]})}),R&&h.jsx("button",{onClick:We,className:"absolute bottom-4 right-4 w-9 h-9 rounded-full bg-card hover:bg-accent border border-border flex items-center justify-center shadow-lg transition-all hover:scale-105 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",title:"Scroll to bottom","aria-label":"Scroll to bottom",children:h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"text-muted-foreground",children:h.jsx("polyline",{points:"6 9 12 15 18 9"})})}),D&&h.jsx(YC,{open:!0,onClose:()=>L(null),paths:D.paths,senderInfo:D.senderInfo,contacts:o,config:m??null,messageId:D.messageId,isOutgoingChan:D.isOutgoingChan,isResendable:Rt,onResend:f})]})}var mr={},da={},Gt={},Ip;function kn(){if(Ip)return Gt;Ip=1,Object.defineProperty(Gt,"__esModule",{value:!0}),Gt.RequestType=Gt.AdvertFlags=Gt.DeviceRole=Gt.PayloadVersion=Gt.ControlSubType=Gt.PayloadType=Gt.RouteType=void 0;var t;(function(u){u[u.TransportFlood=0]="TransportFlood",u[u.Flood=1]="Flood",u[u.Direct=2]="Direct",u[u.TransportDirect=3]="TransportDirect"})(t||(Gt.RouteType=t={}));var o;(function(u){u[u.Request=0]="Request",u[u.Response=1]="Response",u[u.TextMessage=2]="TextMessage",u[u.Ack=3]="Ack",u[u.Advert=4]="Advert",u[u.GroupText=5]="GroupText",u[u.GroupData=6]="GroupData",u[u.AnonRequest=7]="AnonRequest",u[u.Path=8]="Path",u[u.Trace=9]="Trace",u[u.Multipart=10]="Multipart",u[u.Control=11]="Control",u[u.RawCustom=15]="RawCustom"})(o||(Gt.PayloadType=o={}));var s;(function(u){u[u.NodeDiscoverReq=128]="NodeDiscoverReq",u[u.NodeDiscoverResp=144]="NodeDiscoverResp"})(s||(Gt.ControlSubType=s={}));var a;(function(u){u[u.Version1=0]="Version1",u[u.Version2=1]="Version2",u[u.Version3=2]="Version3",u[u.Version4=3]="Version4"})(a||(Gt.PayloadVersion=a={}));var i;(function(u){u[u.Unknown=0]="Unknown",u[u.ChatNode=1]="ChatNode",u[u.Repeater=2]="Repeater",u[u.RoomServer=3]="RoomServer",u[u.Sensor=4]="Sensor"})(i||(Gt.DeviceRole=i={}));var l;(function(u){u[u.HasLocation=16]="HasLocation",u[u.HasFeature1=32]="HasFeature1",u[u.HasFeature2=64]="HasFeature2",u[u.HasName=128]="HasName"})(l||(Gt.AdvertFlags=l={}));var d;return(function(u){u[u.GetStats=1]="GetStats",u[u.Keepalive=2]="Keepalive",u[u.GetTelemetryData=3]="GetTelemetryData",u[u.GetMinMaxAvgData=4]="GetMinMaxAvgData",u[u.GetAccessList=5]="GetAc 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:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- 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(a){var i=s,l=i.lib,d=l.WordArray,u=l.Hasher,p=i.algo,f=d.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=d.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]),m=d.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]),y=d.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]),b=d.create([0,1518500249,1859775393,2400959708,2840853838]),C=d.create([1352829926,1548603684,1836072691,2053994217,0]),_=p.RIPEMD160=u.extend({_doReset:function(){this._hash=d.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(R,T){for(var D=0;D<16;D++){var L=T+D,M=R[L];R[L]=(M<<8|M>>>24)&16711935|(M<<24|M>>>8)&4278255360}var I=this._hash.words,$=b.words,q=C.words,G=f.words,ie=v.words,re=m.words,ce=y.words,oe,se,U,P,O,H,j,K,ee,le;H=oe=I[0],j=se=I[1],K=U=I[2],ee=P=I[3],le=O=I[4];for(var te,D=0;D<80;D+=1)te=oe+R[T+G[D]]|0,D<16?te+=g(se,U,P)+$[0]:D<32?te+=N(se,U,P)+$[1]:D<48?te+=A(se,U,P)+$[2]:D<64?te+=k(se,U,P)+$[3]:te+=B(se,U,P)+$[4],te=te|0,te=S(te,re[D]),te=te+O|0,oe=O,O=P,P=S(U,10),U=se,se=te,te=H+R[T+ie[D]]|0,D<16?te+=B(j,K,ee)+q[0]:D<32?te+=k(j,K,ee)+q[1]:D<48?te+=A(j,K,ee)+q[2]:D<64?te+=N(j,K,ee)+q[3]:te+=g(j,K,ee)+q[4],te=te|0,te=S(te,ce[D]),te=te+le|0,H=le,le=ee,ee=S(K,10),K=j,j=te;te=I[1]+U+ee|0,I[1]=I[2]+P+le|0,I[2]=I[3]+O+H|0,I[3]=I[4]+oe+j|0,I[4]=I[0]+se+K|0,I[0]=te},_doFinalize:function(){var R=this._data,T=R.words,D=this._nDataBytes*8,L=R.sigBytes*8;T[L>>>5]|=128<<24-L%32,T[(L+64>>>9<<4)+14]=(D<<8|D>>>24)&16711935|(D<<24|D>>>8)&4278255360,R.sigBytes=(T.length+1)*4,this._process();for(var M=this._hash,I=M.words,$=0;$<5;$++){var q=I[$];I[$]=(q<<8|q>>>24)&16711935|(q<<24|q>>>8)&4278255360}return M},clone:function(){var R=u.clone.call(this);return R._hash=this._hash.clone(),R}});function g(R,T,D){return R^T^D}function N(R,T,D){return R&T|~R&D}function A(R,T,D){return(R|~T)^D}function k(R,T,D){return R&D|T&~D}function B(R,T,D){return R^(T|~D)}function S(R,T){return R<<T|R>>>32-T}i.RIPEMD160=u._createHelper(_),i.HmacRIPEMD160=u._createHmacHelper(_)})(),s.RIPEMD160})})(bl)),bl.exports}var wl={exports:{}},Sk=wl.exports,om;function td(){return om||(om=1,(function(t,o){(function(s,a){t.exports=a(Ze())})(Sk,function(s){(function(){var a=s,i=a.lib,l=i.Base,d=a.enc,u=d.Utf8,p=a.algo;p.HMAC=l.extend({init:function(f,v){f=this._hasher=new f.init,typeof v=="string"&&(v=u.parse(v));var m=f.blockSize,y=m*4;v.sigBytes>y&&(v=f.finalize(v)),v.clamp();for(var b=this._oKey=v.clone(),C=this._iKey=v.clone(),_=b.words,g=C.words,N=0;N<m;N++)_[N]^=1549556828,g[N]^=909522486;b.sigBytes=C.sigBytes=y,this.reset()},reset:function(){var f=this._hasher;f.reset(),f.update(this._iKey)},update:function(f){return this._hasher.update(f),this},finalize:function(f){var v=this._hasher,m=v.finalize(f);v.reset();var y=v.finalize(this._oKey.clone().concat(m));return y}})})()})})(wl)),wl.exports}var Cl={exports:{}},Ak=Cl.exports,sm;function Nk(){return sm||(sm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),ed(),td())})(Ak,function(s){return(function(){var a=s,i=a.lib,l=i.Base,d=i.WordArray,u=a.algo,p=u.SHA256,f=u.HMAC,v=u.PBKDF2=l.extend({cfg:l.extend({keySize:128/32,hasher:p,iterations:25e4}),init:function(m){this.cfg=this.cfg.extend(m)},compute:function(m,y){for(var b=this.cfg,C=f.create(b.hasher,m),_=d.create(),g=d.create([1]),N=_.words,A=g.words,k=b.keySize,B=b.iterations;N.length<k;){var S=C.update(y).finalize(g);C.reset();for(var R=S.words,T=R.length,D=S,L=1;L<B;L++){D=C.finalize(D),C.reset();for(var M=D.words,I=0;I<T;I++)R[I]^=M[I]}_.concat(S),A[0]++}return _.sigBytes=k*4,_}});a.PBKDF2=function(m,y,b){return v.create(b).compute(m,y)}})(),s.PBKDF2})})(Cl)),Cl.exports}var kl={exports:{}},Bk=kl.exports,am;function Qr(){return am||(am=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),_1(),td())})(Bk,function(s){return(function(){var a=s,i=a.lib,l=i.Base,d=i.WordArray,u=a.algo,p=u.MD5,f=u.EvpKDF=l.extend({cfg:l.extend({keySize:128/32,hasher:p,iterations:1}),init:function(v){this.cfg=this.cfg.extend(v)},compute:function(v,m){for(var y,b=this.cfg,C=b.hasher.create(),_=d.create(),g=_.words,N=b.keySize,A=b.iterations;g.length<N;){y&&C.update(y),y=C.update(v).finalize(m),C.reset();for(var k=1;k<A;k++)y=C.finalize(y),C.reset();_.concat(y)}return _.sigBytes=N*4,_}});a.EvpKDF=function(v,m,y){return f.create(y).compute(v,m)}})(),s.EvpKDF})})(kl)),kl.exports}var El={exports:{}},Dk=El.exports,im;function Ut(){rLine truncated
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/return s.mode.CTRGladman=(function(){var a=s.lib.BlockCipherMode.extend();function i(u){if((u>>24&255)===255){var p=u>>16&255,f=u>>8&255,v=u&255;p===255?(p=0,f===255?(f=0,v===255?v=0:++v):++f):++p,u=0,u+=p<<16,u+=f<<8,u+=v}else u+=1<<24;return u}function l(u){return(u[0]=i(u[0]))===0&&(u[1]=i(u[1])),u}var d=a.Encryptor=a.extend({processBlock:function(u,p){var f=this._cipher,v=f.blockSize,m=this._iv,y=this._counter;m&&(y=this._counter=m.slice(0),this._iv=void 0),l(y);var b=y.slice(0);f.encryptBlock(b,0);for(var C=0;C<v;C++)u[p+C]^=b[C]}});return a.Decryptor=d,a})(),s.mode.CTRGladman})})(Al)),Al.exports}var Nl={exports:{}},zk=Nl.exports,dm;function Ok(){return dm||(dm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(zk,function(s){return s.mode.OFB=(function(){var a=s.lib.BlockCipherMode.extend(),i=a.Encryptor=a.extend({processBlock:function(l,d){var u=this._cipher,p=u.blockSize,f=this._iv,v=this._keystream;f&&(v=this._keystream=f.slice(0),this._iv=void 0),u.encryptBlock(v,0);for(var m=0;m<p;m++)l[d+m]^=v[m]}});return a.Decryptor=i,a})(),s.mode.OFB})})(Nl)),Nl.exports}var Bl={exports:{}},Hk=Bl.exports,fm;function Lk(){return fm||(fm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Hk,function(s){return s.mode.ECB=(function(){var a=s.lib.BlockCipherMode.extend();return a.Encryptor=a.extend({processBlock:function(i,l){this._cipher.encryptBlock(i,l)}}),a.Decryptor=a.extend({processBlock:function(i,l){this._cipher.decryptBlock(i,l)}}),a})(),s.mode.ECB})})(Bl)),Bl.exports}var Dl={exports:{}},Ik=Dl.exports,hm;function $k(){return hm||(hm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Ik,function(s){return s.pad.AnsiX923={pad:function(a,i){var l=a.sigBytes,d=i*4,u=d-l%d,p=l+u-1;a.clamp(),a.words[p>>>2]|=u<<24-p%4*8,a.sigBytes+=u},unpad:function(a){var i=a.words[a.sigBytes-1>>>2]&255;a.sigBytes-=i}},s.pad.Ansix923})})(Dl)),Dl.exports}var Fl={exports:{}},Vk=Fl.exports,pm;function Uk(){return pm||(pm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Vk,function(s){return s.pad.Iso10126={pad:function(a,i){var l=i*4,d=l-a.sigBytes%l;a.concat(s.lib.WordArray.random(d-1)).concat(s.lib.WordArray.create([d<<24],1))},unpad:function(a){var i=a.words[a.sigBytes-1>>>2]&255;a.sigBytes-=i}},s.pad.Iso10126})})(Fl)),Fl.exports}var Rl={exports:{}},Wk=Rl.exports,mm;function qk(){return mm||(mm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Wk,function(s){return s.pad.Iso97971={pad:function(a,i){a.concat(s.lib.WordArray.create([2147483648],1)),s.pad.ZeroPadding.pad(a,i)},unpad:function(a){s.pad.ZeroPadding.unpad(a),a.sigBytes--}},s.pad.Iso97971})})(Rl)),Rl.exports}var Tl={exports:{}},Kk=Tl.exports,xm;function Gk(){return xm||(xm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Kk,function(s){return s.pad.ZeroPadding={pad:function(a,i){var l=i*4;a.clamp(),a.sigBytes+=l-(a.sigBytes%l||l)},unpad:function(a){for(var i=a.words,l=a.sigBytes-1,l=a.sigBytes-1;l>=0;l--)if(i[l>>>2]>>>24-l%4*8&255){a.sigBytes=l+1;break}}},s.pad.ZeroPadding})})(Tl)),Tl.exports}var Pl={exports:{}},Yk=Pl.exports,vm;function Xk(){return vm||(vm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Yk,function(s){return s.pad.NoPadding={pad:function(){},unpad:function(){}},s.pad.NoPadding})})(Pl)),Pl.exports}var jl={exports:{}},Qk=jl.exports,ym;function Zk(){return ym||(ym=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ut())})(Qk,function(s){return(function(a){var i=s,l=i.lib,d=l.CipherParams,u=i.enc,p=u.Hex,f=i.format;f.Hex={stringify:function(v){return v.ciphertext.toString(p)},parse:function(v){var m=p.parse(v);return d.create({ciphertext:m})}}})(),s.format.Hex})})(jl)),jl.exports}var Ml={exports:{}},Jk=Ml.exports,gm;function e8(){return gm||(gm=1,(function(t,o){(function(s,a,i){t.exports=a(Ze(),Ao(),No(),Qr(),Ut())})(Jk,function(s){return(function(){var a=s,i=a.lib,l=i.BlockCipher,d=a.algo,u=[],p=[],f=[],v=[],m=[],y=[],b=[],C=[],_=[],g=[];(function(){for(var k=[],B=0;B<256;B++)B<128?k[B]=B<<1:k[B]=B<<1^283;for(var S=0,R=0,B=0;B<256;B++){var T=R^R<<1^R<<2^R<<3^R<<4;T=T>>>8^T&255^99,u[S]=T,p[T]=S;var D=k[S],L=k[D],M=k[L],I=k[T]*257^T*16843008;f[S]=I<<24|I>>>8,v[S]=I<<16|I>>>16,m[S]=I<<8|I>>>24,y[S]=I;var I=M*16843009^L*65537^D*257^S*16843008;b[T]=I<<24|I>>>8,C[T]=I<<16|I>>>16,_[T]=I<<8|I>>>24,g[T]=I,S?(S=D^k[k[k[M^D]]],R^=k[k[R]]):S=R=1}})();var N=[0,1,2,4,8,16,32,64,128,27,54],A=d.AES=l.extend({_doReset:function(){var k;if(!(this._nRounds&&this._keyPriorReset===this._key)){for(var B=this._keyPriorReset=this._key,S=B.words,R=B.sigBytes/4,T=this._nRounds=R+6,D=(T+1)*4,L=this._keySchedule=[],M=0;M<D;M++)M<R?L[M]=S[M]:(k=L[M-1],M%R?R>6&&M%R==4&&(k=u[k>>>24]<<24|u[k>>>16&255]<<16|u[k>>>8&255]<<8|u[k&255]):(k=k<<8|k>>>24,k=u[k>>>24]<<24|u[k>>>16&255]<<16|u[k>>>8&255]<<8|u[k&255],k^=N[M/R|0]<<24),L[M]=L[M-R]^k);for(var I=this._invKeySchedule=[],$=0;$<D;$++){var M=D-$;if($%4)var k=L[M];else var k=L[M-4];$<4||M<=4?I[$]=k:I[$]=b[u[k>>>24]]^C[u[k>>>16&255]]^_[u[k>>>8&255]]^g[u[k&255]]}}},encryptBlock:Line 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:u+p,endByte:u+i.length-1,value:y});const b={type:t.PayloadType.Request,version:t.PayloadVersion.Version1,isValid:!0,timestamp:0,requestType:t.RequestType.GetStats,requestData:"",destinationHash:f,sourceHash:v,cipherMac:m,ciphertext:y};return l!=null&&l.includeSegments&&(b.segments=d),b}catch(d){return{type:t.PayloadType.Request,version:t.PayloadVersion.Version1,isValid:!1,errors:[d instanceof Error?d.message:"Failed to decode request payload"],timestamp:0,requestType:t.RequestType.GetStats,requestData:"",destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:""}}}}return va.RequestPayloadDecoder=s,va}var ya={},$m;function M8(){if($m)return ya;$m=1,Object.defineProperty(ya,"__esModule",{value:!0}),ya.ResponsePayloadDecoder=void 0;const t=kn(),o=Yt();class s{static decode(i,l){try{if(i.length<4){const C={type:t.PayloadType.Response,version:t.PayloadVersion.Version1,isValid:!1,errors:["Response payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return l!=null&&l.includeSegments&&(C.segments=[{name:"Invalid Response Data",description:"Response payload too short (minimum 4 bytes required)",startByte:l.segmentOffset||0,endByte:(l.segmentOffset||0)+i.length-1,value:(0,o.bytesToHex)(i)}]),C}const d=[],u=(l==null?void 0:l.segmentOffset)||0;let p=0;const f=(0,o.byteToHex)(i[p]);l!=null&&l.includeSegments&&d.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:u+p,endByte:u+p,value:f}),p+=1;const v=(0,o.byteToHex)(i[p]);l!=null&&l.includeSegments&&d.push({name:"Source Hash",description:"First byte of source node public key",startByte:u+p,endByte:u+p,value:v}),p+=1;const m=(0,o.bytesToHex)(i.subarray(p,p+2));l!=null&&l.includeSegments&&d.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:u+p,endByte:u+p+1,value:m}),p+=2;const y=(0,o.bytesToHex)(i.subarray(p));l!=null&&l.includeSegments&&i.length>p&&d.push({name:"Ciphertext",description:"Encrypted response data (tag + content)",startByte:u+p,endByte:u+i.length-1,value:y});const b={type:t.PayloadType.Response,version:t.PayloadVersion.Version1,isValid:!0,destinationHash:f,sourceHash:v,cipherMac:m,ciphertext:y,ciphertextLength:i.length-4};return l!=null&&l.includeSegments&&(b.segments=d),b}catch(d){return{type:t.PayloadType.Response,version:t.PayloadVersion.Version1,isValid:!1,errors:[d instanceof Error?d.message:"Failed to decode response payload"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return ya.ResponsePayloadDecoder=s,ya}var ga={},Vm;function z8(){if(Vm)return ga;Vm=1,Object.defineProperty(ga,"__esModule",{value:!0}),ga.AnonRequestPayloadDecoder=void 0;const t=kn(),o=Yt();class s{static decode(i,l){try{if(i.length<35){const C={type:t.PayloadType.AnonRequest,version:t.PayloadVersion.Version1,isValid:!1,errors:["AnonRequest payload too short (minimum 35 bytes: dest + public key + MAC)"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return l!=null&&l.includeSegments&&(C.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:l.segmentOffset||0,endByte:(l.segmentOffset||0)+i.length-1,value:(0,o.bytesToHex)(i)}]),C}const d=[],u=(l==null?void 0:l.segmentOffset)||0;let p=0;const f=(0,o.byteToHex)(i[0]);l!=null&&l.includeSegments&&d.push({name:"Destination Hash",description:`First byte of destination node public key: 0x${f}`,startByte:u+p,endByte:u+p,value:f}),p+=1;const v=(0,o.bytesToHex)(i.subarray(1,33));l!=null&&l.includeSegments&&d.push({name:"Sender Public Key",description:"Ed25519 public key of the sender (32 bytes)",startByte:u+p,endByte:u+p+31,value:v}),p+=32;const m=(0,o.bytesToHex)(i.subarray(33,35));l!=null&&l.includeSegments&&d.push({name:"Cipher MAC",description:"MAC for encrypted data verification (2 bytes)",startByte:u+p,endByte:u+p+1,value:m}),p+=2;const y=(0,o.bytesToHex)(i.subarray(35));l!=null&&l.includeSegments&&i.length>35&&d.push({name:"Ciphertext",description:`Encrypted message data (${i.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:u+p,endByte:u+i.length-1,value:y});const b={type:t.PayloadType.AnonRequest,version:t.PayloadVersion.Version1,isValid:!0,destinationHash:f,senderPublicKey:v,cipherMac:m,ciphertext:y,ciphertextLength:i.length-35};return l!=null&&l.includeSegments&&(b.segments=d),b}catch(d){return{type:t.PayloadType.AnonRequest,version:t.PayloadVersion.Version1,isValid:!1,errors:[d instanceof Error?d.message:"Failed to decode AnonRequest payload"],destinationHash:"",senderPublicKey:"",cipherMac:"",ciphertext:"",ciphertextLength:0}}}}return ga.AnonRequestPayloadDecoder=s,ga}var ba={},Um;function O8(){if(Um)return ba;Um=1,Object.defineProperty(ba,"__esModule",{value:!0}),ba.AckPayloadDecoder=void 0;const t=kn(),o=Yt();class s{static decode(i,l){try{if(i.length<4){const v={type:t.PayloadType.Ack,version:t.PayloadVersion.Version1,isValid:!1,errors:["Ack payload too short (minimum 4 bytes for checksum)"],checksum:""};return l!=null&&l.includeSegments&&(v.segments=[{name:"Invalid Ack Data",description:"Ack payload too short (minimum 4 bytes required for checksum)",startByte:l.segmentOffset||0,endByte:(l.segmentOffset||0)+i.length-1,value:(0,o.bytesToHex)(i)}]),v}const d=[],u=(l==null?void 0:l.segmentOffset)||0,p=(0,o.bytesToHex)(i.subarray(0,4));l!=null&&l.includeSegments&&d.push({name:"Checksum",description:`CRC checksum of message timestamp, text, and sender pubkey: 0x${p}`,startByte:u,endByte:u+3,value:p}),l!=null&&l.includeSegments&&i.length>4&&d.push({name:"Additional Data",description:"Extra data in Ack payload",startByte:u+4,endByte:u+i.length-1,value:(0,o.bytesToHex)(i.subarray(4))});const f={type:t.PayloadType.Ack,version:t.PayloadVersion.Version1,isValid:!0,checksum:p};return l!=null&&l.includeSegments&&(f.segments=d),f}catch(d){return{type:t.PayloadType.Ack,version:t.PayloadVersion.Version1,isValid:!1,errors:[d instanceof Error?d.message:"Failed to decode Ack payload"],checksum:""}}}}return ba.AckPayloadDecoder=s,ba}var wa={},Wm;function H8(){if(Wm)return wa;Wm=1,Object.defineProperty(wa,"__esModule",{value:!0}),wa.PathPayloadDecoder=void 0;const t=kn(),o=Yt();class s{static decode(i){try{if(i.length<2)return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:["Path payload too short (minimum 2 bytes: path length + extra type)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};const l=i[0],d=(l>>6)+1,u=l&63,p=u*d;if(d===4)return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:["Invalid path length byte: reserved hash size (bits 7:6 = 11)"],pathLength:0,pathHashes:[],extraType:0,extraData:""};if(i.length<1+p+1)return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:[`Path payload too short (need ${1+p+1} bytes for path length + path + extra type)`],pathLength:u,...d>1?{pathHashSize:d}:{},pathHashes:[],extraType:0,extraData:""};const f=[];for(let y=0;y<u;y++){const b=1+y*d,C=i.subarray(b,b+d);f.push((0,o.bytesToHex)(C))}const v=i[1+p];let m="";return i.length>1+p+1&&(m=(0,o.bytesToHex)(i.subarray(1+p+1))),{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!0,pathLength:u,...d>1?{pathHashSize:d}:{},pathHashes:f,extraType:v,extraData:m}}catch(l){return{type:t.PayloadType.Path,version:t.PayloadVersion.Version1,isValid:!1,errors:[l instanceof Error?l.message:"Failed to decode Path payload"],pathLength:0,pathHashes:[],extraType:0,extraData:""}}}}return wa.PathPayloadDecoder=s,wa}var Ca={},qm;function L8(){if(qm)return Ca;qm=1,Object.defineProperty(Ca,"__esModule",{value:!0}),Ca.TextMessagePayloadDecoder=void 0;const t=kn(),o=Yt();class s{static decode(i,l){try{if(i.length<4){const C={type:t.PayloadType.TextMessage,version:t.PayloadVersion.Version1,isValid:!1,errors:["TextMessage payload too short (minimum 4 bytes: dest + source + MAC)"],destinationHash:"",sourceHash:"",cipherMac:"",ciphertext:"",ciphertextLength:0};return l!=null&&l.includeSegments&&(C.segments=[{name:"Invalid TextMessage Data",description:"TextMessage payload too short (minimum 4 bytes required)",startByte:l.segmentOffset||0,endByte:(l.segmentOffset||0)+i.length-1,value:(0,o.bytesToHex)(i)}]),C}const d=[],u=(l==null?void 0:l.segmentOffset)||0;let p=0;const f=(0,o.byteToHex)(i[p]);l!=null&&l.includeSegments&&d.push({name:"Destination Hash",description:"First byte of destination node public key",startByte:u+p,endByte:u+p,value:f}),p+=1;const v=(0,o.byteToHex)(i[p]);l!=null&&l.includeSegments&&d.push({name:"Source Hash",description:"First byte of source node public key",startByte:u+p,endByte:u+p,value:v}),p+=1;const m=(0,o.bytesToHex)(i.subarray(p,p+2));l!=null&&l.includeSegments&&d.push({name:"Cipher MAC",description:"MAC for encrypted data in next field",startByte:u+p,endByte:u+p+1,value:m}),p+=2;const y=(0,o.bytesToHex)(i.subarray(p));l!=null&&l.includeSegments&&i.length>p&&d.push({name:"Ciphertext",description:"Encrypted message data (timestamp + message text)",startByte:u+p,endByte:u+i.leng Line truncated
//# sourceMappingURL=index-BJ3L5G2s.js.map
@@ -0,0 +1 @@
{"version":3,"mappings":"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 truncated
@@ -0,0 +1 @@
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans);font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--font-mono);font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 224 14% 8%;--foreground: 213 15% 90%;--card: 224 13% 11%;--card-foreground: 213 15% 90%;--popover: 224 13% 12%;--popover-foreground: 213 15% 90%;--primary: 152 60% 38%;--primary-foreground: 0 0% 100%;--secondary: 224 12% 17%;--secondary-foreground: 213 12% 85%;--muted: 224 12% 15%;--muted-foreground: 218 10% 65%;--accent: 224 11% 19%;--accent-foreground: 213 15% 90%;--destLine truncated
@@ -0,0 +1 @@
.leaflet-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-container,.leaflet-pane>svg,.leaflet-pane>canvas,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;left:0;top:0}.leaflet-container{overflow:hidden}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-tile::-moz-selection{background:transparent}.leaflet-tile::selection{background:transparent}.leaflet-safari .leaflet-tile{image-rendering:-webkit-optimize-contrast}.leaflet-safari .leaflet-tile-container{width:1600px;height:1600px;-webkit-transform-origin:0 0}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container .leaflet-overlay-pane svg{max-width:none!important;max-height:none!important}.leaflet-container .leaflet-marker-pane img,.leaflet-container .leaflet-shadow-pane img,.leaflet-container .leaflet-tile-pane img,.leaflet-container img.leaflet-image-layer,.leaflet-container .leaflet-tile{max-width:none!important;max-height:none!important;width:auto;padding:0}.leaflet-container img.leaflet-tile{mix-blend-mode:plus-lighter}.leaflet-container.leaflet-touch-zoom{touch-action:pan-x pan-y}.leaflet-container.leaflet-touch-drag{touch-action:none;touch-action:pinch-zoom}.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom{touch-action:none}.leaflet-container{-webkit-tap-highlight-color:transparent}.leaflet-container a{-webkit-tap-highlight-color:rgba(51,181,229,.4)}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{width:0;height:0;box-sizing:border-box;z-index:800}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-pane{z-index:400}.leaflet-tile-pane{z-index:200}.leaflet-overlay-pane{z-index:400}.leaflet-shadow-pane{z-index:500}.leaflet-marker-pane{z-index:600}.leaflet-tooltip-pane{z-index:650}.leaflet-popup-pane{z-index:700}.leaflet-map-pane canvas{z-index:100}.leaflet-map-pane svg{z-index:200}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{position:relative;z-index:800;pointer-events:visiblePainted;pointer-events:auto}.leaflet-top,.leaflet-bottom{position:absolute;z-index:1000;pointer-events:none}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-popup{opacity:0;transition:opacity .2s linear}.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-animated{transform-origin:0 0}svg.leaflet-zoom-animated{will-change:transform}.leaflet-zoom-anim .leaflet-zoom-animated{transition:transform .25s cubic-bezier(0,0,.25,1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile{transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-interactive{cursor:pointer}.leaflet-grab{cursor:grab}.leaflet-crosshair,.leaflet-crosshair .leaflet-interactive{cursor:crosshair}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-grab,.leaflet-dragging .leaflet-grab .leaflet-interactive,.leaflet-dragging .leaflet-marker-draggable{cursor:move;cursor:grabbing}.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-image-layer,.leaflet-pane>svg path,.leaflet-tile-container{pointer-events:none}.leaflet-marker-icon.leaflet-interactive,.leaflet-image-layer.leaflet-interactive,.leaflet-pane>svg path.leaflet-interactive,svg.leaflet-image-layer.leaflet-interactive path{pointer-events:visiblePainted;pointer-events:auto}.leaflet-container{background:#ddd;outline-offset:1px}.leaflet-container a{color:#0078a8}.leaflet-zoom-box{border:2px dotted #38f;background:#ffffff80}.leaflet-container{font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:12px;font-size:.75rem;line-height:1.5}.leaflet-bar{box-shadow:0 1px 5px #000000a6;border-radius:4px}.leaflet-bar a{background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;display:block;text-align:center;text-decoration:none;color:#000}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50% 50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover,.leaflet-bar a:focus{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom:none}.leaflet-bar a.leaflet-disabled{cursor:default;background-color:#f4f4f4;color:#bbb}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-touch .leaflet-bar a:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.leaflet-touch .leaflet-bar a:last-child{border-bottLine truncated
@@ -0,0 +1,5 @@
import{r as O,a3 as si,a4 as ss,v as rs}from"./index-BJ3L5G2s.js";function Mn(d,_){const h=O.useRef(_);O.useEffect(function(){_!==h.current&&d.attributionControl!=null&&(h.current!=null&&d.attributionControl.removeAttribution(h.current),_!=null&&d.attributionControl.addAttribution(_)),h.current=_},[d,_])}const as=1;function hs(d){return Object.freeze({__version:as,map:d})}function xs(d,_){return Object.freeze({...d,..._})}const Cn=O.createContext(null),Sn=Cn.Provider;function ai(){const d=O.useContext(Cn);if(d==null)throw new Error("No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>");return d}function zn(d){function _(h,m){const{instance:f,context:E}=d(h).current;return O.useImperativeHandle(m,()=>f),h.children==null?null:si.createElement(Sn,{value:E},h.children)}return O.forwardRef(_)}function us(d){function _(h,m){const[f,E]=O.useState(!1),{instance:P}=d(h,E).current;O.useImperativeHandle(m,()=>P),O.useEffect(function(){f&&P.update()},[P,f,h.children]);const ot=P._contentNode;return ot?ss.createPortal(h.children,ot):null}return O.forwardRef(_)}function ls(d){function _(h,m){const{instance:f}=d(h).current;return O.useImperativeHandle(m,()=>f),null}return O.forwardRef(_)}function hi(d,_){const h=O.useRef();O.useEffect(function(){return _!=null&&d.instance.on(_),h.current=_,function(){h.current!=null&&d.instance.off(h.current),h.current=null}},[d,_])}function we(d,_){const h=d.pane??_.pane;return h?{...d,pane:h}:d}function cs(d,_){return function(m,f){const E=ai(),P=d(we(m,E),E);return Mn(E.map,m.attribution),hi(P.current,m.eventHandlers),_(P.current,E,m,f),P}}var Jt={exports:{}};/* @preserve
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/var fs=Jt.exports,bn;function ds(){return bn||(bn=1,(function(d,_){(function(h,m){m(_)})(fs,(function(h){var m="1.9.4";function f(t){var e,i,n,o;for(i=1,n=arguments.length;i<n;i++){o=arguments[i];for(e in o)t[e]=o[e]}return t}var E=Object.create||(function(){function t(){}return function(e){return t.prototype=e,new t}})();function P(t,e){var i=Array.prototype.slice;if(t.bind)return t.bind.apply(t,i.call(arguments,1));var n=i.call(arguments,2);return function(){return t.apply(e,n.length?n.concat(i.call(arguments)):arguments)}}var ot=0;function b(t){return"_leaflet_id"in t||(t._leaflet_id=++ot),t._leaflet_id}function At(t,e,i){var n,o,s,r;return r=function(){n=!1,o&&(s.apply(i,o),o=!1)},s=function(){n?o=arguments:(t.apply(i,arguments),setTimeout(r,e),n=!0)},s}function yt(t,e,i){var n=e[1],o=e[0],s=n-o;return t===n&&i?t:((t-o)%s+s)%s+o}function I(){return!1}function X(t,e){if(e===!1)return t;var i=Math.pow(10,e===void 0?6:e);return Math.round(t*i)/i}function U(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function ut(t){return U(t).split(/\s+/)}function k(t,e){Object.prototype.hasOwnProperty.call(t,"options")||(t.options=t.options?E(t.options):{});for(var i in e)t.options[i]=e[i];return t.options}function Qt(t,e,i){var n=[];for(var o in t)n.push(encodeURIComponent(i?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(!e||e.indexOf("?")===-1?"?":"&")+n.join("&")}var $t=/\{ *([\w_ -]+) *\}/g;function wt(t,e){return t.replace($t,function(i,n){var o=e[n];if(o===void 0)throw new Error("No value provided for variable "+i);return typeof o=="function"&&(o=o(e)),o})}var et=Array.isArray||function(t){return Object.prototype.toString.call(t)==="[object Array]"};function Pe(t,e){for(var i=0;i<t.length;i++)if(t[i]===e)return i;return-1}var te="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";function Le(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}var li=0;function ci(t){var e=+new Date,i=Math.max(0,16-(e-li));return li=e+i,window.setTimeout(t,i)}var Te=window.requestAnimationFrame||Le("RequestAnimationFrame")||ci,fi=window.cancelAnimationFrame||Le("CancelAnimationFrame")||Le("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)};function V(t,e,i){if(i&&Te===ci)t.call(e);else return Te.call(window,P(t,e))}function J(t){t&&fi.call(window,t)}var kn={__proto__:null,extend:f,create:E,bind:P,get lastId(){return ot},stamp:b,throttle:At,wrapNum:yt,falseFn:I,formatNum:X,trim:U,splitWords:ut,setOptions:k,getParamString:Qt,template:wt,isArray:et,indexOf:Pe,emptyImageUrl:te,requestFn:Te,cancelFn:fi,requestAnimFrame:V,cancelAnimFrame:J};function lt(){}lt.extend=function(t){var e=function(){k(this),this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},i=e.__super__=this.prototype,n=E(i);n.constructor=e,e.prototype=n;for(var o in this)Object.prototype.hasOwnProperty.call(this,o)&&o!=="prototype"&&o!=="__super__"&&(e[o]=this[o]);return t.statics&&f(e,t.statics),t.includes&&(Zn(t.includes),f.apply(null,[n].concat(t.includes))),f(n,t),delete n.statics,delete n.includes,n.options&&(n.options=i.options?E(i.options):{},f(n.options,t.options)),n._initHooks=[],n.callInitHooks=function(){if(!this._initHooksCalled){i.callInitHooks&&i.callInitHooks.call(this),this._initHooksCalled=!0;for(var s=0,r=n._initHooks.length;s<r;s++)n._initHooks[s].call(this)}},e},lt.include=function(t){var e=this.prototype.options;return f(this.prototype,t),t.options&&(this.prototype.options=e,this.mergeOptions(t.options)),this},lt.mergeOptions=function(t){return f(this.prototype.options,t),this},lt.addInitHook=function(t){var e=Array.prototype.slice.call(arguments,1),i=typeof t=="function"?t:function(){this[t].apply(this,e)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(i),this};function Zn(t){if(!(typeof L>"u"||!L||!L.Mixin)){t=et(t)?t:[t];for(var e=0;e<t.length;e++)t[e]===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 Y={on:function(t,e,i){if(typeof t=="object")for(var n in t)this._on(n,t[n],e);else{t=ut(t);for(var o=0,s=t.length;o<s;o++)this._on(t[o],e,i)}return this},off:function(t,e,i){if(!arguments.length)delete this._events;else if(typeof t=="object")for(var n in t)this._off(n,t[n],e);else{t=ut(t);for(var o=arguments.length===1,s=0,r=t.length;s<r;s++)o?this._off(t[s]):this._off(t[s],e,i)}return this},_on:function(t,e,i,n){if(typeof e!="function"){console.warn("wrong listener type: "+typeof e);return}if(this._listens(t,e,i)===!1){i===this&&(i=void 0);var o={fn:e,ctx:i};n&&(o.once=!0),this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(o)}},_off:function(t,e,i){var n,o,s;if(this._events&&(n=this._events[t],!!n)){if(arguments.length===1){if(this._firingCount)for(o=0,s=n.length;o<s;o++)n[o].fn=I;delete this._events[t];return}if(typeof e!="function"){console.warn("wrong listenLine truncated
//# sourceMappingURL=leaflet-TNk2YzRY.js.map
@@ -0,0 +1 @@
{"version":3,"file":"leaflet-TNk2YzRY.js","sources":["../../node_modules/@react-leaflet/core/lib/attribution.js","../../node_modules/@react-leaflet/core/lib/context.js","../../node_modules/@react-leaflet/core/lib/component.js","../../node_modules/@react-leaflet/core/lib/events.js","../../node_modules/@react-leaflet/core/lib/pane.js","../../node_modules/@react-leaflet/core/lib/div-overlay.js","../../node_modules/leaflet/dist/leaflet-src.js","../../node_modules/@react-leaflet/core/lib/element.js","../../node_modules/@react-leaflet/core/lib/layer.js","../../node_modules/@react-leaflet/core/lib/path.js","../../node_modules/@react-leaflet/core/lib/generic.js","../../node_modules/@react-leaflet/core/lib/grid-layer.js","../../node_modules/react-leaflet/lib/MapContainer.js","../../node_modules/react-leaflet/lib/TileLayer.js"],"sourcesContent":["import { useEffect, useRef } from 'react';\nexport function useAttribution(map, attribution) {\n const attributionRef = useRef(attribution);\n useEffect(function updateAttribution() {\n if (attribution !== attributionRef.current && map.attributionControl != null) {\n if (attributionRef.current != null) {\n map.attributionControl.removeAttribution(attributionRef.current);\n }\n if (attribution != null) {\n map.attributionControl.addAttribution(attribution);\n }\n }\n attributionRef.current = attribution;\n }, [\n map,\n attribution\n ]);\n}\n","import { createContext, useContext } from 'react';\nexport const CONTEXT_VERSION = 1;\nexport function createLeafletContext(map) {\n return Object.freeze({\n __version: CONTEXT_VERSION,\n map\n });\n}\nexport function extendContext(source, extra) {\n return Object.freeze({\n ...source,\n ...extra\n });\n}\nexport const LeafletContext = createContext(null);\nexport const LeafletProvider = LeafletContext.Provider;\nexport function useLeafletContext() {\n const context = useContext(LeafletContext);\n if (context == null) {\n throw new Error('No context provided: useLeafletContext() can only be used in a descendant of <MapContainer>');\n }\n return context;\n}\n","import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { LeafletProvider } from './context.js';\nexport function createContainerComponent(useElement) {\n function ContainerComponent(props, forwardedRef) {\n const { instance , context } = useElement(props).current;\n useImperativeHandle(forwardedRef, ()=>instance);\n return props.children == null ? null : /*#__PURE__*/ React.createElement(LeafletProvider, {\n value: context\n }, props.children);\n }\n return /*#__PURE__*/ forwardRef(ContainerComponent);\n}\nexport function createDivOverlayComponent(useElement) {\n function OverlayComponent(props, forwardedRef) {\n const [isOpen, setOpen] = useState(false);\n const { instance } = useElement(props, setOpen).current;\n useImperativeHandle(forwardedRef, ()=>instance);\n useEffect(function updateOverlay() {\n if (isOpen) {\n instance.update();\n }\n }, [\n instance,\n isOpen,\n props.children\n ]);\n // @ts-ignore _contentNode missing in type definition\n const contentNode = instance._contentNode;\n return contentNode ? /*#__PURE__*/ createPortal(props.children, contentNode) : null;\n }\n return /*#__PURE__*/ forwardRef(OverlayComponent);\n}\nexport function createLeafComponent(useElement) {\n function LeafComponent(props, forwardedRef) {\n const { instance } = useElement(props).current;\n useImperativeHandle(forwardedRef, ()=>instance);\n return null;\n }\n return /*#__PURE__*/ forwardRef(LeafComponent);\n}\n","import { useEffect, useRef } from 'react';\nexport function useEventHandlers(element, eventHandlers) {\n const eventHandlersRef = useRef();\n useEffect(function addEventHandlers() {\n if (eventHandlers != null) {\n element.instance.on(eventHandlers);\n }\n eventHandlersRef.current = eventHandlers;\n return function removeEventHandlers() {\n if (eventHandlersRef.current != null) {\n element.instance.off(eventHandlersRef.current);\n }\n eventHandlersRef.current = null;\n };\n }, [\n element,\n eventHandlers\n ]);\n}\n","export function withPane(props, context) {\n const pane = props.pane ?? context.pane;\n return pane ? {\n ...props,\n pane\n } : props;\n}\n","import { useAttribution } from './attribution.js';\nimport { useLeafletContext } from './context.js';\nimport { useEventHandlers } from './events.js';\nimport { withPane } from './pane.js';\nexport function Line truncated
@@ -0,0 +1,2 @@
import{r as s,j as l,Q as f,l as u}from"./index-BJ3L5G2s.js";var N=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],h=N.reduce((a,r)=>{const t=f(`Primitive.${r}`),o=s.forwardRef((i,e)=>{const{asChild:p,...n}=i,m=p?t:r;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),l.jsx(m,{...n,ref:e})});return o.displayName=`Primitive.${r}`,{...a,[r]:o}},{}),x="Separator",c="horizontal",w=["horizontal","vertical"],d=s.forwardRef((a,r)=>{const{decorative:t,orientation:o=c,...i}=a,e=S(o)?o:c,n=t?{role:"none"}:{"aria-orientation":e==="vertical"?e:void 0,role:"separator"};return l.jsx(h.div,{"data-orientation":e,...n,...i,ref:r})});d.displayName=x;function S(a){return w.includes(a)}var v=d;const O=s.forwardRef(({className:a,orientation:r="horizontal",decorative:t=!0,...o},i)=>l.jsx(v,{ref:i,decorative:t,orientation:r,className:u("shrink-0 bg-border",r==="horizontal"?"h-[1px] w-full":"h-full w-[1px]",a),...o}));O.displayName=v.displayName;export{O as S};
//# sourceMappingURL=separator-ChUIbJIJ.js.map
@@ -0,0 +1 @@
{"version":3,"file":"separator-ChUIbJIJ.js","sources":["../../node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.mjs","../../node_modules/@radix-ui/react-separator/dist/index.mjs","../../src/components/ui/separator.tsx"],"sourcesContent":["// src/primitive.tsx\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { jsx } from \"react/jsx-runtime\";\nvar NODES = [\n \"a\",\n \"button\",\n \"div\",\n \"form\",\n \"h2\",\n \"h3\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"nav\",\n \"ol\",\n \"p\",\n \"select\",\n \"span\",\n \"svg\",\n \"ul\"\n];\nvar Primitive = NODES.reduce((primitive, node) => {\n const Slot = createSlot(`Primitive.${node}`);\n const Node = React.forwardRef((props, forwardedRef) => {\n const { asChild, ...primitiveProps } = props;\n const Comp = asChild ? Slot : node;\n if (typeof window !== \"undefined\") {\n window[Symbol.for(\"radix-ui\")] = true;\n }\n return /* @__PURE__ */ jsx(Comp, { ...primitiveProps, ref: forwardedRef });\n });\n Node.displayName = `Primitive.${node}`;\n return { ...primitive, [node]: Node };\n}, {});\nfunction dispatchDiscreteCustomEvent(target, event) {\n if (target) ReactDOM.flushSync(() => target.dispatchEvent(event));\n}\nvar Root = Primitive;\nexport {\n Primitive,\n Root,\n dispatchDiscreteCustomEvent\n};\n//# sourceMappingURL=index.mjs.map\n","// src/separator.tsx\nimport * as React from \"react\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { jsx } from \"react/jsx-runtime\";\nvar NAME = \"Separator\";\nvar DEFAULT_ORIENTATION = \"horizontal\";\nvar ORIENTATIONS = [\"horizontal\", \"vertical\"];\nvar Separator = React.forwardRef((props, forwardedRef) => {\n const { decorative, orientation: orientationProp = DEFAULT_ORIENTATION, ...domProps } = props;\n const orientation = isValidOrientation(orientationProp) ? orientationProp : DEFAULT_ORIENTATION;\n const ariaOrientation = orientation === \"vertical\" ? orientation : void 0;\n const semanticProps = decorative ? { role: \"none\" } : { \"aria-orientation\": ariaOrientation, role: \"separator\" };\n return /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-orientation\": orientation,\n ...semanticProps,\n ...domProps,\n ref: forwardedRef\n }\n );\n});\nSeparator.displayName = NAME;\nfunction isValidOrientation(orientation) {\n return ORIENTATIONS.includes(orientation);\n}\nvar Root = Separator;\nexport {\n Root,\n Separator\n};\n//# sourceMappingURL=index.mjs.map\n","'use client';\n\nimport * as React from 'react';\nimport * as SeparatorPrimitive from '@radix-ui/react-separator';\n\nimport { cn } from '@/lib/utils';\n\nconst Separator = React.forwardRef<\n React.ElementRef<typeof SeparatorPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => (\n <SeparatorPrimitive.Root\n ref={ref}\n decorative={decorative}\n orientation={orientation}\n className={cn(\n 'shrink-0 bg-border',\n orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',\n className\n )}\n {...props}\n />\n));\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n\nexport { Separator };\n"],"names":["NODES","Primitive","primitive","node","Slot","createSlot","Node","React.forwardRef","props","forwardedRef","asChild","primitiveProps","Comp","jsx","NAME","DEFAULT_ORIENTATION","ORIENTATIONS","Separator","decorative","orientationProp","domProps","orientation","isValidOrientation","semanticProps","Root","className","ref","SeparatorPrimitive.Root","cn"],"mappings":"6DAKA,IAAIA,EAAQ,CACV,IACA,SACA,MACA,OACA,KACA,KACA,MACA,QACA,QACA,KACA,MACA,KACA,IACA,SACA,OACA,MACA,IACF,EACIC,EAAYD,EAAM,OAAO,CAACE,EAAWC,IAAS,CAChD,MAAMC,EAAOC,EAAW,aAAaF,CAAI,EAAE,EACrCG,EAAOC,EAAAA,WAAiB,CAACC,EAAOC,IAAiB,CACrD,KAAM,CAAE,QAAAC,EAAS,GAAGC,CAAc,EAAKH,EACjCI,EAAOF,EAAUN,EAAOD,EAC9B,OAAI,OAAO,OAAW,MACpB,OAAO,OAAO,IAAI,UAAU,CAAC,EAAI,IAEZU,EAAAA,IAAID,EAAM,CAAE,GAAGD,EAAgB,IAAKF,EAAc,CAC3E,CAAC,EACD,OAAAH,EAAK,YAAc,aAAaH,CAAI,GAC7B,CAAE,GAAGD,EAAW,CAACC,CAAI,EAAGG,CAAI,CACrC,EAAG,EAAE,EChCDQ,EAAO,YACPC,EAAsB,aACtBC,EAAe,CAAC,aAAc,UAAU,EACxCC,EAAYV,EAAAA,WAAiB,CAACC,EAAOC,IAAiB,CACxD,KAAM,CAAE,WAAAS,EAAY,YAAaC,EAAkBJ,EAAqB,GAAGK,CAAQ,EAAKZ,EAClFa,EAAcC,EAAmBH,CAAe,EAAIA,EAAkBJ,EAEtEQ,EAAgBL,EAAa,CAAE,KAAM,QAAW,CAAE,mBADhCG,IAAgB,WAAaA,EAAc,OAC0B,KAAM,WAAW,EAC9G,OAAuBR,EAAAA,IACrBZ,EAAU,IACV,CACE,mBAAoBoB,EACpB,GAAGE,EACH,GAAGH,EACH,IAAKX,CACX,CACA,CACA,CAAC,EACDQ,EAAU,YAAcH,EACxB,SAASQ,EAAmBD,EAAa,CACvC,OAAOL,EAAa,SAASK,CAAW,CAC1C,CACA,IAAIG,EAAOP,ECnBX,MAAMA,EAAYV,EAAAA,WAGhB,CAAC,CAAE,UAAAkB,EAAW,YAAAJ,EAAc,aAAc,WAAAH,EAAa,GAAM,GAAGV,CAAA,EAASkB,IACzEb,EAAAA,IAACc,EAAA,CACC,IAAAD,EACA,WAAAR,EACA,YAAAG,EACA,UAAWO,EACT,qBACAP,IAAgB,aAAe,iBAAmB,iBAClDI,CAAA,EAED,GAAGjB,CAAA,CACLine truncated
@@ -0,0 +1,2 @@
const e=["2","1080","10-point","10th","11-point","12-point","16-point","18-point","1st","20-point","2d","2nd","30-30","3d","3-d","3m","3rd","48-point","4-d","4gl","4h","4th","5-point","5-t","5th","6-point","6th","7-point","7th","8-point","8th","9-point","9th","a","a1","a-1","a4","a5","aa","aaa","aaaa","aaaaaa","aaal","aaas","aaberg","aachen","aae","aaee","aaf","aag","aah","aahed","aahing","aahs","aaii","aal","aalborg","aalesund","aalii","aaliis","aals","aalst","aalto","aam","aamsi","aandahl","a-and-r","aani","aao","aap","aapss","aaqbiye","aar","aara","aarau","aarc","aardvark","aardvarks","aardwolf","aardwolves","aaren","aargau","aargh","aarhus","aarika","aaron","aaronic","aaronical","aaronite","aaronitic","aaronsburg","aaronson","aarp","aarrgh","aarrghh","aaru","aas","aasvogel","aasvogels","aau","aaup","aauw","aavso","aax","a-axes","a-axis","ab","aba","ababa","ababdeh","ababua","abac","abaca","abacay","abacas","abacate","abacaxi","abaci","abacinate","abacination","abacisci","abaciscus","abacist","aback","abacli","abaco","abacot","abacterial","abactinal","abactinally","abaction","abactor","abaculi","abaculus","abacus","abacuses","abad","abada","abadan","abaddon","abadejo","abadengo","abadia","abadite","abaff","abaft","abagael","abagail","abagtha","abay","abayah","abailard","abaisance","abaised","abaiser","abaisse","abaissed","abaka","abakan","abakas","abakumov","abalation","abalienate","abalienated","abalienating","abalienation","abalone","abalones","abama","abamp","abampere","abamperes","abamps","abana","aband","abandon","abandonable","abandoned","abandonedly","abandonee","abandoner","abandoners","abandoning","abandonment","abandonments","abandons","abandum","abanet","abanga","abanic","abannition","abantes","abapical","abaptiston","abaptistum","abarambo","abarbarea","abaris","abarthrosis","abarticular","abarticulation","abas","abase","abased","abasedly","abasedness","abasement","abasements","abaser","abasers","abases","abasgi","abash","abashed","abashedly","abashedness","abashes","abashing","abashless","abashlessly","abashment","abashments","abasia","abasias","abasic","abasing","abasio","abask","abassi","abassieh","abassin","abastard","abastardize","abastral","abatable","abatage","abate","abated","abatement","abatements","abater","abaters","abates","abatic","abating","abatis","abatised","abatises","abatjour","abatjours","abaton","abator","abators","abats","abattage","abattis","abattised","abattises","abattoir","abattoirs","abattu","abattue","abatua","abature","abaue","abave","abaxial","abaxile","abaze","abb","abba","abbacy","abbacies","abbacomes","abbadide","abbai","abbaye","abbandono","abbas","abbasi","abbasid","abbassi","abbassid","abbasside","abbate","abbatial","abbatical","abbatie","abbe","abbey","abbeys","abbeystead","abbeystede","abbes","abbess","abbesses","abbest","abbevilean","abbeville","abbevillian","abbi","abby","abbie","abbye","abbyville","abboccato","abbogada","abbot","abbotcy","abbotcies","abbotnullius","abbotric","abbots","abbotsen","abbotsford","abbotship","abbotships","abbotson","abbotsun","abbott","abbottson","abbottstown","abboud","abbozzo","abbr","abbrev","abbreviatable","abbreviate","abbreviated","abbreviately","abbreviates","abbreviating","abbreviation","abbreviations","abbreviator","abbreviatory","abbreviators","abbreviature","abbroachment","abc","abcess","abcissa","abcoulomb","abcs","abd","abdal","abdali","abdaria","abdat","abdel","abd-el-kadir","abd-el-krim","abdella","abderhalden","abderian","abderite","abderus","abdest","abdias","abdicable","abdicant","abdicate","abdicated","abdicates","abdicating","abdication","abdications","abdicative","abdicator","abdiel","abditive","abditory","abdom","abdomen","abdomens","abdomina","abdominal","abdominales","abdominalia","abdominalian","abdominally","abdominals","abdominoanterior","abdominocardiac","abdominocentesis","abdominocystic","abdominogenital","abdominohysterectomy","abdominohysterotomy","abdominoposterior","abdominoscope","abdominoscopy","abdominothoracic","abdominous","abdomino-uterotomy","abdominovaginal","abdominovesical","abdon","abdu","abduce","abduced","abducens","abducent","abducentes","abduces","abducing","abduct","abducted","abducting","abduction","abductions","abductor","abductores","abductors","abducts","abdul","abdul-aziz","abdul-baha","abdulla","abe","a-be","abeam","abear","abearance","abebi","abecedaire","abecedary","abecedaria","abecedarian","abecedarians","abecedaries","abecedarium","abecedarius","abed","abede","abedge","abednego","abegge","abey","abeyance","abeyances","abeyancy","abeyancies","abeyant","abeigh","abel","abelard","abele","abeles","abelia","abelian","abelicea","abelite","abell","abelmoschus","abelmosk","abelmosks","abelmusk","abelonian","abelson","abeltree","abencerrages","abend","abends","abenezra","abenteric","abeokuta","abepithymia","abepp","abercromby","abercrombie","aberdare","aberdavine","aberdeen","aberdeenshire","aberdevine","aberdonian","aberduvine","aberfan","aberglaube","aberia","aberystwyth",Line truncated
//# sourceMappingURL=wordlist-BtmChKSf.js.map
@@ -0,0 +1 @@
{"version":3,"file":"wordlist-BtmChKSf.js","sources":["../../node_modules/meshcore-hashtag-cracker/dist/wordlist.js"],"sourcesContent":["/**\n * English wordlist for dictionary attacks\n * Auto-generated from words.txt - do not edit manually\n *\n * @example\n * ```typescript\n * import { ENGLISH_WORDLIST } from 'meshcore-hashtag-cracker/wordlist';\n * cracker.setWordlist(ENGLISH_WORDLIST);\n * ```\n */\nexport const ENGLISH_WORDLIST = [\"2\", \"1080\", \"10-point\", \"10th\", \"11-point\", \"12-point\", \"16-point\", \"18-point\", \"1st\", \"20-point\", \"2d\", \"2nd\", \"30-30\", \"3d\", \"3-d\", \"3m\", \"3rd\", \"48-point\", \"4-d\", \"4gl\", \"4h\", \"4th\", \"5-point\", \"5-t\", \"5th\", \"6-point\", \"6th\", \"7-point\", \"7th\", \"8-point\", \"8th\", \"9-point\", \"9th\", \"a\", \"a1\", \"a-1\", \"a4\", \"a5\", \"aa\", \"aaa\", \"aaaa\", \"aaaaaa\", \"aaal\", \"aaas\", \"aaberg\", \"aachen\", \"aae\", \"aaee\", \"aaf\", \"aag\", \"aah\", \"aahed\", \"aahing\", \"aahs\", \"aaii\", \"aal\", \"aalborg\", \"aalesund\", \"aalii\", \"aaliis\", \"aals\", \"aalst\", \"aalto\", \"aam\", \"aamsi\", \"aandahl\", \"a-and-r\", \"aani\", \"aao\", \"aap\", \"aapss\", \"aaqbiye\", \"aar\", \"aara\", \"aarau\", \"aarc\", \"aardvark\", \"aardvarks\", \"aardwolf\", \"aardwolves\", \"aaren\", \"aargau\", \"aargh\", \"aarhus\", \"aarika\", \"aaron\", \"aaronic\", \"aaronical\", \"aaronite\", \"aaronitic\", \"aaronsburg\", \"aaronson\", \"aarp\", \"aarrgh\", \"aarrghh\", \"aaru\", \"aas\", \"aasvogel\", \"aasvogels\", \"aau\", \"aaup\", \"aauw\", \"aavso\", \"aax\", \"a-axes\", \"a-axis\", \"ab\", \"aba\", \"ababa\", \"ababdeh\", \"ababua\", \"abac\", \"abaca\", \"abacay\", \"abacas\", \"abacate\", \"abacaxi\", \"abaci\", \"abacinate\", \"abacination\", \"abacisci\", \"abaciscus\", \"abacist\", \"aback\", \"abacli\", \"abaco\", \"abacot\", \"abacterial\", \"abactinal\", \"abactinally\", \"abaction\", \"abactor\", \"abaculi\", \"abaculus\", \"abacus\", \"abacuses\", \"abad\", \"abada\", \"abadan\", \"abaddon\", \"abadejo\", \"abadengo\", \"abadia\", \"abadite\", \"abaff\", \"abaft\", \"abagael\", \"abagail\", \"abagtha\", \"abay\", \"abayah\", \"abailard\", \"abaisance\", \"abaised\", \"abaiser\", \"abaisse\", \"abaissed\", \"abaka\", \"abakan\", \"abakas\", \"abakumov\", \"abalation\", \"abalienate\", \"abalienated\", \"abalienating\", \"abalienation\", \"abalone\", \"abalones\", \"abama\", \"abamp\", \"abampere\", \"abamperes\", \"abamps\", \"abana\", \"aband\", \"abandon\", \"abandonable\", \"abandoned\", \"abandonedly\", \"abandonee\", \"abandoner\", \"abandoners\", \"abandoning\", \"abandonment\", \"abandonments\", \"abandons\", \"abandum\", \"abanet\", \"abanga\", \"abanic\", \"abannition\", \"abantes\", \"abapical\", \"abaptiston\", \"abaptistum\", \"abarambo\", \"abarbarea\", \"abaris\", \"abarthrosis\", \"abarticular\", \"abarticulation\", \"abas\", \"abase\", \"abased\", \"abasedly\", \"abasedness\", \"abasement\", \"abasements\", \"abaser\", \"abasers\", \"abases\", \"abasgi\", \"abash\", \"abashed\", \"abashedly\", \"abashedness\", \"abashes\", \"abashing\", \"abashless\", \"abashlessly\", \"abashment\", \"abashments\", \"abasia\", \"abasias\", \"abasic\", \"abasing\", \"abasio\", \"abask\", \"abassi\", \"abassieh\", \"abassin\", \"abastard\", \"abastardize\", \"abastral\", \"abatable\", \"abatage\", \"abate\", \"abated\", \"abatement\", \"abatements\", \"abater\", \"abaters\", \"abates\", \"abatic\", \"abating\", \"abatis\", \"abatised\", \"abatises\", \"abatjour\", \"abatjours\", \"abaton\", \"abator\", \"abators\", \"abats\", \"abattage\", \"abattis\", \"abattised\", \"abattises\", \"abattoir\", \"abattoirs\", \"abattu\", \"abattue\", \"abatua\", \"abature\", \"abaue\", \"abave\", \"abaxial\", \"abaxile\", \"abaze\", \"abb\", \"abba\", \"abbacy\", \"abbacies\", \"abbacomes\", \"abbadide\", \"abbai\", \"abbaye\", \"abbandono\", \"abbas\", \"abbasi\", \"abbasid\", \"abbassi\", \"abbassid\", \"abbasside\", \"abbate\", \"abbatial\", \"abbatical\", \"abbatie\", \"abbe\", \"abbey\", \"abbeys\", \"abbeystead\", \"abbeystede\", \"abbes\", \"abbess\", \"abbesses\", \"abbest\", \"abbevilean\", \"abbeville\", \"abbevillian\", \"abbi\", \"abby\", \"abbie\", \"abbye\", \"abbyville\", \"abboccato\", \"abbogada\", \"abbot\", \"abbotcy\", \"abbotcies\", \"abbotnullius\", \"abbotric\", \"abbots\", \"abbotsen\", \"abbotsford\", \"abbotship\", \"abbotships\", \"abbotson\", \"abbotsun\", \"abbott\", \"abbottson\", \"abbottstown\", \"abboud\", \"abbozzo\", \"abbr\", \"abbrev\", \"abbreviatable\", \"abbreviate\", \"abbreviated\", \"abbreviately\", \"abbreviates\", \"abbreviating\", \"abbreviation\", \"abbreviations\", \"abbreviator\", \"abbreviatory\", \"abbreviators\", \"abbreviature\", \"abbroachment\", \"abc\", \"abcess\", \"abcissa\", \"abcoulomb\", \"abcs\", \"abd\", \"abdal\", \"abdali\", \"abdaria\", \"abdat\", \"abdel\", \"abd-el-kadir\", \"abd-el-krim\", \"abdella\", \"abderhalden\", \"abderian\", \"abderite\", \"abderLine truncated
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"><g clip-path="url(#SvgjsClipPath1009)"><rect width="1000" height="1000" fill="#ffffff"></rect><g transform="matrix(0.5833333333333334,0,0,0.5833333333333334,150,150)"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1200" height="1200" viewBox="0 0 1200 1200"><image width="1200" height="1200" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAASwCAYAAADrIbPPAAAAxXpUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjabVBbDgMhCPz3FD0Cgg84Dtt1k96gxy+KNnXTSXiOjkho79cVHh0YU0i5cpFSwJAkCaolDA4dPkIafuCAUfV664cvgdYii+QEF49x9eeFFaNaln+E+DmJYyfE5QH5JjQfoj4RWnJOIZlChE7EKaD+LSjCdftagx3sFrq71k6qh3udqm3vzPYOITaKBOaJ2AegbiWQjkTNqB+0Y0qZyvAyJ7GF/NvTQvgArHxZ8kndxUIAAAGEaUNDUElDQyBwcm9maWxlAAB4nH2Rv0vDQBzFX1NLRSoOdijikKE62UWlOJYqFsFCaSu06mBy6S9o0pCkuDgKrgUHfyxWHVycdXVwFQTBHyD+AeKk6CIlfi8ptIjx4LgP7+497t4BQrvOVHMgAaiaZWRTSbFQXBWDrxAQQQBx+CVm6uncYh6e4+sePr7exXiW97k/x7BSMhngE4kTTDcs4g3i+Kalc94nDrOqpBCfE08ZdEHiR67LLr9xrjgs8Mywkc/OE4eJxUofy33MqoZKPEscVVSN8oWCywrnLc5qvcm69+QvDJW0lRzXaY4jhSWkkYEIGU3UUIeFGK0aKSaytJ/08I85/gy5ZHLVwMixgAZUSI4f/A9+d2uWZ6bdpFASCLzY9scEENwFOi3b/j627c4J4H8GrrSev9EG5j5Jb/W06BEwsg1cXPc0eQ+43AEiT7pkSI7kpymUy8D7GX1TERi9BYbW3N66+zh9APLU1fINcHAITFYoe93j3YP9vf17ptvfD57icrgkidHHAAANdmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDpmNmNhZWIyNS05N2Q2LTQyYjQtYmQzYS1kOWQyMzFlZDMyNjIiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MGM3ODA3NTEtNTdiNi00MWM4LWI0YmItZTZhMThkMTg4YTMwIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ODZjNjM3MjktMDg5Yi00YTM2LWI0ZjgtZTViNDE0NzljYTFlIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iV2luZG93cyIKICAgR0lNUDpUaW1lU3RhbXA9IjE3NzE5MTI2MjE1MzM5MTEiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zOCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjY6MDI6MjNUMjE6NTY6NTktMDg6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI2OjAyOjIzVDIxOjU2OjU5LTA4OjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6OGVjMmI3NmUtNTI5YS00ODNhLTkyMTEtMGRhMjQ1N2Y4NzM3IgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDI2LTAyLTIzVDIxOjU3OjAxIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgLine truncated

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="512pt" height="512pt" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<path d="m455.68 85.902c-31.289 0-56.32 25.031-56.32 56.32 0 11.379 3.4141 21.617 8.5352 30.152l-106.38 135.39c12.516 6.2578 23.895 15.359 32.996 25.602l107.52-136.54c4.5508 1.1367 9.1016 1.707 13.652 1.707 31.289 0 56.32-25.031 56.32-56.32 0-30.719-25.031-56.32-56.32-56.32z"/>
<path d="m256 343.04c-5.6875 0-10.809 0.57031-15.93 2.2773l-106.38-135.96c-9.1016 10.809-20.48 19.344-32.996 25.602l106.38 135.96c-5.1211 8.5352-7.3945 18.203-7.3945 28.445 0 31.289 25.031 56.32 56.32 56.32s56.32-25.031 56.32-56.32c0-31.293-25.031-56.324-56.32-56.324z"/>
<path d="m356.69 114.91c3.9805-13.652 10.238-26.738 19.344-37.547-38.113-13.652-78.508-21.047-120.04-21.047-59.164 0-115.48 14.789-166.12 42.668-9.1016-6.8281-21.051-10.809-33.562-10.809-31.289-0.57031-56.32 25.027-56.32 55.75 0 31.289 25.031 56.32 56.32 56.32 31.289 0 56.32-25.031 56.32-56.32 0-3.4141-0.57031-6.8281-1.1367-9.6719 44.371-23.895 93.297-36.41 144.5-36.41 34.703 0 68.836 5.6914 100.69 17.066z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+59
View File
@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="MCTerm" />
<meta name="theme-color" content="#111419" />
<meta name="description" content="Web interface for MeshCore mesh radio networks. Send and receive messages, manage contacts and channels, and configure your radio." />
<title>RemoteTerm for MeshCore</title>
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<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>
// Start critical data fetches before React/Vite JS loads.
// Must be in <head> BEFORE the module script so the browser queues these
// fetches before it discovers and starts downloading the JS bundle.
// React hooks consume the promises via window.__prefetch.
var fetchJsonOrThrow = function(url) {
return fetch(url).then(function(response) {
if (response.ok) {
return response.json();
}
return response.text().then(function(rawError) {
var message = rawError || response.statusText || ('HTTP ' + response.status);
try {
var parsed = JSON.parse(rawError);
if (parsed && typeof parsed.detail === 'string' && parsed.detail.length > 0) {
message = parsed.detail;
}
} catch {
// Keep raw text fallback when body is not JSON.
}
throw new Error('Prefetch failed for ' + url + ': ' + message);
});
}).catch(function(err) {
console.error(err);
throw err;
});
};
window.__prefetch = {
config: fetchJsonOrThrow('/api/radio/config'),
settings: fetchJsonOrThrow('/api/settings'),
channels: fetchJsonOrThrow('/api/channels'),
contacts: fetchJsonOrThrow('/api/contacts?limit=1000&offset=0'),
unreads: fetchJsonOrThrow('/api/read-state/unreads'),
undecryptedCount: fetchJsonOrThrow('/api/packets/undecrypted/count'),
};
</script>
<script type="module" crossorigin src="/assets/index-BJ3L5G2s.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Kkb-Bio9.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
+2
View File
@@ -0,0 +1,2 @@
User-agent: *
Disallow: /
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

+41 -2
View File
@@ -5,8 +5,10 @@ from fastapi.testclient import TestClient
from app.frontend_static import (
ASSET_CACHE_CONTROL,
FRONTEND_BUILD_INSTRUCTIONS,
INDEX_CACHE_CONTROL,
STATIC_FILE_CACHE_CONTROL,
register_first_available_frontend_static_routes,
register_frontend_missing_fallback,
register_frontend_static_routes,
)
@@ -28,8 +30,7 @@ def test_missing_dist_logs_error_and_keeps_app_running(tmp_path, caplog):
with TestClient(app) as client:
resp = client.get("/")
assert resp.status_code == 404
assert "npm install" in resp.json()["detail"]
assert "npm run build" in resp.json()["detail"]
assert FRONTEND_BUILD_INSTRUCTIONS in resp.json()["detail"]
def test_missing_index_logs_error_and_skips_frontend_routes(tmp_path, caplog):
@@ -120,3 +121,41 @@ def test_webmanifest_uses_forwarded_origin_headers(tmp_path):
assert data["start_url"] == "https://mesh.example.com:8443/"
assert data["scope"] == "https://mesh.example.com:8443/"
assert data["id"] == "https://mesh.example.com:8443/"
def test_first_available_prefers_dist_over_prebuilt(tmp_path):
app = FastAPI()
frontend_dir = tmp_path / "frontend"
dist_dir = frontend_dir / "dist"
prebuilt_dir = frontend_dir / "prebuilt"
dist_dir.mkdir(parents=True)
prebuilt_dir.mkdir(parents=True)
(dist_dir / "index.html").write_text("<html><body>dist</body></html>")
(prebuilt_dir / "index.html").write_text("<html><body>prebuilt</body></html>")
selected = register_first_available_frontend_static_routes(app, [dist_dir, prebuilt_dir])
assert selected == dist_dir.resolve()
with TestClient(app) as client:
response = client.get("/")
assert response.status_code == 200
assert "dist" in response.text
def test_first_available_uses_prebuilt_when_dist_missing(tmp_path):
app = FastAPI()
frontend_dir = tmp_path / "frontend"
dist_dir = frontend_dir / "dist"
prebuilt_dir = frontend_dir / "prebuilt"
prebuilt_dir.mkdir(parents=True)
(prebuilt_dir / "index.html").write_text("<html><body>prebuilt</body></html>")
selected = register_first_available_frontend_static_routes(app, [dist_dir, prebuilt_dir])
assert selected == prebuilt_dir.resolve()
with TestClient(app) as client:
response = client.get("/")
assert response.status_code == 200
assert "prebuilt" in response.text