// Generated by Bux C Backend v2
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef const char* String;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;
typedef signed char int8;
typedef short int16;
typedef long long int64;
typedef float float32;
typedef double float64;
typedef char char8;

void* bux_alloc(unsigned int size);
void bux_free(void* ptr);

typedef struct TaskHandle TaskHandle;
typedef struct Mutex Mutex;
typedef struct RwLock RwLock;
typedef struct JsonValue JsonValue;
typedef struct JsonParser JsonParser;
typedef struct StringBuilder StringBuilder;
typedef struct Channel_int Channel_int;
typedef struct Channel_float64 Channel_float64;

typedef enum {
    Result_Ok,
    Result_Err
} Result_Tag;

typedef union {
    int Ok_0;
    String Err_0;
} Result_Data;

typedef struct {
    Result_Tag tag;
    Result_Data data;
} Result;

typedef enum {
    Option_Some,
    Option_None
} Option_Tag;

typedef union {
    int Some_0;
} Option_Data;

typedef struct {
    Option_Tag tag;
    Option_Data data;
} Option;

typedef enum {
    JwtAlg_HS256,
    JwtAlg_HS384,
    JwtAlg_HS512,
    JwtAlg_RS256,
    JwtAlg_RS384,
    JwtAlg_RS512,
    JwtAlg_ES256,
    JwtAlg_ES384,
    JwtAlg_EdDSA
} JwtAlg_Tag;

typedef struct {
    JwtAlg_Tag tag;
} JwtAlg;

#define JsonTagNull 0
#define JsonTagBool 1
#define JsonTagNumber 2
#define JsonTagString 3
#define JsonTagArray 4
#define JsonTagObject 5
#define AES_KEY_SIZE 32
#define AES_IV_SIZE 16
#define AES_GCM_TAG_SIZE 16
#define ED25519_PUBKEY_SIZE 32
#define ED25519_PRIVKEY_SIZE 32
#define ED25519_SIG_SIZE 64

struct TaskHandle {
    void* handle;
};

struct Mutex {
    void* handle;
};

struct RwLock {
    void* handle;
};

struct JsonValue {
    int tag;
    bool boolVal;
    float64 numVal;
    String strVal;
    JsonValue* arrData;
    uint arrLen;
    uint arrCap;
    String* objKeys;
    JsonValue* objValues;
    uint objLen;
    uint objCap;
};

struct JsonParser {
    String src;
    uint pos;
    uint len;
    String error;
};

struct StringBuilder {
    void* handle;
};

struct Channel_int {
    void* handle;
};

struct Channel_float64 {
    void* handle;
};

bool DirExists(String path);
bool Mkdir(String path);
String* ListDir(String dir, String ext, int* count);
String ReadFile(String path);
bool WriteFile(String path, String content);
bool FileExists(String path);
float64 Sqrt(float64 x);
float64 Pow(float64 x, float64 y);
int64 Abs(int64 n);
float64 AbsF(float64 f);
int64 Min(int64 a, int64 b);
int64 Max(int64 a, int64 b);
float64 MinF(float64 a, float64 b);
float64 MaxF(float64 a, float64 b);
void* Alloc(uint size);
void* Realloc(void* ptr, uint size);
void Free(void* ptr);
bool MemEq(void* a, void* b, uint size);
String Path_Join(String a, String b);
String Path_Parent(String path);
String Path_Ext(String path);
void Task_Init(int num_workers);
TaskHandle Task_Spawn(void* fn, void* arg);
void Task_Wait(TaskHandle t);
void Task_Sleep(int64 ms);
void Task_Yield();
int Task_CurrentId();
void Task_Shutdown();
int Os_ArgsCount();
String Os_Args(int index);
String Os_GetEnv(String name);
bool Os_SetEnv(String name, String value);
String Os_GetCwd();
bool Os_Chdir(String path);
int64 Time_NowMs();
int64 Time_NowUs();
void Time_SleepMs(int64 ms);
int Process_Run(String cmd);
String Process_Output(String cmd);
int Net_Create();
bool Net_SetReuse(int fd);
bool Net_Bind(int fd, String addr, int port);
bool Net_Listen(int fd, int backlog);
int Net_Accept(int fd);
bool Net_Connect(int fd, String addr, int port);
int Net_Send(int fd, String data);
String Net_Recv(int fd, int maxLen);
bool Net_Close(int fd);
String Net_LastError();
String Fmt_Fmt3(String tmpl, String a1, String a2, String a3);
String Fmt_Fmt2(String tmpl, String a1, String a2);
String Fmt_FmtFloat(String tmpl, float64 val);
String Fmt_FmtBool(String tmpl, bool val);
String Fmt_FmtInt(String tmpl, int64 val);
String Fmt_Fmt1(String tmpl, String a1);
String Fmt_Format(String tmpl, String* argStrs, int argCount);
String Crypto_Sha256(String data);
String Crypto_HmacSha256(String key, String message);
String Crypto_RandomBytes(int n);
String Crypto_Base64Encode(String s);
String Crypto_HmacSha256Raw(String key, String message);
String Crypto_Base64Decode(String s);
Mutex Mutex_New();
void Mutex_Lock(Mutex* m);
void Mutex_Unlock(Mutex* m);
void Mutex_Free(Mutex* m);
RwLock RwLock_New();
void RwLock_ReadLock(RwLock* rw);
void RwLock_WriteLock(RwLock* rw);
void RwLock_Unlock(RwLock* rw);
void RwLock_Free(RwLock* rw);
void Test_Exit(int code);
void Test_Assert(bool cond);
void Test_AssertEqInt(int a, int b);
void Test_AssertTrue(bool cond);
void Test_AssertFalse(bool cond);
void Test_Fail(String msg);
Result Result_NewOk(int value);
Result Result_NewErr(String msg);
bool Result_IsOk(Result r);
bool Result_IsErr(Result r);
int Result_Unwrap(Result r);
int Result_UnwrapOr(Result r, int fallback);
Option Option_NewSome(int value);
Option Option_NewNone();
bool Option_IsSome(Option o);
bool Option_IsNone(Option o);
int Option_Unwrap(Option o);
int Option_UnwrapOr(Option o, int fallback);
JsonValue Json_Null();
JsonValue Json_Bool(bool b);
JsonValue Json_Number(float64 n);
JsonValue Json_String(String s);
JsonValue Json_Array();
JsonValue Json_Object();
uint Json_ArrayLen(JsonValue v);
JsonValue Json_ArrayGet(JsonValue v, uint index);
void Json_ArrayPush(JsonValue* self, JsonValue val);
uint Json_ObjectLen(JsonValue v);
JsonValue Json_ObjectGet(JsonValue v, String key);
bool Json_ObjectHas(JsonValue v, String key);
void Json_ObjectSet(JsonValue* self, String key, JsonValue val);
bool Json_IsNull(JsonValue v);
bool Json_AsBool(JsonValue v);
float64 Json_AsNumber(JsonValue v);
String Json_AsString(JsonValue v);
int JsonParser_Peek(JsonParser* p);
void JsonParser_Advance(JsonParser* p);
void JsonParser_SkipWhitespace(JsonParser* p);
bool JsonParser_Match(JsonParser* p, String expected);
String JsonParser_ParseString(JsonParser* p);
JsonValue JsonParser_ParseNumber(JsonParser* p);
JsonValue JsonParser_ParseArray(JsonParser* p);
JsonValue JsonParser_ParseObject(JsonParser* p);
JsonValue JsonParser_ParseValue(JsonParser* p);
JsonValue Json_Parse(String s);
void Json_StringifyImpl(StringBuilder* sb, JsonValue v);
String Json_Stringify(JsonValue v);
String Hash_Sha1(String data);
String Hash_Sha256(String data);
String Hash_Sha384(String data);
String Hash_Sha512(String data);
void Hash_Sha256Raw(String data, void* out);
void Hash_Sha384Raw(String data, void* out);
void Hash_Sha512Raw(String data, void* out);
int Hash_Sha1Size();
int Hash_Sha256Size();
int Hash_Sha384Size();
int Hash_Sha512Size();
String Base64_Encode(String s);
String Base64_Decode(String s);
String Base64URL_Encode(String s);
String Base64URL_Decode(String s);
String Hmac_Sha256(String key, String message);
void Hmac_Sha256Raw(String key, String message, void* out);
String Hmac_Sha256Base64(String key, String message);
String Hmac_Sha384(String key, String message);
void Hmac_Sha384Raw(String key, String message, void* out);
String Hmac_Sha384Base64(String key, String message);
String Hmac_Sha512(String key, String message);
void Hmac_Sha512Raw(String key, String message, void* out);
String Hmac_Sha512Base64(String key, String message);
String Random_Bytes(int n);
String Random_Hex(int n);
String Random_Base64(int n);
uint Random_Uint32();
String Aes_GenerateKey();
String Aes_GenerateIV();
String Aes_CbcEncrypt(String plain, String key, String iv);
String Aes_CbcDecrypt(String cipher, String key, String iv);
String Aes_GcmEncrypt(String plain, String key, String iv, void* tag);
String Aes_GcmDecrypt(String cipher, String key, String iv, String tag);
String Jwt_MakeHeader(JwtAlg alg);
String Jwt_Sign(JwtAlg alg, String signingInput, String key);
bool Jwt_Verify(JwtAlg alg, String signingInput, String signatureB64, String key);
String Jwt_Encode(String headerJson, String payloadJson, JwtAlg alg, String key);
bool Jwt_Decode(String token, JwtAlg alg, String key, String* headerOut, String* payloadOut);
String Jwt_EncodeHS256(String payloadJson, String secret);
String Jwt_EncodeHS384(String payloadJson, String secret);
String Jwt_EncodeHS512(String payloadJson, String secret);
String Jwt_EncodeRS256(String payloadJson, String pemPrivateKey);
String Jwt_EncodeES256(String payloadJson, String pemPrivateKey);
String Jwt_EncodeEdDSA(String payloadJson, String rawPrivKey);
String Ecdsa_SignP256(String pemPrivateKey, String data);
String Ecdsa_SignP256Base64(String pemPrivateKey, String data);
bool Ecdsa_VerifyP256(String pemPublicKey, String data, String signature);
bool Ecdsa_VerifyP256Base64(String pemPublicKey, String data, String signatureB64);
String Ecdsa_SignP384(String pemPrivateKey, String data);
String Ecdsa_SignP384Base64(String pemPrivateKey, String data);
bool Ecdsa_VerifyP384(String pemPublicKey, String data, String signature);
bool Ecdsa_VerifyP384Base64(String pemPublicKey, String data, String signatureB64);
bool Ed25519_Keypair(void* pubKey, void* privKey);
String Ed25519_KeypairBase64();
String Ed25519_Sign(String privKey, String data);
String Ed25519_SignBase64(String privKey, String data);
bool Ed25519_Verify(String pubKey, String signature, String data);
bool Ed25519_VerifyBase64(String pubKey, String signatureB64, String data);
String Rsa_SignSha256(String pemPrivateKey, String data);
String Rsa_SignSha384(String pemPrivateKey, String data);
String Rsa_SignSha512(String pemPrivateKey, String data);
String Rsa_SignSha256Base64(String pemPrivateKey, String data);
String Rsa_SignSha384Base64(String pemPrivateKey, String data);
String Rsa_SignSha512Base64(String pemPrivateKey, String data);
bool Rsa_VerifySha256(String pemPublicKey, String data, String signature);
bool Rsa_VerifySha384(String pemPublicKey, String data, String signature);
bool Rsa_VerifySha512(String pemPublicKey, String data, String signature);
bool Rsa_VerifySha256Base64(String pemPublicKey, String data, String signatureB64);
bool Rsa_VerifySha384Base64(String pemPublicKey, String data, String signatureB64);
bool Rsa_VerifySha512Base64(String pemPublicKey, String data, String signatureB64);
uint String_Len(String s);
bool String_IsNull(String s);
bool String_Eq(String a, String b);
String String_Concat(String a, String b);
String String_Copy(String s);
bool String_StartsWith(String s, String prefix);
bool String_EndsWith(String s, String suffix);
bool String_Contains(String s, String substr);
String String_Slice(String s, uint start, uint len);
String String_Trim(String s);
String String_TrimLeft(String s);
String String_TrimRight(String s);
String String_FromInt(int64 n);
int64 String_ToInt(String s);
StringBuilder StringBuilder_New();
StringBuilder StringBuilder_NewCap(uint cap);
void StringBuilder_Append(StringBuilder* sb, String s);
void StringBuilder_AppendInt(StringBuilder* sb, int64 n);
void StringBuilder_AppendFloat(StringBuilder* sb, float64 f);
void StringBuilder_AppendChar(StringBuilder* sb, char8 c);
String StringBuilder_Build(StringBuilder* sb);
void StringBuilder_Free(StringBuilder* sb);
uint String_SplitCount(String s, String delim);
String String_SplitPart(String s, String delim, uint index);
String String_Join2(String a, String b, String sep);
String String_Chars(String s, uint index);
String String_Find(String haystack, String needle);
uint String_Offset(String pos, String base);
String String_Replace(String s, String old, String new);
float64 String_ToFloat(String s);
String String_FromBool(bool b);
String String_FromFloat(float64 f);
String String_Format1(String pattern, String a0);
String String_Format2(String pattern, String a0, String a1);
String String_Format3(String pattern, String a0, String a1, String a2);
void Channel_SendInt(Channel_int* ch, int value);
int Channel_RecvInt(Channel_int* ch);
void Channel_SendFloat64(Channel_float64* ch, float64 value);
float64 Channel_RecvFloat64(Channel_float64* ch);
int Main();

