GENERATED by tools/embed_page.py from views/index.html — do not edit. The demo page template, embedded so installed binaries need no views/ directory on disk (--page FILE overrides). Chunked because released nurlc (≤ v0.11.1) stack-overflows on literals past ~48 KB.
@ index_html_chunks → i@ index_html_chunk i k → syoloe-demo — live in-browser YOLOE segmentation, served by pure NURL.
The browser opens one page, grabs the webcam, and POSTs JPEG frames to this server; the server runs YOLOE (open-vocabulary detection + instance segmentation) on the GPU through the onnx package, composites the segmentation masks onto the frame, and answers with the masked JPEG plus a JSON detection list. The page draws boxes/labels on top and loops — live segmented video, end to end, with no Python, no OpenCV and no inference engine anywhere in the stack:
browser webcam → JPEG POST → http package (pure-NURL HTTP/TLS server) → image package (JPEG decode) → onnx package (every layer a CUDA-C kernel via NVRTC) → yoloe decode + mask branch → JPEG encode → browser
yoloe-demo --model yoloe-v8s-seg.onnx --classes classes.txt [--port 8090] [--host 0.0.0.0] [--gpu 0] [--tls] [--page FILE] (default: the template built into the binary)
--tls generates a self-signed P-256 certificate at startup (std/x509_gen, also pure NURL) so the camera works from other machines on the LAN too — browsers only expose getUserMedia on secure origins (localhost is exempt).
Routes: GET / the demo page (rendered once at startup via the template package with the class list + device name) POST /detect body = JPEG/PNG frame; query: conf=0.25 masks=1 on=0,2,5 → { ms, n, dets:[{n,s,c,k,x,y,w,h}], img:"data:..jpeg" } GET /health liveness probe
: DemoState: DemoState {
Engine eng // the inference engine, for the program's lifetime
OGraph graph
( Vec String ) names
i nc
String device
String model_path
String index_html // pre-rendered demo page
// runtime prompting (kmax > 0 → the promptable K-slot export is loaded):
i kmax // prompt slots baked into the detector graph (0 = baked vocab)
OGraph tgraph // MobileCLIP text encoder (pure NURL on the GPU)
Tokenizer tk // CLIP BPE tokenizer
( Vec u ) tpe // kmax×512 f32 text embeddings, zero-padded past nc
( Vec u ) model_bytes // raw .onnx, served to the wasm client mode
b wasm_mode // web/yoloe_detect.wasm present → offer in-browser compute
}
: Demo { s ctl }The server's state is a handle the route closures capture: every copy is the same state, and the last owner (the app's routes, when the server returns) releases the engine, the graphs and the buffers.
@ Demo_drop sink Demo h → v@ yd_name_at ( Vec String ) names i k → s@ yd_read_names s path → ( Vec String )classes.txt: one prompt per line (must match the model export)
@ yd_shape4 i a i b i c i d → ( Vec i )@ yd_pal_r i k → i8-colour instance palette (matches the page's JS palette by index)
@ yd_pal_g i k → i@ yd_pal_b i k → i@ yd_pal i ch → ( Vec i )@ yd_query_f ( Vec UrlParam ) ps s key f dflt → fvalue of key as float, or dflt when absent/garbage
@ yd_query_b ( Vec UrlParam ) ps s key b dflt → bflag key (0/1), dflt when absent
@ yd_enabled ( Vec UrlParam ) ps i nc i ncap → ( Vec i )per-class enable flags from on=0,2,5; no on param → all ACTIVE classes enabled. ncap is the decode width (kmax in prompt mode) — ids in [nc, ncap) are inert pad slots and stay off either way.
@ h_health HttpRequest req Params p → HttpResponse@ wd_probe s path → ( Vec u )1-byte marker vec when path exists and is readable ([] otherwise).
@ yd_load_graph s path → ?OGraph@ yd_builtin_page → Stringrender the page template once with the static context The page template compiled into the binary (src/index_html_data.nu, generated by tools/embed_page.py) — an installed tool has no views/ directory on disk. --page FILE overrides it.
wasm_detect.nu — YOLOE inference as a wasm32-wasi module: the SAME pure-NURL onnx runtime the server runs on the GPU, compiled for the browser and executed on the gpu package's STATIC backend (precompiled kernels_static.wasm.o linked in — no NVRTC, no dlopen, no compiler).
This is a WASI command module driven by host imports (env.*): the embedder (a web worker — see web/worker.js — or the node test harness) supplies blobs and frames, the module loops forever inside start. Blocking hostframe is legal because the module runs in a worker thread (Atomics.wait), never on the UI thread.
host_blob_size(kind) → bytes 0 = model.onnx, 1 = seed tpe f32 host_blob_read(kind, dst) → 0/-1 embedder memcpys the blob in host_frame(rgb, ctl) → cmd 0 = frame ready, 2 = add prompt, anything else = exit host_result(dets, nd, ms) nd detections ready; the masked frame is in-place in rgb host_status(code, extra) 1 model-parsed, 2 engine-ready, -1 fatal (extra = detail)
ctl is an i32/f32 slab (4-byte slots): [0] conf ‰ (i32, e.g. 250 = 0.25) [1] masks 0/1 (i32) [2] enabled-class bitmask (i32, bit k = class k) [4] add-prompt slot index (i32) [16..527] add-prompt embedding (f32) dets out: 6 f32 per detection [cls, score, x, y, w, h], max 64.
Frame geometry is fixed 640×480 RGB (the embedder letterboxes the camera into that, exactly like the host-mode page does).
& c @ host_blob_size i kind → i& c @ host_blob_read i kind *u dst → i& c @ host_frame *u rgb *u ctl → i& c @ host_result *u dets i nd i ms → v& c @ host_status i code i extra → v& c @ host_use_webgpu → i1 → run the WebGPU backend, else the static CPU kernels
: i WD_W 640: i WD_H 480: i WD_K 32: i WD_MAXDET 64@ wd_shape4 i a i b i c i d → ( Vec i )@ wd_pal i ch i k → i8-colour instance palette (matches the page's JS palette by index)