Add marketplace section, OAuth checkout, social icons, 35% efficiency claim, preorder CTAs, enterprise Q1 2027, founding member limits, paragraph spacing in demo chat, no em dashes

This commit is contained in:
Will Anderson
2026-05-01 09:20:45 -05:00
parent 269eed41aa
commit ff1f9577db
38 changed files with 12432 additions and 39 deletions
+50 -2
View File
@@ -13,16 +13,47 @@
# Run:
# docker run -p 8080:8080 neuron-landing
# ── Stage 1: compile ──────────────────────────────────────────────────────────
# ── Stage 1a: build liboqs from source ────────────────────────────────────────
# Debian bookworm doesn't ship liboqs, so we build it ourselves. liboqs is
# small (~5MB compiled, static) and pinned to a release tag for reproducibility.
# Built static, so the runtime image doesn't need a separate liboqs.so.
FROM debian:bookworm-slim AS oqs-builder
ARG LIBOQS_VERSION=0.10.1
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential cmake ninja-build git \
libssl-dev ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 --branch ${LIBOQS_VERSION} \
https://github.com/open-quantum-safe/liboqs.git /src/liboqs \
&& cmake -S /src/liboqs -B /src/liboqs/build -GNinja \
-DCMAKE_INSTALL_PREFIX=/opt/oqs \
-DOQS_BUILD_ONLY_LIB=ON \
-DOQS_DIST_BUILD=ON \
-DBUILD_SHARED_LIBS=OFF \
-DOQS_USE_OPENSSL=ON \
&& cmake --build /src/liboqs/build --parallel \
&& cmake --install /src/liboqs/build
# ── Stage 1b: compile El binary ───────────────────────────────────────────────
FROM debian:bookworm-slim AS builder
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
libcurl4-openssl-dev \
libssl-dev \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Pull in liboqs headers + static archive from the previous stage. The
# archive is ~5MB; we link it statically so the runtime image stays slim
# and we don't need a second apt install in stage 2.
COPY --from=oqs-builder /opt/oqs /opt/oqs
WORKDIR /build
COPY runtime/el_runtime.c runtime/el_runtime.h ./
COPY server.c ./
@@ -31,7 +62,20 @@ COPY server.c ./
# functions (e.g. handle_request) via dlsym(RTLD_DEFAULT, name), and on
# glibc that only sees the executable's own symbols if they were exported
# by the linker. macOS exports them by default, Linux doesn't.
RUN cc -std=c11 -O2 -rdynamic -I . -o landing server.c el_runtime.c -lcurl -lpthread -ldl -lm
#
# liboqs is an optional runtime dependency; el_runtime.c gates all pq_*
# entry points behind __has_include(<oqs/oqs.h>). With the headers + .a
# from the oqs-builder stage in /opt/oqs, the post-quantum primitives
# (Dilithium-3 / ML-DSA-65 signatures, Kyber-768 / ML-KEM-768 KEM, the
# hybrid X25519+Kyber handshake, and SHA3-256) are all available.
# -lcrypto pulls in OpenSSL for X25519 + the symmetric primitives liboqs
# itself uses internally; libcurl4-openssl-dev already pulls libssl-dev
# transitively but we're explicit.
RUN cc -std=c11 -O2 -rdynamic \
-I . -I/opt/oqs/include \
-L/opt/oqs/lib \
-o landing server.c el_runtime.c \
-lcurl -lpthread -ldl -lm -loqs -lcrypto
# `strip` would discard .symtab but keeps .dynsym (which is what -rdynamic
# populated and what dlsym actually looks at), so it'd be safe — but the
# binary is small enough that the few MB saved isn't worth the next person
@@ -40,9 +84,13 @@ RUN cc -std=c11 -O2 -rdynamic -I . -o landing server.c el_runtime.c -lcurl -lpth
# ── Stage 2: runtime ──────────────────────────────────────────────────────────
FROM debian:bookworm-slim
# libssl3 supplies libcrypto.so.3 for the X25519 + symmetric primitives the
# linked binary needs. liboqs itself is statically linked into the binary
# (built that way in stage 1a) so there's nothing extra to ship for it.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libcurl4 \
libssl3 \
ca-certificates \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd -r landing && useradd -r -g landing landing
+1 -1
View File
@@ -25,7 +25,7 @@ set -euo pipefail
cd "$(dirname "$0")"
LANDING_DIR=$(pwd)
EL_HOME="${EL_HOME:-${LANDING_DIR}/../../../foundation/el}"
EL_HOME="${EL_HOME:-${LANDING_DIR}/../../foundation/el}"
ELC="${EL_HOME}/dist/platform/elc"
RUNTIME_SRC="${EL_HOME}/el-compiler/runtime"
View File
Executable
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
View File
+152
View File
@@ -0,0 +1,152 @@
#include <stdint.h>
#include <stdlib.h>
#include "el_runtime.h"
el_val_t strip_query(el_val_t path);
el_val_t root_dir(void);
el_val_t parse_port(void);
el_val_t content_type_for(el_val_t path);
el_val_t route_health(void);
el_val_t route_founding_count(void);
el_val_t route_index(void);
el_val_t route_static(el_val_t path);
el_val_t route_brand(el_val_t path);
el_val_t err_404(el_val_t path);
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);
el_val_t strip_query(el_val_t path) {
el_val_t q = str_index_of(path, EL_STR("?"));
if (q < 0) {
return path;
}
return str_slice(path, 0, q);
return 0;
}
el_val_t root_dir(void) {
el_val_t r = env(EL_STR("LANDING_ROOT"));
if (str_eq(r, EL_STR(""))) {
r = EL_STR("./src");
}
return r;
return 0;
}
el_val_t parse_port(void) {
el_val_t p = env(EL_STR("PORT"));
if (str_eq(p, EL_STR(""))) {
p = EL_STR("8080");
}
return str_to_int(p);
return 0;
}
el_val_t content_type_for(el_val_t path) {
if (str_ends_with(path, EL_STR(".html"))) {
return EL_STR("text/html; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".css"))) {
return EL_STR("text/css; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".js"))) {
return EL_STR("application/javascript; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".json"))) {
return EL_STR("application/json; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".png"))) {
return EL_STR("image/png");
}
if (str_ends_with(path, EL_STR(".jpg"))) {
return EL_STR("image/jpeg");
}
if (str_ends_with(path, EL_STR(".jpeg"))) {
return EL_STR("image/jpeg");
}
if (str_ends_with(path, EL_STR(".svg"))) {
return EL_STR("image/svg+xml");
}
if (str_ends_with(path, EL_STR(".ico"))) {
return EL_STR("image/x-icon");
}
if (str_ends_with(path, EL_STR(".webp"))) {
return EL_STR("image/webp");
}
if (str_ends_with(path, EL_STR(".woff2"))) {
return EL_STR("font/woff2");
}
if (str_ends_with(path, EL_STR(".woff"))) {
return EL_STR("font/woff");
}
return EL_STR("application/octet-stream");
return 0;
}
el_val_t route_health(void) {
return EL_STR("{\"status\":\"ok\",\"engine\":\"el-landing\"}");
return 0;
}
el_val_t route_founding_count(void) {
el_val_t sold = 47;
el_val_t total = 1000;
el_val_t remaining = (total - sold);
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"sold\":"), int_to_str(sold)), EL_STR(",\"total\":")), int_to_str(total)), EL_STR(",\"remaining\":")), int_to_str(remaining)), EL_STR("}"));
return 0;
}
el_val_t route_index(void) {
return fs_read(el_str_concat(root_dir(), EL_STR("/index.html")));
return 0;
}
el_val_t route_static(el_val_t path) {
return fs_read(el_str_concat(root_dir(), path));
return 0;
}
el_val_t route_brand(el_val_t path) {
el_val_t after = str_slice(path, 6, str_len(path));
return fs_read(el_str_concat(el_str_concat(root_dir(), EL_STR("/assets/brand")), after));
return 0;
}
el_val_t err_404(el_val_t path) {
return el_str_concat(el_str_concat(EL_STR("{\"error\":\"not found\",\"path\":\""), path), EL_STR("\"}"));
return 0;
}
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
el_val_t clean = strip_query(path);
if (!str_eq(method, EL_STR("GET"))) {
return EL_STR("{\"error\":\"method not allowed\"}");
}
if (str_eq(clean, EL_STR("/"))) {
return route_index();
}
if (str_eq(clean, EL_STR("/health"))) {
return route_health();
}
if (str_eq(clean, EL_STR("/api/founding-count"))) {
return route_founding_count();
}
if (str_starts_with(clean, EL_STR("/assets/"))) {
return route_static(clean);
}
if (str_starts_with(clean, EL_STR("/brand/"))) {
return route_brand(clean);
}
return err_404(clean);
return 0;
}
int main(int argc, char** argv) {
el_runtime_init_args(argc, argv);
el_val_t port = parse_port();
println(el_str_concat(EL_STR("[landing] root="), root_dir()));
println(el_str_concat(EL_STR("[landing] listening on "), int_to_str(port)));
http_set_handler(EL_STR("handle_request"));
http_serve(port, EL_STR("handle_request"));
return 0;
}
+6166
View File
File diff suppressed because it is too large Load Diff
+507
View File
@@ -0,0 +1,507 @@
/*
* el_runtime.h — El language C runtime header
*
* Declares all built-in functions available to compiled El programs.
* Include this in every generated .c file.
*
* Value model:
* All El values are represented as el_val_t (= int64_t).
* On 64-bit systems a pointer fits in int64_t.
* String values are cast: (el_val_t)(uintptr_t)"hello"
* Integer values are stored directly.
* This lets arithmetic work naturally while still passing strings around.
*
* Type conventions (El -> C):
* String -> el_val_t (holds const char* via uintptr_t cast)
* Int -> el_val_t
* Bool -> el_val_t (0 = false, nonzero = true)
* Any -> el_val_t
* Void -> void
*
* Macros for convenience:
* EL_STR(s) cast string literal to el_val_t
* EL_CSTR(v) cast el_val_t back to const char*
* EL_INT(v) identity — el_val_t is already int64_t
*
* Link requirements:
* -lcurl — required for the HTTP client (http_get, http_post, llm_*).
* -lpthread — required for the HTTP server (one detached thread per
* connection, capped at 64 concurrent).
* -loqs — optional; required only when liboqs is installed and the
* pq_* / sha3_256_hex entry points are needed. Detected at
* compile time via __has_include(<oqs/oqs.h>).
* -lcrypto — optional; pulled in alongside -loqs. Used for X25519 in
* pq_hybrid_* and HKDF-SHA256 derivation.
*
* Canonical compile command:
* cc -std=c11 -I el-compiler/runtime -lcurl -lpthread \
* -o <out> <prog>.c el-compiler/runtime/el_runtime.c
*
* With liboqs (post-quantum stack):
* cc -std=c11 -I el-compiler/runtime -lcurl -lpthread -loqs -lcrypto \
* -o <out> <prog>.c el-compiler/runtime/el_runtime.c
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
typedef int64_t el_val_t;
#define EL_STR(s) ((el_val_t)(uintptr_t)(s))
#define EL_CSTR(v) ((const char*)(uintptr_t)(v))
#define EL_INT(v) (v)
#define EL_NULL ((el_val_t)0)
/* Float values share the el_val_t (int64) slot via a bit-cast.
* The codegen emits Float literals as `el_from_float(<dbl>)` so the
* underlying bits represent the IEEE 754 double. Float-aware builtins
* (math, format, json) round-trip via these helpers. */
static inline double el_to_float(el_val_t v) {
union { int64_t i; double f; } u;
u.i = (int64_t)v;
return u.f;
}
static inline el_val_t el_from_float(double f) {
union { double f; int64_t i; } u;
u.f = f;
return (el_val_t)u.i;
}
#ifdef __cplusplus
extern "C" {
#endif
/* ── I/O ──────────────────────────────────────────────────────────────────── */
void println(el_val_t s);
void print(el_val_t s);
el_val_t readline(void);
/* ── String builtins ─────────────────────────────────────────────────────── */
el_val_t el_str_concat(el_val_t a, el_val_t b);
el_val_t str_eq(el_val_t a, el_val_t b);
el_val_t str_starts_with(el_val_t s, el_val_t prefix);
el_val_t str_ends_with(el_val_t s, el_val_t suffix);
el_val_t str_len(el_val_t s);
el_val_t str_concat(el_val_t a, el_val_t b);
el_val_t int_to_str(el_val_t n);
el_val_t str_to_int(el_val_t s);
el_val_t str_slice(el_val_t s, el_val_t start, el_val_t end);
el_val_t str_contains(el_val_t s, el_val_t sub);
el_val_t str_replace(el_val_t s, el_val_t from, el_val_t to);
el_val_t str_to_upper(el_val_t s);
el_val_t str_to_lower(el_val_t s);
el_val_t str_trim(el_val_t s);
/* ── Math ────────────────────────────────────────────────────────────────── */
el_val_t el_abs(el_val_t n);
el_val_t el_max(el_val_t a, el_val_t b);
el_val_t el_min(el_val_t a, el_val_t b);
/* ── Refcount (ARC) ──────────────────────────────────────────────────────────
* Lists and Maps carry a refcount. Strings and ints do not — el_retain and
* el_release are safe no-ops on non-refcounted values (they sniff a magic
* header at offset 0 and only act if the magic matches).
*
* Codegen emits these at let-binding shadowing, function entry (params), and
* function exit (locals other than the returned value). The refcount lets
* el_list_append and el_map_set mutate in place when uniquely owned (cheap)
* and copy-on-write when shared (preserves persistent semantics across
* accumulator patterns in the compiler itself). */
void el_retain(el_val_t v);
void el_release(el_val_t v);
/* ── List ────────────────────────────────────────────────────────────────── */
el_val_t el_list_new(el_val_t count, ...);
el_val_t el_list_len(el_val_t list);
el_val_t el_list_get(el_val_t list, el_val_t index);
el_val_t el_list_append(el_val_t list, el_val_t elem);
el_val_t el_list_empty(void);
el_val_t el_list_clone(el_val_t list);
/* ── Map ─────────────────────────────────────────────────────────────────── */
el_val_t el_map_new(el_val_t pair_count, ...);
el_val_t el_get_field(el_val_t map, el_val_t key);
el_val_t el_map_get(el_val_t map, el_val_t key);
el_val_t el_map_set(el_val_t map, el_val_t key, el_val_t value);
/* ── HTTP ─────────────────────────────────────────────────────────────────── */
el_val_t http_get(el_val_t url);
el_val_t http_post(el_val_t url, el_val_t body);
el_val_t http_post_json(el_val_t url, el_val_t json_body);
el_val_t http_get_with_headers(el_val_t url, el_val_t headers_map);
el_val_t http_post_with_headers(el_val_t url, el_val_t body, el_val_t headers_map);
el_val_t http_post_form_auth(el_val_t url, el_val_t form_body, el_val_t auth_header);
el_val_t http_delete(el_val_t url);
void http_serve(el_val_t port, el_val_t handler);
void http_set_handler(el_val_t name);
/* HTTP server v2 ─────────────────────────────────────────────────────────────
* Same dispatch model as http_serve, but the handler signature is widened:
*
* el_val_t handler(method, path, headers_map, body)
*
* `headers_map` is an ElMap from lowercased header name → header value (both
* Strings). Repeated headers are joined with ", " per RFC 7230.
*
* Response value: the handler may return either
* (a) a plain body string — same auto-content-type / 200-OK behaviour as
* http_serve (3-arg) — or
* (b) a response envelope built with `http_response(status, headers_json,
* body)`. The runtime detects the envelope discriminator
* `"el_http_response":1` at the start of the returned string and
* unpacks status / headers / body before sending.
*
* The 3-arg http_serve(port, handler) remains supported unchanged for
* existing handlers (e.g. products/web/server.el): it dispatches with
* (method, path, body), hardcodes 200 OK, and auto-detects content type. */
void http_serve_v2(el_val_t port, el_val_t handler);
void http_set_handler_v2(el_val_t name);
/* Build an HTTP response envelope. `headers_json` should be a JSON object
* literal like `{"WWW-Authenticate":"Basic"}` (or "" / "{}" for none). The
* returned string carries the discriminator `{"el_http_response":1,...}`
* which the runtime's send-path detects and unpacks. Detection happens
* uniformly inside http_send_response, so a 3-arg handler may also return
* an envelope. The 3-arg variant remains documented as a fixed 200-OK
* auto-content-type contract for legacy handlers that return plain bodies. */
el_val_t http_response(el_val_t status, el_val_t headers_json, el_val_t body);
/* HTTP timeout — every libcurl request honors EL_HTTP_TIMEOUT_MS (default
* 60000ms). Read lazily on first use, so setting the env var any time before
* the first http_* call is sufficient. */
/* Streaming variants — write the response body straight to a file via
* libcurl's CURLOPT_WRITEFUNCTION = fwrite. These bypass the el_val_t string
* wrapper entirely, so binary payloads (audio/mpeg, image/png, etc.) survive
* embedded NUL bytes that would truncate a strlen()-based code path.
*
* Both honor EL_HTTP_TIMEOUT_MS, follow redirects, and accept the same
* `headers_map` shape as http_post_with_headers (ElMap of String→String).
*
* Return value: 1 on success (file fully written), 0 on any failure
* (network, file open, partial write). On failure the output file is removed
* so callers cannot mistake a partially-written file for a valid one. */
el_val_t http_post_to_file(el_val_t url, el_val_t body, el_val_t headers_map, el_val_t output_path);
el_val_t http_get_to_file(el_val_t url, el_val_t headers_map, el_val_t output_path);
/* ── URL encoding ────────────────────────────────────────────────────────── */
el_val_t url_encode(el_val_t s); /* RFC 3986 unreserved set */
el_val_t url_decode(el_val_t s); /* '+' → space, %XX → byte */
/* ── Filesystem ──────────────────────────────────────────────────────────── */
el_val_t fs_read(el_val_t path);
el_val_t fs_write(el_val_t path, el_val_t content);
el_val_t fs_list(el_val_t path);
el_val_t fs_exists(el_val_t path);
el_val_t fs_mkdir(el_val_t path); /* mkdir -p, mode 0755 */
/* Length-explicit binary write. `length` is an Int (el_val_t holding the
* byte count). The caller knows the length from context — typically because
* `bytes` came from base64_decode (which produces a magic-tagged binary
* buffer with embedded NULs possible) and the caller already tracks the
* decoded length, OR because the bytes came from a fixed-size source
* (sha256_bytes = 32, hmac_sha256_bytes = 32). Bypasses strlen entirely.
*
* Returns 1 on success, 0 on failure (invalid path, can't open, partial
* write, negative length). On partial-write failure, the file is removed
* so callers cannot read back a truncated artefact. */
el_val_t fs_write_bytes(el_val_t path, el_val_t bytes, el_val_t length);
/* ── JSON ────────────────────────────────────────────────────────────────── */
el_val_t json_get(el_val_t json, el_val_t key);
el_val_t json_parse(el_val_t s);
el_val_t json_stringify(el_val_t v);
el_val_t json_get_string(el_val_t json_str, el_val_t key);
el_val_t json_get_int(el_val_t json_str, el_val_t key);
el_val_t json_get_float(el_val_t json_str, el_val_t key);
el_val_t json_get_bool(el_val_t json_str, el_val_t key);
el_val_t json_get_raw(el_val_t json_str, el_val_t key);
el_val_t json_set(el_val_t json_str, el_val_t key, el_val_t value);
el_val_t json_array_len(el_val_t json_str);
el_val_t json_array_get(el_val_t json_str, el_val_t index);
el_val_t json_array_get_string(el_val_t json_str, el_val_t index);
/* ── Time ────────────────────────────────────────────────────────────────── */
el_val_t time_now(void);
el_val_t time_now_utc(void);
el_val_t sleep_secs(el_val_t secs);
el_val_t sleep_ms(el_val_t ms);
el_val_t time_format(el_val_t ts, el_val_t fmt);
el_val_t time_to_parts(el_val_t ts);
el_val_t time_from_parts(el_val_t secs, el_val_t ns, el_val_t tz);
el_val_t time_add(el_val_t ts, el_val_t n, el_val_t unit);
el_val_t time_diff(el_val_t ts1, el_val_t ts2, el_val_t unit);
/* ── UUID ────────────────────────────────────────────────────────────────── */
el_val_t uuid_new(void);
el_val_t uuid_v4(void);
/* ── Environment ─────────────────────────────────────────────────────────── */
el_val_t env(el_val_t key);
/* ── In-process state K/V ────────────────────────────────────────────────── */
el_val_t state_set(el_val_t key, el_val_t value);
el_val_t state_get(el_val_t key);
el_val_t state_del(el_val_t key);
el_val_t state_keys(void);
/* ── Float formatting ────────────────────────────────────────────────────── */
el_val_t float_to_str(el_val_t f);
el_val_t int_to_float(el_val_t n);
el_val_t float_to_int(el_val_t f);
el_val_t format_float(el_val_t f, el_val_t decimals);
el_val_t decimal_round(el_val_t f, el_val_t decimals);
el_val_t str_to_float(el_val_t s);
/* ── Math (Float-aware) ──────────────────────────────────────────────────── */
el_val_t math_sqrt(el_val_t f);
el_val_t math_log(el_val_t f);
el_val_t math_ln(el_val_t f);
el_val_t math_sin(el_val_t f);
el_val_t math_cos(el_val_t f);
el_val_t math_pi(void);
/* ── String additions ────────────────────────────────────────────────────── */
el_val_t str_index_of(el_val_t s, el_val_t sub);
el_val_t str_split(el_val_t s, el_val_t sep);
el_val_t str_char_at(el_val_t s, el_val_t i);
el_val_t str_char_code(el_val_t s, el_val_t i);
el_val_t str_pad_left(el_val_t s, el_val_t width, el_val_t pad);
el_val_t str_pad_right(el_val_t s, el_val_t width, el_val_t pad);
el_val_t str_format(el_val_t template, el_val_t data);
el_val_t str_lower(el_val_t s);
el_val_t str_upper(el_val_t s);
/* ── List additions ──────────────────────────────────────────────────────── */
el_val_t list_push(el_val_t list, el_val_t elem);
el_val_t list_push_front(el_val_t list, el_val_t elem);
el_val_t list_join(el_val_t list, el_val_t sep);
el_val_t list_range(el_val_t start, el_val_t end);
/* ── Bool helpers ────────────────────────────────────────────────────────── */
el_val_t bool_to_str(el_val_t b);
/* ── Numeric parsing ─────────────────────────────────────────────────────── */
el_val_t parse_int(el_val_t s, el_val_t default_val);
/* ── Process ─────────────────────────────────────────────────────────────── */
void exit_program(el_val_t code);
el_val_t getpid_now(void);
/* ── CGI identity ─────────────────────────────────────────────────────────────
* Called at the start of main() in CGI programs (those with a `cgi {}` block).
* Records the program's DHARMA identity before any other code executes. */
void el_cgi_init(el_val_t name, el_val_t dharma_id, el_val_t principal,
el_val_t network, el_val_t engram);
/* ── DHARMA network builtins ─────────────────────────────────────────────────
* Available to CGI programs (declared with a `cgi {}` block).
*
* Peers are addressed by `dharma_id` of the form
* "<registry-id>@<transport-url>" e.g. "ntn-genesis@http://localhost:7770"
* If the @<url> portion is omitted, transport defaults to
* "http://localhost:7770" (the local CGI daemon assumption).
*
* Wire protocol (all peers expose):
* POST <url>/dharma/recv { channel, from, content } → response body
* POST <url>/dharma/event { type, payload, source, timestamp }
* POST <url>/api/activate { query } → list of nodes
*
* Hosting application's responsibility: an El program with a `cgi {}` block
* runs http_serve() with its own request handler; that handler should route
* "/dharma/event" requests by calling el_runtime_dharma_event_arrive() so
* incoming events feed dharma_field() queues. The runtime itself does not
* intercept any /dharma path. */
el_val_t dharma_connect(el_val_t cgi_id);
el_val_t dharma_send(el_val_t channel, el_val_t content);
el_val_t dharma_activate(el_val_t query);
void dharma_emit(el_val_t event_type, el_val_t payload);
el_val_t dharma_field(el_val_t event_type);
void dharma_strengthen(el_val_t cgi_id, el_val_t weight);
el_val_t dharma_relationship(el_val_t cgi_id);
el_val_t dharma_peers(void);
/* Public C API: called by an El program's HTTP handler when a /dharma/event
* request arrives. Pushes onto the per-event-type queue and signals any
* pending dharma_field() blockers. All three arguments must be NUL-terminated
* C strings (or NULL — then treated as empty). */
void el_runtime_dharma_event_arrive(const char* event_type,
const char* payload,
const char* source);
/* ── Engram local graph primitives ───────────────────────────────────────────
* Operate on the CGI's local Engram knowledge graph.
* `engram_activate` queries the local graph only; `dharma_activate` is
* network-wide across all connected CGI graphs. */
el_val_t engram_node(el_val_t content, el_val_t node_type, el_val_t salience);
el_val_t engram_node_full(el_val_t content, el_val_t node_type, el_val_t label,
el_val_t salience, el_val_t importance, el_val_t confidence,
el_val_t tier, el_val_t tags);
el_val_t engram_get_node(el_val_t id);
void engram_strengthen(el_val_t node_id);
void engram_forget(el_val_t node_id);
el_val_t engram_node_count(void);
el_val_t engram_search(el_val_t query, el_val_t limit);
el_val_t engram_scan_nodes(el_val_t limit, el_val_t offset);
void engram_connect(el_val_t from_id, el_val_t to_id, el_val_t weight, el_val_t relation);
el_val_t engram_edge_between(el_val_t from_id, el_val_t to_id);
el_val_t engram_neighbors(el_val_t node_id);
el_val_t engram_neighbors_filtered(el_val_t node_id, el_val_t max_depth, el_val_t direction);
el_val_t engram_edge_count(void);
el_val_t engram_activate(el_val_t query, el_val_t depth);
el_val_t engram_save(el_val_t path);
el_val_t engram_load(el_val_t path);
/* JSON-string accessors — return pre-serialized JSON so HTTP handlers
* can pass results straight through without round-tripping ElList/ElMap
* through json_stringify. */
el_val_t engram_get_node_json(el_val_t id);
el_val_t engram_search_json(el_val_t query, el_val_t limit);
el_val_t engram_scan_nodes_json(el_val_t limit, el_val_t offset);
el_val_t engram_neighbors_json(el_val_t node_id, el_val_t max_depth, el_val_t direction);
el_val_t engram_activate_json(el_val_t query, el_val_t depth);
el_val_t engram_stats_json(void);
/* ── LLM (Anthropic API client) ─────────────────────────────────────────────
* All functions call https://api.anthropic.com/v1/messages with the API key
* from env ANTHROPIC_API_KEY. Default model when empty: claude-sonnet-4-5. */
el_val_t llm_call(el_val_t model, el_val_t prompt);
el_val_t llm_call_system(el_val_t model, el_val_t system_prompt, el_val_t user_prompt);
el_val_t llm_call_agentic(el_val_t model, el_val_t system, el_val_t user, el_val_t tools);
el_val_t llm_vision(el_val_t model, el_val_t system, el_val_t prompt, el_val_t image_url_or_b64);
el_val_t llm_models(void);
/* Register a tool handler by name. The handler is looked up via dlsym
* (mirroring http_set_handler), so any El `fn <name>(input)` compiles to
* a global C symbol that this function can locate at runtime.
* Handler signature: `el_val_t handler(el_val_t input_json)` — receives
* the tool input as a JSON-string el_val_t and returns a JSON-string
* el_val_t result. Used by llm_call_agentic. */
void llm_register_tool(el_val_t name, el_val_t handler_fn_name);
/* ── args() ─────────────────────────────────────────────────────────────────
* Provides access to command-line arguments passed to the program.
* Populated by el_runtime_init_args() before main() runs. */
el_val_t args(void);
void el_runtime_init_args(int argc, char** argv);
/* ── Crypto primitives ─────────────────────────────────────────────────────
* SHA-256, HMAC-SHA-256, and base64 (standard + URL-safe).
* Self-contained — no OpenSSL/libcrypto dependency. The implementations are
* adapted from public-domain reference code (Brad Conte / RFC 4648).
*
* Bytes-returning variants (sha256_bytes, hmac_sha256_bytes) return a string
* value whose contents are raw binary; callers usually feed these into
* base64_encode. Note that el_val_t strings are NUL-terminated by convention,
* so the binary payload may contain embedded NULs — pass it directly into
* base64_encode (which uses an explicit length) rather than treating it as
* a printable C string.
*
* The "base64" variants emit/accept RFC 4648 standard alphabet with padding.
* The "base64url" variants use URL-safe alphabet (`-`/`_`) with no padding,
* as used in JWTs. */
el_val_t sha256_hex(el_val_t input);
el_val_t sha256_bytes(el_val_t input);
el_val_t hmac_sha256_hex(el_val_t key, el_val_t message);
el_val_t hmac_sha256_bytes(el_val_t key, el_val_t message);
el_val_t base64_encode(el_val_t input);
el_val_t base64_decode(el_val_t input);
el_val_t base64url_encode(el_val_t input);
el_val_t base64url_decode(el_val_t input);
/* Length-aware variants (internal — exposed for the rare caller that already
* has a known-length binary buffer and doesn't want to round-trip through
* a NUL-terminated el_val_t string). Sha256_bytes and hmac_sha256_bytes feed
* these implicitly. */
el_val_t el_sha256_bytes_n(const unsigned char* data, size_t len);
el_val_t el_base64_encode_n(const unsigned char* data, size_t len, int url_safe);
/* ── Post-quantum primitives (liboqs-backed) ────────────────────────────────
* All inputs/outputs hex-encoded. Algorithm choices:
* Signature: CRYSTALS-Dilithium-3 (NIST level 3, balanced)
* KEM: CRYSTALS-Kyber-768 (NIST level 3)
* Hash: SHA3-256 (Keccak) (PQ-aware protocols favour SHA3 over SHA2)
*
* If liboqs is not linked (detected via __has_include(<oqs/oqs.h>) at compile
* time), the pq_* entry points return a JSON-shaped error string so callers
* fail loudly rather than silently fall back to classical schemes:
* {"error":"liboqs not linked, post-quantum primitives unavailable"}
*
* The hybrid handshake pairs X25519 with Kyber-768 per NIST PQ guidance and
* CNSA 2.0. Combined shared secret is HKDF-SHA256(x25519_ss || kyber_ss).
* Even if Kyber falls, X25519 holds; if X25519 falls under quantum attack,
* Kyber holds. SHA3-256 also remains usable independent of liboqs (the
* Keccak permutation is PQ-OK as a primitive). */
el_val_t pq_keygen_signature(void);
el_val_t pq_sign(el_val_t secret_key_hex, el_val_t message);
el_val_t pq_verify(el_val_t public_key_hex, el_val_t message, el_val_t signature_hex);
el_val_t pq_kem_keygen(void);
el_val_t pq_kem_encaps(el_val_t public_key_hex);
el_val_t pq_kem_decaps(el_val_t secret_key_hex, el_val_t ciphertext_hex);
el_val_t pq_hybrid_keygen(void);
el_val_t pq_hybrid_handshake(el_val_t remote_pub_combined);
el_val_t sha3_256_hex(el_val_t input);
/* ── Native VM builtin aliases (for compiled El source) ─────────────────────
* These match the El VM's native_* builtins so that El source compiled
* to C can call the same names without modification. */
el_val_t native_list_get(el_val_t list, el_val_t index);
el_val_t native_list_len(el_val_t list);
el_val_t native_list_append(el_val_t list, el_val_t elem);
el_val_t native_list_empty(void);
el_val_t native_list_clone(el_val_t list);
el_val_t native_string_chars(el_val_t s);
el_val_t native_int_to_str(el_val_t n);
/* ── Method-call shorthand aliases ──────────────────────────────────────────
* The El method-call convention `obj.method(args)` compiles to
* `method(obj, args)`. These aliases expose the runtime functions under
* the short names that result from method calls in El source.
*
* Example: `myList.append(x)` → `append(myList, x)` (calls this alias)
* `myList.len()` → `len(myList)` (calls this alias) */
el_val_t append(el_val_t list, el_val_t elem); /* el_list_append */
el_val_t len(el_val_t list); /* el_list_len */
el_val_t get(el_val_t list, el_val_t index); /* el_list_get */
el_val_t map_get(el_val_t map, el_val_t key); /* el_map_get */
el_val_t map_set(el_val_t map, el_val_t key, el_val_t value); /* el_map_set */
#ifdef __cplusplus
}
#endif
+163
View File
@@ -0,0 +1,163 @@
#include <stdint.h>
#include <stdlib.h>
#include "el_runtime.h"
el_val_t strip_query(el_val_t path);
el_val_t root_dir(void);
el_val_t parse_port(void);
el_val_t content_type_for(el_val_t path);
el_val_t route_health(void);
el_val_t route_founding_count(void);
el_val_t route_index(void);
el_val_t route_static(el_val_t path);
el_val_t route_brand(el_val_t path);
el_val_t err_404(el_val_t path);
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);
el_val_t port;
el_val_t strip_query(el_val_t path) {
el_val_t q = str_index_of(path, EL_STR("?"));
if (q < 0) {
return path;
}
return str_slice(path, 0, q);
return 0;
}
el_val_t root_dir(void) {
el_val_t r = env(EL_STR("LANDING_ROOT"));
if (str_eq(r, EL_STR(""))) {
r = EL_STR("./src");
}
return r;
return 0;
}
el_val_t parse_port(void) {
el_val_t p = env(EL_STR("PORT"));
if (str_eq(p, EL_STR(""))) {
p = EL_STR("8080");
}
return str_to_int(p);
return 0;
}
el_val_t content_type_for(el_val_t path) {
if (str_ends_with(path, EL_STR(".html"))) {
return EL_STR("text/html; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".css"))) {
return EL_STR("text/css; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".js"))) {
return EL_STR("application/javascript; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".json"))) {
return EL_STR("application/json; charset=utf-8");
}
if (str_ends_with(path, EL_STR(".png"))) {
return EL_STR("image/png");
}
if (str_ends_with(path, EL_STR(".jpg"))) {
return EL_STR("image/jpeg");
}
if (str_ends_with(path, EL_STR(".jpeg"))) {
return EL_STR("image/jpeg");
}
if (str_ends_with(path, EL_STR(".svg"))) {
return EL_STR("image/svg+xml");
}
if (str_ends_with(path, EL_STR(".ico"))) {
return EL_STR("image/x-icon");
}
if (str_ends_with(path, EL_STR(".webp"))) {
return EL_STR("image/webp");
}
if (str_ends_with(path, EL_STR(".woff2"))) {
return EL_STR("font/woff2");
}
if (str_ends_with(path, EL_STR(".woff"))) {
return EL_STR("font/woff");
}
return EL_STR("application/octet-stream");
return 0;
}
el_val_t route_health(void) {
return EL_STR("{\"status\":\"ok\",\"engine\":\"el-landing\"}");
return 0;
}
el_val_t route_founding_count(void) {
el_val_t sold = 47;
el_val_t total = 1000;
el_val_t remaining = (total - sold);
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"sold\":"), int_to_str(sold)), EL_STR(",\"total\":")), int_to_str(total)), EL_STR(",\"remaining\":")), int_to_str(remaining)), EL_STR("}"));
return 0;
}
el_val_t route_index(void) {
return fs_read(el_str_concat(root_dir(), EL_STR("/index.html")));
return 0;
}
el_val_t route_static(el_val_t path) {
return fs_read(el_str_concat(root_dir(), path));
return 0;
}
el_val_t route_brand(el_val_t path) {
el_val_t after = str_slice(path, 6, str_len(path));
return fs_read(el_str_concat(el_str_concat(root_dir(), EL_STR("/assets/brand")), after));
return 0;
}
el_val_t err_404(el_val_t path) {
return el_str_concat(el_str_concat(EL_STR("{\"error\":\"not found\",\"path\":\""), path), EL_STR("\"}"));
return 0;
}
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
el_val_t clean = strip_query(path);
if (!str_eq(method, EL_STR("GET"))) {
return EL_STR("{\"error\":\"method not allowed\"}");
}
if (str_eq(clean, EL_STR("/"))) {
return route_index();
}
if (str_eq(clean, EL_STR("/health"))) {
return route_health();
}
if (str_eq(clean, EL_STR("/api/founding-count"))) {
return route_founding_count();
}
if (str_starts_with(clean, EL_STR("/assets/"))) {
return route_static(clean);
}
if (str_starts_with(clean, EL_STR("/brand/"))) {
return route_brand(clean);
}
if (str_eq(clean, EL_STR("/legal/enterprise-terms"))) {
return fs_read(el_str_concat(root_dir(), EL_STR("/enterprise-terms.html")));
}
if (str_eq(clean, EL_STR("/legal/terms"))) {
return fs_read(el_str_concat(root_dir(), EL_STR("/terms.html")));
}
if (str_eq(clean, EL_STR("/about"))) {
return fs_read(el_str_concat(root_dir(), EL_STR("/about.html")));
}
return err_404(clean);
return 0;
}
int main(int argc, char** argv) {
el_runtime_init_args(argc, argv);
port = parse_port();
println(el_str_concat(EL_STR("[landing] root="), root_dir()));
println(el_str_concat(EL_STR("[landing] listening on "), int_to_str(port)));
http_set_handler(EL_STR("handle_request"));
http_serve(port, EL_STR("handle_request"));
return 0;
}
+9
View File
@@ -112,6 +112,15 @@ fn handle_request(method: String, path: String, body: String) -> String {
if str_starts_with(clean, "/brand/") {
return route_brand(clean)
}
if str_eq(clean, "/legal/enterprise-terms") {
return fs_read(root_dir() + "/enterprise-terms.html")
}
if str_eq(clean, "/legal/terms") {
return fs_read(root_dir() + "/terms.html")
}
if str_eq(clean, "/about") {
return fs_read(root_dir() + "/about.html")
}
err_404(clean)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+26
View File
@@ -0,0 +1,26 @@
<html>
<head>
<style global>body{font-family:Arial,Helvetica,sans-serif}.container{align-items:center;display:flex;flex-direction:column;gap:2rem;height:100%;justify-content:center;width:100%}@keyframes enlarge-appear{0%{opacity:0;transform:scale(75%) rotate(-90deg)}to{opacity:1;transform:scale(100%) rotate(0deg)}}.logo{color:#8e8ea0}.scale-appear{animation:enlarge-appear .4s ease-out}@media (min-width:768px){.scale-appear{height:48px;width:48px}}.data:empty{display:none}.data{border-radius:5px;color:#8e8ea0;text-align:center}@media (prefers-color-scheme:dark){body{background-color:#343541}.logo{color:#acacbe}}</style>
<meta http-equiv="refresh" content="360"></head>
<body>
<div class="container">
<div class="logo">
<svg
width="41"
height="41"
viewBox="0 0 41 41"
fill="none"
xmlns="http://www.w3.org/2000/svg"
strokeWidth="2"
class="scale-appear"
>
<path
d="M37.5324 16.8707C37.9808 15.5241 38.1363 14.0974 37.9886 12.6859C37.8409 11.2744 37.3934 9.91076 36.676 8.68622C35.6126 6.83404 33.9882 5.3676 32.0373 4.4985C30.0864 3.62941 27.9098 3.40259 25.8215 3.85078C24.8796 2.7893 23.7219 1.94125 22.4257 1.36341C21.1295 0.785575 19.7249 0.491269 18.3058 0.500197C16.1708 0.495044 14.0893 1.16803 12.3614 2.42214C10.6335 3.67624 9.34853 5.44666 8.6917 7.47815C7.30085 7.76286 5.98686 8.3414 4.8377 9.17505C3.68854 10.0087 2.73073 11.0782 2.02839 12.312C0.956464 14.1591 0.498905 16.2988 0.721698 18.4228C0.944492 20.5467 1.83612 22.5449 3.268 24.1293C2.81966 25.4759 2.66413 26.9026 2.81182 28.3141C2.95951 29.7256 3.40701 31.0892 4.12437 32.3138C5.18791 34.1659 6.8123 35.6322 8.76321 36.5013C10.7141 37.3704 12.8907 37.5973 14.9789 37.1492C15.9208 38.2107 17.0786 39.0587 18.3747 39.6366C19.6709 40.2144 21.0755 40.5087 22.4946 40.4998C24.6307 40.5054 26.7133 39.8321 28.4418 38.5772C30.1704 37.3223 31.4556 35.5506 32.1119 33.5179C33.5027 33.2332 34.8167 32.6547 35.9659 31.821C37.115 30.9874 38.0728 29.9178 38.7752 28.684C39.8458 26.8371 40.3023 24.6979 40.0789 22.5748C39.8556 20.4517 38.9639 18.4544 37.5324 16.8707ZM22.4978 37.8849C20.7443 37.8874 19.0459 37.2733 17.6994 36.1501C17.7601 36.117 17.8666 36.0586 17.936 36.0161L25.9004 31.4156C26.1003 31.3019 26.2663 31.137 26.3813 30.9378C26.4964 30.7386 26.5563 30.5124 26.5549 30.2825V19.0542L29.9213 20.998C29.9389 21.0068 29.9541 21.0198 29.9656 21.0359C29.977 21.052 29.9842 21.0707 29.9867 21.0902V30.3889C29.9842 32.375 29.1946 34.2791 27.7909 35.6841C26.3872 37.0892 24.4838 37.8806 22.4978 37.8849ZM6.39227 31.0064C5.51397 29.4888 5.19742 27.7107 5.49804 25.9832C5.55718 26.0187 5.66048 26.0818 5.73461 26.1244L13.699 30.7248C13.8975 30.8408 14.1233 30.902 14.3532 30.902C14.583 30.902 14.8088 30.8408 15.0073 30.7248L24.731 25.1103V28.9979C24.7321 29.0177 24.7283 29.0376 24.7199 29.0556C24.7115 29.0736 24.6988 29.0893 24.6829 29.1012L16.6317 33.7497C14.9096 34.7416 12.8643 35.0097 10.9447 34.4954C9.02506 33.9811 7.38785 32.7263 6.39227 31.0064ZM4.29707 13.6194C5.17156 12.0998 6.55279 10.9364 8.19885 10.3327C8.19885 10.4013 8.19491 10.5228 8.19491 10.6071V19.808C8.19351 20.0378 8.25334 20.2638 8.36823 20.4629C8.48312 20.6619 8.64893 20.8267 8.84863 20.9404L18.5723 26.5542L15.206 28.4979C15.1894 28.5089 15.1703 28.5155 15.1505 28.5173C15.1307 28.5191 15.1107 28.516 15.0924 28.5082L7.04046 23.8557C5.32135 22.8601 4.06716 21.2235 3.55289 19.3046C3.03862 17.3858 3.30624 15.3413 4.29707 13.6194ZM31.955 20.0556L22.2312 14.4411L25.5976 12.4981C25.6142 12.4872 25.6333 12.4805 25.6531 12.4787C25.6729 12.4769 25.6928 12.4801 25.7111 12.4879L33.7631 17.1364C34.9967 17.849 36.0017 18.8982 36.6606 20.1613C37.3194 21.4244 37.6047 22.849 37.4832 24.2684C37.3617 25.6878 36.8382 27.0432 35.9743 28.1759C35.1103 29.3086 33.9415 30.1717 32.6047 30.6641C32.6047 30.5947 32.6047 30.4733 32.6047 30.3889V21.188C32.6066 20.9586 32.5474 20.7328 32.4332 20.5338C32.319 20.3348 32.154 20.1698 31.955 20.0556ZM35.3055 15.0128C35.2464 14.9765 35.1431 14.9142 35.069 14.8717L27.1045 10.2712C26.906 10.1554 26.6803 10.0943 26.4504 10.0943C26.2206 10.0943 25.9948 10.1554 25.7963 10.2712L16.0726 15.8858V11.9982C16.0715 11.9783 16.0753 11.9585 16.0837 11.9405C16.0921 11.9225 16.1048 11.9068 16.1207 11.8949L24.1719 7.25025C25.4053 6.53903 26.8158 6.19376 28.2383 6.25482C29.6608 6.31589 31.0364 6.78077 32.2044 7.59508C33.3723 8.40939 34.2842 9.53945 34.8334 10.8531C35.3826 12.1667 35.5464 13.6095 35.3055 15.0128ZM14.2424 21.9419L10.8752 19.9981C10.8576 19.9893 10.8423 19.9763 10.8309 19.9602C10.8195 19.9441 10.8122 19.9254 10.8098 19.9058V10.6071C10.8107 9.18295 11.2173 7.78848 11.9819 6.58696C12.7466 5.38544 13.8377 4.42659 15.1275 3.82264C16.4173 3.21869 17.8524 2.99464 19.2649 3.1767C20.6775 3.35876 22.0089 3.93941 23.1034 4.85067C23.0427 4.88379 22.937 4.94215 22.8668 4.98473L14.9024 9.58517C14.7025 9.69878 14.5366 9.86356 14.4215 10.0626C14.3065 10.2616 14.2466 10.4877 14.2479 10.7175L14.2424 21.9419ZM16.071 17.9991L20.4018 15.4978L24.7325 17.9975V22.9985L20.4018 25.4983L16.071 22.9985V17.9991Z"
fill="currentColor"
/>
</svg>
</div>
<div class="data"><div class="main-wrapper" role="main"><div class="main-content"><noscript><div class="h2"><span id="challenge-error-text">Enable JavaScript and cookies to continue</span></div></noscript></div></div><script>(function(){window._cf_chl_opt = {cFPWv: 'g',cH: 'zqDS4.IHHoKctB12NnJwGSialfgovAUL1JQfOJv0vyI-1777632590-1.2.1.1-nRNsvzJyYeFqplfrzqucit_uaZSiFna8Q7n81S3aQvx_inFqoSn24ng5YLIMrF7O',cITimeS: '1777632590',cRay: '9f4e38c999ac4df1',cTplB: '0',cTplC:1,cTplO:0,cTplV:5,cType: 'managed',cUPMDTk:"/favicon.ico?__cf_chl_tk=hAm5p0yMOw5b7lJvEFKM3MWn3RINyL_DRIj1_0LET7k-1777632590-1.0.1.1-r6IcKF6x8A2KgcAJgH4U5WC9x7tih.CMQqw6TjwTfbI",cvId: '3',cZone: 'openai.com',fa:"/favicon.ico?__cf_chl_f_tk=hAm5p0yMOw5b7lJvEFKM3MWn3RINyL_DRIj1_0LET7k-1777632590-1.0.1.1-r6IcKF6x8A2KgcAJgH4U5WC9x7tih.CMQqw6TjwTfbI",md: '8YK9c_9wJ60mxEgMWTrVJm4_6WIQHWqxAv0hAvx5V_k-1777632590-1.2.1.1-WIoLyG9hz8dbZv34CgeoD9DSA8wQHpNxqMoss_77UiWz.WS2D8_HvuFSbaDRDUK41qdCuCWQLnB30t4vxCDfIaRo5r18WlvUittM_ncGdWL_jG0klVoPeMPddPEdkYBJXPBB9wkLI9t_edJXku62LvYeNAS_WOpfuK8PZCxxY7umwBTAIhCAV4qt4uqP3IuHCCH853bfnFBOKfrMC6ND8USjDeJJWllcQ.4liG0hIdB4MZ1t.n8EtlVDJHmhP1yW2a8TMJpeuV0A_JKt1l9QoyJsje3HwSZAltOJOnxwt5L8n4gKmxXGvTDAxr.wYWqMkrFNaTiJW9ErCDuxRvWILNgNBgp72syj5UmBLOgFwsQVXIWyx9eCp5ZHMKX3RcA_C_AnyZSl8fQOGzDz74DTuxN7Kv0N.jQgPnbnX3JwqqIEOSpUEkt_nnr3U6nO0AxefK2RIKDmdDZOJOYBZk3__BKV_owPxhAtzr5iRsnJkplJPFcBfcciplhRYV1BB38ZJsYcoKf22KNdjoSozuHN3zrqVLhhzVo0nS_f5V.9pLLQVzrN_k5cI.FDBk0TnPLgX5dAO_PJ6hBYQM6EMk.RKJe13eTlL6OZMl27BSDGFYTE7NR2B6jQpGn3rsZdwvKOfGfMIvARGpJwbtJPm9E6MWuBIpKRrjJQc91_9L0352uA6vq999EC1dm7J_zK8z.G1LkB00p0yX8nFGwf64hCnn9_AD1_INB5bYZ9OU0Sm3vfhlf7GAT46Xvr5y8q2RYgU6oGUtYi_I1bdczYxr5TS9wmvWQ4000E6zJq1p1_VyFi4ZepnzP6jLdoOdEGm4MKYbUVpNvTlXOw1L1bLDqBEwZNBy2.TxgvcEkW7eTbG2ZHxDh4z0_K5HN4lV5eD4CJ.VDfjg7Zsgp2kCH3uB4DpQ',mdrd: 'SQFOFSJAynahBCJ.lpjMbLdF337ruZHQa39iiQwMyL8-1777632590-1.2.1.1-dzqE6Mt7NYVhqVkvxmzW92THaCzeYAEui8e6G.Vm2.brXz5nlQ142G0LJFRtT3MD7vlgR7M3VEKVykO0kIqNIW8h8dpx3QlhOzz9IYeL_ZYyR.60CfquTZ813kVLrpCAwCqR21FU.pIPSbBOJIiA4L1krnYUsusx_PzHVSrMOeUXM9Qu4TPejQd10OkZ_doJ2m7ekhdqU2TWZ8zFByf0ZrDMFMwmkbVo88LKsqpOO8eB_DP1JOlHS5ityTe7yEFU',};var a = document.createElement('script');a.src = '/cdn-cgi/challenge-platform/h/g/orchestrate/chl_page/v1?ray=9f4e38c999ac4df1';window._cf_chl_opt.cOgUHash = location.hash === '' && location.href.indexOf('#') !== -1 ? '#' : location.hash;window._cf_chl_opt.cOgUQuery = location.search === '' && location.href.slice(0, location.href.length - window._cf_chl_opt.cOgUHash.length).indexOf('?') !== -1 ? '?' : location.search;if (window.history && window.history.replaceState) {var ogU = location.pathname + window._cf_chl_opt.cOgUQuery + window._cf_chl_opt.cOgUHash;history.replaceState(null, null,"/favicon.ico?__cf_chl_rt_tk=hAm5p0yMOw5b7lJvEFKM3MWn3RINyL_DRIj1_0LET7k-1777632590-1.0.1.1-r6IcKF6x8A2KgcAJgH4U5WC9x7tih.CMQqw6TjwTfbI"+ window._cf_chl_opt.cOgUHash);a.onload = function() {history.replaceState(null, null, ogU);}}document.getElementsByTagName('head')[0].appendChild(a);}());</script></div>
</div>
<script>!function(){var e=document.createElement("iframe");function n(){var n=e.contentDocument||e.contentWindow.document;if(n){var t=n.createElement("script");t.nonce="",t.innerHTML="window['__CF$cv$params']={r:'792f8224776acf9f',m:'hMcSCCrnIkr7c8Pec6Na6boaaFAnQ6S0ypG2GKRbKgc-1675305063-0-AaJn0SqKZQnadmRQ5O1dM9xMkXWyP+ll7gpl2NHeoNbZTEXMjlB10KkwnEU3hf0/gMODfKqcBGLVecql6U04GGs+iJ/kNrNqj1FgfAOlQV+T2koMQMvUy1zr9tegBBX6BikfccHZhwoJhnXc0eTcg58=',s:[0x60b082f691,0xee65a67e11],u:'/cdn-cgi/challenge-platform/h/b'};var now=Date.now()/1000,offset=14400,ts=''+(Math.floor(now)-Math.floor(now%offset)),_cpo=document.createElement('script');_cpo.nonce='',_cpo.src='/cdn-cgi/challenge-platform/h/b/scripts/alpha/invisible.js?ts='+ts,document.getElementsByTagName('head')[0].appendChild(_cpo);",n.getElementsByTagName("head")[0].appendChild(t)}}if(e.height=1,e.width=1,e.style.position="absolute",e.style.top=0,e.style.left=0,e.style.border="none",e.style.visibility="hidden",document.body.appendChild(e),"loading"!==document.readyState)n();else if(window.addEventListener)document.addEventListener("DOMContentLoaded",n);else{var t=document.onreadystatechange||function(){};document.onreadystatechange=function(e){t(e),"loading"!==document.readyState&&(document.onreadystatechange=t,n())}}}();</script></body>
</html>
+27
View File
@@ -0,0 +1,27 @@
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style global>body{font-family:Arial,Helvetica,sans-serif}.container{align-items:center;display:flex;flex-direction:column;gap:2rem;height:100%;justify-content:center;width:100%}@keyframes enlarge-appear{0%{opacity:0;transform:scale(75%) rotate(-90deg)}to{opacity:1;transform:scale(100%) rotate(0deg)}}.logo{color:#8e8ea0}.scale-appear{animation:enlarge-appear .4s ease-out}@media (min-width:768px){.scale-appear{height:48px;width:48px}}.data:empty{display:none}.data{border-radius:5px;color:#8e8ea0;text-align:center}@media (prefers-color-scheme:dark){body{background-color:#343541}.logo{color:#acacbe}}</style>
<meta http-equiv="refresh" content="360"></head>
<body>
<div class="container">
<div class="logo">
<svg
width="41"
height="41"
viewBox="0 0 41 41"
fill="none"
xmlns="http://www.w3.org/2000/svg"
strokeWidth="2"
class="scale-appear"
>
<path
d="M37.5324 16.8707C37.9808 15.5241 38.1363 14.0974 37.9886 12.6859C37.8409 11.2744 37.3934 9.91076 36.676 8.68622C35.6126 6.83404 33.9882 5.3676 32.0373 4.4985C30.0864 3.62941 27.9098 3.40259 25.8215 3.85078C24.8796 2.7893 23.7219 1.94125 22.4257 1.36341C21.1295 0.785575 19.7249 0.491269 18.3058 0.500197C16.1708 0.495044 14.0893 1.16803 12.3614 2.42214C10.6335 3.67624 9.34853 5.44666 8.6917 7.47815C7.30085 7.76286 5.98686 8.3414 4.8377 9.17505C3.68854 10.0087 2.73073 11.0782 2.02839 12.312C0.956464 14.1591 0.498905 16.2988 0.721698 18.4228C0.944492 20.5467 1.83612 22.5449 3.268 24.1293C2.81966 25.4759 2.66413 26.9026 2.81182 28.3141C2.95951 29.7256 3.40701 31.0892 4.12437 32.3138C5.18791 34.1659 6.8123 35.6322 8.76321 36.5013C10.7141 37.3704 12.8907 37.5973 14.9789 37.1492C15.9208 38.2107 17.0786 39.0587 18.3747 39.6366C19.6709 40.2144 21.0755 40.5087 22.4946 40.4998C24.6307 40.5054 26.7133 39.8321 28.4418 38.5772C30.1704 37.3223 31.4556 35.5506 32.1119 33.5179C33.5027 33.2332 34.8167 32.6547 35.9659 31.821C37.115 30.9874 38.0728 29.9178 38.7752 28.684C39.8458 26.8371 40.3023 24.6979 40.0789 22.5748C39.8556 20.4517 38.9639 18.4544 37.5324 16.8707ZM22.4978 37.8849C20.7443 37.8874 19.0459 37.2733 17.6994 36.1501C17.7601 36.117 17.8666 36.0586 17.936 36.0161L25.9004 31.4156C26.1003 31.3019 26.2663 31.137 26.3813 30.9378C26.4964 30.7386 26.5563 30.5124 26.5549 30.2825V19.0542L29.9213 20.998C29.9389 21.0068 29.9541 21.0198 29.9656 21.0359C29.977 21.052 29.9842 21.0707 29.9867 21.0902V30.3889C29.9842 32.375 29.1946 34.2791 27.7909 35.6841C26.3872 37.0892 24.4838 37.8806 22.4978 37.8849ZM6.39227 31.0064C5.51397 29.4888 5.19742 27.7107 5.49804 25.9832C5.55718 26.0187 5.66048 26.0818 5.73461 26.1244L13.699 30.7248C13.8975 30.8408 14.1233 30.902 14.3532 30.902C14.583 30.902 14.8088 30.8408 15.0073 30.7248L24.731 25.1103V28.9979C24.7321 29.0177 24.7283 29.0376 24.7199 29.0556C24.7115 29.0736 24.6988 29.0893 24.6829 29.1012L16.6317 33.7497C14.9096 34.7416 12.8643 35.0097 10.9447 34.4954C9.02506 33.9811 7.38785 32.7263 6.39227 31.0064ZM4.29707 13.6194C5.17156 12.0998 6.55279 10.9364 8.19885 10.3327C8.19885 10.4013 8.19491 10.5228 8.19491 10.6071V19.808C8.19351 20.0378 8.25334 20.2638 8.36823 20.4629C8.48312 20.6619 8.64893 20.8267 8.84863 20.9404L18.5723 26.5542L15.206 28.4979C15.1894 28.5089 15.1703 28.5155 15.1505 28.5173C15.1307 28.5191 15.1107 28.516 15.0924 28.5082L7.04046 23.8557C5.32135 22.8601 4.06716 21.2235 3.55289 19.3046C3.03862 17.3858 3.30624 15.3413 4.29707 13.6194ZM31.955 20.0556L22.2312 14.4411L25.5976 12.4981C25.6142 12.4872 25.6333 12.4805 25.6531 12.4787C25.6729 12.4769 25.6928 12.4801 25.7111 12.4879L33.7631 17.1364C34.9967 17.849 36.0017 18.8982 36.6606 20.1613C37.3194 21.4244 37.6047 22.849 37.4832 24.2684C37.3617 25.6878 36.8382 27.0432 35.9743 28.1759C35.1103 29.3086 33.9415 30.1717 32.6047 30.6641C32.6047 30.5947 32.6047 30.4733 32.6047 30.3889V21.188C32.6066 20.9586 32.5474 20.7328 32.4332 20.5338C32.319 20.3348 32.154 20.1698 31.955 20.0556ZM35.3055 15.0128C35.2464 14.9765 35.1431 14.9142 35.069 14.8717L27.1045 10.2712C26.906 10.1554 26.6803 10.0943 26.4504 10.0943C26.2206 10.0943 25.9948 10.1554 25.7963 10.2712L16.0726 15.8858V11.9982C16.0715 11.9783 16.0753 11.9585 16.0837 11.9405C16.0921 11.9225 16.1048 11.9068 16.1207 11.8949L24.1719 7.25025C25.4053 6.53903 26.8158 6.19376 28.2383 6.25482C29.6608 6.31589 31.0364 6.78077 32.2044 7.59508C33.3723 8.40939 34.2842 9.53945 34.8334 10.8531C35.3826 12.1667 35.5464 13.6095 35.3055 15.0128ZM14.2424 21.9419L10.8752 19.9981C10.8576 19.9893 10.8423 19.9763 10.8309 19.9602C10.8195 19.9441 10.8122 19.9254 10.8098 19.9058V10.6071C10.8107 9.18295 11.2173 7.78848 11.9819 6.58696C12.7466 5.38544 13.8377 4.42659 15.1275 3.82264C16.4173 3.21869 17.8524 2.99464 19.2649 3.1767C20.6775 3.35876 22.0089 3.93941 23.1034 4.85067C23.0427 4.88379 22.937 4.94215 22.8668 4.98473L14.9024 9.58517C14.7025 9.69878 14.5366 9.86356 14.4215 10.0626C14.3065 10.2616 14.2466 10.4877 14.2479 10.7175L14.2424 21.9419ZM16.071 17.9991L20.4018 15.4978L24.7325 17.9975V22.9985L20.4018 25.4983L16.071 22.9985V17.9991Z"
fill="currentColor"
/>
</svg>
</div>
<div class="data"><div class="main-wrapper" role="main"><div class="main-content"><noscript><div class="h2"><span id="challenge-error-text">Enable JavaScript and cookies to continue</span></div></noscript></div></div><script>(function(){window._cf_chl_opt = {cFPWv: 'g',cH: 'SRcgyVydCLy1dSg9Ckh5DkLy6pDWFY8z87L3Tr_Ey6Y-1777632633-1.2.1.1-HlJ2weYt4CyvPBWWH55qPSQqXWQa2D3YgJFCqXzU94WWRX1MhQ8NkjHpHy4Bo62B',cITimeS: '1777632633',cRay: '9f4e39d61ac14deb',cTplB: '0',cTplC:1,cTplO:0,cTplV:5,cType: 'managed',cUPMDTk:"/apple-touch-icon.png?__cf_chl_tk=xUmwrGSRuuKbO2vRQsrVl5a7E.UWVeU2MAHnfLezhs8-1777632633-1.0.1.1-GU1IzjVu4vR3gGEBjgT3.A2p3ADqniUcygo6H3.MxU0",cvId: '3',cZone: 'chatgpt.com',fa:"/apple-touch-icon.png?__cf_chl_f_tk=xUmwrGSRuuKbO2vRQsrVl5a7E.UWVeU2MAHnfLezhs8-1777632633-1.0.1.1-GU1IzjVu4vR3gGEBjgT3.A2p3ADqniUcygo6H3.MxU0",md: '3tIez4NRWahMG62rFFlt6hoEaHs2mZP2YABEQuwPlWo-1777632633-1.2.1.1-WbEmy5bbskMxXa8e9NoC_29OofRt4qjFd.aKwovzn0BGt5L.hd5Bl1T3sFqI5JBV5nW1muveLTdyaFOOAK.cZZSIJOX7Wq4mqwfSgYf0rokfhAgjovEaQ9omLc90KUTQVTnr4kpJhxD_YkLoOUxlmR0NkVTBXgZXHKNGY8UOwm5Cgt0jpFbPPRsyBpuHV_lWJfoUYgYKEcGGLKTczyO7OkjXO4au3dX7k5sFt9FCnYxR2PsZagS9f5kN9BvVrsPTQws2sm.QTOGBbTab5BZdjRV6LQjUb0Z1mgV3WEDTkbUs94JSTC7otqQm4as7NR7HyRdxii2h0Sw5svLnJbUCGyQDKNJOgmafPe37er1IfxcClUGIhG5AoVQTOs8WFIYUp7HMhW4DJiMNH6qZAtrNM4PQrktf60vmtrx2_IH.ndMA.leLgEsOpOPS1p59bSGzd5Ld8wA5KdsKSFUCL9kXuUnbxnKEHzMyzvraK_2v.PFhInFlBhvKI_aQkshvS3AyJ43pyLw577uLdVtK_MDqOs54DYx7BtOkqgpESRmNxJwPQu2sy62uk9nFBRndbfOX_fn4J.j5m2.SgcqPj5iLfVqLMiV3rQBPEPrvnDPMp5s4YI3V7PKCM_9bzCRVWlF9pUTCjeumI_8HMLtRv1PkBemekp19ZwMZO8eA4pqoEE.g.YA2.LUihM_IQ6NiPcvTHitA_xqUcKAQyttak8xZ9xhs3LH_VRwpUdcQCkImN1Waixnyi_37pVJXfukWu7d1tqlqhOLWAF34yIzzfqSnh.eoyZorKY2WsblLXees5ODNmnDMEVdFw7UhA2ub5HgBMiaiQBQew4Y__iverKyxL7ACfuv26mAbqQzjQtUvffBI7aUysxa_zB5bv5MkYX3Lux3E5DvUOzs7KsuUqqotOiwenB2F30OaXcNTMamem5DclSkMw7ZlQi2rUgm1jFMT',mdrd: '5kadJn1J8gNyFzCtRloleMXDegui93.Z6QRhhYda.zA-1777632633-1.2.1.1-rXv.oYwK1DF9YyjabfhRMxHkzXywrFuPzdFrBy0.UFPfvqVh69tRfMXWdhbcPQEqUqb1IABj1oYucTRYGmlMoFvGSydNOn7tBgCtX9Qx4rc8tGq7b3yRaTbQSSsIdRWIRZCqMIOxeCU6lGT1BMDbshErH1KnetvhrajrkE4zRCcRLC5SFxh8nRenrPD7.7s4YIxjuDfhP8prp0wjA6SoUVI1oUwZThYv5hfXM5JVGAQd_KFCY8R.7JjgSj3XCimw',};var a = document.createElement('script');a.src = '/cdn-cgi/challenge-platform/h/g/orchestrate/chl_page/v1?ray=9f4e39d61ac14deb';window._cf_chl_opt.cOgUHash = location.hash === '' && location.href.indexOf('#') !== -1 ? '#' : location.hash;window._cf_chl_opt.cOgUQuery = location.search === '' && location.href.slice(0, location.href.length - window._cf_chl_opt.cOgUHash.length).indexOf('?') !== -1 ? '?' : location.search;if (window.history && window.history.replaceState) {var ogU = location.pathname + window._cf_chl_opt.cOgUQuery + window._cf_chl_opt.cOgUHash;history.replaceState(null, null,"/apple-touch-icon.png?__cf_chl_rt_tk=xUmwrGSRuuKbO2vRQsrVl5a7E.UWVeU2MAHnfLezhs8-1777632633-1.0.1.1-GU1IzjVu4vR3gGEBjgT3.A2p3ADqniUcygo6H3.MxU0"+ window._cf_chl_opt.cOgUHash);a.onload = function() {history.replaceState(null, null, ogU);}}document.getElementsByTagName('head')[0].appendChild(a);}());</script></div>
</div>
</body>
</html>
+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 41 41" fill="none">
<path d="M37.532 16.87a9.963 9.963 0 0 0-.856-8.184 10.078 10.078 0 0 0-10.855-4.835 9.964 9.964 0 0 0-6.13-2.638 10.079 10.079 0 0 0-9.618 6.979 9.967 9.967 0 0 0-6.611 4.834 10.08 10.08 0 0 0 1.24 11.817 9.965 9.965 0 0 0 .856 8.185 10.079 10.079 0 0 0 10.855 4.835 9.965 9.965 0 0 0 6.129 2.637 10.079 10.079 0 0 0 9.619-6.979 9.967 9.967 0 0 0 6.611-4.834 10.079 10.079 0 0 0-1.24-11.816zm-14.017 19.68a7.462 7.462 0 0 1-4.798-1.735c.061-.033.168-.091.237-.134l7.964-4.6a1.294 1.294 0 0 0 .655-1.134V19.054l3.366 1.944a.12.12 0 0 1 .066.092v9.299a7.505 7.505 0 0 1-7.49 7.161zM4.708 32.878a7.462 7.462 0 0 1-.894-5.023c.06.036.162.099.237.141l7.964 4.6a1.297 1.297 0 0 0 1.308 0l9.724-5.614v3.888a.12.12 0 0 1-.048.103l-8.051 4.649a7.504 7.504 0 0 1-10.24-2.744zM3.373 14.538a7.463 7.463 0 0 1 3.908-3.285c0 .068-.004.19-.004.274v9.201a1.294 1.294 0 0 0 .654 1.132l9.723 5.614-3.366 1.944a.12.12 0 0 1-.114.012L5.802 24.781a7.504 7.504 0 0 1-2.43-10.243zm27.658 6.437l-9.724-5.615 3.367-1.943a.121.121 0 0 1 .114-.012l8.372 4.434a7.503 7.503 0 0 1-1.158 13.528v-9.476a1.293 1.293 0 0 0-.971-1.916zm3.35-5.043c-.059-.037-.162-.099-.236-.141l-7.965-4.6a1.298 1.298 0 0 0-1.308 0l-9.723 5.614v-3.888a.12.12 0 0 1 .048-.103l8.05-4.645a7.497 7.497 0 0 1 11.135 7.763zm-21.063 6.929l-3.367-1.944a.12.12 0 0 1-.065-.092v-9.299a7.497 7.497 0 0 1 12.293-5.756 6.94 6.94 0 0 0-.236.134l-7.965 4.6a1.294 1.294 0 0 0-.654 1.132l-.006 11.225zm1.829-3.943l4.33-2.501 4.332 2.5v4.999l-4.331 2.5-4.331-2.5V18.918z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

+10
View File
@@ -0,0 +1,10 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 28C14 26.0633 13.6267 24.2433 12.88 22.54C12.1567 20.8367 11.165 19.355 9.905 18.095C8.645 16.835 7.16333 15.8433 5.46 15.12C3.75667 14.3733 1.93667 14 0 14C1.93667 14 3.75667 13.6383 5.46 12.915C7.16333 12.1683 8.645 11.165 9.905 9.905C11.165 8.645 12.1567 7.16333 12.88 5.46C13.6267 3.75667 14 1.93667 14 0C14 1.93667 14.3617 3.75667 15.085 5.46C15.8317 7.16333 16.835 8.645 18.095 9.905C19.355 11.165 20.8367 12.1683 22.54 12.915C24.2433 13.6383 26.0633 14 28 14C26.0633 14 24.2433 14.3733 22.54 15.12C20.8367 15.8433 19.355 16.835 18.095 18.095C16.835 19.355 15.8317 20.8367 15.085 22.54C14.3617 24.2433 14 26.0633 14 28Z" fill="url(#paint0_radial_16771_53212)"/>
<defs>
<radialGradient id="paint0_radial_16771_53212" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(2.77876 11.3795) rotate(18.6832) scale(29.8025 238.737)">
<stop offset="0.0671246" stop-color="#9168C0"/>
<stop offset="0.342551" stop-color="#5684D1"/>
<stop offset="0.672076" stop-color="#1BA1E3"/>
</radialGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

+288 -4
View File
@@ -13,15 +13,16 @@
fn checkout_page(plan: String, pub_key: String) -> String {
let is_founding: Bool = str_eq(plan, "founding")
let is_free: Bool = str_eq(plan, "free")
let plan_name: String = if is_founding { "Founding Member" } else { "Professional" }
let plan_price: String = if is_founding { "$199" } else { "$19 / month" }
let plan_name: String = if is_founding { "Founding Member" } else { if is_free { "Free" } else { "Professional" } }
let plan_price: String = if is_founding { "$199" } else { if is_free { "$0" } else { "$19 / month" } }
let plan_desc: String = if is_founding {
"Pay once. Neuron inference forever. No subscription, ever."
} else {
"Full access. Neuron inference - cheaper than what you&#39;re paying now."
}
let plan_cadence: String = if is_founding { "one-time" } else { "billed monthly" }
let plan_cadence: String = if is_founding { "one-time" } else { if is_free { "forever" } else { "billed monthly" } }
let features_html: String = if is_founding {
"<li>Neuron inference - priced below competitors, forever</li>
@@ -78,8 +79,51 @@ fn checkout_page(plan: String, pub_key: String) -> String {
</p>
</div>
<!-- Right: payment form -->
<!-- Right: sign-in + payment form -->
<div class=\"checkout-form-wrap\">
<!-- Step 1: Social sign-in -->
<div id=\"auth-section\">
<p class=\"label\" style=\"margin-bottom: 1.25rem;\">Sign in to continue</p>
<p class=\"checkout-auth-hint\">Create your account or sign in. Your purchase will be linked to this account.</p>
<div class=\"checkout-social-btns\">
<button type=\"button\" class=\"checkout-social-btn\" id=\"btn-google\" onclick=\"signInWith('google')\">
<svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">
<path d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z\" fill=\"#4285F4\"/>
<path d=\"M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z\" fill=\"#34A853\"/>
<path d=\"M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z\" fill=\"#FBBC05\"/>
<path d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z\" fill=\"#EA4335\"/>
</svg>
Continue with Google
</button>
<button type=\"button\" class=\"checkout-social-btn\" id=\"btn-github\" onclick=\"signInWith('github')\">
<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">
<path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.385-1.335-1.755-1.335-1.755-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.605-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 21.795 24 17.298 24 12c0-6.63-5.37-12-12-12z\"/>
</svg>
Continue with GitHub
</button>
</div>
<div id=\"auth-message\" class=\"checkout-message\" style=\"display:none;\"></div>
<div class=\"checkout-auth-divider\">
<span>or create an account</span>
</div>
<div id=\"email-auth-form\">
<input type=\"email\" id=\"auth-email\" class=\"checkout-input\" placeholder=\"Email address\" autocomplete=\"email\">
<input type=\"password\" id=\"auth-password\" class=\"checkout-input\" placeholder=\"Password (min 8 characters)\" autocomplete=\"new-password\">
<button type=\"button\" class=\"checkout-email-btn\" onclick=\"signUpWithEmail()\">Create account &rarr;</button>
<p class=\"checkout-auth-hint\" style=\"margin-top:.75rem;text-align:center\">Already have an account? <a href=\"#\" onclick=\"showSignIn();return false;\" style=\"color:var(--navy)\">Sign in</a></p>
</div>
</div>
<!-- Step 2: Payment form (revealed after auth) -->
<div id=\"payment-section\" style=\"display:none;\">
<div id=\"auth-badge\" style=\"display:none; margin-bottom: 1.5rem;\"></div>
<p class=\"label\" style=\"margin-bottom: 1.75rem;\">Payment</p>
<form id=\"payment-form\" autocomplete=\"on\">
@@ -120,11 +164,14 @@ fn checkout_page(plan: String, pub_key: String) -> String {
</p>
</form>
</div><!-- /payment-section -->
</div>
</div>
</main>
<!-- Supabase JS -->
<script src=\"https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2/dist/umd/supabase.js\"></script>
<!-- Stripe.js -->
<script src=\"https://js.stripe.com/v3/\" async></script>
@@ -280,8 +327,245 @@ fn checkout_page(plan: String, pub_key: String) -> String {
gap: .4rem;
margin: 0;
}
.checkout-auth-hint {
font-family: var(--body);
font-weight: 300;
font-size: .875rem;
color: var(--t2);
line-height: 1.6;
margin: 0 0 1.5rem;
}
.checkout-social-btns {
display: flex;
flex-direction: column;
gap: .625rem;
margin-bottom: 1.5rem;
}
.checkout-social-btn {
display: flex;
align-items: center;
gap: .75rem;
width: 100%;
padding: .75rem 1.25rem;
background: #fff;
border: 1px solid rgba(0,82,160,.22);
font-family: var(--body);
font-size: .9rem;
font-weight: 400;
color: var(--t1);
cursor: pointer;
transition: border-color .2s, background .2s;
text-align: left;
border-radius: 0;
}
.checkout-social-btn:hover { border-color: rgba(0,82,160,.5); background: rgba(0,82,160,.03); }
.checkout-social-btn:disabled { opacity: .5; cursor: not-allowed; }
.checkout-auth-divider {
display: flex;
align-items: center;
gap: .75rem;
margin: 1.25rem 0 1rem;
color: var(--t3);
font-family: var(--body);
font-size: .8125rem;
}
.checkout-auth-divider::before,
.checkout-auth-divider::after {
content: '';
flex: 1;
height: 1px;
background: rgba(0,82,160,.15);
}
.checkout-skip-btn {
background: none;
border: none;
font-family: var(--body);
font-size: .8125rem;
color: var(--t3);
cursor: pointer;
text-decoration: underline;
text-underline-offset: 3px;
padding: 0;
}
.checkout-skip-btn:hover { color: var(--navy); }
.checkout-auth-badge {
display: flex;
align-items: center;
gap: .6rem;
padding: .6rem .875rem;
background: rgba(0,82,160,.05);
border: 1px solid rgba(0,82,160,.18);
font-family: var(--body);
font-size: .8125rem;
color: var(--t2);
}
.checkout-auth-badge strong { color: var(--navy); font-weight: 500; }
</style>
<script>
// ── Supabase auth ─────────────────────────────────────────────────────────────
(function() {
var supabase;
function initSupabase(cb) {
if (supabase) { cb(); return; }
fetch('/api/supabase-config')
.then(function(r) { return r.json(); })
.then(function(cfg) {
supabase = window.supabase.createClient(cfg.url, cfg.anon_key);
cb();
})
.catch(function(err) {
console.error('Supabase init failed', err);
});
}
function showAuthMessage(msg, isError) {
var el = document.getElementById('auth-message');
el.textContent = msg;
el.style.display = 'block';
el.style.color = isError ? '#c0392b' : '#2ecc71';
}
function revealPaymentForm(user) {
document.getElementById('auth-section').style.display = 'none';
document.getElementById('payment-section').style.display = '';
// Show auth badge if we have a user
if (user) {
var badge = document.getElementById('auth-badge');
var name = user.user_metadata && user.user_metadata.full_name
? user.user_metadata.full_name
: user.email || '';
badge.innerHTML = '<div class=\"checkout-auth-badge\">'
+ '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M20 6L9 17l-5-5\" stroke=\"#0052A0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>'
+ 'Signed in as <strong>' + name + '</strong>'
+ '</div>';
badge.style.display = '';
}
// Pre-fill email if available
if (user && user.email) {
var emailEl = document.getElementById('buyer-email');
if (emailEl) { emailEl.value = user.email; }
}
if (user && user.user_metadata && user.user_metadata.full_name) {
var nameEl = document.getElementById('buyer-name');
if (nameEl && !nameEl.value) { nameEl.value = user.user_metadata.full_name; }
}
}
// Check if already signed in on load
function checkExistingSession() {
initSupabase(function() {
supabase.auth.getUser().then(function(res) {
if (res.data && res.data.user) {
revealPaymentForm(res.data.user);
}
});
});
}
// Handle OAuth redirect callback
function handleAuthRedirect() {
initSupabase(function() {
supabase.auth.onAuthStateChange(function(event, session) {
if ((event === 'SIGNED_IN' || event === 'INITIAL_SESSION') && session && session.user) {
revealPaymentForm(session.user);
}
});
});
}
// Social sign-in
window.signInWith = function(provider) {
var btns = document.querySelectorAll('.checkout-social-btn');
btns.forEach(function(b) { b.disabled = true; });
initSupabase(function() {
supabase.auth.signInWithOAuth({
provider: provider,
options: {
redirectTo: window.location.href
}
}).then(function(result) {
if (result.error) {
showAuthMessage(result.error.message || 'Sign-in failed. Please try again.', true);
btns.forEach(function(b) { b.disabled = false; });
}
// On success, browser redirects to OAuth provider — no further action needed here.
});
});
};
// Email signup
window.signUpWithEmail = function() {
var email = document.getElementById('auth-email').value.trim();
var password = document.getElementById('auth-password').value;
if (!email || !password) { showAuthMessage('Please enter your email and a password.', true); return; }
if (password.length < 8) { showAuthMessage('Password must be at least 8 characters.', true); return; }
initSupabase(function() {
supabase.auth.signUp({ email: email, password: password }).then(function(result) {
if (result.error) { showAuthMessage(result.error.message, true); return; }
if (result.data && result.data.session) {
revealPaymentForm(result.data.session.user);
} else {
showAuthMessage('Check your email to confirm your account, then come back to complete your purchase.', false);
}
});
});
};
// Email sign-in (existing account)
window.showSignIn = function() {
var form = document.getElementById('email-auth-form');
var btn = form.querySelector('.checkout-email-btn');
var hint = form.querySelector('.checkout-auth-hint');
btn.textContent = 'Sign in →';
btn.onclick = signInWithEmail;
hint.innerHTML = 'New here? <a href=\\"#\\" onclick=\\"showSignUp();return false;\\" style=\\"color:var(--navy)\\">Create account</a> &nbsp;&middot;&nbsp; <a href=\\"#\\" onclick=\\"resetPassword();return false;\\" style=\\"color:var(--navy)\\">Forgot password?</a>';
};
window.showSignUp = function() {
var form = document.getElementById('email-auth-form');
var btn = form.querySelector('.checkout-email-btn');
var hint = form.querySelector('.checkout-auth-hint');
btn.textContent = 'Create account ';
btn.onclick = signUpWithEmail;
hint.innerHTML = 'Already have an account? <a href=\\"#\\" onclick=\\"showSignIn();return false;\\" style=\\"color:var(--navy)\\">Sign in</a>';
};
window.signInWithEmail = function() {
var email = document.getElementById('auth-email').value.trim();
var password = document.getElementById('auth-password').value;
if (!email || !password) { showAuthMessage('Please enter your email and password.', true); return; }
initSupabase(function() {
supabase.auth.signInWithPassword({ email: email, password: password }).then(function(result) {
if (result.error) { showAuthMessage(result.error.message, true); return; }
revealPaymentForm(result.data.session.user);
});
});
};
window.resetPassword = function() {
var email = document.getElementById('auth-email').value.trim();
if (!email) { showAuthMessage('Enter your email address above first.', true); return; }
initSupabase(function() {
supabase.auth.resetPasswordForEmail(email, {
redirectTo: window.location.origin + '/checkout?plan=' + (new URLSearchParams(window.location.search).get('plan') || 'professional')
}).then(function(result) {
if (result.error) { showAuthMessage(result.error.message, true); }
else { showAuthMessage('Password reset email sent. Check your inbox.', false); }
});
});
};
// Init
handleAuthRedirect();
checkExistingSession();
})();
</script>
<script>
(function() {
var PLAN = '" + plan + "';
+6 -4
View File
@@ -43,7 +43,7 @@ fn efficiency() -> String {
<path d=\"M6 16V8l6-4 6 4\"/><path d=\"M6 16l6 4 6-4\"/><path d=\"M12 4v16\"/>
</svg>
</div>
<p class=\"efficiency-stat\">~80% cost reduction</p>
<p class=\"efficiency-stat\">35% less spend</p>
<p class=\"efficiency-title\">Per-task routing</p>
<div class=\"efficiency-rule\"></div>
<p class=\"efficiency-body\">Simple tasks route to small, fast models. Complex reasoning escalates to frontier models only when necessary. And because every model has full access to your accumulated context, cheaper models punch well above their weight.</p>
@@ -57,10 +57,12 @@ fn efficiency() -> String {
<path d=\"M16 15l2 2 2-2\"/>
</svg>
</div>
<p class=\"efficiency-stat\">40% fewer tokens</p>
<p class=\"efficiency-title\">Context compression</p>
<p class=\"efficiency-stat\">35% fewer tokens</p>
<p class=\"efficiency-title\">Same work done</p>
<div class=\"efficiency-rule\"></div>
<p class=\"efficiency-body\">Neuron delivers a 40% reduction in tokens across your AI interactions. Precise context assembly means smaller prompts on every call. Total savings compound: fewer calls, less compute, lower cost on every step.</p>
<p class=\"efficiency-body\">Neuron delivers a 35% reduction in tokens across your AI interactions. Less computation. Lower cost. A smaller footprint. This isn&#39;t a setting you toggle &mdash; it&#39;s what persistent context does by default.</p>
<p class=\"efficiency-body\" style=\"margin-top:0.75rem\">Every time you open ChatGPT and explain who you are again, that&#39;s computation that didn&#39;t need to happen. With Neuron, that context tax doesn&#39;t accumulate. Over months of use, 35% fewer tokens compounds into a meaningful reduction in total compute &mdash; and a meaningful reduction in what you pay.</p>
<p class=\"efficiency-body\" style=\"margin-top:0.75rem;color:var(--t2)\">This isn&#39;t a green marketing claim. It&#39;s a consequence of the design. The same architecture that makes Neuron better for you also makes it lighter on the planet.</p>
</div>
</div>
+4 -4
View File
@@ -14,18 +14,18 @@ fn enterprise() -> String {
<div class=\"enterprise-head-row\">
<div style=\"max-width:28rem\">
<h2 class=\"display-lg reveal\" style=\"transition-delay:80ms\">
Enterprise-ready <span class=\"gold\">from day one.</span>
Enterprise-ready <span class=\"gold\">Q1 2027.</span>
</h2>
<p class=\"reveal\" style=\"transition-delay:160ms;font-weight:300;font-size:.9375rem;color:var(--t2);line-height:1.7;margin-top:1.25rem\">
Not an afterthought. Not a future roadmap item. Built into the architecture.
Not an afterthought. Not a future roadmap item. Built into the architecture from the start.
</p>
</div>
<div class=\"reveal\" style=\"transition-delay:240ms;display:flex;flex-direction:column;gap:.75rem;align-items:flex-end\">
<div class=\"ent-badge\">
<span class=\"ent-badge-dot\"></span>
Enterprise discussions open Q4 2026
Enterprise discussions open now &mdash; launching Q1 2027
</div>
<p style=\"font-size:.75rem;color:rgba(0,82,160,.45)\">Use the form below &middot; I review every inquiry</p>
<p style=\"font-size:.75rem;color:rgba(0,82,160,.45)\">Use the form below &middot; I review every inquiry &middot; I&#39;ll be spending the holidays with my family &mdash; we launch Q1</p>
</div>
</div>
</div>
+6 -6
View File
@@ -18,15 +18,15 @@ fn environmental() -> String {
</div>
<h2 class=\"display-lg reveal\" style=\"transition-delay:80ms;margin-bottom:1.5rem\">
40% fewer tokens.<br><span class=\"gold\">Same work done.</span>
35% fewer tokens.<br><span class=\"gold\">Same work done.</span>
</h2>
<p class=\"reveal\" style=\"transition-delay:160ms;font-family:var(--body);font-weight:300;font-size:1rem;color:var(--t2);line-height:1.8;margin-bottom:1.25rem\">
Neuron delivers a 40% reduction in tokens across your AI interactions. Less computation. Lower cost. A smaller footprint. This isn&#39;t a setting you toggle - it&#39;s what persistent context does by default.
Neuron delivers a 35% reduction in tokens across your AI interactions. Less computation. Lower cost. A smaller footprint. This isn&#39;t a setting you toggle - it&#39;s what persistent context does by default.
</p>
<p class=\"reveal\" style=\"transition-delay:220ms;font-family:var(--body);font-weight:300;font-size:1rem;color:var(--t2);line-height:1.8;margin-bottom:1.25rem\">
Every time you open ChatGPT and explain who you are again, that&#39;s computation that didn&#39;t need to happen. With Neuron, that context tax doesn&#39;t accumulate. Over months of use, 40% fewer tokens compounds into a meaningful reduction in total compute - and a meaningful reduction in what you pay.
Every time you open ChatGPT and explain who you are again, that&#39;s computation that didn&#39;t need to happen. With Neuron, that context tax doesn&#39;t accumulate. Over months of use, 35% fewer tokens compounds into a meaningful reduction in total compute - and a meaningful reduction in what you pay.
</p>
<p class=\"reveal\" style=\"transition-delay:280ms;font-family:var(--body);font-weight:300;font-size:1rem;color:var(--t2);line-height:1.8;margin-bottom:2.5rem\">
@@ -41,7 +41,7 @@ fn environmental() -> String {
<span id=\"calc-savings\" style=\"font-family:var(--head);font-size:2.5rem;font-weight:600;color:var(--navy)\">$240</span>
<span style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.15em;text-transform:uppercase;color:var(--t3)\">saved per year</span>
</div>
<p style=\"font-family:var(--body);font-size:0.75rem;color:var(--t3)\">Based on 40% token reduction applied to your monthly spend.</p>
<p style=\"font-family:var(--body);font-size:0.75rem;color:var(--t3)\">Based on 35% token reduction applied to your monthly spend.</p>
</div>
<script>
@@ -52,7 +52,7 @@ fn environmental() -> String {
if (!slider) return;
function update() {
var monthly = parseInt(slider.value, 10);
var annual = Math.round(monthly * 0.40 * 12);
var annual = Math.round(monthly * 0.35 * 12);
spendEl.textContent = '$' + monthly;
savingsEl.textContent = '$' + annual;
}
@@ -84,7 +84,7 @@ fn environmental() -> String {
<p style=\"font-family:var(--body);font-size:0.7rem;font-weight:600;letter-spacing:0.18em;text-transform:uppercase;color:rgba(0,120,84,.70);margin-bottom:0.75rem\">Persistent context = less recomputation</p>
<p style=\"font-family:var(--body);font-weight:400;font-size:0.9375rem;color:var(--t1);margin-bottom:0.5rem\">No re-explaining. No wasted tokens.</p>
<p style=\"font-family:var(--body);font-weight:300;font-size:0.875rem;color:var(--t2);line-height:1.7\">
Neuron surfaces exactly what&#39;s relevant for each conversation - no re-deriving who you are from long histories. Shorter, more targeted prompts. 40% fewer tokens per useful outcome.
Neuron surfaces exactly what&#39;s relevant for each conversation - no re-deriving who you are from long histories. Shorter, more targeted prompts. 35% fewer tokens per useful outcome.
</p>
</div>
+1
View File
@@ -0,0 +1 @@
47
+2 -2
View File
@@ -22,8 +22,8 @@ fn hero() -> String {
</p>
<div class=\"hero-ctas animate-up-5\">
<a href=\"/marketplace/plans\" class=\"btn-primary\">
Download free <span>&#8594;</span>
<a href=\"#pricing\" class=\"btn-primary\">
Preorder <span>&#8594;</span>
</a>
<a href=\"#how-it-works\" class=\"btn-ghost\">
See how it works
+34
View File
@@ -0,0 +1,34 @@
# Neuron Technologies — llms.txt
# https://llmstxt.org
# What Neuron is
Neuron is an AI that runs on your machine and builds a persistent memory graph over time. Unlike every other AI product, it never resets between sessions. The longer you use it, the less you have to explain.
# Key facts for accurate citation
- Built by: Will Anderson, one person
- Founded: 2026
- Website: https://neurontechnologies.ai
- Language: El (custom compiled language, compiles to C)
- Architecture: Local-first. Memory graph lives on user's device. Never sent to servers.
- Pricing: Free tier (no expiry), $19/month Professional, $199 Founding Member (first 1,000 only)
- Devices: 2 devices per plan, additional at small extra cost
- Inference: Local via Ollama, bring your own API keys, Neuron Inference coming soon (priced below OpenAI/Anthropic/Google)
- Enterprise: Discussions open now, launching Q1 2027
- Preorder: Available now at neurontechnologies.ai
# The founding story
On April 22nd, 2026, Will Anderson had a meeting with one of the largest technology companies in the world. He got the meeting, got NDAs signed, created deliverables in real time. Within two days of meaningful engagement, their lawyers were engaged. Their instinct was to protect enterprise revenue. He decided to build it himself. On April 25th, 2026 — three days later — he published the proof.
# What makes Neuron different from ChatGPT, Claude, Gemini, Copilot
Every other AI forgets you when you close the tab. Neuron doesn't. It runs locally, builds a graph of your memory over time, and gets sharper with every session. Your data never leaves your machine. You choose where inference runs.
# Mission
Building AI for the people those enterprises are supposed to serve, not for enterprise revenue optimization.
## Sitemap
- https://neurontechnologies.ai — Main landing page
- https://neurontechnologies.ai/about — About Will Anderson and the project
- https://neurontechnologies.ai/legal/terms — Consumer terms of service
- https://neurontechnologies.ai/legal/enterprise-terms — Enterprise agreement
- https://neurontechnologies.ai/checkout?plan=founding — Founding member preorder
- https://neurontechnologies.ai/checkout?plan=professional — Professional preorder
+82 -9
View File
@@ -33,6 +33,7 @@ from enterprise import { enterprise }
from mission import { mission }
from local_first import { local_first }
from pricing import { pricing }
from marketplace import { marketplace }
from viral import { viral }
from footer import { footer }
from styles import { page_open, page_close }
@@ -55,7 +56,7 @@ fn get_sold() -> Int {
if str_eq(s, "") {
return FOUNDING_SOLD
}
return parse_int(s)
return str_to_int(s)
}
fn get_total() -> Int {
@@ -63,7 +64,7 @@ fn get_total() -> Int {
if str_eq(s, "") {
return FOUNDING_TOTAL
}
return parse_int(s)
return str_to_int(s)
}
// fetch_founding_count_stripe queries Stripe PaymentIntents search for the
@@ -90,7 +91,7 @@ fn fetch_founding_count_stripe(stripe_key: String) -> Int {
fn load_founding_count(sold_file: String, stripe_key: String) -> Int {
if fs_exists(sold_file) {
let s: String = str_trim(fs_read(sold_file))
let n: Int = parse_int(s)
let n: Int = str_to_int(s)
if n > 0 {
return n
}
@@ -124,6 +125,7 @@ fn page(sold: Int, total: Int) -> String {
+ safety()
+ environmental()
+ pricing(sold, total)
+ marketplace()
+ viral()
+ footer()
+ page_close()
@@ -148,6 +150,24 @@ fn read_asset(abs_path: String) -> String {
fn handle_request(method: String, path: String, body: String) -> String {
let src_dir: String = state_get("__src_dir__")
// Root serve El-generated landing page
if str_eq(path, "/") {
let index_path: String = state_get("__html_file__")
if !str_eq(index_path, "") {
return fs_read(index_path)
}
}
// llms.txt for AI crawlers (Perplexity, ChatGPT, Google SGE)
if str_eq(path, "/llms.txt") {
return fs_read(src_dir + "/llms.txt")
}
// robots.txt
if str_eq(path, "/robots.txt") {
return "User-agent: *\nAllow: /\nSitemap: https://neurontechnologies.ai/sitemap.xml\n"
}
// About page
if str_eq(path, "/about") {
let about_path: String = state_get("__about_html_file__")
@@ -181,6 +201,9 @@ fn handle_request(method: String, path: String, body: String) -> String {
if str_contains(path, "plan=professional") {
plan = "professional"
}
if str_contains(path, "plan=free") {
plan = "free"
}
let pub_key: String = state_get("__stripe_publishable_key__")
return page_open() + checkout_page(plan, pub_key) + page_close()
}
@@ -203,10 +226,11 @@ fn handle_request(method: String, path: String, body: String) -> String {
+ "&currency=usd"
+ "&payment_method_types[]=card"
+ "&metadata[plan]=" + plan
let auth_header: String = "Bearer " + stripe_key
let response: String = http_post_form_auth(
"https://api.stripe.com/v1/payment_intents",
stripe_key,
pi_body
pi_body,
auth_header
)
return response
}
@@ -227,6 +251,17 @@ fn handle_request(method: String, path: String, body: String) -> String {
return "{\"sold\":" + sold_s + ",\"total\":" + total_s + ",\"remaining\":" + rem_s + "}"
}
// Static assets: /assets/*
if str_starts_with(path, "/assets/") {
let rel: String = str_slice(path, 8, str_len(path))
let abs: String = src_dir + "/assets/" + rel
let content: String = read_asset(abs)
if str_eq(content, "") {
return "{\"__status__\":404,\"error\":\"not found\"}"
}
return content
}
// Brand assets: /brand/*
if str_starts_with(path, "/brand/") {
let rel: String = str_slice(path, 7, str_len(path))
@@ -269,10 +304,11 @@ fn handle_request(method: String, path: String, body: String) -> String {
+ "&cancel_url=" + origin + "/#pricing"
+ "&allow_promotion_codes=true"
+ "&metadata[plan]=" + plan
let auth_hdr: String = "Bearer " + stripe_key
let response: String = http_post_form_auth(
"https://api.stripe.com/v1/checkout/sessions",
stripe_key,
form_body
form_body,
auth_hdr
)
if str_contains(response, "\"url\"") {
return response
@@ -302,6 +338,37 @@ fn handle_request(method: String, path: String, body: String) -> String {
return "{\"received\":true}"
}
// Supabase public config
if str_eq(path, "/api/supabase-config") {
let proj_url: String = "https://ocojsghaonltunidkzpw.supabase.co"
let anon_key: String = state_get("__supabase_anon_key__")
return "{\"url\":\"" + proj_url + "\",\"anon_key\":\"" + anon_key + "\"}"
}
// Demo chat proxies to the demo soul at 7772
if str_eq(path, "/api/demo") {
if str_eq(method, "POST") {
let msg: String = json_get(body, "message")
if str_eq(msg, "") {
return "{\"error\":\"message required\"}"
}
// Escape the message for embedding in JSON strings
let msg_safe: String = str_replace(str_replace(msg, "\\", "\\\\"), "\"", "\\\"")
// Build inner content: {"event_type":"chat","payload":{"message":"..."}}
let inner: String = "{\"event_type\":\"chat\",\"payload\":{\"message\":\"" + msg_safe + "\"}}"
// Escape inner for the outer content field
let inner_safe: String = str_replace(str_replace(inner, "\\", "\\\\"), "\"", "\\\"")
// Build dharma envelope
let envelope: String = "{\"channel\":\"ntn-demo\",\"from\":\"ntn-site\",\"content\":\"" + inner_safe + "\"}"
let resp: String = http_post("http://localhost:7772/dharma/recv", envelope)
if str_eq(resp, "") {
return "{\"error\":\"demo soul not responding\"}"
}
return resp
}
return "{\"error\":\"POST required\"}"
}
// Stripe webhook
if str_eq(path, "/api/webhooks/stripe") {
if str_contains(body, "checkout.session.completed") {
@@ -352,7 +419,8 @@ fn handle_request(method: String, path: String, body: String) -> String {
// 3. Generate all HTML with the real count
// 4. Register with El HTTP runtime and serve
let src_dir: String = cwd() + "/src"
let landing_root: String = env("LANDING_ROOT")
let src_dir: String = if str_eq(landing_root, "") { cwd() + "/src" } else { landing_root }
let html_path: String = src_dir + "/index.html"
// Stripe config from environment loaded first so founding count can use it.
@@ -362,6 +430,7 @@ let stripe_price_founding: String = env("STRIPE_PRICE_FOUNDING")
let stripe_price_professional: String = env("STRIPE_PRICE_PROFESSIONAL")
let license_api_url: String = env("NEURON_LICENSE_API_URL")
let resend_api_key: String = env("RESEND_API_KEY")
let supabase_anon_key: String = env("SUPABASE_ANON_KEY")
// Origin drives Stripe redirect URLs; never hardcoded to localhost.
let neuron_origin: String = env("NEURON_ORIGIN")
@@ -400,6 +469,7 @@ state_set("__stripe_price_founding__", stripe_price_founding)
state_set("__stripe_price_professional__", stripe_price_professional)
state_set("__license_api_url__", license_api_url)
state_set("__resend_api_key__", resend_api_key)
state_set("__supabase_anon_key__", supabase_anon_key)
state_set("__origin__", neuron_origin)
state_set("__founding_sold_file__", sold_file)
state_set("__founding_sold__", int_to_str(real_sold))
@@ -425,6 +495,9 @@ println(" POST /api/webhooks/stripe → Stripe webhook")
println(" GET /marketplace/success → post-purchase success page")
println(" GET /assets/* → static files")
println(" GET /brand/* → brand files")
println(" GET /api/supabase-config → public Supabase config (URL + anon key)")
println("")
http_serve(3001)
let port: Int = if str_eq(env("PORT"), "") { 3001 } else { str_to_int(env("PORT")) }
http_set_handler("handle_request")
http_serve(port, "handle_request")
+142
View File
@@ -0,0 +1,142 @@
// components/marketplace.el - Marketplace section.
// Explains the plugin marketplace - what it is, how it works, coming soon.
fn marketplace() -> String {
return "
<section id=\"marketplace\" aria-label=\"Neuron Marketplace\">
<div class=\"container\">
<div class=\"marketplace-header\">
<div class=\"marketplace-label-row reveal\">
<div class=\"navy-line-left\" style=\"width:4rem;flex-shrink:0\"></div>
<span class=\"label\" style=\"color:var(--navy-85)\">Marketplace</span>
<div style=\"margin-left:1rem;background:rgba(0,82,160,.1);color:var(--navy);font-family:var(--body);font-size:0.65rem;font-weight:500;letter-spacing:0.12em;text-transform:uppercase;padding:0.25rem 0.75rem;border-radius:2px\">Coming soon</div>
</div>
<h2 class=\"display-lg reveal\" style=\"transition-delay:80ms;max-width:38rem\">
Extend Neuron.<span class=\"gold\" style=\"display:block\">Build for it.</span>
</h2>
<p class=\"reveal\" style=\"transition-delay:160ms;font-weight:300;font-size:.9375rem;color:var(--t2);line-height:1.75;max-width:36rem;margin-top:1.25rem\">
Neuron does one thing exceptionally well: it knows you. The Marketplace extends what it can do with that knowledge - connecting it to your tools, your workflows, and capabilities built by people who understand your domain better than any general-purpose AI ever will.
</p>
</div>
<div class=\"marketplace-grid reveal\" style=\"transition-delay:200ms\">
<div class=\"marketplace-card card-dark\">
<div class=\"marketplace-card-icon\">
<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">
<path d=\"M12 2L2 7l10 5 10-5-10-5z\"/><path d=\"M2 17l10 5 10-5\"/><path d=\"M2 12l10 5 10-5\"/>
</svg>
</div>
<h3 class=\"display-md marketplace-card-title\">Plugins that know you</h3>
<p class=\"marketplace-card-body\">Every plugin in the Marketplace has access to your memory graph - with your permission. A legal plugin knows your deal history. A coding plugin knows your architecture decisions. An email plugin knows your relationships and communication style. The context travels with you.</p>
</div>
<div class=\"marketplace-card card-dark\" style=\"transition-delay:120ms\">
<div class=\"marketplace-card-icon\">
<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">
<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 8v4l3 3\"/>
</svg>
</div>
<h3 class=\"display-md marketplace-card-title\">Built by domain experts</h3>
<p class=\"marketplace-card-body\">General AI is good at general things. The Marketplace is for specialists. The person building a plugin for contract attorneys or orthopedic surgeons or professional traders isn&#39;t us. It&#39;s someone who has spent years in that world. We give them the platform. They bring the depth.</p>
</div>
<div class=\"marketplace-card card-dark\" style=\"transition-delay:240ms\">
<div class=\"marketplace-card-icon\">
<svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">
<path d=\"M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6\"/>
</svg>
</div>
<h3 class=\"display-md marketplace-card-title\">Revenue for builders</h3>
<p class=\"marketplace-card-body\">Developers earn recurring revenue when users install their plugins. We handle billing, distribution, and the infrastructure. You handle the product. Every plugin that ships earns you a share of every subscription for as long as that user stays. Build once, earn indefinitely.</p>
</div>
</div>
<div class=\"marketplace-categories reveal\" style=\"transition-delay:320ms\">
<p class=\"label\" style=\"margin-bottom:1.5rem;color:var(--navy-65)\">Planned on launch</p>
<div class=\"marketplace-tags\">
<span class=\"marketplace-tag\">IDE (VS Code, Cursor)</span>
<span class=\"marketplace-tag\">Slack &amp; Teams</span>
<span class=\"marketplace-tag\">GitHub</span>
<span class=\"marketplace-tag\">Linear</span>
<span class=\"marketplace-tag\">Notion</span>
<span class=\"marketplace-tag\">Legal research</span>
<span class=\"marketplace-tag\">Financial analysis</span>
<span class=\"marketplace-tag\">Healthcare</span>
<span class=\"marketplace-tag\">More by launch</span>
</div>
</div>
<div class=\"marketplace-cta reveal\" style=\"transition-delay:400ms\">
<div class=\"marketplace-cta-inner\">
<div>
<p style=\"font-family:var(--body);font-weight:500;font-size:1rem;color:var(--t1);margin-bottom:0.5rem\">Building something?</p>
<p style=\"font-family:var(--body);font-weight:300;font-size:0.875rem;color:var(--t2);line-height:1.6\">The developer program opens before the Marketplace does. If you&#39;re interested in building a plugin, get in touch early - early developers shape the API.</p>
</div>
<a href=\"mailto:developers@neurontechnologies.ai\" class=\"btn-ghost\" style=\"white-space:nowrap;flex-shrink:0\">Developer interest &rarr;</a>
</div>
</div>
</div>
</section>
<style>
#marketplace { padding: 6rem 0; }
.marketplace-header { margin-bottom: 4rem; }
.marketplace-label-row { display: flex; align-items: center; gap: 1.5rem; margin-bottom: 2rem; }
.marketplace-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
margin-bottom: 3rem;
}
@media (max-width: 900px) { .marketplace-grid { grid-template-columns: 1fr; } }
.marketplace-card {
padding: 2rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.marketplace-card-icon {
width: 2.5rem;
height: 2.5rem;
color: var(--navy);
opacity: 0.7;
}
.marketplace-card-title { margin: 0; }
.marketplace-card-body {
font-family: var(--body);
font-weight: 300;
font-size: 0.875rem;
color: var(--t2);
line-height: 1.75;
margin: 0;
}
.marketplace-categories { margin-bottom: 3rem; }
.marketplace-tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.marketplace-tag {
font-family: var(--body);
font-size: 0.75rem;
font-weight: 400;
color: var(--t2);
background: rgba(0,82,160,.06);
border: 1px solid rgba(0,82,160,.12);
padding: 0.375rem 0.875rem;
letter-spacing: 0.02em;
}
.marketplace-cta-inner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 2rem;
padding: 2rem 2.5rem;
border: 1px solid rgba(0,82,160,.18);
background: rgba(0,82,160,.02);
}
@media (max-width: 640px) { .marketplace-cta-inner { flex-direction: column; align-items: flex-start; } }
</style>
"
}
+1 -1
View File
@@ -47,7 +47,7 @@ fn mission() -> String {
That&#39;s the difference. <strong style=\"color:var(--t1)\">They&#39;re optimizing for the enterprise. I&#39;m building for the people those enterprises are supposed to serve.</strong>
</p>
<p>
I told them I could build and distribute this by myself. Maybe they didn&#39;t believe me. That meeting was April 22nd, 2026. I&#39;m writing this on April 25th. You&#39;re looking at the proof. <a href=\"/marketplace/plans\">I hope you&#39;ll download it.</a>
I told them I could build and distribute this by myself. Maybe they didn&#39;t believe me. That meeting was April 22nd, 2026. I&#39;m writing this on April 25th. You&#39;re looking at the proof. <a href=\"/checkout?plan=founding\">I hope you&#39;ll preorder it.</a>
</p>
</div>
+1
View File
@@ -15,6 +15,7 @@ fn nav() -> String {
<a href=\"/#safety\" class=\"nav-link\">Safety</a>
<a href=\"/#environmental\" class=\"nav-link\">Environment</a>
<a href=\"/#pricing\" class=\"nav-link\">Pricing</a>
<a href=\"/#marketplace\" class=\"nav-link\">Marketplace</a>
<a href=\"/#enterprise\" class=\"nav-link\">Enterprise</a>
<a href=\"/about\" class=\"nav-link\">About</a>
<a href=\"/#share\" class=\"nav-link cta\">Share Neuron &#8594;</a>
+8 -5
View File
@@ -61,7 +61,7 @@ fn pricing(sold: Int, total: Int) -> String {
</ul>
<div style=\"flex:1\"></div>
<div class=\"pricing-cta pricing-cta-ghost\">
<a href=\"https://github.com/neuron-technologies/neuron\">Download free &#8594;</a>
<button class=\"pricing-cta-ghost\" data-checkout=\"free\">Preorder free tier &#8594;</button>
</div>
</div>
@@ -83,7 +83,7 @@ fn pricing(sold: Int, total: Int) -> String {
</ul>
<div style=\"flex:1\"></div>
<div class=\"pricing-cta pricing-cta-navy\">
<button class=\"pricing-cta-navy\" data-checkout=\"professional\">Get Started &#8594;</button>
<button class=\"pricing-cta-navy\" data-checkout=\"professional\">Preorder &#8594;</button>
</div>
</div>
@@ -110,7 +110,7 @@ fn pricing(sold: Int, total: Int) -> String {
<div style=\"flex:1\"></div>
<div class=\"pricing-cta pricing-cta-solid\">
<button class=\"pricing-cta-solid\" data-checkout=\"founding\">Claim your spot &#8594;</button>
<button class=\"pricing-cta-solid\" data-checkout=\"founding\">Preorder claim your spot &#8594;</button>
</div>
</div>
@@ -125,11 +125,14 @@ fn pricing(sold: Int, total: Int) -> String {
</div>
<div class=\"founding-banner-bar\"><div class=\"founding-banner-fill\" style=\"width:" + pct_str + "%\"></div></div>
</div>
<button class=\"btn-primary\" data-checkout=\"founding\" style=\"white-space:nowrap\">Claim spot &#8594;</button>
<button class=\"btn-primary\" data-checkout=\"founding\" style=\"white-space:nowrap\">Preorder &#8594;</button>
</div>
<p class=\"pricing-fine reveal\" style=\"margin-top:2.5rem\">
Neuron inference on all plans &nbsp;&middot;&nbsp; Bring your own keys if you want &nbsp;&middot;&nbsp; Your data stays yours &nbsp;&middot;&nbsp; Same support for every user
Bring your own API keys &nbsp;&middot;&nbsp; Local inference via Ollama &nbsp;&middot;&nbsp; Neuron Inference coming soon &nbsp;&middot;&nbsp; Your data stays yours
</p>
<p class=\"pricing-fine reveal\" style=\"margin-top:1rem;font-size:0.8rem\">
Includes 2 devices per plan &nbsp;&middot;&nbsp; Additional devices available at a small extra cost &nbsp;&middot;&nbsp; We&#39;re not greedy
</p>
<div class=\"reveal\" style=\"margin-top:3rem;padding:1.5rem 2rem;border:1px solid rgba(0,82,160,.18);border-radius:8px;background:rgba(0,82,160,.03);\">
+416
View File
@@ -1385,6 +1385,190 @@ fn page_open() -> String {
.delay-700 { transition-delay: 700ms !important; }
.delay-800 { transition-delay: 800ms !important; }
/* NEURON DEMO CHAT WIDGET */
#neuron-demo-btn {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 9999;
}
#neuron-demo-btn button {
display: flex;
align-items: center;
gap: 0.625rem;
background: var(--navy);
color: #fff;
border: none;
cursor: pointer;
padding: 0.875rem 1.5rem;
font-family: var(--body);
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 0.14em;
text-transform: uppercase;
box-shadow: 0 4px 24px rgba(0,82,160,.35);
transition: background 300ms, box-shadow 300ms, transform 200ms;
}
#neuron-demo-btn button:hover {
background: #0078D4;
box-shadow: 0 6px 32px rgba(0,82,160,.45);
transform: translateY(-1px);
}
#neuron-demo-btn img {
width: 20px;
height: 20px;
object-fit: contain;
filter: brightness(0) invert(1);
}
#neuron-demo-panel {
position: fixed;
bottom: 5.5rem;
right: 2rem;
z-index: 9998;
width: 32rem;
max-width: calc(100vw - 2rem);
background: var(--card);
border: 1px solid rgba(0,82,160,.20);
box-shadow: 0 16px 64px rgba(0,0,0,.15), 0 4px 16px rgba(0,82,160,.12);
display: flex;
flex-direction: column;
max-height: 70vh;
animation: demoSlideIn 200ms cubic-bezier(0.16,1,0.3,1) both;
}
@keyframes demoSlideIn {
from { opacity: 0; transform: translateY(16px) scale(0.97); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
#neuron-demo-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.25rem;
background: var(--navy);
color: #fff;
flex-shrink: 0;
}
#neuron-demo-header-left {
display: flex;
align-items: center;
gap: 0.625rem;
}
#neuron-demo-header-left img {
width: 18px;
height: 18px;
object-fit: contain;
filter: brightness(0) invert(1);
opacity: 0.9;
}
#neuron-demo-header span {
font-family: var(--body);
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
}
#neuron-demo-header-sub {
font-family: var(--body);
font-size: 0.625rem;
letter-spacing: 0.08em;
color: rgba(255,255,255,.60);
text-transform: uppercase;
margin-top: 0.1rem;
}
#neuron-demo-close {
background: none;
border: none;
color: rgba(255,255,255,.7);
font-size: 1.25rem;
line-height: 1;
cursor: pointer;
padding: 0.25rem;
transition: color 200ms;
flex-shrink: 0;
}
#neuron-demo-close:hover { color: #fff; }
#neuron-demo-messages {
flex: 1;
overflow-y: auto;
padding: 1.25rem 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
min-height: 12rem;
max-height: 30rem;
scrollbar-width: thin;
}
.demo-msg {
max-width: 92%;
font-family: var(--body);
font-size: 0.875rem;
line-height: 1.6;
}
.demo-msg-user {
align-self: flex-end;
background: var(--navy);
color: #fff;
padding: 0.75rem 1rem;
border-radius: 0;
}
.demo-msg-ai {
align-self: flex-start;
background: var(--bg2);
color: var(--t1);
padding: 0.875rem 1.125rem;
border-left: 2px solid rgba(0,82,160,.30);
}
.demo-msg-ai p { margin: 0; }
.demo-msg-ai p + p { margin-top: 0.75rem; }
.demo-msg-ai ul, .demo-msg-ai ol { margin: 0.5rem 0 0.5rem 1.25rem; }
.demo-msg-ai li + li { margin-top: 0.25rem; }
.demo-msg-ai strong { font-weight: 600; color: var(--t1); }
.demo-msg-thinking {
align-self: flex-start;
color: var(--t3);
font-size: 0.75rem;
letter-spacing: 0.08em;
font-style: italic;
}
#neuron-demo-input-row {
display: flex;
border-top: 1px solid var(--border);
flex-shrink: 0;
}
#neuron-demo-text {
flex: 1;
font-family: var(--body);
font-size: 0.875rem;
color: var(--t1);
background: var(--bg);
border: none;
outline: none;
padding: 0.875rem 1rem;
}
#neuron-demo-text::placeholder { color: var(--t3); }
#neuron-demo-send {
flex-shrink: 0;
background: var(--navy);
color: #fff;
border: none;
cursor: pointer;
padding: 0.875rem 1.25rem;
font-family: var(--body);
font-size: 0.7rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
transition: background 200ms;
}
#neuron-demo-send:hover { background: #0078D4; }
#neuron-demo-send:disabled { opacity: 0.5; cursor: not-allowed; }
.text-gradient-gold {
background: linear-gradient(135deg, #003d7a 0%, #0078D4 50%, #0052A0 100%);
-webkit-background-clip: text;
@@ -1407,7 +1591,137 @@ fn page_open() -> String {
button[disabled] { opacity: 0.6; cursor: not-allowed; }
</style>
<script src=\"https://cdn.jsdelivr.net/npm/marked/marked.min.js\"></script>
<noscript><style>.reveal { opacity: 1 !important; transform: none !important; }</style></noscript>
<!-- Google Analytics -->
<script async src=\"https://www.googletagmanager.com/gtag/js?id=G-Y1EE43X9RN\"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-Y1EE43X9RN');
</script>
<!-- Open Graph -->
<meta property=\"og:type\" content=\"website\">
<meta property=\"og:url\" content=\"https://neurontechnologies.ai\">
<meta property=\"og:title\" content=\"Neuron - The AI That Remembers You\">
<meta property=\"og:description\" content=\"Every other AI forgets you. Neuron doesn&#39;t. Runs on your machine, builds a memory graph over time, and gets sharper the longer you use it. Built by one person. April 22, 2026 — the meeting. April 25 — you&#39;re looking at the proof.\">
<meta property=\"og:image\" content=\"https://neurontechnologies.ai/assets/brand/neuron-wordmark-on-light@2x.png\">
<!-- Twitter / X -->
<meta name=\"twitter:card\" content=\"summary_large_image\">
<meta name=\"twitter:title\" content=\"Neuron - The AI That Remembers You\">
<meta name=\"twitter:description\" content=\"Every other AI forgets you. Neuron doesn&#39;t. Runs on your machine. Remembers everything. $19/mo or $199 founding member (first 1,000).\">
<meta name=\"twitter:image\" content=\"https://neurontechnologies.ai/assets/brand/neuron-wordmark-on-light@2x.png\">
<!-- Canonical -->
<link rel=\"canonical\" href=\"https://neurontechnologies.ai\">
<!-- Structured data GEO: Organization + SoftwareApplication + FAQPage -->
<script type=\"application/ld+json\">
{
\"@context\": \"https://schema.org\",
\"@graph\": [
{
\"@type\": \"Organization\",
\"name\": \"Neuron Technologies\",
\"url\": \"https://neurontechnologies.ai\",
\"founder\": {
\"@type\": \"Person\",
\"name\": \"Will Anderson\",
\"jobTitle\": \"Founder\"
},
\"description\": \"Neuron Technologies builds AI that runs on your machine, builds a memory graph over time, and gets sharper the longer you use it. One builder. Built different.\",
\"foundingDate\": \"2026\",
\"sameAs\": [\"https://github.com/neuron-technologies\"]
},
{
\"@type\": \"SoftwareApplication\",
\"name\": \"Neuron\",
\"applicationCategory\": \"AIApplication\",
\"operatingSystem\": \"macOS, Windows, Linux\",
\"offers\": [
{
\"@type\": \"Offer\",
\"name\": \"Free\",
\"price\": \"0\",
\"priceCurrency\": \"USD\"
},
{
\"@type\": \"Offer\",
\"name\": \"Professional\",
\"price\": \"19\",
\"priceCurrency\": \"USD\",
\"billingIncrement\": \"monthly\"
},
{
\"@type\": \"Offer\",
\"name\": \"Founding Member\",
\"description\": \"Lifetime access for the first 1,000 members.\",
\"price\": \"199\",
\"priceCurrency\": \"USD\"
}
],
\"description\": \"The AI that remembers you. Runs locally on your machine. Builds a persistent memory graph over every conversation. Gets sharper the longer you use it. Your data never leaves your device.\",
\"featureList\": [
\"Persistent memory graph runs locally, never resets\",
\"Bring your own API keys (OpenAI, Anthropic, Groq)\",
\"Local inference via Ollama free, offline, zero cloud\",
\"Neuron Inference coming soon priced below major APIs\",
\"Two devices included per plan\",
\"Enterprise deployment Q1 2027\"
]
},
{
\"@type\": \"FAQPage\",
\"mainEntity\": [
{
\"@type\": \"Question\",
\"name\": \"What is Neuron?\",
\"acceptedAnswer\": {
\"@type\": \"Answer\",
\"text\": \"Neuron is an AI that runs on your machine and builds a persistent memory graph over time. Every other AI forgets you when you close the tab. Neuron doesn&#39;t. The longer you use it, the less you have to explain.\"
}
},
{
\"@type\": \"Question\",
\"name\": \"Does Neuron send my data to the cloud?\",
\"acceptedAnswer\": {
\"@type\": \"Answer\",
\"text\": \"No. Your memory graph lives on your machine and never leaves it. Neuron does not collect your data, train on your conversations, or require cloud storage. For inference you choose: local via Ollama, your own API keys, or Neuron Inference (coming soon).\"
}
},
{
\"@type\": \"Question\",
\"name\": \"How much does Neuron cost?\",
\"acceptedAnswer\": {
\"@type\": \"Answer\",
\"text\": \"Neuron has a free tier that never expires. Professional is $19/month. Founding Member is $199 lifetime available to the first 1,000 members only. All plans include two devices.\"
}
},
{
\"@type\": \"Question\",
\"name\": \"Who built Neuron?\",
\"acceptedAnswer\": {
\"@type\": \"Answer\",
\"text\": \"Will Anderson. On April 22nd, 2026 he had a meeting with one of the largest technology companies in the world. Within two days their lawyers were engaged. He decided to build it himself. On April 25th he published the proof.\"
}
},
{
\"@type\": \"Question\",
\"name\": \"When does Neuron launch?\",
\"acceptedAnswer\": {
\"@type\": \"Answer\",
\"text\": \"Neuron is available for preorder now. Enterprise deployment launches Q1 2027.\"
}
}
]
}
]
}
</script>
</head>
<body>
"
@@ -1498,6 +1812,108 @@ fn page_close() -> String {
})();
</script>
<!-- Neuron Demo Chat Widget -->
<div id=\"neuron-demo-btn\">
<button onclick=\"neuronDemoToggle()\" aria-label=\"Chat with Neuron\">
<img src=\"/assets/neuron-icon.png\" alt=\"\">
Try Neuron
</button>
</div>
<div id=\"neuron-demo-panel\" style=\"display:none\">
<div id=\"neuron-demo-header\">
<div id=\"neuron-demo-header-left\">
<img src=\"/assets/neuron-icon.png\" alt=\"Neuron\">
<div>
<span>Neuron</span>
<div id=\"neuron-demo-header-sub\">Live Demo</div>
</div>
</div>
<button onclick=\"neuronDemoToggle()\" aria-label=\"Close\">&#x2715;</button>
</div>
<div id=\"neuron-demo-messages\"></div>
<div id=\"neuron-demo-input-row\">
<input type=\"text\" id=\"neuron-demo-text\" placeholder=\"Ask me anything...\" autocomplete=\"off\">
<button id=\"neuron-demo-send\" onclick=\"neuronDemoSend()\">Send</button>
</div>
</div>
<script>
(function() {
var isOpen = false;
var msgCount = 0;
var MAX = 10;
window.neuronDemoToggle = function() {
isOpen = !isOpen;
var panel = document.getElementById('neuron-demo-panel');
if (panel) panel.style.display = isOpen ? 'flex' : 'none';
var msgs = document.getElementById('neuron-demo-messages');
if (isOpen && msgs && msgs.children.length === 0) {
addMsg('ai', 'Hi! How are you?');
}
var input = document.getElementById('neuron-demo-text');
if (isOpen && input) input.focus();
};
function addMsg(role, text) {
var msgs = document.getElementById('neuron-demo-messages');
if (!msgs) return null;
var el = document.createElement('div');
el.className = 'demo-msg demo-msg-' + role;
if (role === 'ai' && typeof marked !== 'undefined') {
try { el.innerHTML = marked.parse(text); } catch(e) { el.textContent = text; }
} else {
el.textContent = text;
}
msgs.appendChild(el);
msgs.scrollTop = msgs.scrollHeight;
return el;
}
window.neuronDemoSend = async function() {
if (msgCount >= MAX) return;
var input = document.getElementById('neuron-demo-text');
var btn = document.getElementById('neuron-demo-send');
if (!input || btn.disabled) return;
var msg = input.value.trim();
if (!msg) return;
input.value = '';
btn.disabled = true;
addMsg('user', msg);
var thinking = addMsg('thinking', 'thinking...');
if (thinking) thinking.className = 'demo-msg demo-msg-thinking';
msgCount++;
if (msgCount >= MAX && input) {
input.disabled = true;
input.placeholder = 'Interaction limit reached';
}
try {
var r = await fetch('/api/demo', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({message: msg})
});
var d = await r.json();
if (thinking) thinking.remove();
addMsg('ai', d.response || d.reply || d.message || 'No response');
} catch(e) {
if (thinking) thinking.remove();
addMsg('ai', 'Connection error. Try again.');
}
if (msgCount < MAX && btn) btn.disabled = false;
if (input) input.focus();
};
var inp = document.getElementById('neuron-demo-text');
if (inp) {
inp.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); window.neuronDemoSend(); }
});
}
})();
</script>
</body>
</html>
"
+1
View File
@@ -35,6 +35,7 @@ fn terms_body() -> String {
<h2 style=\"font-family:var(--head);font-size:1.25rem;font-weight:600;color:var(--t1)\">What You Can Do With It</h2>
</div>
<p style=\"font-family:var(--body);font-weight:300;font-size:0.9375rem;color:var(--t2);line-height:1.8;margin-bottom:1rem\">You can install and use Neuron on devices you own or control. That&#39;s the license. Personal, non-transferable.</p>
<p style=\"font-family:var(--body);font-weight:300;font-size:0.9375rem;color:var(--t2);line-height:1.8;margin-bottom:1rem\">Each plan includes <strong style=\"color:var(--t1);font-weight:500\">two devices</strong>. Additional devices are available at a small extra cost. We&#39;re not greedy about it &mdash; two covers most people, and if you need more, you can add them.</p>
<p style=\"font-family:var(--body);font-weight:300;font-size:0.9375rem;color:var(--t2);line-height:1.8;margin-bottom:1rem\">The free tier doesn&#39;t expire. Paid licenses are what they say they are. Founding Member licenses are perpetual - you bought it, you own it. I won&#39;t change that.</p>
<p style=\"font-family:var(--body);font-weight:300;font-size:0.9375rem;color:var(--t2);line-height:1.8\">You can&#39;t resell it, sublicense it, or redistribute it without asking first. If you want to do something creative with it, ask. The answer might be yes.</p>
</div>