int bux_dir_exists(String path);
int bux_mkdir_if_needed(String path);
String* bux_list_dir(String dir, String ext, int* out_count);
void PrintLine(String s);
void Print(String s);
void PrintInt(int n);
void PrintInt64(int64 n);
void PrintFloat(float64 f);
void PrintBool(bool b);
String ReadLine();
String bux_read_file(String path);
int bux_write_file(String path, String content);
int bux_file_exists(String path);
float64 bux_sqrt(float64 x);
float64 bux_pow(float64 x, float64 y);
int64 bux_abs_i64(int64 x);
float64 bux_abs_f64(float64 x);
int64 bux_min_i64(int64 a, int64 b);
int64 bux_max_i64(int64 a, int64 b);
float64 bux_min_f64(float64 a, float64 b);
float64 bux_max_f64(float64 a, float64 b);
void* bux_alloc(uint size);
void* bux_realloc(void* ptr, uint size);
void bux_free(void* ptr);
int bux_mem_eq(void* a, void* b, uint size);
String bux_path_join(String a, String b);
String bux_path_parent(String path);
String bux_path_ext(String path);
void bux_task_init(int num_workers);
void* bux_task_spawn(void* fn, void* arg);
void bux_task_join(void* handle);
void bux_task_sleep(int64 ms);
void bux_task_yield();
int bux_task_current_id();
void bux_task_shutdown();
int bux_argc();
String bux_argv(int index);
String bux_getenv(String name);
int bux_setenv(String name, String value);
String bux_getcwd();
int bux_chdir(String path);
int64 bux_time_ms();
int64 bux_time_us();
void bux_sleep_ms(int64 ms);
int bux_process_run(String cmd);
String bux_process_output(String cmd);
int bux_socket_create();
int bux_socket_reuse(int fd);
int bux_socket_bind(int fd, String addr, int port);
int bux_socket_listen(int fd, int backlog);
int bux_socket_accept(int fd);
int bux_socket_connect(int fd, String addr, int port);
int bux_socket_send(int fd, String data, int len);
String bux_socket_recv(int fd, int maxLen);
int bux_socket_close(int fd);
String bux_socket_error();
void* bux_alloc(uint size);
int64 bux_str_to_int(String s);
uint bux_strlen(String s);
void bux_sha256(String data, int len, void* out);
void bux_hmac_sha256(String key, int keylen, String msg, int msglen, void* out);
int bux_random_bytes(void* buf, int len);
String bux_base64_encode(String data, int len);
String bux_base64_decode(String data, int len, int* outlen);
String bux_bytes_to_hex(void* data, int len);
void* bux_mutex_new();
void bux_mutex_lock(void* handle);
void bux_mutex_unlock(void* handle);
void bux_mutex_free(void* handle);
void* bux_rwlock_new();
void bux_rwlock_rdlock(void* handle);
void bux_rwlock_wrlock(void* handle);
void bux_rwlock_unlock(void* handle);
void bux_rwlock_free(void* handle);
void bux_exit(int code);
void bux_assert(int cond, String file, int line, String expr);
void bux_sha1(String data, int len, void* out);
void bux_sha256(String data, int len, void* out);
void bux_sha384(String data, int len, void* out);
void bux_sha512(String data, int len, void* out);
String bux_bytes_to_hex(void* data, int len);
String bux_base64_encode(String data, int len);
String bux_base64_decode(String data, int len, int* outlen);
String bux_base64url_encode(String data, int len);
String bux_base64url_decode(String data, int len, int* outlen);
void bux_hmac_sha256(String key, int keylen, String msg, int msglen, void* out);
void bux_hmac_sha384(String key, int keylen, String msg, int msglen, void* out);
void bux_hmac_sha512(String key, int keylen, String msg, int msglen, void* out);
String bux_bytes_to_hex(void* data, int len);
String bux_base64_encode(String data, int len);
int bux_random_bytes(void* buf, int len);
String bux_base64_encode(String data, int len);
String bux_bytes_to_hex(void* data, int len);
int bux_random_bytes(void* buf, int len);
String bux_aes_256_cbc_encrypt(String plain, int plainlen, String key, String iv, int* outlen);
String bux_aes_256_cbc_decrypt(String cipher, int cipherlen, String key, String iv, int* outlen);
String bux_aes_256_gcm_encrypt(String plain, int plainlen, String key, String iv, void* tag, int* outlen);
String bux_aes_256_gcm_decrypt(String cipher, int cipherlen, String key, String iv, String tag, int* outlen);
String bux_base64_encode(String data, int len);
uint bux_str_split_count(String s, String delim);
String bux_str_split_part(String s, String delim, uint index);
String bux_ecdsa_sign_p256(String key, int keylen, String data, int datalen, int* outlen);
int bux_ecdsa_verify_p256(String key, int keylen, String data, int datalen, String sig, int siglen);
String bux_ecdsa_sign_p384(String key, int keylen, String data, int datalen, int* outlen);
int bux_ecdsa_verify_p384(String key, int keylen, String data, int datalen, String sig, int siglen);
String bux_base64_encode(String data, int len);
String bux_base64_decode(String data, int len, int* outlen);
int bux_ed25519_keypair(void* pubKey, void* privKey);
int bux_ed25519_sign(String privKey, String data, int datalen, void* sig);
int bux_ed25519_verify(String pubKey, String sig, String data, int datalen);
String bux_base64_encode(String data, int len);
String bux_base64_decode(String data, int len, int* outlen);
String bux_rsa_sign_sha256(String key, int keylen, String data, int datalen, int* outlen);
String bux_rsa_sign_sha384(String key, int keylen, String data, int datalen, int* outlen);
String bux_rsa_sign_sha512(String key, int keylen, String data, int datalen, int* outlen);
int bux_rsa_verify_sha256(String key, int keylen, String data, int datalen, String sig, int siglen);
int bux_rsa_verify_sha384(String key, int keylen, String data, int datalen, String sig, int siglen);
int bux_rsa_verify_sha512(String key, int keylen, String data, int datalen, String sig, int siglen);
String bux_base64_encode(String data, int len);
String bux_base64_decode(String data, int len, int* outlen);
uint bux_strlen(String s);
int bux_strcmp(String a, String b);
int bux_strncmp(String a, String b, uint n);
char8* bux_strcpy(char8* dest, String src);
char8* bux_strcat(char8* dest, String src);
char8* bux_strncpy(char8* dest, String src, uint n);
String bux_strstr(String haystack, String needle);
int bux_str_contains(String haystack, String needle);
uint bux_str_offset(String pos, String base);
int bux_str_is_null(String s);
String bux_str_slice(String s, uint start, uint len);
String bux_str_trim_left(String s);
String bux_str_trim_right(String s);
String bux_str_trim(String s);
String bux_int_to_str(int64 n);
int64 bux_str_to_int(String s);
void* bux_sb_new(uint initial_cap);
void bux_sb_append(void* sb, String s);
void bux_sb_append_int(void* sb, int64 n);
void bux_sb_append_float(void* sb, float64 f);
void bux_sb_append_char(void* sb, char8 c);
String bux_sb_build(void* sb);
void bux_sb_free(void* sb);
uint bux_str_split_count(String s, String delim);
String bux_str_split_part(String s, String delim, uint index);
String bux_str_join2(String a, String b, String sep);
String bux_float_to_string(float64 f);
String bux_str_format(String pattern, String a0, String a1, String a2, String a3, String a4, String a5, String a6, String a7);
float64 bux_str_to_float(String s);
void bux_bounds_check(uint index, uint len);
void* bux_alloc(uint size);
void* bux_realloc(void* ptr, uint size);
void bux_free(void* ptr);
void bux_bounds_check(uint index, uint len);
void* bux_channel_new(int64 capacity, int64 elem_size);
void bux_channel_send(void* handle, void* elem);
int bux_channel_recv(void* handle, void* out);
void bux_channel_close(void* handle);
void bux_channel_free(void* handle);
uint bux_hash_bytes(void* ptr, uint size);
uint bux_hash_string(String s);
uint bux_hash_bytes(void* ptr, uint size);
int bux_mem_eq(void* a, void* b, uint size);
void* bux_alloc(uint size);
void bux_free(void* ptr);

