<!doctype html>
<script class="injected-ffc2e83d85"> (function(){'use strict';function q(b){var c=0;return function(){return c>>0)+"_",l=0;return c}); x("Symbol.iterator",function(b){if(b)return b;b=Symbol("Symbol.iterator");u(Array.prototype,b,{configurable:!0,writable:!0,value:function(){return J(q(this))}});return b});function J(b){b={next:b};b[Symbol.iterator]=function(){return this};return b} x("Promise",function(b){function c(f){this.h=0;this.i=void 0;this.g=[];this.u=!1;var a=this.j();try{f(a.resolve,a.reject)}catch(d){a.reject(d)}}function g(){this.g=null}function h(f){return f instanceof c?f:new c(function(a){a(f)})}if(b)return b;g.prototype.h=function(f){if(this.g==null){this.g=[];var a=this;this.i(function(){a.l()})}this.g.push(f)};var l=w.setTimeout;g.prototype.i=function(f){l(f,0)};g.prototype.l=function(){for(;this.g&&this.g.length;){var f=this.g;this.g=[];for(var a=0;a0&&setTimeout(function(){d.forEach(function(p){c(p)})},500)})).observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class"],characterData:!0})})}).catch(function(a){console.error("IconChecker: Font loading error. Scanning icons anyway.", a);requestAnimationFrame(function(){g(document.body)})})}var l=["material-icons","material-symbols-outlined","material-symbols-rounded","material-symbols-sharp"].map(function(a){return"."+a}).join(","),m=null,f=null;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){h()}):h()})();}).call(this); </script> <title>DeepSeek mHC Architecture Simulator</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <style data-exported-from="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0">/* fallback */ @font-face { font-family: 'Material Symbols Outlined'; font-style: normal; font-weight: 400; src: url(https://fonts.gstatic.com/s/materialsymbolsoutlined/v307/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOejbd5zrDAt.woff2) format('woff2'); }.material-symbols-outlined {
font-family: 'Material Symbols Outlined';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
</style>
<style data-exported-from="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@300;400;600;800&display=swap">/* cyrillic-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/ cyrillic /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/ greek-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/ greek /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/ vietnamese /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/ latin-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/ latin /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/ cyrillic-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/ cyrillic /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/ greek-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/ greek /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/ vietnamese /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/ latin-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/ latin /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/ cyrillic-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/ cyrillic /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/ greek-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/ greek /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/ vietnamese /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/ latin-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/ latin /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/ cyrillic-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2JL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/ cyrillic /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa0ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/ greek-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2ZL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/ greek /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/ vietnamese /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa2pL7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/ latin-ext /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa25L7W0Q5n-wU.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/ latin /
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7W0Q5nw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/ cyrillic-ext /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx3cwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/ cyrillic /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxTcwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/ greek /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxPcwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/ vietnamese /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx_cwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/ latin-ext /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx7cwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/ latin /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxDcwgknk-4.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/ cyrillic-ext /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx3cwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/ cyrillic /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxTcwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/ greek /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxPcwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/ vietnamese /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx_cwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/ latin-ext /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPx7cwgknk-6nFg.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/ latin /
@font-face {
font-family: 'JetBrains Mono';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/jetbrainsmono/v24/tDbv2o-flEEny0FZhsfKu5WU4zr3E_BX0PnT8RD8yKwBNntkaToggR7BYRbKPxDcwgknk-4.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
</style>
<style>
body { font-family: 'Inter', sans-serif; background-color: #0f172a; color: #e2e8f0; }
.font-mono { font-family: 'JetBrains Mono', monospace; }
.glass-panel { background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(12px); border: 1px solid rgba(148, 163, 184, 0.1); }
.highlight-text { color: #38bdf8; } / Light Blue */
.neon-border { box-shadow: 0 0 10px rgba(56, 189, 248, 0.3); }
input[type=range] {
-webkit-appearance: none;
background: transparent;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 16px; width: 16px;
border-radius: 50%; background: #38bdf8;
cursor: pointer; margin-top: -6px;
box-shadow: 0 0 10px rgba(56, 189, 248, 0.8);
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%; height: 4px;
cursor: pointer; background: #334155;
border-radius: 2px;
}
.matrix-cell { transition: all 0.3s ease; }
</style>
<script>
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="ib",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=https://maps.${c}apis.com/maps/api/js?+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>dl)})({
key: "AIzaSyBB_SVKlC9CcEjDt1H01_B7Gjmb8FiIaGw",
v: "weekly",
});
</script>
<!-- Header -->
<header class="border-b border-slate-800 bg-slate-900/80 sticky top-0 z-50 backdrop-blur-md">
<div class="max-w-7xl mx-auto px-4 py-4 flex items-center justify-between">
<div class="flex items-center gap-3">
<span class="material-symbols-outlined text-sky-400 text-3xl">hub</span>
<div>
<h1 class="text-xl font-bold tracking-tight text-white">DeepSeek <span class="text-sky-400">mHC</span> Architect</h1>
<p class="text-xs text-slate-400 font-mono">Manifold-Constrained Hyper-Connections Simulator</p>
</div>
</div>
<div class="hidden md:flex items-center gap-4 text-xs font-mono text-slate-400">
<div class="flex items-center gap-1"><span class="w-2 h-2 rounded-full bg-green-500"></span> System Stable</div>
<div class="flex items-center gap-1"><span class="material-symbols-outlined text-sm">science</span> Paper: 2512.24880</div>
</div>
</div>
</header>
<main class="flex-grow p-4 max-w-7xl mx-auto w-full grid grid-cols-1 lg:grid-cols-12 gap-6">
<!-- Left Column: Context & Controls -->
<div class="lg:col-span-4 space-y-6">
<!-- The Quote / Mission -->
<div class="glass-panel p-6 rounded-xl border-l-4 border-sky-500">
<h2 class="text-sm font-bold text-sky-400 uppercase tracking-widest mb-3 flex items-center gap-2">
<span class="material-symbols-outlined text-sm">format_quote</span> Core Hypothesis
</h2>
<p class="text-lg font-light leading-relaxed italic text-white mb-4">
"With <span class="font-bold text-sky-300">n=4</span> configuration, mHC only adds about <span class="font-bold text-red-300">6.7%</span> training overhead. This small computational cost trades for <span class="font-bold text-green-300">extremely high stability</span>."
</p>
<div class="text-xs text-slate-400 border-t border-slate-700 pt-3">
Your Goal: Balance the expansion rate (<span class="font-mono">n</span>) and the constraint algorithm (Sinkhorn) to maximize model capacity without crashing the training run.
</div>
</div>
<!-- Controls -->
<div class="glass-panel p-6 rounded-xl space-y-8">
<!-- Parameter n -->
<div>
<div class="flex justify-between items-end mb-2">
<label class="text-sm font-semibold text-slate-300">Expansion Rate (n)</label>
<span class="text-2xl font-mono text-sky-400" id="val-n">4</span>
</div>
<input type="range" id="slider-n" min="1" max="16" value="4" step="1" class="w-full">
<p class="text-xs text-slate-500 mt-2">Increases residual width & capacity. Standard ResNet is n=1.</p>
</div>
<!-- Sinkhorn Iterations -->
<div>
<div class="flex justify-between items-end mb-2">
<label class="text-sm font-semibold text-slate-300">Sinkhorn Iterations (k)</label>
<span class="text-2xl font-mono text-green-400" id="val-k">20</span>
</div>
<input type="range" id="slider-k" min="0" max="20" value="20" step="1" class="w-full">
<p class="text-xs text-slate-500 mt-2">Projects matrix to Birkhoff Polytope. k=0 is standard HC (Unstable).</p>
</div>
<!-- Simulation Toggle -->
<div class="flex items-center justify-between bg-slate-800/50 p-3 rounded-lg border border-slate-700">
<span class="text-sm font-medium text-slate-300">Show Matrix Visualization</span>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" id="toggle-matrix" class="sr-only peer" checked="">
<div class="w-11 h-6 bg-slate-600 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-sky-500"></div>
</label>
</div>
<!-- Metrics Summary -->
<div class="grid grid-cols-2 gap-4 pt-4 border-t border-slate-700">
<div class="bg-slate-800 p-3 rounded text-center">
<div class="text-xs text-slate-400 uppercase">Training Overhead</div>
<div class="text-xl font-mono text-red-300 mt-1" id="metric-cost">+6.7%</div>
</div>
<div class="bg-slate-800 p-3 rounded text-center">
<div class="text-xs text-slate-400 uppercase">Stability Score</div>
<div class="text-xl font-mono text-green-300 mt-1" id="metric-stability">99.0</div>
</div>
</div>
</div>
<!-- Action Button -->
<button id="btn-train" class="w-full py-4 bg-gradient-to-r from-sky-600 to-blue-700 hover:from-sky-500 hover:to-blue-600 text-white font-bold rounded-xl shadow-lg shadow-sky-900/50 transition-all transform active:scale-95 flex items-center justify-center gap-2">
<span class="material-symbols-outlined">play_circle</span>
Run Training Simulation
</button>
</div>
<!-- Right Column: Visualization -->
<div class="lg:col-span-8 flex flex-col gap-6">
<!-- Real-time Matrix Viewer (Educational) -->
<div id="matrix-container" class="glass-panel p-6 rounded-xl min-h-[200px] flex flex-col items-center justify-center relative overflow-hidden">
<div class="absolute top-4 left-4 text-xs font-mono text-slate-400 uppercase tracking-widest">
Residual Mixing Matrix (Subsample)
</div>
<div class="absolute top-4 right-4 flex gap-4 text-xs">
<div class="flex items-center gap-1"><div class="w-3 h-3 bg-red-500 rounded sm"></div> > 1.0 (Unstable)</div>
<div class="flex items-center gap-1"><div class="w-3 h-3 bg-sky-500 rounded sm"></div> Doubly Stochastic</div>
</div>
<!-- The Matrix Grid -->
<div id="matrix-grid" class="grid gap-1 p-4 bg-slate-900 rounded border border-slate-700 shadow-2xl transition-all duration-500" style="grid-template-columns: repeat(5, minmax(0px, 1fr));"><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div><div class="w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell" style="background-color: rgba(56, 189, 248, 0.3); color: white;">0.20</div></div>
<div class="mt-4 text-center text-sm text-slate-400 max-w-md">
<span id="matrix-status" class="mt-4 text-center text-sm text-green-400">Manifold Constrained (mHC): Perfectly Balanced. Energy Preserved.</span>
</div>
</div>
<!-- Signal Propagation Chart -->
<div class="glass-panel p-6 rounded-xl flex-grow flex flex-col">
<div class="flex justify-between items-center mb-4">
<h3 class="text-sm font-bold text-white uppercase tracking-widest flex items-center gap-2">
<span class="material-symbols-outlined text-yellow-400">show_chart</span>
Signal Norm vs. Depth
</h3>
<span id="explosion-alert" class="hidden text-xs font-bold bg-red-900 text-red-200 px-2 py-1 rounded animate-pulse">
⚠️ SIGNAL EXPLOSION DETECTED
</span>
</div>
<div class="relative w-full h-64">
<canvas id="signalChart" width="1281" height="512" style="display: block; box-sizing: border-box; height: 256px; width: 640.7px;"></canvas>
</div>
<p class="text-xs text-slate-500 mt-2">
Visualizes how signal magnitude changes as it propagates through deep layers. A flat line (Norm ≈ 1) is ideal for stability.
</p>
</div>
<!-- Training Loss Simulation -->
<div class="glass-panel p-6 rounded-xl flex-grow flex flex-col">
<h3 class="text-sm font-bold text-white uppercase tracking-widest mb-4 flex items-center gap-2">
<span class="material-symbols-outlined text-purple-400">history_edu</span>
Training Dynamics
</h3>
<div class="relative w-full h-48">
<canvas id="lossChart" width="1281" height="384" style="display: block; box-sizing: border-box; height: 192px; width: 640.7px;"></canvas>
</div>
</div>
</div>
</main>
<!-- Overlay for Training -->
<div id="training-overlay" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-[100] flex flex-col items-center justify-center hidden">
<div class="bg-slate-900 border border-sky-500/50 p-8 rounded-2xl max-w-md w-full text-center shadow-2xl shadow-sky-500/20">
<div class="mb-6">
<span class="material-symbols-outlined text-6xl text-sky-400 animate-spin">autorenew</span>
</div>
<h2 class="text-2xl font-bold text-white mb-2">Training DeepSeek-V3...</h2>
<div class="space-y-4 mb-6">
<div class="flex justify-between text-sm text-slate-400">
<span>Progress</span>
<span id="train-progress-text">100%</span>
</div>
<div class="w-full bg-slate-800 rounded-full h-2 overflow-hidden">
<div id="train-bar" class="bg-sky-500 h-2 rounded-full transition-all duration-100" style="width: 100%;"></div>
</div>
<div id="train-status" class="font-mono text-lg text-green-400 font-bold h-6">Training Complete! Model Converged.</div>
</div>
<button id="btn-stop" class="px-6 py-2 bg-slate-700 hover:bg-slate-600 text-white rounded-lg text-sm font-semibold transition-colors">
Abort
</button>
</div>
</div>
<!-- Scripts -->
<script>
// --- Logic & Math Models ---
// Configuration State
const state = {
n: 4, // Expansion Rate
k: 20, // Sinkhorn Iterations
baseCost: 1.0,
baseStability: 1.0
};
// DOM Elements
const els = {
sliderN: document.getElementById('slider-n'),
sliderK: document.getElementById('slider-k'),
valN: document.getElementById('val-n'),
valK: document.getElementById('val-k'),
metricCost: document.getElementById('metric-cost'),
metricStability: document.getElementById('metric-stability'),
matrixGrid: document.getElementById('matrix-grid'),
matrixStatus: document.getElementById('matrix-status'),
alert: document.getElementById('explosion-alert'),
btnTrain: document.getElementById('btn-train'),
trainingOverlay: document.getElementById('training-overlay'),
trainBar: document.getElementById('train-bar'),
trainText: document.getElementById('train-progress-text'),
trainStatus: document.getElementById('train-status'),
btnStop: document.getElementById('btn-stop')
};
// Charts
let signalChart, lossChart;
// --- Math Functions ---
// Calculate Cost Overhead Percentage
// Based on prompt: n=4 -> 6.7%.
// Assumption: Linear scaling O(n). overhead = 1.675 * n.
function getOverheadPercent(n) {
return (1.675 * n).toFixed(1);
}
// Calculate Stability Factor (0 to 1)
// Depends heavily on k (Sinkhorn iterations).
// If k=0 (HC), stability degrades with n.
// If k=20 (mHC), stability is high regardless of n.
function getStabilityFactor(n, k) {
// k ranges 0-20.
// Normalized k:
const kNorm = k / 20;
// Base instability from width n (wider = more chance for explosion without constraints)
// If n is high and k is low -> Very Unstable.
// If k is high -> Very Stable.
// Equation: Stability = Base + (Gain from k) - (Penalty from n if k is low)
let s = 0.5 + (0.49 * (1 - Math.exp(-0.5 * k)));
// Penalty: if k < 5, n hurts stability significantly
if (k < 5) {
s -= (n * 0.05 * (5-k)/5);
}
return Math.max(0.1, Math.min(0.999, s));
}
// Simulate Signal Propagation (Norm vs Depth)
function simulateSignalNorm(n, k) {
const depths = Array.from({length: 64}, (_, i) => i); // 64 Layers
// Growth factor per layer.
// If k is high, growth is ~1.0 (Doubly Stochastic).
// If k is low, growth is > 1.0 (random matrix).
// Base growth rate
// at k=0, growth might be 1.1 per layer (explodes to 1.1^60 ~ 300)
// at k=20, growth is 1.0001
const kFactor = Math.max(0, 20 - k) / 20; // 1.0 at k=0, 0.0 at k=20
const growthRate = 1.0 + (kFactor * 0.15) + (n * kFactor * 0.02);
return depths.map(d => {
let val = Math.pow(growthRate, d);
// Add some noise
val = val * (1 + (Math.random() * 0.1 - 0.05));
return Math.min(val, 1000); // Cap for chart
});
}
// --- Visualization Functions ---
function updateMatrixVisual(n, k) {
// We visualize a 4x4 or nxn (clamped) matrix
const size = Math.min(n + 1, 6); // Visual cap
els.matrixGrid.style.gridTemplateColumns = `repeat(${size}, minmax(0, 1fr))`;
els.matrixGrid.innerHTML = '';
const isStable = k > 10;
const variance = Math.max(0, 20 - k) / 20; // 0 if stable, 1 if chaos
for(let i=0; i<size*size; i++) {
const cell = document.createElement('div');
cell.className = 'w-8 h-8 rounded text-[10px] flex items-center justify-center font-mono matrix-cell';
// Value logic
let val;
if(isStable) {
// Doubly stochastic ideal: 1/size
const noise = (Math.random() - 0.5) * variance;
val = (1/size) + noise;
} else {
// Random HC
val = Math.random() * 2.0;
}
// Color Logic
if (val > 1.2) {
cell.style.backgroundColor = `rgba(239, 68, 68, ${Math.min(1, val/2)})`; // Red
cell.style.color = 'white';
} else {
const alpha = Math.max(0.1, val * 1.5);
cell.style.backgroundColor = `rgba(56, 189, 248, ${alpha})`; // Blue
cell.style.color = alpha > 0.5 ? '#0f172a' : 'white';
}
cell.textContent = val.toFixed(2);
els.matrixGrid.appendChild(cell);
}
if (k === 0) {
els.matrixStatus.textContent = "Raw Hyper-Connection: Unbounded values. Risk of explosion.";
els.matrixStatus.className = "mt-4 text-center text-sm text-red-400 font-bold animate-pulse";
} else if (k < 15) {
els.matrixStatus.textContent = `Sinkhorn Iteration ${k}: Converging to doubly stochastic...`;
els.matrixStatus.className = "mt-4 text-center text-sm text-yellow-400";
} else {
els.matrixStatus.textContent = "Manifold Constrained (mHC): Perfectly Balanced. Energy Preserved.";
els.matrixStatus.className = "mt-4 text-center text-sm text-green-400";
}
}
function updateMetrics() {
const overhead = getOverheadPercent(state.n);
const stability = getStabilityFactor(state.n, state.k);
els.metricCost.innerText = `+${overhead}%`;
els.metricStability.innerText = (stability * 100).toFixed(1);
// Signal Chart Update
const signalData = simulateSignalNorm(state.n, state.k);
signalChart.data.datasets[0].data = signalData;
signalChart.update();
// Check explosion
if (signalData[signalData.length-1] > 10) {
els.alert.classList.remove('hidden');
els.metricStability.classList.replace('text-green-300', 'text-red-500');
} else {
els.alert.classList.add('hidden');
els.metricStability.classList.replace('text-red-500', 'text-green-300');
}
}
// --- Chart Initialization ---
function initCharts() {
// Signal Norm Chart
const ctxSignal = document.getElementById('signalChart').getContext('2d');
signalChart = new Chart(ctxSignal, {
type: 'line',
data: {
labels: Array.from({length: 64}, (_, i) => i),
datasets: [{
label: 'Signal Norm (Forward Pass)',
borderColor: '#38bdf8',
backgroundColor: 'rgba(56, 189, 248, 0.1)',
borderWidth: 2,
fill: true,
data: [],
pointRadius: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
type: 'logarithmic',
grid: { color: '#334155' },
ticks: { color: '#94a3b8' },
title: { display: true, text: 'Log Scale', color: '#64748b' }
},
x: {
grid: { display: false },
ticks: { color: '#94a3b8' },
title: { display: true, text: 'Layer Depth', color: '#64748b' }
}
},
plugins: { legend: { display: false } }
}
});
// Loss Chart
const ctxLoss = document.getElementById('lossChart').getContext('2d');
lossChart = new Chart(ctxLoss, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'Training Loss',
borderColor: '#a78bfa',
borderWidth: 2,
data: [],
pointRadius: 0,
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
animation: false,
scales: {
y: {
grid: { color: '#334155' },
ticks: { color: '#94a3b8' }
},
x: { display: false }
},
plugins: { legend: { display: false } }
}
});
}
// --- Simulation Logic ---
let trainingInterval;
function startTraining() {
els.trainingOverlay.classList.remove('hidden');
const n = state.n;
const k = state.k;
const stability = getStabilityFactor(n, k);
const overhead = parseFloat(getOverheadPercent(n));
// Speed depends on cost. Higher cost = Slower progress.
// Base speed: 100ms per tick. Cost adds delay.
const tickSpeed = 50 * (1 + overhead/10);
let progress = 0;
let step = 0;
let currentLoss = 10.0;
// Reset Loss Chart
lossChart.data.labels = [];
lossChart.data.datasets[0].data = [];
trainingInterval = setInterval(() => {
progress += 1;
step++;
// Logic for Loss Curve
// If stable: exponential decay with noise.
// If unstable: random spikes, potential divergence.
if (Math.random() > stability) {
// Instability Event!
currentLoss += (Math.random() * 5); // Spike
els.trainStatus.innerText = `Gradient Spike detected at step ${step}...`;
els.trainStatus.className = "font-mono text-sm text-red-400 h-6 animate-pulse";
} else {
// Normal Descent
currentLoss = currentLoss * 0.95;
els.trainStatus.innerText = `Step ${step}: Optimizing manifold constraints...`;
els.trainStatus.className = "font-mono text-sm text-sky-300 h-6";
}
// Add noise
let displayLoss = currentLoss + (Math.random() * 0.5);
// Check Divergence (Game Over)
if (displayLoss > 50) {
clearInterval(trainingInterval);
els.trainStatus.innerText = "TRAINING DIVERGED due to instability!";
els.trainStatus.className = "font-mono text-lg text-red-500 font-bold h-6";
setTimeout(() => els.trainingOverlay.classList.add('hidden'), 2000);
return;
}
// Update UI
els.trainBar.style.width = `${progress}%`;
els.trainText.innerText = `${progress}%`;
lossChart.data.labels.push(step);
lossChart.data.datasets[0].data.push(displayLoss);
lossChart.update();
if (progress >= 100) {
clearInterval(trainingInterval);
els.trainStatus.innerText = "Training Complete! Model Converged.";
els.trainStatus.className = "font-mono text-lg text-green-400 font-bold h-6";
setTimeout(() => els.trainingOverlay.classList.add('hidden'), 1500);
}
}, tickSpeed);
}
// --- Event Listeners ---
els.sliderN.addEventListener('input', (e) => {
state.n = parseInt(e.target.value);
els.valN.innerText = state.n;
updateMetrics();
updateMatrixVisual(state.n, state.k);
});
els.sliderK.addEventListener('input', (e) => {
state.k = parseInt(e.target.value);
els.valK.innerText = state.k;
updateMetrics();
updateMatrixVisual(state.n, state.k);
});
els.btnTrain.addEventListener('click', startTraining);
els.btnStop.addEventListener('click', () => {
clearInterval(trainingInterval);
els.trainingOverlay.classList.add('hidden');
});
document.getElementById('toggle-matrix').addEventListener('change', (e) => {
document.getElementById('matrix-container').classList.toggle('hidden');
});
// --- Init ---
window.addEventListener('DOMContentLoaded', () => {
initCharts();
updateMetrics();
updateMatrixVisual(4, 20);
// Initial flash of n=4 logic
setTimeout(() => {
// Intro animation or tooltip could go here
}, 500);
});
</script>