dark theme

This commit is contained in:
Guilleag01
2025-09-21 21:44:22 +02:00
parent 709e19469c
commit 1fa789fc88
12 changed files with 407 additions and 744 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
/target
/dist

1
Cargo.lock generated
View File

@@ -921,6 +921,7 @@ dependencies = [
name = "simplex_web"
version = "0.1.0"
dependencies = [
"wasm-bindgen",
"web-sys",
"yew",
]

View File

@@ -4,5 +4,6 @@ version = "0.1.0"
edition = "2024"
[dependencies]
wasm-bindgen = "0.2.103"
web-sys = { version = "0.3.80", features = ["console"] }
yew = { version = "0.21.0", features = ["csr"] }

162
dist/index.html vendored
View File

@@ -1,10 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simplex Optimizer</title>
<style>
/* --- Light Theme (default) --- */
html,
body {
height: 100%;
margin: 0;
}
.big-container {
display: flex;
flex-direction: column;
min-height: 100vh;
/* ensures container is at least full viewport height */
}
body {
margin: 0;
font-family: Arial, sans-serif;
@@ -12,6 +28,38 @@
flex-direction: column;
height: 100vh;
background: #f8f9fa;
color: #212529;
transition: background 0.3s, color 0.3s;
}
/* Header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background: #ffffff;
border-bottom: 1px solid #dee2e6;
transition: background 0.3s, color 0.3s;
}
.header h1 {
margin: 0;
font-size: 1.5rem;
color: #212529;
}
/* Theme toggle button */
.theme-btn {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
transition: transform 0.2s;
}
.theme-btn:hover {
transform: rotate(20deg);
}
.container {
@@ -28,6 +76,7 @@
gap: 20px;
background: #ffffff;
border-bottom: 2px solid #dee2e6;
transition: background 0.3s, border-color 0.3s;
}
.input-box {
@@ -39,12 +88,14 @@
padding: 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
overflow-y: auto;
transition: background 0.3s;
}
.input-box h2 {
margin: 0 0 10px 0;
font-size: 1.2rem;
color: #343a40;
transition: color 0.3s;
}
.sub-section {
@@ -55,6 +106,7 @@
margin: 0 0 8px 0;
font-size: 1rem;
color: #495057;
transition: color 0.3s;
}
.input-row {
@@ -69,6 +121,9 @@
border: 1px solid #ced4da;
border-radius: 5px;
font-size: 0.9rem;
background: #ffffff;
color: #212529;
transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.input-row button {
@@ -79,6 +134,7 @@
border-radius: 5px;
cursor: pointer;
font-size: 0.9rem;
transition: background 0.3s;
}
.input-row button:hover {
@@ -101,6 +157,7 @@
border: 1px solid #dee2e6;
border-radius: 5px;
font-size: 0.9rem;
transition: background 0.3s, border-color 0.3s, color 0.3s;
}
.remove-btn {
@@ -111,6 +168,7 @@
font-size: 0.75rem;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
.remove-btn:hover {
@@ -131,6 +189,9 @@
border: 1px solid #ced4da;
border-radius: 5px;
font-size: 0.9rem;
background: #ffffff;
color: #212529;
transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.objective button {
@@ -141,6 +202,7 @@
border-radius: 5px;
cursor: pointer;
font-size: 0.95rem;
transition: background 0.3s;
}
.objective button:hover {
@@ -155,6 +217,7 @@
padding: 20px;
background: #fdfdfd;
overflow-y: auto;
transition: background 0.3s;
}
.steps {
@@ -165,11 +228,13 @@
border: 1px solid #dee2e6;
border-radius: 8px;
margin-bottom: 15px;
transition: background 0.3s, border-color 0.3s;
}
.steps h3 {
margin-top: 0;
color: #495057;
transition: color 0.3s;
}
.steps ul {
@@ -183,15 +248,105 @@
border-radius: 8px;
font-weight: bold;
color: #155724;
transition: background 0.3s, color 0.3s, border-color 0.3s;
}
/* --- Dark Theme --- */
.big-container.dark-theme {
background: #121212;
color: #e9ecef;
}
.big-container.dark-theme .header {
background: #1e1e1e;
border-bottom: 1px solid #343a40;
}
.big-container.dark-theme .header h1 {
color: #f8f9fa;
}
.big-container.dark-theme .input-section {
background: #1e1e1e;
border-bottom: 2px solid #343a40;
}
.big-container.dark-theme .input-box {
background: #2a2a2a;
}
.big-container.dark-theme .input-box h2,
.big-container.dark-theme .sub-section h3 {
color: #f8f9fa;
}
.big-container.dark-theme .input-row input,
.big-container.dark-theme .objective input {
background: #343a40;
color: #e9ecef;
border: 1px solid #495057;
}
.big-container.dark-theme li {
background: #1e1e1e;
border: 1px solid #495057;
color: #e9ecef;
}
.big-container.dark-theme .output-section {
background: #1a1a1a;
}
.big-container.dark-theme .steps {
background: #2a2a2a;
border: 1px solid #495057;
}
.big-container.dark-theme .steps h3 {
color: #f8f9fa;
}
.big-container.dark-theme .final-result {
background: #1e3d2d;
border: 1px solid #155724;
color: #a8e6a3;
}
.big-container.dark-theme .input-row button {
background: #0d6efd;
}
.big-container.dark-theme .input-row button:hover {
background: #084298;
}
.big-container.dark-theme .objective button {
background: #198754;
}
.big-container.dark-theme .objective button:hover {
background: #145c32;
}
.big-container.dark-theme .remove-btn {
background: #dc3545;
}
.big-container.dark-theme .remove-btn:hover {
background: #b02a37;
}
</style>
<link rel="modulepreload" href="/simplex_web-8bf72546f0e8aebd.js" crossorigin="anonymous" integrity="sha384-x4nFKfiSWzB0sCXnR6hQoO3c8Lv83ztLT8H6Lf0vfHMtRqYUsNign5AzLC+tCans"><link rel="preload" href="/simplex_web-8bf72546f0e8aebd_bg.wasm" crossorigin="anonymous" integrity="sha384-AGnm5INB9StBmD88/MSZ4spWf1Mkktyx60q0tH9gpQto4jlI9JqVHktjhhBfORAV" as="fetch" type="application/wasm"></head>
<link rel="modulepreload" href="/simplex_web-c17f0d3b3483d1df.js" crossorigin="anonymous" integrity="sha384-N6NbmI2kXhtLKxU84HCP168wd/JaKiw9gvaTItFQ73ibm8plWJNvdpDLLXdRWPXp"><link rel="preload" href="/simplex_web-c17f0d3b3483d1df_bg.wasm" crossorigin="anonymous" integrity="sha384-3HZCB6oIMDFCv9h2J2OUGzBwI1zybrRD7BgPyGTDAFMv1FD8m8p2/25UfdwG3mYx" as="fetch" type="application/wasm"></head>
<body>
<script type="module">
import init, * as bindings from '/simplex_web-8bf72546f0e8aebd.js';
const wasm = await init({ module_or_path: '/simplex_web-8bf72546f0e8aebd_bg.wasm' });
import init, * as bindings from '/simplex_web-c17f0d3b3483d1df.js';
const wasm = await init({ module_or_path: '/simplex_web-c17f0d3b3483d1df_bg.wasm' });
window.wasmBindings = bindings;
@@ -329,4 +484,5 @@ dispatchEvent(new CustomEvent("TrunkApplicationStarted", {detail: {wasm}}));
})()
</script></body>
</html>

View File

@@ -1,723 +0,0 @@
let wasm;
let cachedUint8ArrayMemory0 = null;
function getUint8ArrayMemory0() {
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8ArrayMemory0;
}
let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
const MAX_SAFARI_DECODE_BYTES = 2146435072;
let numBytesDecoded = 0;
function decodeText(ptr, len) {
numBytesDecoded += len;
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
cachedTextDecoder.decode();
numBytesDecoded = len;
}
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}
function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return decodeText(ptr, len);
}
function addToExternrefTable0(obj) {
const idx = wasm.__externref_table_alloc();
wasm.__wbindgen_export_2.set(idx, obj);
return idx;
}
function handleError(f, args) {
try {
return f.apply(this, args);
} catch (e) {
const idx = addToExternrefTable0(e);
wasm.__wbindgen_exn_store(idx);
}
}
function isLikeNone(x) {
return x === undefined || x === null;
}
let cachedDataViewMemory0 = null;
function getDataViewMemory0() {
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
}
return cachedDataViewMemory0;
}
function getArrayJsValueFromWasm0(ptr, len) {
ptr = ptr >>> 0;
const mem = getDataViewMemory0();
const result = [];
for (let i = ptr; i < ptr + 4 * len; i += 4) {
result.push(wasm.__wbindgen_export_2.get(mem.getUint32(i, true)));
}
wasm.__externref_drop_slice(ptr, len);
return result;
}
let WASM_VECTOR_LEN = 0;
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length, 1) >>> 0;
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len, 1) >>> 0;
const mem = getUint8ArrayMemory0();
let offset = 0;
for (; offset < len; offset++) {
const code = arg.charCodeAt(offset);
if (code > 0x7F) break;
mem[ptr + offset] = code;
}
if (offset !== len) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
offset += ret.written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
}
WASM_VECTOR_LEN = offset;
return ptr;
}
function debugString(val) {
// primitive types
const type = typeof val;
if (type == 'number' || type == 'boolean' || val == null) {
return `${val}`;
}
if (type == 'string') {
return `"${val}"`;
}
if (type == 'symbol') {
const description = val.description;
if (description == null) {
return 'Symbol';
} else {
return `Symbol(${description})`;
}
}
if (type == 'function') {
const name = val.name;
if (typeof name == 'string' && name.length > 0) {
return `Function(${name})`;
} else {
return 'Function';
}
}
// objects
if (Array.isArray(val)) {
const length = val.length;
let debug = '[';
if (length > 0) {
debug += debugString(val[0]);
}
for(let i = 1; i < length; i++) {
debug += ', ' + debugString(val[i]);
}
debug += ']';
return debug;
}
// Test for built-in
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
let className;
if (builtInMatches && builtInMatches.length > 1) {
className = builtInMatches[1];
} else {
// Failed to match the standard '[object ClassName]'
return toString.call(val);
}
if (className == 'Object') {
// we're a user defined class or Object
// JSON.stringify avoids problems with cycles, and is generally much
// easier than looping through ownProperties of `val`.
try {
return 'Object(' + JSON.stringify(val) + ')';
} catch (_) {
return 'Object';
}
}
// errors
if (val instanceof Error) {
return `${val.name}: ${val.message}\n${val.stack}`;
}
// TODO we could test for more things here, like `Set`s and `Map`s.
return className;
}
const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
? { register: () => {}, unregister: () => {} }
: new FinalizationRegistry(
state => {
wasm.__wbindgen_export_7.get(state.dtor)(state.a, state.b);
}
);
function makeMutClosure(arg0, arg1, dtor, f) {
const state = { a: arg0, b: arg1, cnt: 1, dtor };
const real = (...args) => {
// First up with a closure we increment the internal reference
// count. This ensures that the Rust closure environment won't
// be deallocated while we're invoking it.
state.cnt++;
const a = state.a;
state.a = 0;
try {
return f(a, state.b, ...args);
} finally {
if (--state.cnt === 0) {
wasm.__wbindgen_export_7.get(state.dtor)(a, state.b);
CLOSURE_DTORS.unregister(state);
} else {
state.a = a;
}
}
};
real.original = state;
CLOSURE_DTORS.register(real, state, state);
return real;
}
function makeClosure(arg0, arg1, dtor, f) {
const state = { a: arg0, b: arg1, cnt: 1, dtor };
const real = (...args) => {
// First up with a closure we increment the internal reference
// count. This ensures that the Rust closure environment won't
// be deallocated while we're invoking it.
state.cnt++;
try {
return f(state.a, state.b, ...args);
} finally {
if (--state.cnt === 0) {
wasm.__wbindgen_export_7.get(state.dtor)(state.a, state.b); state.a = 0;
CLOSURE_DTORS.unregister(state);
}
}
};
real.original = state;
CLOSURE_DTORS.register(real, state, state);
return real;
}
function __wbg_adapter_8(arg0, arg1, arg2) {
wasm.closure257_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_11(arg0, arg1, arg2) {
wasm.closure321_externref_shim(arg0, arg1, arg2);
}
const EXPECTED_RESPONSE_TYPES = new Set(['basic', 'cors', 'default']);
async function __wbg_load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
const validResponse = module.ok && EXPECTED_RESPONSE_TYPES.has(module.type);
if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
} else {
throw e;
}
}
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_addEventListener_c8d39d7dcff00d2f = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
arg0.addEventListener(getStringFromWasm0(arg1, arg2), arg3, arg4);
}, arguments) };
imports.wbg.__wbg_body_3af439ac76af2afb = function(arg0) {
const ret = arg0.body;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_bubbles_54d1d18366d19d6d = function(arg0) {
const ret = arg0.bubbles;
return ret;
};
imports.wbg.__wbg_cachekey_57601dac16343711 = function(arg0) {
const ret = arg0.__yew_subtree_cache_key;
return isLikeNone(ret) ? 0x100000001 : (ret) >>> 0;
};
imports.wbg.__wbg_call_2f8d426a20a307fe = function() { return handleError(function (arg0, arg1) {
const ret = arg0.call(arg1);
return ret;
}, arguments) };
imports.wbg.__wbg_cancelBubble_ba3496c52eac50f9 = function(arg0) {
const ret = arg0.cancelBubble;
return ret;
};
imports.wbg.__wbg_childNodes_ef176b83ab95436c = function(arg0) {
const ret = arg0.childNodes;
return ret;
};
imports.wbg.__wbg_cloneNode_f3cc6cddf7979990 = function() { return handleError(function (arg0) {
const ret = arg0.cloneNode();
return ret;
}, arguments) };
imports.wbg.__wbg_composedPath_e3274d4b1a25887d = function(arg0) {
const ret = arg0.composedPath();
return ret;
};
imports.wbg.__wbg_createElementNS_a9f53206c738878b = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
const ret = arg0.createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
return ret;
}, arguments) };
imports.wbg.__wbg_createElement_4f7fbf335b949252 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.createElement(getStringFromWasm0(arg1, arg2));
return ret;
}, arguments) };
imports.wbg.__wbg_createTextNode_09ae71620b19776d = function(arg0, arg1, arg2) {
const ret = arg0.createTextNode(getStringFromWasm0(arg1, arg2));
return ret;
};
imports.wbg.__wbg_document_a6efcd95d74a2ff6 = function(arg0) {
const ret = arg0.document;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_error_3c7d958458bf649b = function(arg0, arg1) {
var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
wasm.__wbindgen_free(arg0, arg1 * 4, 4);
console.error(...v0);
};
imports.wbg.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
let deferred0_0;
let deferred0_1;
try {
deferred0_0 = arg0;
deferred0_1 = arg1;
console.error(getStringFromWasm0(arg0, arg1));
} finally {
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
}
};
imports.wbg.__wbg_from_237b1ad767238d8b = function(arg0) {
const ret = Array.from(arg0);
return ret;
};
imports.wbg.__wbg_get_59c6316d15f9f1d0 = function(arg0, arg1) {
const ret = arg0[arg1 >>> 0];
return ret;
};
imports.wbg.__wbg_host_e3d0174ee47b29da = function(arg0) {
const ret = arg0.host;
return ret;
};
imports.wbg.__wbg_insertBefore_ff3cdc8f07aee445 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = arg0.insertBefore(arg1, arg2);
return ret;
}, arguments) };
imports.wbg.__wbg_instanceof_Element_96b17c2bf2f962ff = function(arg0) {
let result;
try {
result = arg0 instanceof Element;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_Event_d6f301b8e3144b40 = function(arg0) {
let result;
try {
result = arg0 instanceof Event;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_HtmlInputElement_6e301f5298c2216e = function(arg0) {
let result;
try {
result = arg0 instanceof HTMLInputElement;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_ShadowRoot_ae4bc62016938ece = function(arg0) {
let result;
try {
result = arg0 instanceof ShadowRoot;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_instanceof_Window_7f29e5c72acbfd60 = function(arg0) {
let result;
try {
result = arg0 instanceof Window;
} catch (_) {
result = false;
}
const ret = result;
return ret;
};
imports.wbg.__wbg_is_a001cd6ada1df292 = function(arg0, arg1) {
const ret = Object.is(arg0, arg1);
return ret;
};
imports.wbg.__wbg_lastChild_5847fcd93bd5162a = function(arg0) {
const ret = arg0.lastChild;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_length_246fa1f85a0dea5b = function(arg0) {
const ret = arg0.length;
return ret;
};
imports.wbg.__wbg_listenerid_ed1678830a5b97ec = function(arg0) {
const ret = arg0.__yew_listener_id;
return isLikeNone(ret) ? 0x100000001 : (ret) >>> 0;
};
imports.wbg.__wbg_log_f3c04200b995730f = function(arg0) {
console.log(arg0);
};
imports.wbg.__wbg_namespaceURI_16a9ca763a61b64a = function(arg0, arg1) {
const ret = arg1.namespaceURI;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_new_1930cbb8d9ffc31b = function() {
const ret = new Object();
return ret;
};
imports.wbg.__wbg_new_8a6f238a6ece86ea = function() {
const ret = new Error();
return ret;
};
imports.wbg.__wbg_newnoargs_a81330f6e05d8aca = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return ret;
};
imports.wbg.__wbg_nextSibling_179d0a1601577aec = function(arg0) {
const ret = arg0.nextSibling;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_outerHTML_7306ec658b1ed630 = function(arg0, arg1) {
const ret = arg1.outerHTML;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_parentElement_90704850d3ceb7ee = function(arg0) {
const ret = arg0.parentElement;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_parentNode_aa589bbf69854710 = function(arg0) {
const ret = arg0.parentNode;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_queueMicrotask_bcc6e26d899696db = function(arg0) {
const ret = arg0.queueMicrotask;
return ret;
};
imports.wbg.__wbg_queueMicrotask_f24a794d09c42640 = function(arg0) {
queueMicrotask(arg0);
};
imports.wbg.__wbg_removeAttribute_6930c6c8a4db23d2 = function() { return handleError(function (arg0, arg1, arg2) {
arg0.removeAttribute(getStringFromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbg_removeChild_3b3d6d5ab2fadc87 = function() { return handleError(function (arg0, arg1) {
const ret = arg0.removeChild(arg1);
return ret;
}, arguments) };
imports.wbg.__wbg_removeEventListener_b25c194da9564efa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
arg0.removeEventListener(getStringFromWasm0(arg1, arg2), arg3, arg4 !== 0);
}, arguments) };
imports.wbg.__wbg_resolve_5775c0ef9222f556 = function(arg0) {
const ret = Promise.resolve(arg0);
return ret;
};
imports.wbg.__wbg_setAttribute_6a3ee9b5deb88ed3 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
arg0.setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments) };
imports.wbg.__wbg_set_b33e7a98099eed58 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = Reflect.set(arg0, arg1, arg2);
return ret;
}, arguments) };
imports.wbg.__wbg_setcachekey_bb5f908a0e3ee714 = function(arg0, arg1) {
arg0.__yew_subtree_cache_key = arg1 >>> 0;
};
imports.wbg.__wbg_setcapture_db2ee3e30ffd4878 = function(arg0, arg1) {
arg0.capture = arg1 !== 0;
};
imports.wbg.__wbg_setchecked_7b7c0d2599d9cdb7 = function(arg0, arg1) {
arg0.checked = arg1 !== 0;
};
imports.wbg.__wbg_setinnerHTML_fec7cc6bdfe27049 = function(arg0, arg1, arg2) {
arg0.innerHTML = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setlistenerid_3d14d37a42484593 = function(arg0, arg1) {
arg0.__yew_listener_id = arg1 >>> 0;
};
imports.wbg.__wbg_setnodeValue_67b8289cc9bf7650 = function(arg0, arg1, arg2) {
arg0.nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setpassive_ff0de39cdf5a633e = function(arg0, arg1) {
arg0.passive = arg1 !== 0;
};
imports.wbg.__wbg_setsubtreeid_32b8ceff55862e29 = function(arg0, arg1) {
arg0.__yew_subtree_id = arg1 >>> 0;
};
imports.wbg.__wbg_setvalue_43593e9f2309b239 = function(arg0, arg1, arg2) {
arg0.value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_setvalue_ccf2650f7af384e0 = function(arg0, arg1, arg2) {
arg0.value = getStringFromWasm0(arg1, arg2);
};
imports.wbg.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
const ret = arg1.stack;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_static_accessor_GLOBAL_1f13249cc3acc96d = function() {
const ret = typeof global === 'undefined' ? null : global;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_static_accessor_GLOBAL_THIS_df7ae94b1e0ed6a3 = function() {
const ret = typeof globalThis === 'undefined' ? null : globalThis;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_static_accessor_SELF_6265471db3b3c228 = function() {
const ret = typeof self === 'undefined' ? null : self;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_static_accessor_WINDOW_16fb482f8ec52863 = function() {
const ret = typeof window === 'undefined' ? null : window;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_subtreeid_e65dfcc52d403fd9 = function(arg0) {
const ret = arg0.__yew_subtree_id;
return isLikeNone(ret) ? 0x100000001 : (ret) >>> 0;
};
imports.wbg.__wbg_target_bfb4281bfa013115 = function(arg0) {
const ret = arg0.target;
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
};
imports.wbg.__wbg_textContent_094fcf277dd9df42 = function(arg0, arg1) {
const ret = arg1.textContent;
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
var len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_then_9cc266be2bf537b6 = function(arg0, arg1) {
const ret = arg0.then(arg1);
return ret;
};
imports.wbg.__wbg_value_1ae15635193fdbb5 = function(arg0, arg1) {
const ret = arg1.value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_value_b3bb6dd468d1cb71 = function(arg0, arg1) {
const ret = arg1.value;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_wbindgencbdrop_a85ed476c6a370b9 = function(arg0) {
const obj = arg0.original;
if (obj.cnt-- == 1) {
obj.a = 0;
return true;
}
const ret = false;
return ret;
};
imports.wbg.__wbg_wbindgendebugstring_bb652b1bc2061b6d = function(arg0, arg1) {
const ret = debugString(arg1);
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
};
imports.wbg.__wbg_wbindgenisfunction_ea72b9d66a0e1705 = function(arg0) {
const ret = typeof(arg0) === 'function';
return ret;
};
imports.wbg.__wbg_wbindgenisundefined_71f08a6ade4354e7 = function(arg0) {
const ret = arg0 === undefined;
return ret;
};
imports.wbg.__wbg_wbindgenthrow_4c11a24fca429ccf = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};
imports.wbg.__wbindgen_cast_1fd9af4f8d234577 = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 320, function: Function { arguments: [Externref], shim_idx: 321, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
const ret = makeMutClosure(arg0, arg1, 320, __wbg_adapter_11);
return ret;
};
imports.wbg.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {
// Cast intrinsic for `Ref(String) -> Externref`.
const ret = getStringFromWasm0(arg0, arg1);
return ret;
};
imports.wbg.__wbindgen_cast_24e68085ee0f966a = function(arg0, arg1) {
// Cast intrinsic for `Closure(Closure { dtor_idx: 256, function: Function { arguments: [Ref(NamedExternref("Event"))], shim_idx: 257, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.
const ret = makeClosure(arg0, arg1, 256, __wbg_adapter_8);
return ret;
};
imports.wbg.__wbindgen_init_externref_table = function() {
const table = wasm.__wbindgen_export_2;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
;
};
return imports;
}
function __wbg_init_memory(imports, memory) {
}
function __wbg_finalize_init(instance, module) {
wasm = instance.exports;
__wbg_init.__wbindgen_wasm_module = module;
cachedDataViewMemory0 = null;
cachedUint8ArrayMemory0 = null;
wasm.__wbindgen_start();
return wasm;
}
function initSync(module) {
if (wasm !== undefined) return wasm;
if (typeof module !== 'undefined') {
if (Object.getPrototypeOf(module) === Object.prototype) {
({module} = module)
} else {
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
}
}
const imports = __wbg_get_imports();
__wbg_init_memory(imports);
if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}
const instance = new WebAssembly.Instance(module, imports);
return __wbg_finalize_init(instance, module);
}
async function __wbg_init(module_or_path) {
if (wasm !== undefined) return wasm;
if (typeof module_or_path !== 'undefined') {
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
({module_or_path} = module_or_path)
} else {
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
}
}
if (typeof module_or_path === 'undefined') {
module_or_path = new URL('simplex_web_bg.wasm', import.meta.url);
}
const imports = __wbg_get_imports();
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
module_or_path = fetch(module_or_path);
}
__wbg_init_memory(imports);
const { instance, module } = await __wbg_load(await module_or_path, imports);
return __wbg_finalize_init(instance, module);
}
export { initSync };
export default __wbg_init;

Binary file not shown.

View File

@@ -1,10 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simplex Optimizer</title>
<style>
/* --- Light Theme (default) --- */
html,
body {
height: 100%;
margin: 0;
}
.big-container {
display: flex;
flex-direction: column;
min-height: 100vh;
/* ensures container is at least full viewport height */
}
body {
margin: 0;
font-family: Arial, sans-serif;
@@ -12,6 +28,38 @@
flex-direction: column;
height: 100vh;
background: #f8f9fa;
color: #212529;
transition: background 0.3s, color 0.3s;
}
/* Header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
background: #ffffff;
border-bottom: 1px solid #dee2e6;
transition: background 0.3s, color 0.3s;
}
.header h1 {
margin: 0;
font-size: 1.5rem;
color: #212529;
}
/* Theme toggle button */
.theme-btn {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
transition: transform 0.2s;
}
.theme-btn:hover {
transform: rotate(20deg);
}
.container {
@@ -28,6 +76,7 @@
gap: 20px;
background: #ffffff;
border-bottom: 2px solid #dee2e6;
transition: background 0.3s, border-color 0.3s;
}
.input-box {
@@ -39,12 +88,14 @@
padding: 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
overflow-y: auto;
transition: background 0.3s;
}
.input-box h2 {
margin: 0 0 10px 0;
font-size: 1.2rem;
color: #343a40;
transition: color 0.3s;
}
.sub-section {
@@ -55,6 +106,7 @@
margin: 0 0 8px 0;
font-size: 1rem;
color: #495057;
transition: color 0.3s;
}
.input-row {
@@ -69,6 +121,9 @@
border: 1px solid #ced4da;
border-radius: 5px;
font-size: 0.9rem;
background: #ffffff;
color: #212529;
transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.input-row button {
@@ -79,6 +134,7 @@
border-radius: 5px;
cursor: pointer;
font-size: 0.9rem;
transition: background 0.3s;
}
.input-row button:hover {
@@ -101,6 +157,7 @@
border: 1px solid #dee2e6;
border-radius: 5px;
font-size: 0.9rem;
transition: background 0.3s, border-color 0.3s, color 0.3s;
}
.remove-btn {
@@ -111,6 +168,7 @@
font-size: 0.75rem;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
.remove-btn:hover {
@@ -131,6 +189,9 @@
border: 1px solid #ced4da;
border-radius: 5px;
font-size: 0.9rem;
background: #ffffff;
color: #212529;
transition: background 0.3s, color 0.3s, border-color 0.3s;
}
.objective button {
@@ -141,6 +202,7 @@
border-radius: 5px;
cursor: pointer;
font-size: 0.95rem;
transition: background 0.3s;
}
.objective button:hover {
@@ -155,6 +217,7 @@
padding: 20px;
background: #fdfdfd;
overflow-y: auto;
transition: background 0.3s;
}
.steps {
@@ -165,11 +228,13 @@
border: 1px solid #dee2e6;
border-radius: 8px;
margin-bottom: 15px;
transition: background 0.3s, border-color 0.3s;
}
.steps h3 {
margin-top: 0;
color: #495057;
transition: color 0.3s;
}
.steps ul {
@@ -183,10 +248,101 @@
border-radius: 8px;
font-weight: bold;
color: #155724;
transition: background 0.3s, color 0.3s, border-color 0.3s;
}
/* --- Dark Theme --- */
.big-container.dark-theme {
background: #121212;
color: #e9ecef;
}
.big-container.dark-theme .header {
background: #1e1e1e;
border-bottom: 1px solid #343a40;
}
.big-container.dark-theme .header h1 {
color: #f8f9fa;
}
.big-container.dark-theme .input-section {
background: #1e1e1e;
border-bottom: 2px solid #343a40;
}
.big-container.dark-theme .input-box {
background: #2a2a2a;
}
.big-container.dark-theme .input-box h2,
.big-container.dark-theme .sub-section h3 {
color: #f8f9fa;
}
.big-container.dark-theme .input-row input,
.big-container.dark-theme .objective input {
background: #343a40;
color: #e9ecef;
border: 1px solid #495057;
}
.big-container.dark-theme li {
background: #1e1e1e;
border: 1px solid #495057;
color: #e9ecef;
}
.big-container.dark-theme .output-section {
background: #1a1a1a;
}
.big-container.dark-theme .steps {
background: #2a2a2a;
border: 1px solid #495057;
}
.big-container.dark-theme .steps h3 {
color: #f8f9fa;
}
.big-container.dark-theme .final-result {
background: #1e3d2d;
border: 1px solid #155724;
color: #a8e6a3;
}
.big-container.dark-theme .input-row button {
background: #0d6efd;
}
.big-container.dark-theme .input-row button:hover {
background: #084298;
}
.big-container.dark-theme .objective button {
background: #198754;
}
.big-container.dark-theme .objective button:hover {
background: #145c32;
}
.big-container.dark-theme .remove-btn {
background: #dc3545;
}
.big-container.dark-theme .remove-btn:hover {
background: #b02a37;
}
</style>
</head>
<body>
</body>
</html>

View File

@@ -15,6 +15,7 @@ pub struct App {
simplex: Simplex,
solution: Option<f32>,
final_values: Vec<(String, f32)>,
theme: String,
}
pub enum Msg {
@@ -26,6 +27,7 @@ pub enum Msg {
AddConstraint,
ClearConstraints,
RunSimplex,
ChangeTheme,
}
impl App {}
@@ -39,6 +41,7 @@ impl Default for App {
simplex: Default::default(),
solution: None,
final_values: Default::default(),
theme: Default::default(),
}
}
}
@@ -129,6 +132,13 @@ impl Component for App {
self.solution = Some(sol);
self.final_values = values;
}
Msg::ChangeTheme => {
if self.theme == "" {
self.theme = "dark-theme".to_string()
} else {
self.theme = "".to_string()
}
}
}
true
}
@@ -142,8 +152,17 @@ impl Component for App {
let clear_constraint = ctx.link().callback(|_| Msg::ClearConstraints);
let add_constraint = ctx.link().callback(|_| Msg::AddConstraint);
let run_simplex = ctx.link().callback(|_| Msg::RunSimplex);
let change_theme = ctx.link().callback(|_| Msg::ChangeTheme);
html! {
<div class={format!("big-container {}", self.theme)}>
// <button onclick={change_theme}>{"Add"}</button>
<header class="header">
<h1>{"Simplex optimizer"}</h1>
<button onclick={change_theme} id="theme-toggle" class="theme-btn" title="Toggle Dark/Light Mode">
{ if self.theme == "".to_string() { "🌙" } else { "☀️" } }
</button>
</header>
<div class="container">
// <!-- Top: Input Section -->
@@ -185,7 +204,8 @@ impl Component for App {
{
for self.simplex.get_constraints().iter().map(|c| {
html! {
<li>{
<li>
{
for zip(c, self.simplex.get_variables()).take(c.len() - 1).enumerate().map(|(i, (v, var))| {
let v_2 = if i > 0 { v.abs() } else { *v };
html! {
@@ -193,6 +213,7 @@ impl Component for App {
}
}
)}
{
format!("{}", c[c.len() - 1])
}
@@ -250,6 +271,7 @@ impl Component for App {
</div>
</div>
</div>
</div>
}
}

View File

@@ -37,14 +37,18 @@ pub fn variable_input(properties: &Props) -> Html {
for variables.iter().enumerate().map(|(i, v)| {
html! {
<>
<strong>
<input type="text" oninput={oninputs[i].clone()}/>
{v}{if i < variables.len() -1 {" + "} else { " " }}
{" "}{v}{if i < variables.len() -1 {" + "} else { " " }}
</strong>
</>
}
})
}
<strong>
{""}
<input type="text" oninput={oninputs.last().unwrap().clone()}/>
</strong>
</>
}
}

View File

@@ -1,5 +1,6 @@
pub mod app;
pub mod constraint_input;
pub mod math;
pub mod simplex;
pub mod target_input;
pub mod variable_input;

42
src/math.rs Normal file
View File

@@ -0,0 +1,42 @@
// use wasm_bindgen::prelude::*;
// use web_sys::window;
// use yew::prelude::*;
// #[wasm_bindgen]
// extern "C" {
// fn renderMath();
// }
// #[function_component(Math)]
// pub fn math(props: &Props) -> Html {
// let formula = &props.formula;
// // Trigger MathJax typesetting when component mounts
// {
// let formula = formula.clone();
// use_effect(|| {
// if let Some(window) = window() {
// let _ = window.eval("renderMath()");
// }
// })
// // use_effect_with_deps(
// // move |_| {
// // if let Some(window) = window() {
// // let _ = window.eval("MathJax.typesetPromise()");
// // }
// // || ()
// // },
// // formula,
// // );
// }
// html! {
// <p>{ formula }</p> // You can use <div> or <span> depending on display mode
// }
// }
// #[derive(Properties, PartialEq, Clone)]
// pub struct Props {
// pub formula: String,
// }

View File

@@ -38,8 +38,10 @@ pub fn variable_input(properties: &Props) -> Html {
for variables.iter().enumerate().map(|(i, v)| {
html! {
<>
<strong>
<input type="text" oninput={oninputs[i].clone()}/>
{" "}{v}{if i < variables.len() -1 {" + "} else { "" }}
</strong>
</>
}
})