bool DirExists(String path) {
    return bux_dir_exists(path) != 0;

}

bool Mkdir(String path) {
    return bux_mkdir_if_needed(path) != 0;

}

String* ListDir(String dir, String ext, int* count) {
    return bux_list_dir(dir, ext, count);

}

String ReadFile(String path) {
    return bux_read_file(path);

}

bool WriteFile(String path, String content) {
    int r = bux_write_file(path, content);
    return r != 0;

}

bool FileExists(String path) {
    int r = bux_file_exists(path);
    return r != 0;

}

float64 Sqrt(float64 x) {
    return bux_sqrt(x);

}

float64 Pow(float64 x, float64 y) {
    return bux_pow(x, y);

}

int64 Abs(int64 n) {
    return bux_abs_i64(n);

}

float64 AbsF(float64 f) {
    return bux_abs_f64(f);

}

int64 Min(int64 a, int64 b) {
    return bux_min_i64(a, b);

}

int64 Max(int64 a, int64 b) {
    return bux_max_i64(a, b);

}

float64 MinF(float64 a, float64 b) {
    return bux_min_f64(a, b);

}

float64 MaxF(float64 a, float64 b) {
    return bux_max_f64(a, b);

}

void* Alloc(uint size) {
    return bux_alloc(size);

}

void* Realloc(void* ptr, uint size) {
    return bux_realloc(ptr, size);

}

void Free(void* ptr) {
    bux_free(ptr);

}

bool MemEq(void* a, void* b, uint size) {
    return bux_mem_eq(a, b, size) != 0;

}

String Path_Join(String a, String b) {
    return bux_path_join(a, b);

}

String Path_Parent(String path) {
    return bux_path_parent(path);

}

String Path_Ext(String path) {
    return bux_path_ext(path);

}

void Task_Init(int num_workers) {
    bux_task_init(num_workers);

}

TaskHandle Task_Spawn(void* fn, void* arg) {
    return ((TaskHandle){.handle = bux_task_spawn(fn, arg)});

}

void Task_Wait(TaskHandle t) {
    bux_task_join(t.handle);

}

void Task_Sleep(int64 ms) {
    bux_task_sleep(ms);

}

void Task_Yield() {
    bux_task_yield();

}

int Task_CurrentId() {
    return bux_task_current_id();

}

void Task_Shutdown() {
    bux_task_shutdown();

}

int Os_ArgsCount() {
    return bux_argc();

}

String Os_Args(int index) {
    return bux_argv(index);

}

String Os_GetEnv(String name) {
    return bux_getenv(name);

}

bool Os_SetEnv(String name, String value) {
    return bux_setenv(name, value) == 0;

}

String Os_GetCwd() {
    return bux_getcwd();

}

bool Os_Chdir(String path) {
    return bux_chdir(path) == 0;

}

int64 Time_NowMs() {
    return bux_time_ms();

}

int64 Time_NowUs() {
    return bux_time_us();

}

void Time_SleepMs(int64 ms) {
    bux_sleep_ms(ms);

}

int Process_Run(String cmd) {
    return bux_process_run(cmd);

}

String Process_Output(String cmd) {
    return bux_process_output(cmd);

}

int Net_Create() {
    return bux_socket_create();

}

bool Net_SetReuse(int fd) {
    return bux_socket_reuse(fd) == 0;

}

bool Net_Bind(int fd, String addr, int port) {
    return bux_socket_bind(fd, addr, port) == 0;

}

bool Net_Listen(int fd, int backlog) {
    return bux_socket_listen(fd, backlog) == 0;

}

int Net_Accept(int fd) {
    return bux_socket_accept(fd);

}

bool Net_Connect(int fd, String addr, int port) {
    return bux_socket_connect(fd, addr, port) == 0;

}

int Net_Send(int fd, String data) {
    return bux_socket_send(fd, data, ((int)bux_strlen(data)));

}

String Net_Recv(int fd, int maxLen) {
    return bux_socket_recv(fd, maxLen);

}

bool Net_Close(int fd) {
    return bux_socket_close(fd) == 0;

}

String Net_LastError() {
    return bux_socket_error();

}

String Fmt_Fmt3(String tmpl, String a1, String a2, String a3) {
    String* args = ((String*)bux_alloc(3 * sizeof(String)));
    args[0] = a1;
    args[1] = a2;
    args[2] = a3;
    return Fmt_Format(tmpl, args, 3);

}

String Fmt_Fmt2(String tmpl, String a1, String a2) {
    String* args = ((String*)bux_alloc(2 * sizeof(String)));
    args[0] = a1;
    args[1] = a2;
    return Fmt_Format(tmpl, args, 2);

}

String Fmt_FmtFloat(String tmpl, float64 val) {
    String s = String_FromFloat(val);
    return Fmt_Fmt1(tmpl, s);

}

String Fmt_FmtBool(String tmpl, bool val) {
    String s = String_FromBool(val);
    return Fmt_Fmt1(tmpl, s);

}

String Fmt_FmtInt(String tmpl, int64 val) {
    String s = String_FromInt(val);
    return Fmt_Fmt1(tmpl, s);

}

String Fmt_Fmt1(String tmpl, String a1) {
    String* args = ((String*)bux_alloc(sizeof(String)));
    args[0] = a1;
    return Fmt_Format(tmpl, args, 1);

}

String Fmt_Format(String tmpl, String* argStrs, int argCount) {
    StringBuilder sb = StringBuilder_New();
    uint i = 0;
    uint tmplLen = bux_strlen(tmpl);
    while (i < tmplLen) {
        String ch = String_Chars(tmpl, i);
        if (String_Eq(ch, "{")) {
            uint digitIdx = i + 1;
            if (digitIdx < tmplLen) {
                String digitCh = String_Chars(tmpl, digitIdx);
                int64 d = bux_str_to_int(digitCh);
                if (d >= 0 && d < ((int64)argCount)) {
                    i = i + 2;
                    if (i < tmplLen) {
                        String closeCh = String_Chars(tmpl, i);
                        if (String_Eq(closeCh, "}")) {
                            i = i + 1;
                            String argStr = argStrs[((uint)d)];
                            StringBuilder_Append(&sb, argStr);
                            continue;
                        }

                    }

                }

            }

        }

        StringBuilder_Append(&sb, ch);
        i = i + 1;
    }
    return StringBuilder_Build(&sb);

}

String Crypto_Sha256(String data) {
    int len = ((int)String_Len(data));
    void* hashBuf = Alloc(32);
    bux_sha256(data, len, hashBuf);
    String result = bux_bytes_to_hex(((void*)hashBuf), 32);
    Free(hashBuf);
    return result;

}

String Crypto_HmacSha256(String key, String message) {
    int keylen = ((int)String_Len(key));
    int msglen = ((int)String_Len(message));
    void* hmacBuf = Alloc(32);
    bux_hmac_sha256(key, keylen, message, msglen, hmacBuf);
    String result = bux_bytes_to_hex(((void*)hmacBuf), 32);
    Free(hmacBuf);
    return result;

}

String Crypto_RandomBytes(int n) {
    if (n <= 0) {
        return "";
    }

    void* buf = Alloc(((uint)n));
    if (bux_random_bytes(buf, n) != 1) {
        Free(buf);
        return "";
    }

    String result = bux_base64_encode(((String)buf), n);
    Free(buf);
    return result;

}

String Crypto_Base64Encode(String s) {
    return bux_base64_encode(s, ((int)String_Len(s)));

}

String Crypto_HmacSha256Raw(String key, String message) {
    int keylen = ((int)String_Len(key));
    int msglen = ((int)String_Len(message));
    void* hmacBuf = Alloc(32);
    bux_hmac_sha256(key, keylen, message, msglen, hmacBuf);
    String result = bux_base64_encode(((String)hmacBuf), 32);
    Free(hmacBuf);
    return result;

}

String Crypto_Base64Decode(String s) {
    int outlen = 0;
    return bux_base64_decode(s, ((int)String_Len(s)), &outlen);

}

Mutex Mutex_New() {
    return ((Mutex){.handle = bux_mutex_new()});

}

void Mutex_Lock(Mutex* m) {
    bux_mutex_lock(m->handle);

}

void Mutex_Unlock(Mutex* m) {
    bux_mutex_unlock(m->handle);

}

void Mutex_Free(Mutex* m) {
    bux_mutex_free(m->handle);

}

RwLock RwLock_New() {
    return ((RwLock){.handle = bux_rwlock_new()});

}

void RwLock_ReadLock(RwLock* rw) {
    bux_rwlock_rdlock(rw->handle);

}

void RwLock_WriteLock(RwLock* rw) {
    bux_rwlock_wrlock(rw->handle);

}

void RwLock_Unlock(RwLock* rw) {
    bux_rwlock_unlock(rw->handle);

}

void RwLock_Free(RwLock* rw) {
    bux_rwlock_free(rw->handle);

}

void Test_Exit(int code) {
    bux_exit(code);

}

void Test_Assert(bool cond) {
    bux_assert(((int)cond), "", 0, "");

}

void Test_AssertEqInt(int a, int b) {
    if (a != b) {
        PrintLine("ASSERT_EQ FAILED:");
        PrintInt(a);
        PrintLine(" != ");
        PrintInt(b);
        bux_exit(1);
    }


}

void Test_AssertTrue(bool cond) {
    if (!cond) {
        PrintLine("ASSERT_TRUE FAILED");
        bux_exit(1);
    }


}

void Test_AssertFalse(bool cond) {
    if (cond) {
        PrintLine("ASSERT_FALSE FAILED");
        bux_exit(1);
    }


}

void Test_Fail(String msg) {
    PrintLine("FAIL:");
    PrintLine(msg);
    bux_exit(1);

}

Result Result_NewOk(int value) {
    Result r = ((Result){.tag = Result_Ok});
    r.data.Ok_0 = value;
    return r;

}

Result Result_NewErr(String msg) {
    Result r = ((Result){.tag = Result_Err});
    r.data.Err_0 = msg;
    return r;

}

bool Result_IsOk(Result r) {
    return r.tag == Result_Ok;

}

bool Result_IsErr(Result r) {
    return r.tag == Result_Err;

}

int Result_Unwrap(Result r) {
    if (r.tag != Result_Ok) {
        PrintLine("panic: unwrap on Err");
        return 0;
    }

    return r.data.Ok_0;

}

int Result_UnwrapOr(Result r, int fallback) {
    if (r.tag == Result_Ok) {
        return r.data.Ok_0;
    }

    return fallback;

}

Option Option_NewSome(int value) {
    Option o = ((Option){.tag = Option_Some});
    o.data.Some_0 = value;
    return o;

}

Option Option_NewNone() {
    return ((Option){.tag = Option_None});

}

bool Option_IsSome(Option o) {
    return o.tag == Option_Some;

}

bool Option_IsNone(Option o) {
    return o.tag == Option_None;

}

int Option_Unwrap(Option o) {
    if (o.tag != Option_Some) {
        PrintLine("panic: unwrap on None");
        return 0;
    }

    return o.data.Some_0;

}

int Option_UnwrapOr(Option o, int fallback) {
    if (o.tag == Option_Some) {
        return o.data.Some_0;
    }

    return fallback;

}

JsonValue Json_Null() {
    return ((JsonValue){.tag = JsonTagNull, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0});

}

JsonValue Json_Bool(bool b) {
    return ((JsonValue){.tag = JsonTagBool, .boolVal = b, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0});

}

JsonValue Json_Number(float64 n) {
    return ((JsonValue){.tag = JsonTagNumber, .boolVal = false, .numVal = n, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0});

}

JsonValue Json_String(String s) {
    return ((JsonValue){.tag = JsonTagString, .boolVal = false, .numVal = 0.0, .strVal = s, .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0});

}

JsonValue Json_Array() {
    return ((JsonValue){.tag = JsonTagArray, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0});

}

JsonValue Json_Object() {
    return ((JsonValue){.tag = JsonTagObject, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0});

}

uint Json_ArrayLen(JsonValue v) {
    if (v.tag != JsonTagArray) {
        return 0;
    }

    return v.arrLen;

}

JsonValue Json_ArrayGet(JsonValue v, uint index) {
    if (v.tag != JsonTagArray) {
        return Json_Null();
    }

    if (index >= v.arrLen) {
        return Json_Null();
    }

    return v.arrData[index];

}

void Json_ArrayPush(JsonValue* self, JsonValue val) {
    if (self->tag != JsonTagArray) {
        return;
    }

    if (self->arrLen >= self->arrCap) {
        uint arrNewCap = self->arrCap;
        if (arrNewCap == 0) {
            self->arrCap = 4;
            self->arrData = ((JsonValue*)Alloc(4 * sizeof(JsonValue)));
        } else {
            uint doubleCap = arrNewCap * 2;
            self->arrCap = doubleCap;
            self->arrData = ((JsonValue*)Realloc(((void*)self->arrData), doubleCap * sizeof(JsonValue)));
        }

    }

    self->arrData[self->arrLen] = val;
    self->arrLen = self->arrLen + 1;

}

uint Json_ObjectLen(JsonValue v) {
    if (v.tag != JsonTagObject) {
        return 0;
    }

    return v.objLen;

}

JsonValue Json_ObjectGet(JsonValue v, String key) {
    if (v.tag != JsonTagObject) {
        return Json_Null();
    }

    uint i = 0;
    while (i < v.objLen) {
        if (String_Eq(v.objKeys[i], key)) {
            return v.objValues[i];
        }

        i = i + 1;
    }
    return Json_Null();

}

bool Json_ObjectHas(JsonValue v, String key) {
    if (v.tag != JsonTagObject) {
        return false;
    }

    uint i = 0;
    while (i < v.objLen) {
        if (String_Eq(v.objKeys[i], key)) {
            return true;
        }

        i = i + 1;
    }
    return false;

}

void Json_ObjectSet(JsonValue* self, String key, JsonValue val) {
    if (self->tag != JsonTagObject) {
        return;
    }

    uint i = 0;
    while (i < self->objLen) {
        if (String_Eq(self->objKeys[i], key)) {
            self->objValues[i] = val;
            return;
        }

        i = i + 1;
    }
    if (self->objLen >= self->objCap) {
        uint objNewCap = self->objCap;
        if (objNewCap == 0) {
            self->objCap = 4;
            self->objKeys = ((String*)Alloc(4 * sizeof(String)));
            self->objValues = ((JsonValue*)Alloc(4 * sizeof(JsonValue)));
        } else {
            uint doubleCap = objNewCap * 2;
            self->objCap = doubleCap;
            self->objKeys = ((String*)Realloc(((void*)self->objKeys), doubleCap * sizeof(String)));
            self->objValues = ((JsonValue*)Realloc(((void*)self->objValues), doubleCap * sizeof(JsonValue)));
        }

    }

    self->objKeys[self->objLen] = key;
    self->objValues[self->objLen] = val;
    self->objLen = self->objLen + 1;

}

bool Json_IsNull(JsonValue v) {
    return v.tag == JsonTagNull;

}

bool Json_AsBool(JsonValue v) {
    if (v.tag == JsonTagBool) {
        return v.boolVal;
    }

    return false;

}

float64 Json_AsNumber(JsonValue v) {
    if (v.tag == JsonTagNumber) {
        return v.numVal;
    }

    return 0.0;

}

String Json_AsString(JsonValue v) {
    if (v.tag == JsonTagString) {
        return v.strVal;
    }

    return "";

}

int JsonParser_Peek(JsonParser* p) {
    if (p->pos >= p->len) {
        return 0;
    }

    return ((int)p->src[p->pos]);

}

void JsonParser_Advance(JsonParser* p) {
    if (p->pos < p->len) {
        p->pos = p->pos + 1;
    }


}

void JsonParser_SkipWhitespace(JsonParser* p) {
    while (true) {
        int c = JsonParser_Peek(p);
        if (c == 32 || c == 9 || c == 10 || c == 13) {
            JsonParser_Advance(p);
        } else {
            return;
        }

    }

}

bool JsonParser_Match(JsonParser* p, String expected) {
    uint elen = String_Len(expected);
    if (p->pos + elen > p->len) {
        return false;
    }

    uint i = 0;
    while (i < elen) {
        if (p->src[p->pos + i] != expected[i]) {
            return false;
        }

        i = i + 1;
    }
    p->pos = p->pos + elen;
    return true;

}

String JsonParser_ParseString(JsonParser* p) {
    if (JsonParser_Peek(p) != 34) {
        p->error = "Expected string";
        return "";
    }

    JsonParser_Advance(p);
    StringBuilder sb = StringBuilder_New();
    while (true) {
        int c = JsonParser_Peek(p);
        if (c == 0 || c == 34) {
            break;
        }

        if (c == 92) {
            JsonParser_Advance(p);
            int esc = JsonParser_Peek(p);
            if (esc == 0) {
                p->error = "Unterminated string escape";
                StringBuilder_Free(&sb);
                return "";
            }

            if (esc == 110) {
                StringBuilder_AppendChar(&sb, ((char8)10));
            } else {
                if (esc == 116) {
                    StringBuilder_AppendChar(&sb, ((char8)9));
                } else {
                    if (esc == 114) {
                        StringBuilder_AppendChar(&sb, ((char8)13));
                    } else {
                        if (esc == 98) {
                            StringBuilder_AppendChar(&sb, ((char8)8));
                        } else {
                            if (esc == 102) {
                                StringBuilder_AppendChar(&sb, ((char8)12));
                            } else {
                                if (esc == 34) {
                                    StringBuilder_AppendChar(&sb, ((char8)34));
                                } else {
                                    if (esc == 92) {
                                        StringBuilder_AppendChar(&sb, ((char8)92));
                                    } else {
                                        StringBuilder_AppendChar(&sb, ((char8)92));
                                        StringBuilder_AppendChar(&sb, ((char8)esc));
                                    }

                                }

                            }

                        }

                    }

                }

            }

            JsonParser_Advance(p);
        } else {
            StringBuilder_AppendChar(&sb, ((char8)c));
            JsonParser_Advance(p);
        }

    }
    if (JsonParser_Peek(p) != 34) {
        p->error = "Unterminated string";
        StringBuilder_Free(&sb);
        return "";
    }

    JsonParser_Advance(p);
    String result = StringBuilder_Build(&sb);
    StringBuilder_Free(&sb);
    return result;

}

JsonValue JsonParser_ParseNumber(JsonParser* p) {
    uint start = p->pos;
    int c0 = JsonParser_Peek(p);
    if (c0 == 45) {
        JsonParser_Advance(p);
    }

    while (true) {
        int c = JsonParser_Peek(p);
        if (c >= 48 && c <= 57) {
            JsonParser_Advance(p);
        } else {
            break;
        }

    }
    if (JsonParser_Peek(p) == 46) {
        JsonParser_Advance(p);
        while (true) {
            int c = JsonParser_Peek(p);
            if (c >= 48 && c <= 57) {
                JsonParser_Advance(p);
            } else {
                break;
            }

        }
    }

    String numStr = String_Slice(p->src, start, p->pos - start);
    float64 n = String_ToFloat(numStr);
    return Json_Number(n);

}

JsonValue JsonParser_ParseArray(JsonParser* p) {
    JsonParser_Advance(p);
    JsonValue arr = Json_Array();
    JsonParser_SkipWhitespace(p);
    if (JsonParser_Peek(p) == 93) {
        JsonParser_Advance(p);
        return arr;
    }

    while (true) {
        JsonParser_SkipWhitespace(p);
        JsonValue val = JsonParser_ParseValue(p);
        if (p->error != "") {
            return Json_Null();
        }

        Json_ArrayPush(&arr, val);
        JsonParser_SkipWhitespace(p);
        int c = JsonParser_Peek(p);
        if (c == 93) {
            JsonParser_Advance(p);
            return arr;
        }

        if (c == 44) {
            JsonParser_Advance(p);
        } else {
            p->error = "Expected ',' or ']' in array";
            return Json_Null();
        }

    }

}

JsonValue JsonParser_ParseObject(JsonParser* p) {
    JsonParser_Advance(p);
    JsonValue obj = Json_Object();
    JsonParser_SkipWhitespace(p);
    if (JsonParser_Peek(p) == 125) {
        JsonParser_Advance(p);
        return obj;
    }

    while (true) {
        JsonParser_SkipWhitespace(p);
        String key = JsonParser_ParseString(p);
        if (p->error != "") {
            return Json_Null();
        }

        JsonParser_SkipWhitespace(p);
        if (JsonParser_Peek(p) != 58) {
            p->error = "Expected ':' after object key";
            return Json_Null();
        }

        JsonParser_Advance(p);
        JsonParser_SkipWhitespace(p);
        JsonValue val = JsonParser_ParseValue(p);
        if (p->error != "") {
            return Json_Null();
        }

        Json_ObjectSet(&obj, key, val);
        JsonParser_SkipWhitespace(p);
        int c = JsonParser_Peek(p);
        if (c == 125) {
            JsonParser_Advance(p);
            return obj;
        }

        if (c == 44) {
            JsonParser_Advance(p);
        } else {
            p->error = "Expected ',' or '}' in object";
            return Json_Null();
        }

    }

}

JsonValue JsonParser_ParseValue(JsonParser* p) {
    JsonParser_SkipWhitespace(p);
    int c = JsonParser_Peek(p);
    if (c == 0) {
        p->error = "Unexpected end of input";
        return Json_Null();
    }

    if (c == 34) {
        return Json_String(JsonParser_ParseString(p));
    }

    if (c == 123) {
        return JsonParser_ParseObject(p);
    }

    if (c == 91) {
        return JsonParser_ParseArray(p);
    }

    if (c == 116) {
        if (JsonParser_Match(p, "true")) {
            return Json_Bool(true);
        }

        p->error = "Expected 'true'";
        return Json_Null();
    }

    if (c == 102) {
        if (JsonParser_Match(p, "false")) {
            return Json_Bool(false);
        }

        p->error = "Expected 'false'";
        return Json_Null();
    }

    if (c == 110) {
        if (JsonParser_Match(p, "null")) {
            return Json_Null();
        }

        p->error = "Expected 'null'";
        return Json_Null();
    }

    if (c >= 48 && c <= 57 || c == 45) {
        return JsonParser_ParseNumber(p);
    }

    p->error = "Unexpected character";
    return Json_Null();

}

JsonValue Json_Parse(String s) {
    JsonParser p = ((JsonParser){.src = s, .pos = 0, .len = String_Len(s), .error = ""});
    JsonValue result = JsonParser_ParseValue(&p);
    JsonParser_SkipWhitespace(&p);
    if (p.error == "" && p.pos != p.len) {
        p.error = "Trailing data after JSON value";
        return Json_Null();
    }

    return result;

}

void Json_StringifyImpl(StringBuilder* sb, JsonValue v) {
    if (v.tag == JsonTagNull) {
        StringBuilder_Append(sb, "null");
        return;
    }

    if (v.tag == JsonTagBool) {
        if (v.boolVal) {
            StringBuilder_Append(sb, "true");
        } else {
            StringBuilder_Append(sb, "false");
        }

        return;
    }

    if (v.tag == JsonTagNumber) {
        StringBuilder_AppendFloat(sb, v.numVal);
        return;
    }

    if (v.tag == JsonTagString) {
        StringBuilder_AppendChar(sb, ((char8)34));
        StringBuilder_Append(sb, v.strVal);
        StringBuilder_AppendChar(sb, ((char8)34));
        return;
    }

    if (v.tag == JsonTagArray) {
        StringBuilder_AppendChar(sb, ((char8)91));
        uint i = 0;
        while (i < v.arrLen) {
            if (i > 0) {
                StringBuilder_AppendChar(sb, ((char8)44));
            }

            Json_StringifyImpl(sb, v.arrData[i]);
            i = i + 1;
        }
        StringBuilder_AppendChar(sb, ((char8)93));
        return;
    }

    if (v.tag == JsonTagObject) {
        StringBuilder_AppendChar(sb, ((char8)123));
        uint i = 0;
        while (i < v.objLen) {
            if (i > 0) {
                StringBuilder_AppendChar(sb, ((char8)44));
            }

            StringBuilder_AppendChar(sb, ((char8)34));
            StringBuilder_Append(sb, v.objKeys[i]);
            StringBuilder_AppendChar(sb, ((char8)34));
            StringBuilder_AppendChar(sb, ((char8)58));
            Json_StringifyImpl(sb, v.objValues[i]);
            i = i + 1;
        }
        StringBuilder_AppendChar(sb, ((char8)125));
        return;
    }


}

String Json_Stringify(JsonValue v) {
    StringBuilder sb = StringBuilder_New();
    Json_StringifyImpl(&sb, v);
    return StringBuilder_Build(&sb);

}

String Hash_Sha1(String data) {
    int len = ((int)String_Len(data));
    void* buf = Alloc(20);
    bux_sha1(data, len, buf);
    String result = bux_bytes_to_hex(buf, 20);
    Free(buf);
    return result;

}

String Hash_Sha256(String data) {
    int len = ((int)String_Len(data));
    void* buf = Alloc(32);
    bux_sha256(data, len, buf);
    String result = bux_bytes_to_hex(buf, 32);
    Free(buf);
    return result;

}

String Hash_Sha384(String data) {
    int len = ((int)String_Len(data));
    void* buf = Alloc(48);
    bux_sha384(data, len, buf);
    String result = bux_bytes_to_hex(buf, 48);
    Free(buf);
    return result;

}

String Hash_Sha512(String data) {
    int len = ((int)String_Len(data));
    void* buf = Alloc(64);
    bux_sha512(data, len, buf);
    String result = bux_bytes_to_hex(buf, 64);
    Free(buf);
    return result;

}

void Hash_Sha256Raw(String data, void* out) {
    bux_sha256(data, ((int)String_Len(data)), out);

}

void Hash_Sha384Raw(String data, void* out) {
    bux_sha384(data, ((int)String_Len(data)), out);

}

void Hash_Sha512Raw(String data, void* out) {
    bux_sha512(data, ((int)String_Len(data)), out);

}

int Hash_Sha1Size() {
    return 20;

}

int Hash_Sha256Size() {
    return 32;

}

int Hash_Sha384Size() {
    return 48;

}

int Hash_Sha512Size() {
    return 64;

}

String Base64_Encode(String s) {
    return bux_base64_encode(s, ((int)String_Len(s)));

}

String Base64_Decode(String s) {
    int outlen = 0;
    return bux_base64_decode(s, ((int)String_Len(s)), &outlen);

}

String Base64URL_Encode(String s) {
    return bux_base64url_encode(s, ((int)String_Len(s)));

}

String Base64URL_Decode(String s) {
    int outlen = 0;
    return bux_base64url_decode(s, ((int)String_Len(s)), &outlen);

}

String Hmac_Sha256(String key, String message) {
    int kl = ((int)String_Len(key));
    int ml = ((int)String_Len(message));
    void* buf = Alloc(32);
    bux_hmac_sha256(key, kl, message, ml, buf);
    String result = bux_bytes_to_hex(buf, 32);
    Free(buf);
    return result;

}

void Hmac_Sha256Raw(String key, String message, void* out) {
    bux_hmac_sha256(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out);

}

String Hmac_Sha256Base64(String key, String message) {
    int kl = ((int)String_Len(key));
    int ml = ((int)String_Len(message));
    void* buf = Alloc(32);
    bux_hmac_sha256(key, kl, message, ml, buf);
    String result = bux_base64_encode(((String)buf), 32);
    Free(buf);
    return result;

}

String Hmac_Sha384(String key, String message) {
    int kl = ((int)String_Len(key));
    int ml = ((int)String_Len(message));
    void* buf = Alloc(48);
    bux_hmac_sha384(key, kl, message, ml, buf);
    String result = bux_bytes_to_hex(buf, 48);
    Free(buf);
    return result;

}

void Hmac_Sha384Raw(String key, String message, void* out) {
    bux_hmac_sha384(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out);

}

String Hmac_Sha384Base64(String key, String message) {
    int kl = ((int)String_Len(key));
    int ml = ((int)String_Len(message));
    void* buf = Alloc(48);
    bux_hmac_sha384(key, kl, message, ml, buf);
    String result = bux_base64_encode(((String)buf), 48);
    Free(buf);
    return result;

}

String Hmac_Sha512(String key, String message) {
    int kl = ((int)String_Len(key));
    int ml = ((int)String_Len(message));
    void* buf = Alloc(64);
    bux_hmac_sha512(key, kl, message, ml, buf);
    String result = bux_bytes_to_hex(buf, 64);
    Free(buf);
    return result;

}

void Hmac_Sha512Raw(String key, String message, void* out) {
    bux_hmac_sha512(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out);

}

String Hmac_Sha512Base64(String key, String message) {
    int kl = ((int)String_Len(key));
    int ml = ((int)String_Len(message));
    void* buf = Alloc(64);
    bux_hmac_sha512(key, kl, message, ml, buf);
    String result = bux_base64_encode(((String)buf), 64);
    Free(buf);
    return result;

}

String Random_Bytes(int n) {
    if (n <= 0) {
        return "";
    }

    void* buf = Alloc(((uint)n));
    if (bux_random_bytes(buf, n) != 1) {
        Free(buf);
        return "";
    }

    return ((String)buf);

}

String Random_Hex(int n) {
    if (n <= 0) {
        return "";
    }

    void* buf = Alloc(((uint)n));
    if (bux_random_bytes(buf, n) != 1) {
        Free(buf);
        return "";
    }

    String result = bux_bytes_to_hex(buf, n);
    Free(buf);
    return result;

}

String Random_Base64(int n) {
    if (n <= 0) {
        return "";
    }

    void* buf = Alloc(((uint)n));
    if (bux_random_bytes(buf, n) != 1) {
        Free(buf);
        return "";
    }

    String result = bux_base64_encode(((String)buf), n);
    Free(buf);
    return result;

}

uint Random_Uint32() {
    void* buf = Alloc(4);
    if (bux_random_bytes(buf, 4) != 1) {
        Free(buf);
        return 0;
    }

    uint* ptr = ((uint*)buf);
    uint val = *ptr;
    Free(buf);
    return val;

}

String Aes_GenerateKey() {
    void* buf = Alloc(((uint)AES_KEY_SIZE));
    if (bux_random_bytes(buf, AES_KEY_SIZE) != 1) {
        Free(buf);
        return "";
    }

    return ((String)buf);

}

String Aes_GenerateIV() {
    void* buf = Alloc(((uint)AES_IV_SIZE));
    if (bux_random_bytes(buf, AES_IV_SIZE) != 1) {
        Free(buf);
        return "";
    }

    return ((String)buf);

}

String Aes_CbcEncrypt(String plain, String key, String iv) {
    int outlen = 0;
    return bux_aes_256_cbc_encrypt(plain, ((int)String_Len(plain)), key, iv, &outlen);

}

String Aes_CbcDecrypt(String cipher, String key, String iv) {
    int outlen = 0;
    return bux_aes_256_cbc_decrypt(cipher, ((int)String_Len(cipher)), key, iv, &outlen);

}

String Aes_GcmEncrypt(String plain, String key, String iv, void* tag) {
    int outlen = 0;
    return bux_aes_256_gcm_encrypt(plain, ((int)String_Len(plain)), key, iv, tag, &outlen);

}

String Aes_GcmDecrypt(String cipher, String key, String iv, String tag) {
    int outlen = 0;
    return bux_aes_256_gcm_decrypt(cipher, ((int)String_Len(cipher)), key, iv, tag, &outlen);

}

String Jwt_MakeHeader(JwtAlg alg) {
    if (alg.tag == JwtAlg_HS256) {
        return "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_HS384) {
        return "{\"alg\":\"HS384\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_HS512) {
        return "{\"alg\":\"HS512\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_RS256) {
        return "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_RS384) {
        return "{\"alg\":\"RS384\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_RS512) {
        return "{\"alg\":\"RS512\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_ES256) {
        return "{\"alg\":\"ES256\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_ES384) {
        return "{\"alg\":\"ES384\",\"typ\":\"JWT\"}";
    }

    if (alg.tag == JwtAlg_EdDSA) {
        return "{\"alg\":\"EdDSA\",\"typ\":\"JWT\"}";
    }

    return "{\"alg\":\"none\",\"typ\":\"JWT\"}";

}

String Jwt_Sign(JwtAlg alg, String signingInput, String key) {
    if (alg.tag == JwtAlg_HS256) {
        void* buf = Alloc(32);
        Hmac_Sha256Raw(key, signingInput, buf);
        String result = bux_base64_encode(((String)buf), 32);
        Free(buf);
        return result;
    }

    if (alg.tag == JwtAlg_HS384) {
        void* buf = Alloc(48);
        Hmac_Sha384Raw(key, signingInput, buf);
        String result = bux_base64_encode(((String)buf), 48);
        Free(buf);
        return result;
    }

    if (alg.tag == JwtAlg_HS512) {
        void* buf = Alloc(64);
        Hmac_Sha512Raw(key, signingInput, buf);
        String result = bux_base64_encode(((String)buf), 64);
        Free(buf);
        return result;
    }

    if (alg.tag == JwtAlg_RS256) {
        String raw = Rsa_SignSha256(key, signingInput);
        return bux_base64_encode(raw, ((int)String_Len(raw)));
    }

    if (alg.tag == JwtAlg_RS384) {
        String raw = Rsa_SignSha384(key, signingInput);
        return bux_base64_encode(raw, ((int)String_Len(raw)));
    }

    if (alg.tag == JwtAlg_RS512) {
        String raw = Rsa_SignSha512(key, signingInput);
        return bux_base64_encode(raw, ((int)String_Len(raw)));
    }

    if (alg.tag == JwtAlg_ES256) {
        String raw = Ecdsa_SignP256(key, signingInput);
        return bux_base64_encode(raw, ((int)String_Len(raw)));
    }

    if (alg.tag == JwtAlg_ES384) {
        String raw = Ecdsa_SignP384(key, signingInput);
        return bux_base64_encode(raw, ((int)String_Len(raw)));
    }

    if (alg.tag == JwtAlg_EdDSA) {
        return Ed25519_Sign(key, signingInput);
    }

    return "";

}

bool Jwt_Verify(JwtAlg alg, String signingInput, String signatureB64, String key) {
    if (alg.tag == JwtAlg_HS256) {
        void* expectBuf = Alloc(32);
        Hmac_Sha256Raw(key, signingInput, expectBuf);
        String expectB64 = bux_base64_encode(((String)expectBuf), 32);
        Free(expectBuf);
        return String_Eq(expectB64, signatureB64);
    }

    if (alg.tag == JwtAlg_HS384) {
        void* expectBuf = Alloc(48);
        Hmac_Sha384Raw(key, signingInput, expectBuf);
        String expectB64 = bux_base64_encode(((String)expectBuf), 48);
        Free(expectBuf);
        return String_Eq(expectB64, signatureB64);
    }

    if (alg.tag == JwtAlg_HS512) {
        void* expectBuf = Alloc(64);
        Hmac_Sha512Raw(key, signingInput, expectBuf);
        String expectB64 = bux_base64_encode(((String)expectBuf), 64);
        Free(expectBuf);
        return String_Eq(expectB64, signatureB64);
    }

    if (alg.tag == JwtAlg_RS256) {
        return Rsa_VerifySha256(key, signingInput, signatureB64);
    }

    if (alg.tag == JwtAlg_RS384) {
        return Rsa_VerifySha384(key, signingInput, signatureB64);
    }

    if (alg.tag == JwtAlg_RS512) {
        return Rsa_VerifySha512(key, signingInput, signatureB64);
    }

    if (alg.tag == JwtAlg_ES256) {
        return Ecdsa_VerifyP256(key, signingInput, signatureB64);
    }

    if (alg.tag == JwtAlg_ES384) {
        return Ecdsa_VerifyP384(key, signingInput, signatureB64);
    }

    if (alg.tag == JwtAlg_EdDSA) {
        return Ed25519_Verify(key, signatureB64, signingInput);
    }

    return false;

}

String Jwt_Encode(String headerJson, String payloadJson, JwtAlg alg, String key) {
    String headerB64 = Base64URL_Encode(headerJson);
    String payloadB64 = Base64URL_Encode(payloadJson);
    String signingInput = String_Concat(headerB64, ".");
    String signingInputFull = String_Concat(signingInput, payloadB64);
    String sigB64 = Jwt_Sign(alg, signingInputFull, key);
    String part1 = String_Concat(signingInputFull, ".");
    return String_Concat(part1, sigB64);

}

bool Jwt_Decode(String token, JwtAlg alg, String key, String* headerOut, String* payloadOut) {
    uint partCount = bux_str_split_count(token, ".");
    if (partCount != 3) {
        return false;
    }

    String headerB64 = bux_str_split_part(token, ".", 0);
    String payloadB64 = bux_str_split_part(token, ".", 1);
    String sigB64 = bux_str_split_part(token, ".", 2);
    String input = String_Concat(headerB64, ".");
    String signingInput = String_Concat(input, payloadB64);
    if (!Jwt_Verify(alg, signingInput, sigB64, key)) {
        return false;
    }

    headerOut[0] = Base64URL_Decode(headerB64);
    payloadOut[0] = Base64URL_Decode(payloadB64);
    return true;

}

String Jwt_EncodeHS256(String payloadJson, String secret) {
    String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS256}));
    return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS256}), secret);

}

String Jwt_EncodeHS384(String payloadJson, String secret) {
    String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS384}));
    return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS384}), secret);

}

String Jwt_EncodeHS512(String payloadJson, String secret) {
    String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS512}));
    return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS512}), secret);

}

String Jwt_EncodeRS256(String payloadJson, String pemPrivateKey) {
    String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_RS256}));
    return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_RS256}), pemPrivateKey);

}

String Jwt_EncodeES256(String payloadJson, String pemPrivateKey) {
    String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_ES256}));
    return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_ES256}), pemPrivateKey);

}

String Jwt_EncodeEdDSA(String payloadJson, String rawPrivKey) {
    String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_EdDSA}));
    return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_EdDSA}), rawPrivKey);

}

String Ecdsa_SignP256(String pemPrivateKey, String data) {
    int siglen = 0;
    return bux_ecdsa_sign_p256(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen);

}

String Ecdsa_SignP256Base64(String pemPrivateKey, String data) {
    String raw = Ecdsa_SignP256(pemPrivateKey, data);
    return bux_base64_encode(raw, ((int)String_Len(raw)));

}

bool Ecdsa_VerifyP256(String pemPublicKey, String data, String signature) {
    int r = bux_ecdsa_verify_p256(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature)));
    return r == 1;

}

bool Ecdsa_VerifyP256Base64(String pemPublicKey, String data, String signatureB64) {
    int outlen = 0;
    String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen);
    return Ecdsa_VerifyP256(pemPublicKey, data, sig);

}

String Ecdsa_SignP384(String pemPrivateKey, String data) {
    int siglen = 0;
    return bux_ecdsa_sign_p384(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen);

}

String Ecdsa_SignP384Base64(String pemPrivateKey, String data) {
    String raw = Ecdsa_SignP384(pemPrivateKey, data);
    return bux_base64_encode(raw, ((int)String_Len(raw)));

}

bool Ecdsa_VerifyP384(String pemPublicKey, String data, String signature) {
    int r = bux_ecdsa_verify_p384(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature)));
    return r == 1;

}

bool Ecdsa_VerifyP384Base64(String pemPublicKey, String data, String signatureB64) {
    int outlen = 0;
    String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen);
    return Ecdsa_VerifyP384(pemPublicKey, data, sig);

}

bool Ed25519_Keypair(void* pubKey, void* privKey) {
    int r = bux_ed25519_keypair(pubKey, privKey);
    return r == 1;

}

String Ed25519_KeypairBase64() {
    void* pubBuf = Alloc(((uint)ED25519_PUBKEY_SIZE));
    void* priv = Alloc(((uint)ED25519_PRIVKEY_SIZE));
    if (bux_ed25519_keypair(pubBuf, priv) != 1) {
        Free(pubBuf);
        Free(priv);
        return "";
    }

    String pubB64 = bux_base64_encode(((String)pubBuf), ED25519_PUBKEY_SIZE);
    String privB64 = bux_base64_encode(((String)priv), ED25519_PRIVKEY_SIZE);
    Free(pubBuf);
    Free(priv);
    String pair = String_Concat(pubB64, ":");
    return String_Concat(pair, privB64);

}

String Ed25519_Sign(String privKey, String data) {
    void* sig = Alloc(((uint)ED25519_SIG_SIZE));
    if (bux_ed25519_sign(privKey, data, ((int)String_Len(data)), sig) != 1) {
        Free(sig);
        return "";
    }

    return ((String)sig);

}

String Ed25519_SignBase64(String privKey, String data) {
    String sig = Ed25519_Sign(privKey, data);
    if (String_Len(sig) == 0) {
        return "";
    }

    return bux_base64_encode(sig, ED25519_SIG_SIZE);

}

bool Ed25519_Verify(String pubKey, String signature, String data) {
    int r = bux_ed25519_verify(pubKey, signature, data, ((int)String_Len(data)));
    return r == 1;

}

bool Ed25519_VerifyBase64(String pubKey, String signatureB64, String data) {
    int outlen = 0;
    String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen);
    if (outlen != ED25519_SIG_SIZE) {
        return false;
    }

    return Ed25519_Verify(pubKey, sig, data);

}

String Rsa_SignSha256(String pemPrivateKey, String data) {
    int siglen = 0;
    return bux_rsa_sign_sha256(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen);

}

String Rsa_SignSha384(String pemPrivateKey, String data) {
    int siglen = 0;
    return bux_rsa_sign_sha384(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen);

}

String Rsa_SignSha512(String pemPrivateKey, String data) {
    int siglen = 0;
    return bux_rsa_sign_sha512(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen);

}

String Rsa_SignSha256Base64(String pemPrivateKey, String data) {
    String raw = Rsa_SignSha256(pemPrivateKey, data);
    return bux_base64_encode(raw, ((int)String_Len(raw)));

}

String Rsa_SignSha384Base64(String pemPrivateKey, String data) {
    String raw = Rsa_SignSha384(pemPrivateKey, data);
    return bux_base64_encode(raw, ((int)String_Len(raw)));

}

String Rsa_SignSha512Base64(String pemPrivateKey, String data) {
    String raw = Rsa_SignSha512(pemPrivateKey, data);
    return bux_base64_encode(raw, ((int)String_Len(raw)));

}

bool Rsa_VerifySha256(String pemPublicKey, String data, String signature) {
    int r = bux_rsa_verify_sha256(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature)));
    return r == 1;

}

bool Rsa_VerifySha384(String pemPublicKey, String data, String signature) {
    int r = bux_rsa_verify_sha384(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature)));
    return r == 1;

}

bool Rsa_VerifySha512(String pemPublicKey, String data, String signature) {
    int r = bux_rsa_verify_sha512(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature)));
    return r == 1;

}

bool Rsa_VerifySha256Base64(String pemPublicKey, String data, String signatureB64) {
    int outlen = 0;
    String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen);
    return Rsa_VerifySha256(pemPublicKey, data, sig);

}

bool Rsa_VerifySha384Base64(String pemPublicKey, String data, String signatureB64) {
    int outlen = 0;
    String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen);
    return Rsa_VerifySha384(pemPublicKey, data, sig);

}

bool Rsa_VerifySha512Base64(String pemPublicKey, String data, String signatureB64) {
    int outlen = 0;
    String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen);
    return Rsa_VerifySha512(pemPublicKey, data, sig);

}

uint String_Len(String s) {
    return bux_strlen(s);

}

bool String_IsNull(String s) {
    return bux_str_is_null(s) != 0;

}

bool String_Eq(String a, String b) {
    return bux_strcmp(a, b) == 0;

}

String String_Concat(String a, String b) {
    uint len_a = bux_strlen(a);
    uint len_b = bux_strlen(b);
    uint total = len_a + len_b + 1;
    char8* buf = ((char8*)bux_alloc(total));
    bux_strcpy(buf, a);
    bux_strcat(buf, b);
    return buf;

}

String String_Copy(String s) {
    uint len = bux_strlen(s);
    char8* buf = ((char8*)bux_alloc(len + 1));
    bux_strcpy(buf, s);
    return buf;

}

bool String_StartsWith(String s, String prefix) {
    uint s_len = bux_strlen(s);
    uint p_len = bux_strlen(prefix);
    if (p_len > s_len) {
        return false;
    }

    int r = bux_strncmp(s, prefix, p_len);
    return r == 0;

}

bool String_EndsWith(String s, String suffix) {
    uint s_len = bux_strlen(s);
    uint suf_len = bux_strlen(suffix);
    if (suf_len > s_len) {
        return false;
    }

    uint start = s_len - suf_len;
    String tail = bux_str_slice(s, start, suf_len);
    bool eq = bux_strcmp(tail, suffix) == 0;
    return eq;

}

bool String_Contains(String s, String substr) {
    int r = bux_str_contains(s, substr);
    return r != 0;

}

String String_Slice(String s, uint start, uint len) {
    return bux_str_slice(s, start, len);

}

String String_Trim(String s) {
    return bux_str_trim(s);

}

String String_TrimLeft(String s) {
    return bux_str_trim_left(s);

}

String String_TrimRight(String s) {
    return bux_str_trim_right(s);

}

String String_FromInt(int64 n) {
    return bux_int_to_str(n);

}

int64 String_ToInt(String s) {
    return bux_str_to_int(s);

}

StringBuilder StringBuilder_New() {
    return ((StringBuilder){.handle = bux_sb_new(64)});

}

StringBuilder StringBuilder_NewCap(uint cap) {
    return ((StringBuilder){.handle = bux_sb_new(cap)});

}

void StringBuilder_Append(StringBuilder* sb, String s) {
    bux_sb_append(sb->handle, s);

}

void StringBuilder_AppendInt(StringBuilder* sb, int64 n) {
    bux_sb_append_int(sb->handle, n);

}

void StringBuilder_AppendFloat(StringBuilder* sb, float64 f) {
    bux_sb_append_float(sb->handle, f);

}

void StringBuilder_AppendChar(StringBuilder* sb, char8 c) {
    bux_sb_append_char(sb->handle, c);

}

String StringBuilder_Build(StringBuilder* sb) {
    return bux_sb_build(sb->handle);

}

void StringBuilder_Free(StringBuilder* sb) {
    bux_sb_free(sb->handle);

}

uint String_SplitCount(String s, String delim) {
    return bux_str_split_count(s, delim);

}

String String_SplitPart(String s, String delim, uint index) {
    return bux_str_split_part(s, delim, index);

}

String String_Join2(String a, String b, String sep) {
    return bux_str_join2(a, b, sep);

}

String String_Chars(String s, uint index) {
    return bux_str_slice(s, index, 1);

}

String String_Find(String haystack, String needle) {
    return bux_strstr(haystack, needle);

}

uint String_Offset(String pos, String base) {
    return bux_str_offset(pos, base);

}

String String_Replace(String s, String old, String new) {
    String pos = bux_strstr(s, old);
    if (String_IsNull(pos)) {
        return s;
    }

    uint oldLen = bux_strlen(old);
    uint prefixLen = String_Offset(pos, s);
    String prefix = bux_str_slice(s, 0, prefixLen);
    String suffix = bux_str_slice(s, prefixLen + oldLen, bux_strlen(s) - prefixLen - oldLen);
    String temp = String_Concat(prefix, new);
    String result = String_Concat(temp, suffix);
    return result;

}

float64 String_ToFloat(String s) {
    return bux_str_to_float(s);

}

String String_FromBool(bool b) {
    if (b) {
        return "true";
    }

    return "false";

}

String String_FromFloat(float64 f) {
    return bux_float_to_string(f);

}

String String_Format1(String pattern, String a0) {
    return bux_str_format(pattern, a0, "", "", "", "", "", "", "");

}

String String_Format2(String pattern, String a0, String a1) {
    return bux_str_format(pattern, a0, a1, "", "", "", "", "", "");

}

String String_Format3(String pattern, String a0, String a1, String a2) {
    return bux_str_format(pattern, a0, a1, a2, "", "", "", "", "");

}

void Channel_SendInt(Channel_int* ch, int value) {
    bux_channel_send(ch->handle, ((void*)&value));

}

int Channel_RecvInt(Channel_int* ch) {
    int result = 0;
    bux_channel_recv(ch->handle, ((void*)&result));
    return result;

}

void Channel_SendFloat64(Channel_float64* ch, float64 value) {
    bux_channel_send(ch->handle, ((void*)&value));

}

float64 Channel_RecvFloat64(Channel_float64* ch) {
    float64 result = 0.0;
    bux_channel_recv(ch->handle, ((void*)&result));
    return result;

}

int Main() {
    int x = "hello";
    return 0;

}

extern int g_argc;
extern char** g_argv;
int main(int argc, char** argv) {
    g_argc = argc;
    g_argv = argv;
    return Main();
}
