<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mayuresh Smita Suresh</title>
    <description>The latest articles on DEV Community by Mayuresh Smita Suresh (@mayu2008).</description>
    <link>https://dev.to/mayu2008</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3571903%2Ffce1104c-74aa-424e-9521-7195968d0ad0.jpeg</url>
      <title>DEV Community: Mayuresh Smita Suresh</title>
      <link>https://dev.to/mayu2008</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mayu2008"/>
    <language>en</language>
    <item>
      <title>Honoured to receive Google AI Badge. Awarded for publishing a top Google AI post. Thank you Dev team.</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Fri, 20 Mar 2026 05:37:17 +0000</pubDate>
      <link>https://dev.to/mayu2008/honoured-to-receive-google-ai-badge-awarded-for-publishing-a-top-google-ai-post-thank-you-dev-1c56</link>
      <guid>https://dev.to/mayu2008/honoured-to-receive-google-ai-badge-awarded-for-publishing-a-top-google-ai-post-thank-you-dev-1c56</guid>
      <description></description>
    </item>
    <item>
      <title>mcpnest.cloud 
Calling all dev to support my new platform, I am building a robust platform to deploy any MCP easily and manage it and scale it easy. Please join the waitlist your support matters a lot. Thank you.</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 11 Mar 2026 07:00:34 +0000</pubDate>
      <link>https://dev.to/mayu2008/mcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-to-4ndn</link>
      <guid>https://dev.to/mayu2008/mcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-to-4ndn</guid>
      <description></description>
    </item>
    <item>
      <title>https://mcpnest.cloud 
Calling all dev to support my new platform, I am building a robust platform to deploy any MCP easily and manage it and scale it easy. Please join the waitlist your support matters a lot. Thank you.</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 11 Mar 2026 07:00:02 +0000</pubDate>
      <link>https://dev.to/mayu2008/httpsmcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-4o9i</link>
      <guid>https://dev.to/mayu2008/httpsmcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-4o9i</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://mcpnest.cloud/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmcpnest.cloud%2FMCPNest-logo.png" height="800" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://mcpnest.cloud/" rel="noopener noreferrer" class="c-link"&gt;
            MCPNest | Deploy MCP Servers Instantly
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Deploy, scale, and manage your Model Context Protocol servers in minutes.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmcpnest.cloud%2Ficon.ico%3Ficon.7e10ef02.ico" width="16" height="16"&gt;
          mcpnest.cloud
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Why MCP servers deployments are so hard?</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Tue, 10 Mar 2026 13:39:06 +0000</pubDate>
      <link>https://dev.to/mayu2008/why-mcp-servers-deployments-are-so-hard-27ho</link>
      <guid>https://dev.to/mayu2008/why-mcp-servers-deployments-are-so-hard-27ho</guid>
      <description></description>
      <category>ai</category>
      <category>devops</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>MILP From Scratch in Pure Rust — No Dependencies, Full Branch and Bound</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 04 Mar 2026 18:33:49 +0000</pubDate>
      <link>https://dev.to/mayu2008/milp-from-scratch-in-pure-rust-no-dependencies-full-branch-and-bound-2a01</link>
      <guid>https://dev.to/mayu2008/milp-from-scratch-in-pure-rust-no-dependencies-full-branch-and-bound-2a01</guid>
      <description>&lt;p&gt;If you’ve ever seen terms like &lt;em&gt;linear programming&lt;/em&gt;, &lt;em&gt;integer optimisation&lt;/em&gt;, or &lt;em&gt;Branch and Bound&lt;/em&gt; and felt lost — this post is for you.&lt;/p&gt;

&lt;p&gt;We’ll build a &lt;strong&gt;complete MILP solver in pure Rust&lt;/strong&gt; (zero external crates) that solves a real factory planning problem. Every term is explained from scratch. The code compiles and runs today.&lt;/p&gt;

&lt;p&gt;By the end you’ll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What MILP is and why it’s hard&lt;/li&gt;
&lt;li&gt;The full mathematical formulation&lt;/li&gt;
&lt;li&gt;What Branch and Bound actually does (with the real tree output)&lt;/li&gt;
&lt;li&gt;Why this matters for quantum optimisation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: A Furniture Factory
&lt;/h2&gt;

&lt;p&gt;A furniture factory makes two products:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Product&lt;/th&gt;
&lt;th&gt;Profit&lt;/th&gt;
&lt;th&gt;Machine hrs needed&lt;/th&gt;
&lt;th&gt;Wood units needed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table (x₁)&lt;/td&gt;
&lt;td&gt;£50 each&lt;/td&gt;
&lt;td&gt;3 hrs&lt;/td&gt;
&lt;td&gt;4 units&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chair (x₂)&lt;/td&gt;
&lt;td&gt;£30 each&lt;/td&gt;
&lt;td&gt;2 hrs&lt;/td&gt;
&lt;td&gt;3 units&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Available resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Machine hours:&lt;/strong&gt; 120 total&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wood:&lt;/strong&gt; 160 units total&lt;/li&gt;
&lt;li&gt;Market demand caps: max 30 tables, max 40 chairs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question: How many tables and chairs to make to maximise profit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can’t make 16.7 tables. They must be whole numbers. That’s the key challenge — and it’s what makes this MILP.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is MILP? (Every Word Explained)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Linear&lt;/strong&gt; → All relationships are proportional. Profit scales linearly with units. &lt;code&gt;profit = 50 × tables + 30 × chairs&lt;/code&gt; — no powers, no curves, just straight lines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Programming&lt;/strong&gt; → Old term for “optimisation”. Nothing to do with coding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integer&lt;/strong&gt; → Some variables must be whole numbers. You can’t produce 2.5 tables or hire 0.7 people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mixed&lt;/strong&gt; → Some variables can be continuous (e.g. temperature, weight, price) while others must be integer (units, people, machines). Our problem has &lt;em&gt;all&lt;/em&gt; integer variables, but MILP handles both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is it hard?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pure LP (without integers) is solvable in polynomial time — milliseconds even for massive problems. The moment you add integer constraints, the problem becomes &lt;strong&gt;NP-hard&lt;/strong&gt;. You can’t just solve equations — you need to search through combinations. A factory with 100 products has more valid integer combinations than atoms in the universe.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mathematics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Decision Variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x₁ = number of Tables to produce  (integer, ≥ 0)
x₂ = number of Chairs to produce  (integer, ≥ 0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are what the solver decides. Everything else is fixed input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objective Function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Maximise:  Z = 50·x₁ + 30·x₂
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every table adds £50 to profit. Every chair adds £30. We want Z as large as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constraints
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3·x₁ + 2·x₂  ≤  120     ← machine hours: can't exceed 120 total
4·x₁ + 3·x₂  ≤  160     ← wood: can't exceed 160 units
      x₁      ≤   30     ← market can only absorb 30 tables
           x₂ ≤   40     ← market can only absorb 40 chairs
x₁, x₂       ≥    0     ← can't produce negative quantities
x₁, x₂       ∈   ℤ⁺    ← must be whole numbers (the "Integer" in MILP)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Matrix Form
&lt;/h3&gt;

&lt;p&gt;Solvers work with matrices. Written as &lt;code&gt;A·x ≤ b&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     A           x      b
[ 3  2 ]   [ x₁ ]   [ 120 ]
[ 4  3 ] · [ x₂ ] ≤ [ 160 ]

Objective vector c = [50, 30]
Maximise cᵀ·x  subject to  A·x ≤ b,  lb ≤ x ≤ ub,  x ∈ ℤ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Does the Feasible Region Look Like?
&lt;/h3&gt;

&lt;p&gt;Plot x₁ on the x-axis, x₂ on the y-axis. Each constraint is a line. The &lt;strong&gt;feasible region&lt;/strong&gt; is the polygon where all constraints are satisfied simultaneously. The optimal solution always sits at a corner (vertex) of this polygon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x₂ (Chairs)
40 |---.
   |    \   ← demand cap x₂ ≤ 40
   |     \
   |      ◆ ← OPTIMAL: (30, 13), Profit = £1890
   |      .\
   |      . \  ← Wood: 4x₁ + 3x₂ = 160
   |      .  \
   |      .   \__ Machine: 3x₁ + 2x₂ = 120
   |___________ x₁ (Tables)
   0           30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Algorithm: Branch and Bound
&lt;/h2&gt;

&lt;p&gt;This is how every serious MILP solver works at its core.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: LP Relaxation
&lt;/h3&gt;

&lt;p&gt;First, forget the integer constraint. Solve as pure LP (allowing fractions). This gives the &lt;strong&gt;upper bound&lt;/strong&gt; — the best profit achievable if fractions were allowed.&lt;/p&gt;

&lt;p&gt;For our problem, LP relaxation gives: x₁ = 30, x₂ = 13.33, profit = £1,900.&lt;/p&gt;

&lt;p&gt;But x₂ = 13.33 is fractional. We can’t make 13.33 chairs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Branch
&lt;/h3&gt;

&lt;p&gt;Pick the fractional variable (x₂ = 13.33). Split into two sub-problems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Branch A: x₂ ≤ 13   (round down)
Branch B: x₂ ≥ 14   (round up)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push both onto the search stack. Now solve each one’s LP relaxation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Bound
&lt;/h3&gt;

&lt;p&gt;For each sub-problem, the LP relaxation gives an upper bound. If that upper bound is worse than the best integer solution found so far — &lt;strong&gt;prune the branch&lt;/strong&gt; (don’t explore further). This is what makes B&amp;amp;B efficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Repeat
&lt;/h3&gt;

&lt;p&gt;Keep branching on fractional variables, pruning hopeless branches, until every branch is either pruned or yields an integer solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Actual Search Tree (from the code output)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Node  1] depth=0  LP=1900.0 → BRANCH x₂=13.33 (≤13 | ≥14)
[Node  2] depth=1  LP=1895.0 → BRANCH x₁=29.5  (≤29 | ≥30)
[Node  3] depth=2  → INFEASIBLE, pruned
[Node  4] depth=2  LP=1890.0 → BRANCH x₂=14.67 (≤14 | ≥15)
[Node  5] depth=3  LP=1887.5 → BRANCH x₁=28.75 (≤28 | ≥29)
[Node  6] depth=4  → INFEASIBLE, pruned
[Node  7] depth=4  LP=1880.0 → ✓ INTEGER (x1=28, x2=16) ★ £1880
[Node  8] depth=3  LP=1870.0 ≤ best=1880 → PRUNED
[Node  9] depth=1  LP=1890.0 → ✓ INTEGER (x1=30, x2=13) ★ £1890
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only &lt;strong&gt;9 nodes&lt;/strong&gt; to find the global optimum. Without B&amp;amp;B, brute force would check 30×40 = 1,200 combinations. For larger problems (1,000 variables), B&amp;amp;B reduces billions of checks to thousands.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Rust Code
&lt;/h2&gt;

&lt;p&gt;Pure Rust. Zero external dependencies. The full solver from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Structures
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// The LP problem in standard form: Maximise c·x subject to A·x ≤ b&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LpProblem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// objective coefficients&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// constraint matrix&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// rhs of constraints&lt;/span&gt;
    &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// lower bounds per variable&lt;/span&gt;
    &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// upper bounds per variable&lt;/span&gt;
    &lt;span class="n"&gt;n_vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/// One node in the Branch and Bound search tree.&lt;/span&gt;
&lt;span class="cd"&gt;/// Each node represents a sub-problem with tightened bounds.&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// current lower bounds (tightened by branching)&lt;/span&gt;
    &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// current upper bounds (tightened by branching)&lt;/span&gt;
    &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// depth in tree (for logging)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LP Relaxation Solver (Coordinate Ascent)
&lt;/h3&gt;

&lt;p&gt;For each node we solve the LP relaxation — the same problem but without integer constraints.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;coordinate ascent&lt;/strong&gt;: move each variable as far as possible in its profit-improving direction while staying feasible. For small bounded problems like ours, this converges to the exact LP optimum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;solve_lp_relaxation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LpResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.n_vars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Start at lower bounds (always feasible when b ≥ 0)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_iter&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10_000&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;improved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;           &lt;span class="c1"&gt;// gradient: improving direction for x[i]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;1e-10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Find how far we can move x[i] before hitting a constraint&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;max_step_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// move up&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;max_step_down&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// move down&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1e-9&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1e-10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;improved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// revert if no improvement&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;improved&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// converged&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nn"&gt;LpResult&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Optimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;max_step_up&lt;/code&gt; computes the maximum safe step by checking each constraint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;max_step_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;max_step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;            &lt;span class="c1"&gt;// can't exceed upper bound&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.b&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_ki&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a_ki&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1e-10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bk&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;a_ki&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// slack / coefficient = max safe step&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_step&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;max_step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;max_step&lt;/span&gt;&lt;span class="nf"&gt;.max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Branch and Bound
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;branch_and_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;integer_vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MilpSolution&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NEG_INFINITY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;best_x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                                               &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}];&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// 1. Solve LP relaxation for this node&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;solve_lp_relaxation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;LpResult&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Infeasible&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// prune: infeasible&lt;/span&gt;
            &lt;span class="nn"&gt;LpResult&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Optimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// 2. Prune if LP bound can't beat current best&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lp_obj&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Find most fractional integer variable (closest fraction to 0.5)&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;branch_var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;integer_vars&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;is_int&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;is_int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;frac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;frac&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;frac&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="nf"&gt;.min_by&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="nf"&gt;.partial_cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;fj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;branch_var&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// All integer vars are integral → valid integer solution!&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lp_obj&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;best_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;floor_v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.floor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ceil_v&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.ceil&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                &lt;span class="c1"&gt;// Child 1: x[vi] ≤ floor (round down branch)&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ub2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;ub2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ub2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;floor_v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ub2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.depth&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

                &lt;span class="c1"&gt;// Child 2: x[vi] ≥ ceil (round up branch)&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lb2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;lb2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lb2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ceil_v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lb2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.depth&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;best_x&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MilpSolution&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;nodes_explored&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Defining the Problem
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;30.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;        &lt;span class="c1"&gt;// objective: max 50x₁ + 30x₂&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// 3x₁ + 2x₂ ≤ 120  (machine hours)&lt;/span&gt;
            &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// 4x₁ + 3x₂ ≤ 160  (wood supply)&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;120.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;160.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// rhs&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mf"&gt;0.0&lt;/span&gt;  &lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// lower bounds: x₁, x₂ ≥ 0&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;30.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mf"&gt;40.0&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// upper bounds: x₁ ≤ 30, x₂ ≤ 40&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;integer_vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;   &lt;span class="c1"&gt;// both must be integers&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;branch_and_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;integer_vars&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;╔══════════════════════════════════════════════════════════╗
║     MILP Solver — Pure Rust, Zero Dependencies          ║
║     Factory Production Planning (Branch and Bound)      ║
╚══════════════════════════════════════════════════════════╝

BRANCH AND BOUND TREE:
──────────────────────────────────────────────────────────
  [Node   1] depth=0 obj=1900.0 → BRANCH x2=13.333 (≤13 | ≥14)
  [Node   2] depth=1 obj=1895.0 → BRANCH x1=29.500 (≤29 | ≥30)
  [Node   3] depth=2 → INFEASIBLE, pruned
  [Node   4] depth=2 obj=1890.0 → BRANCH x2=14.667 (≤14 | ≥15)
  [Node   5] depth=3 obj=1887.5 → BRANCH x1=28.750 (≤28 | ≥29)
  [Node   6] depth=4 → INFEASIBLE, pruned
  [Node   7] depth=4 obj=1880.0 → ✓ INTEGER (x1=28, x2=16)  ★ £1880
  [Node   8] depth=3 LP=1870.0 ≤ best=1880.0 → PRUNED
  [Node   9] depth=1 obj=1890.0 → ✓ INTEGER (x1=30, x2=13)  ★ £1890

╔══════════════════════════════════════════════════════════╗
║               ✅ OPTIMAL SOLUTION                       ║
╠══════════════════════════════════════════════════════════╣
║  Tables  (x₁) :    30 units                            ║
║  Chairs  (x₂) :    13 units                            ║
║  Max Profit   : £1890                                   ║
╠══════════════════════════════════════════════════════════╣
║  Machine hrs  : 116 / 120  (96.7% utilised)            ║
║  Wood used    : 159 / 160  (99.4% utilised)            ║
║  B&amp;amp;B Nodes    :    9 explored                          ║
╠══════════════════════════════════════════════════════════╣
║  CONSTRAINT CHECK:                                      ║
║  3(30)+2(13) = 116 ≤ 120  ✓                            ║
║  4(30)+3(13) = 159 ≤ 160  ✓                            ║
║  x₁=30 ≤ 30  ✓                                         ║
║  x₂=13 ≤ 40  ✓                                         ║
╚══════════════════════════════════════════════════════════╝

WHY NOT A SIMPLER GUESS?
──────────────────────────────────────────────────────────
  All tables (30, 0)         profit=£1500  ✓
  All chairs (0, 40)         profit=£1200  ✓
  Equal split (20, 20)       profit=£1600  ✓
  Optimal (30, 13)           profit=£1890  ✓  ← solver wins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The solver found &lt;strong&gt;£1,890&lt;/strong&gt; — significantly better than every naive guess, and it verified all constraints automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new milp_solver
&lt;span class="c"&gt;# paste main.rs (link below)&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;Cargo.toml&lt;/code&gt; dependencies needed. Pure Rust standard library only.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Terms — Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decision variable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What the solver decides (x₁, x₂)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Objective function&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What you’re maximising or minimising (Z = 50x₁ + 30x₂)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Constraint&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A rule the solution must satisfy (3x₁ + 2x₂ ≤ 120)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feasible region&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All points satisfying every constraint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LP relaxation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same problem without integer constraint — gives upper bound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Branch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Split a fractional variable into two sub-problems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bound&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prune branches whose LP bound can’t beat the current best&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prune&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Discard a branch — guaranteed to not contain the optimum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integer solution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All integer variables have whole-number values&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why This Matters for Quantum Computing
&lt;/h2&gt;

&lt;p&gt;Classical MILP solvers (HiGHS, Gurobi, OR-Tools) handle problems up to roughly 10,000–100,000 variables well. Beyond that, Branch and Bound’s exponential tree becomes intractable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quantum optimisation&lt;/strong&gt; attacks this differently. Instead of sequentially searching the B&amp;amp;B tree, quantum algorithms explore combinations simultaneously via superposition. But to feed problems to a quantum computer, you need to convert them to &lt;strong&gt;QUBO&lt;/strong&gt; (Quadratic Unconstrained Binary Optimisation):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MILP → convert integer vars to binary → add constraint penalties → QUBO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once in QUBO form, quantum algorithms like &lt;strong&gt;QAOA&lt;/strong&gt; or quantum-inspired algorithms like &lt;strong&gt;Simulated Bifurcation&lt;/strong&gt; can solve it — and they scale better on large, dense combinatorial problems where classical B&amp;amp;B degrades.&lt;/p&gt;

&lt;p&gt;This Rust implementation is the foundation. In the next post, we’ll convert this exact MILP into a QUBO matrix and run it through a Simulated Bifurcation solver — still in pure Rust.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 2:&lt;/strong&gt; QUBO conversion — turning this MILP into a matrix a quantum solver can eat&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3:&lt;/strong&gt; Simulated Bifurcation in Rust — quantum-inspired solver from scratch, no hardware needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4:&lt;/strong&gt; Benchmarking against HiGHS on large-scale problems&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;I’m &lt;a href="https://tagnovate.com/mayuresh" rel="noopener noreferrer"&gt;Mayuresh&lt;/a&gt;, Founder &amp;amp; CTO at &lt;a href="https://ambicube.com" rel="noopener noreferrer"&gt;AmbiCube&lt;/a&gt;. Building quantum-classical optimisation infrastructure in Rust. My vision is to build world’s best schedule solution company, if anyone is interested in learning something real computer science then get in touch and help me. Follow for posts on Rust, quantum algorithms, and applied AI systems&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What do you think about my idea?</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sun, 01 Mar 2026 14:11:57 +0000</pubDate>
      <link>https://dev.to/mayu2008/what-do-you-think-about-my-idea-3ne7</link>
      <guid>https://dev.to/mayu2008/what-do-you-think-about-my-idea-3ne7</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/mayu2008" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3571903%2Ffce1104c-74aa-424e-9521-7195968d0ad0.jpeg" alt="mayu2008"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/mayu2008/i-built-an-app-to-help-elderly-and-disabled-people-in-my-neighbourhood-90h" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;I built an app to help Elderly and Disabled people in my neighbourhood&lt;/h2&gt;
      &lt;h3&gt;Mayuresh Smita Suresh ・ Feb 28&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#devchallenge&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#weekendchallenge&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I built an app to help Elderly and Disabled people in my neighbourhood</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sat, 28 Feb 2026 10:46:22 +0000</pubDate>
      <link>https://dev.to/mayu2008/i-built-an-app-to-help-elderly-and-disabled-people-in-my-neighbourhood-90h</link>
      <guid>https://dev.to/mayu2008/i-built-an-app-to-help-elderly-and-disabled-people-in-my-neighbourhood-90h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My grandmother couldn't change a lightbulb, neither can take her dog on walk and I live 200 miles away, I cant be there every time.
&lt;/h2&gt;

&lt;p&gt;Not because she was frail. Not because she lacked the will. But at 78, with arthritic hands and a second-floor flat with no elevator, climbing a stepladder to reach a ceiling fixture was genuinely dangerous. She lived alone. My family was two cities away. And she sat in a dim room for six days before she finally asked her neighbor — a stranger she'd shared a building with for three years — for help.&lt;/p&gt;

&lt;p&gt;Six days in a dim room. Because she didn't know if it was okay to ask.&lt;/p&gt;

&lt;p&gt;That's the problem NearbyHelp is built to solve. Not emergencies. Not disasters. The quiet, grinding, invisible difficulty of daily life for millions of elderly and disabled people who need small help — and have no idea who around them is willing to give it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The community I built for is one that rarely gets built for: elderly individuals, disabled people, and anyone who lives alone and needs occasional help with day-to-day tasks that most of us take for granted.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're talking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An 80-year-old who needs someone to carry a heavy box down from a shelf&lt;/li&gt;
&lt;li&gt;A person with MS who needs a neighbor to pick up their prescription on the way back from the shops&lt;/li&gt;
&lt;li&gt;A visually impaired resident who needs help navigating a council form online&lt;/li&gt;
&lt;li&gt;Someone post-surgery who just needs their groceries picked up once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't crises. There's no ambulance to call. There's no app for this. There's just... the hope that someone nearby is kind enough, and that you're brave enough to ask.&lt;/p&gt;

&lt;p&gt;The second part of that equation — the willingness of neighbors to help — already exists in abundance. What's missing is the infrastructure to make that willingness &lt;em&gt;visible&lt;/em&gt;. Right now, the goodwill is there. It's just invisible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NearbyHelp makes it visible.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;NearbyHelp is a community-first web application where local volunteers register specific tasks they're willing to help with — and anyone nearby can open a map, see exactly who's available, how far away they are, and call them directly.&lt;/p&gt;

&lt;p&gt;The philosophy is deliberate simplicity: &lt;strong&gt;one volunteer, one skill offer, one pin on the map.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No social network. No messaging layer. No karma points. Just a live map of willing neighbors, searchable by task type, sorted by distance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Features
&lt;/h3&gt;

&lt;p&gt;** Live Interactive Map**&lt;br&gt;
Built on &lt;code&gt;react-leaflet&lt;/code&gt;, the map shows every registered volunteer as a color-coded pin based on their task category. Tap a pin, see their name, what they can help with, and a direct call button. That's it. Designed specifically to be usable by elderly people on tablets — large tap targets, high contrast, no clutter.&lt;/p&gt;

&lt;p&gt;** Haversine Proximity Sorting**&lt;br&gt;
Every volunteer's distance from your location is calculated in real time using the Haversine formula — the same spherical geometry used in aviation navigation. It's not "roughly in your area." It's "0.4 km away." That specificity matters when you're deciding whether to ask someone for help.&lt;/p&gt;

&lt;p&gt;** AI Skill Categorization (Google Gemini)**&lt;br&gt;
Volunteers type what they can help with in plain English: &lt;em&gt;"I can help move furniture and do heavy lifting"&lt;/em&gt; or &lt;em&gt;"happy to help with tech stuff, phones, tablets, computers."&lt;/em&gt; Google's Gemini AI reads their natural language and maps it to a standardized tag: &lt;code&gt;MAINTENANCE&lt;/code&gt;, &lt;code&gt;TECH_HELP&lt;/code&gt;, &lt;code&gt;ERRANDS&lt;/code&gt;, &lt;code&gt;HOUSEWORK&lt;/code&gt;, &lt;code&gt;TRANSPORT&lt;/code&gt;, &lt;code&gt;COMPANIONSHIP&lt;/code&gt;. This means the map filter works reliably regardless of how different people describe the same task.&lt;/p&gt;

&lt;p&gt;** One-Tap Direct Call**&lt;br&gt;
Volunteers who opt in share a contact number. The app generates a native &lt;code&gt;tel:&lt;/code&gt; link — on mobile, one tap opens the phone dialer. No messaging, no waiting for a reply. Direct human contact, immediately.&lt;/p&gt;

&lt;p&gt;** Mobile-First List View**&lt;br&gt;
A swipeable overlay on mobile showing volunteers as cards sorted nearest-first. Built specifically because many of the people &lt;em&gt;looking&lt;/em&gt; for help are elderly tablet users who find maps cognitively harder to parse.&lt;/p&gt;

&lt;p&gt;** Secure by Default**&lt;br&gt;
Strict Row Level Security (RLS) in Supabase PostgreSQL. Users can only edit their own profiles. Volunteer visibility is opt-in. No one's location is stored with more precision than they choose to provide.&lt;/p&gt;


&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔴 &lt;strong&gt;Live App:&lt;/strong&gt; &lt;a href="https://nearbyhelp.vercel.app" rel="noopener noreferrer"&gt;https://nearbyhelp.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sign in with Google, allow location access, and you'll see the map immediately populated with volunteers nearby. Use the filter panel to narrow by task type. On mobile, swipe up for the list view.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Screenshots:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The main map: color-coded pins by task category, live distance shown on each popup&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6s88fvrkg738kzpnx3c8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6s88fvrkg738kzpnx3c8.png" alt="screenshot 1" width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw8ycshv577ngymnemj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frw8ycshv577ngymnemj2.png" alt="screenshot 2" width="800" height="444"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnh8j3lfqmdewzd2s6vf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnh8j3lfqmdewzd2s6vf.png" alt="screenshot 3" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/mayureshsmitasuresh/nearbyhelp" rel="noopener noreferrer"&gt;Github code&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Stack
&lt;/h3&gt;

&lt;p&gt;Every technology choice was made with two users in mind simultaneously: the &lt;strong&gt;volunteer&lt;/strong&gt; (typically a younger, tech-comfortable neighbor) and the &lt;strong&gt;person seeking help&lt;/strong&gt; (often elderly, on a tablet, with limited tech confidence). The stack had to be fast to ship, reliable in production, and genuinely accessible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js 14 (App Router)&lt;/strong&gt;&lt;br&gt;
React Server Components for near-instant page loads. The map page is a protected route — unauthenticated users are redirected cleanly. API routes handle the Gemini integration server-side so API keys never touch the client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supabase — the backbone of the whole thing&lt;/strong&gt;&lt;br&gt;
Supabase does three jobs here that would have taken three separate services otherwise:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; — Google OAuth, one provider, zero friction. First sign-in auto-creates a profile row via a PostgreSQL trigger. No separate user management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; — PostgreSQL with a custom &lt;code&gt;get_nearby_profiles&lt;/code&gt; function that does bounding-box pre-filtering before Haversine calculation, keeping queries fast even at scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row Level Security&lt;/strong&gt; — Users can only update their own rows. Volunteer contact info is only exposed if they've explicitly opted in. Security is enforced at the database layer, not just the application layer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Supabase database trigger that auto-creates a profile on first Google login was one of the most satisfying pieces to build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handle_new_user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
  &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;profiles&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;avatar_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw_user_meta_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'full_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw_user_meta_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'avatar_url'&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt; &lt;span class="k"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt; &lt;span class="k"&gt;SECURITY&lt;/span&gt; &lt;span class="k"&gt;DEFINER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;on_auth_user_created&lt;/span&gt;
  &lt;span class="k"&gt;AFTER&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;
  &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;EACH&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; &lt;span class="k"&gt;EXECUTE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handle_new_user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero onboarding friction. Sign in, you exist in the database. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Haversine Formula&lt;/strong&gt;&lt;br&gt;
I implemented Haversine in pure TypeScript rather than relying on a library. I wanted to understand every line of the distance logic, and it's satisfying code to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;haversineDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;lat1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lng1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;lat2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lng2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6371&lt;/span&gt; &lt;span class="c1"&gt;// Earth's radius in km&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dLat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lat2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lat1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dLng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lng2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lng1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dLat&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lat1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
    &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lat2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
    &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dLng&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every volunteer card on the map shows their distance to two decimal places. &lt;em&gt;0.4 km away.&lt;/em&gt; That specificity was important to me — vague proximity ("nearby") doesn't give someone the confidence to reach out. Exact distance does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Gemini AI — the quiet magic&lt;/strong&gt;&lt;br&gt;
The AI feature is invisible to users, which is exactly how it should be. Volunteers type naturally. Gemini reads it and returns a standardized category. Here's the API route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/categorize/route.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TASK_TAGS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ERRANDS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HOUSEWORK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MAINTENANCE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TECH_HELP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TRANSPORT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COMPANIONSHIP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OTHER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  You are a community volunteer task categorizer.
  Given this offer: '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;skillText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'
  Return ONLY one tag from: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;TASK_TAGS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;
  No explanation. Just the tag.
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constraint of returning &lt;em&gt;only one tag&lt;/em&gt; from a fixed enum was deliberate. I don't want AI creativity here — I want consistency. Every "I can drive you to appointments" maps to &lt;code&gt;TRANSPORT&lt;/code&gt;. Every "I'm good with computers" maps to &lt;code&gt;TECH_HELP&lt;/code&gt;. The map filter relies on this being reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;react-leaflet + Custom Pins&lt;/strong&gt;&lt;br&gt;
No Google Maps API key required. Leaflet is open source, fast, and renders beautifully on mobile. Custom SVG pins are color-coded by task category so you can read the map at a glance without reading any text — important for elderly users who may have reduced vision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt;&lt;br&gt;
Glassmorphism-inspired UI with high contrast ratios throughout. WCAG AA compliance was a design constraint, not an afterthought. Every interactive element has a minimum 44×44px tap target for accessibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture Decision I'm Most Proud Of
&lt;/h3&gt;

&lt;p&gt;I chose to put the Haversine calculation in JavaScript rather than SQL, but the &lt;em&gt;pre-filtering&lt;/em&gt; (bounding box) in a Supabase PostgreSQL function. This means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The database returns a small, geographically bounded set of profiles (fast)&lt;/li&gt;
&lt;li&gt;JavaScript sorts them by exact spherical distance (precise)&lt;/li&gt;
&lt;li&gt;The client renders cards in perfect nearest-first order (useful)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's a clean separation: database does what databases are good at (filtering large datasets quickly), JavaScript does what it's good at (precise calculation on a small set).&lt;/p&gt;

&lt;h3&gt;
  
  
  What Was Hard
&lt;/h3&gt;

&lt;p&gt;The mobile list view took longer than I expected. The UX challenge was real: elderly users navigating a swipeable overlay need smooth momentum scrolling, large text, and clear visual hierarchy. I went through four iterations before the swipe gesture felt natural enough that I'd be comfortable handing a tablet to my grandmother.&lt;/p&gt;

&lt;p&gt;The other challenge was the Supabase RLS policies. Getting the policies right — where anyone can read volunteer profiles, but only the authenticated owner can write to theirs, and contact info is only exposed with explicit opt-in — required careful thinking. I've documented the full policy setup in the repo README for anyone who wants to fork it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Community. Why Now.
&lt;/h2&gt;

&lt;p&gt;By 2030, 1 in 6 people in the world will be over 60. In many cities, over 30% of elderly people report feeling lonely. The infrastructure of community that used to exist — knowing your neighbors, looking out for each other — has eroded in modern urban life.&lt;/p&gt;

&lt;p&gt;The solution isn't a government program or an expensive subscription service. It's already living three doors down from you. It's your neighbor who said "let me know if you ever need anything" and meant it — but never got the call because nobody had a way to make asking feel natural and safe.&lt;/p&gt;

&lt;p&gt;NearbyHelp is that way.&lt;/p&gt;

&lt;p&gt;It's not built for crisis. It's built for Tuesday afternoon when the jar won't open and there's nobody to call.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Next.js 14, Supabase, Google Gemini AI, react-leaflet, and Tailwind CSS v4.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Live at &lt;a href="https://nearbyhelp.vercel.app" rel="noopener noreferrer"&gt;https://nearbyhelp.vercel.app&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Mathematical Optimisation in Rust: A Complete Guide to good_lp + HiGHS (Production Ready with Axum)</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sat, 21 Feb 2026 10:26:27 +0000</pubDate>
      <link>https://dev.to/mayu2008/mathematical-optimisation-in-rust-a-complete-guide-to-goodlp-highs-production-ready-with-axum-4pnm</link>
      <guid>https://dev.to/mayu2008/mathematical-optimisation-in-rust-a-complete-guide-to-goodlp-highs-production-ready-with-axum-4pnm</guid>
      <description>&lt;p&gt;Modern backend systems often need to make &lt;strong&gt;optimal decisions under&lt;br&gt;
constraints&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Allocate limited resources&lt;/li&gt;
&lt;li&gt;  Minimize operational cost&lt;/li&gt;
&lt;li&gt;  Select optimal product mix&lt;/li&gt;
&lt;li&gt;  Plan logistics efficiently&lt;/li&gt;
&lt;li&gt;  Build smart pricing engines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;mathematical optimization&lt;/strong&gt; becomes powerful.&lt;/p&gt;

&lt;p&gt;In Rust, two tools make this practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;good_lp&lt;/code&gt; → Modeling layer (DSL for optimization problems)&lt;/li&gt;
&lt;li&gt;  HiGHS → High-performance optimization solver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This guide covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Mathematical foundations&lt;/li&gt;
&lt;li&gt;  What &lt;code&gt;good_lp&lt;/code&gt; and HiGHS are&lt;/li&gt;
&lt;li&gt;  When to use them&lt;/li&gt;
&lt;li&gt;  Rust examples&lt;/li&gt;
&lt;li&gt;  Production-ready Axum backend integration&lt;/li&gt;
&lt;li&gt;  Scaling considerations&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1. Mathematical Optimization (Concept)
&lt;/h2&gt;

&lt;p&gt;Optimization problems look like this:&lt;/p&gt;

&lt;p&gt;Minimize or Maximize:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Subject to:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;g1(x) ≤ b1
g2(x) = b2
x ∈ feasible set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  x = decision variables&lt;/li&gt;
&lt;li&gt;  f(x) = objective function&lt;/li&gt;
&lt;li&gt;  g(x) = constraints&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. LP vs MIP
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Linear Programming (LP)
&lt;/h2&gt;

&lt;p&gt;All expressions are linear.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Maximize: 3x + 2y&lt;/p&gt;

&lt;p&gt;Subject to: x + y ≤ 10 x ≥ 0 y ≥ 0&lt;/p&gt;

&lt;p&gt;LP problems are solved efficiently using simplex or interior-point&lt;br&gt;
methods.&lt;/p&gt;


&lt;h2&gt;
  
  
  Mixed Integer Programming (MIP)
&lt;/h2&gt;

&lt;p&gt;Some variables must be integers or binary.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x ∈ {0,1}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;MIP is NP-hard.&lt;/p&gt;

&lt;p&gt;Solvers use: - LP relaxation - Branch-and-bound - Cutting planes&lt;/p&gt;


&lt;h2&gt;
  
  
  3. What Is HiGHS?
&lt;/h2&gt;

&lt;p&gt;HiGHS is a high-performance open-source solver written in C++.&lt;/p&gt;

&lt;p&gt;It supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Linear Programming (LP)&lt;/li&gt;
&lt;li&gt;  Mixed Integer Programming (MIP)&lt;/li&gt;
&lt;li&gt;  Quadratic Programming (QP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HiGHS is the computation engine.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. What Is &lt;code&gt;good_lp&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;good_lp&lt;/code&gt; is a Rust modeling crate.&lt;/p&gt;

&lt;p&gt;It: - Builds constraint matrices - Translates to solver format - Calls&lt;br&gt;
backend solver (like HiGHS)&lt;/p&gt;

&lt;p&gt;It does not solve problems itself.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;/p&gt;

&lt;p&gt;Rust Code → good_lp → HiGHS → Optimal Solution&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Installation
&lt;/h2&gt;

&lt;p&gt;Cargo.toml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;good_lp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.4"&lt;/span&gt;
&lt;span class="py"&gt;highs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.8"&lt;/span&gt;
&lt;span class="py"&gt;axum&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.7"&lt;/span&gt;
&lt;span class="py"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"full"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"derive"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Basic Optimization Example
&lt;/h2&gt;

&lt;p&gt;Maximize: 3x + 2y&lt;/p&gt;

&lt;p&gt;Subject to: x + y ≤ 10&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;good_lp&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SolverModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;solve_lp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;variables!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;
        &lt;span class="nf"&gt;.maximise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.solve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"y = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Production-Ready Axum Backend Example
&lt;/h2&gt;

&lt;p&gt;We now build a simple optimization API.&lt;/p&gt;

&lt;p&gt;It solves:&lt;/p&gt;

&lt;p&gt;Maximize: profit_a * A + profit_b * B&lt;/p&gt;

&lt;p&gt;Subject to: A + B ≤ limit A, B ∈ {0,1}&lt;/p&gt;




&lt;h2&gt;
  
  
  main.rs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;good_lp&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SolverModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OptimizeRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;profit_a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;profit_b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OptimizeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OptimizeRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OptimizeResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;variables!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.binary&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.binary&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;
        &lt;span class="nf"&gt;.maximise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.limit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.solve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OptimizeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/optimize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="mi"&gt;127&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server running at http://{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="nf"&gt;.into_make_service&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Running the API
&lt;/h2&gt;

&lt;p&gt;Start server:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Call endpoint:&lt;/p&gt;

&lt;p&gt;POST &lt;a href="http://localhost:3000/optimize" rel="noopener noreferrer"&gt;http://localhost:3000/optimize&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Body:&lt;/p&gt;

&lt;p&gt;{ "profit_a": 10, "profit_b": 6, "limit": 1 }&lt;/p&gt;

&lt;p&gt;Response:&lt;/p&gt;

&lt;p&gt;{ "a": 1, "b": 0, "objective": 10 }&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Production Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Set solver time limits&lt;/li&gt;
&lt;li&gt;  Handle infeasible models gracefully&lt;/li&gt;
&lt;li&gt;  Log solver status&lt;/li&gt;
&lt;li&gt;  Separate optimization into service layer&lt;/li&gt;
&lt;li&gt;  Consider async worker if solve time is long&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Scaling
&lt;/h2&gt;

&lt;p&gt;To scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Partition large problems&lt;/li&gt;
&lt;li&gt;  Avoid symmetry&lt;/li&gt;
&lt;li&gt;  Use soft constraints carefully&lt;/li&gt;
&lt;li&gt;  Monitor solver time&lt;/li&gt;
&lt;li&gt;  Use time limits for MIP&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Optimization is a powerful backend capability.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;good_lp&lt;/code&gt; provides clean modeling. HiGHS provides industrial-grade&lt;br&gt;
solving. Axum provides modern Rust web infrastructure.&lt;/p&gt;

&lt;p&gt;Together, they form a production-ready optimization backend stack.&lt;/p&gt;

&lt;p&gt;If your system needs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best possible decision under constraints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then mathematical optimization in Rust is the correct architectural&lt;br&gt;
choice.&lt;/p&gt;

&lt;p&gt;Please ask me any questions you have in your mind I’ll be happy to guide you through &lt;/p&gt;

&lt;p&gt;Thanks,&lt;br&gt;
Mayuresh&lt;br&gt;
&lt;a href="https://tagnovate.com/mayuresh" rel="noopener noreferrer"&gt;About me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>backend</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create A Powerful Mobile App - Rust as the Brain, Flutter as the Face</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 18 Feb 2026 13:43:53 +0000</pubDate>
      <link>https://dev.to/mayu2008/create-a-powerful-mobile-app-rust-as-the-brain-flutter-as-the-face-5bm1</link>
      <guid>https://dev.to/mayu2008/create-a-powerful-mobile-app-rust-as-the-brain-flutter-as-the-face-5bm1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Design beautiful interfaces in Flutter. Run serious logic in Rust.&lt;br&gt;
Connect them like a pro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modern applications are evolving beyond simple UI rendering and API&lt;br&gt;
calls. Today's apps handle heavy data processing, encryption, offline&lt;br&gt;
computation, and performance‑critical operations. While Flutter is&lt;br&gt;
exceptional for building beautiful cross‑platform interfaces, it is not&lt;br&gt;
optimized for low‑level, high‑performance computation. That's where Rust&lt;br&gt;
fits perfectly.&lt;/p&gt;

&lt;p&gt;This article explains how to architect your application with Rust as the&lt;br&gt;
"brain" and Flutter as the "face," and how they communicate efficiently.&lt;/p&gt;


&lt;h2&gt;
  
  
  Architecture Philosophy
&lt;/h2&gt;

&lt;p&gt;Think of your app in two layers:&lt;/p&gt;

&lt;p&gt;Flutter → Presentation Layer (UI)\&lt;br&gt;
Rust → Core Logic Layer (Brain)&lt;/p&gt;

&lt;p&gt;Flutter handles: - UI rendering - Animations - Navigation - State&lt;br&gt;
management&lt;/p&gt;

&lt;p&gt;Rust handles: - Heavy computation - Data processing - Encryption -&lt;br&gt;
Parsing - Performance‑critical algorithms - Offline engines&lt;/p&gt;

&lt;p&gt;Flutter does not need to understand internal logic. It simply calls Rust&lt;br&gt;
functions and displays results. This separation keeps the system clean&lt;br&gt;
and maintainable.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Rust Works So Well
&lt;/h2&gt;

&lt;p&gt;Rust provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Near C‑level performance\&lt;/li&gt;
&lt;li&gt;  Memory safety without garbage collection\&lt;/li&gt;
&lt;li&gt;  Strong type guarantees\&lt;/li&gt;
&lt;li&gt;  Safe concurrency\&lt;/li&gt;
&lt;li&gt;  Cross‑platform compilation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike putting heavy computation inside Dart, Rust gives you predictable&lt;br&gt;
performance and control over memory behaviour. You can even reuse the&lt;br&gt;
same Rust core across Android, iOS, desktop, or backend systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  How Flutter and Rust Communicate
&lt;/h2&gt;

&lt;p&gt;Flutter and Rust communicate using FFI (Foreign Function Interface).&lt;br&gt;
Instead of writing raw FFI manually, you can use &lt;code&gt;flutter_rust_bridge&lt;/code&gt;,&lt;br&gt;
which generates safe bindings between Dart and Rust.&lt;/p&gt;

&lt;p&gt;This eliminates: - Manual pointer management - Unsafe memory passing -&lt;br&gt;
Complex native glue code&lt;/p&gt;


&lt;h2&gt;
  
  
  Basic Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Create a Rust Library
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new core_engine &lt;span class="nt"&gt;--lib&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[lib]&lt;/span&gt;
&lt;span class="py"&gt;crate-type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cdylib"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Add flutter_rust_bridge
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;flutter_rust_bridge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"latest"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Write a Rust Function
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;lib.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flutter_rust_bridge&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;frb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[frb]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processed: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Generate Bridge Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter_rust_bridge_codegen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Call Rust from Flutter
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RustApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;input:&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Flutter calls Rust. Rust processes the logic. Flutter renders&lt;br&gt;
the result.&lt;/p&gt;




&lt;h2&gt;
  
  
  Streaming Data from Rust
&lt;/h2&gt;

&lt;p&gt;For long‑running tasks, streaming is important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust Side
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flutter_rust_bridge&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StreamSink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[frb]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;compute_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StreamSink&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Step {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Flutter Side
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeStream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows background processing while keeping the UI smooth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recommended Project Structure
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project_root/
│
├── flutter_app/
│   └── lib/
│
└── rust_core/
    ├── src/
    │   ├── lib.rs
    │   ├── logic.rs
    │   ├── services.rs
    │   └── models.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Keep UI concerns inside Flutter and business logic inside Rust. The Rust&lt;br&gt;
The core should be testable independently of Flutter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Keep Flutter thin --- only UI and state.&lt;/li&gt;
&lt;li&gt;  Keep Rust pure --- no UI dependencies.&lt;/li&gt;
&lt;li&gt;  Avoid blocking calls --- use threads or streaming.&lt;/li&gt;
&lt;li&gt;  Design simple Rust APIs for Flutter to consume.&lt;/li&gt;
&lt;li&gt;  Test Rust independently via CLI before integrating.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When This Architecture Makes Sense
&lt;/h2&gt;

&lt;p&gt;Use Flutter + Rust when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You need high performance&lt;/li&gt;
&lt;li&gt;  You process large datasets&lt;/li&gt;
&lt;li&gt;  You require strong memory safety&lt;/li&gt;
&lt;li&gt;  You build offline‑first applications&lt;/li&gt;
&lt;li&gt;  You need shared core logic across platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For simple CRUD apps, this may be unnecessary. But for performance‑heavy&lt;br&gt;
systems, this separation is powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Flutter builds beautiful experiences. Rust builds powerful systems.&lt;/p&gt;

&lt;p&gt;Together, they allow you to create applications that are fast, stable,&lt;br&gt;
scalable, and maintainable, with a clear separation between&lt;br&gt;
presentation and logic.&lt;/p&gt;

&lt;p&gt;If you're building something beyond just screens, consider making Rust&lt;br&gt;
Your brain and Flutter your face.&lt;/p&gt;

&lt;p&gt;Mayuresh Smita Suresh&lt;br&gt;
&lt;a href="https://tagnovate.com/mayuresh" rel="noopener noreferrer"&gt;My work&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>flutter</category>
      <category>mobile</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Building an Ultra-Low Latency Live Streaming Server: A Developer's Guide to OvenMediaEngine</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sat, 07 Feb 2026 11:47:05 +0000</pubDate>
      <link>https://dev.to/mayu2008/building-an-ultra-low-latency-live-streaming-server-a-developers-guide-to-ovenmediaengine-jco</link>
      <guid>https://dev.to/mayu2008/building-an-ultra-low-latency-live-streaming-server-a-developers-guide-to-ovenmediaengine-jco</guid>
      <description>&lt;p&gt;If you've ever tried to build a live streaming app, you know the "0.5-second latency" dream can quickly turn into a firewall nightmare. I recently set up a sub-second latency streaming backend using &lt;strong&gt;OvenMediaEngine (OME)&lt;/strong&gt; on &lt;strong&gt;Oracle Cloud&lt;/strong&gt;, and I'm sharing the exact steps to save you hours of troubleshooting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Traditional streaming solutions like RTMP deliver video with 20-60 second latency. For interactive applications—live auctions, gaming, webinars, or financial trading—this lag breaks the user experience. WebRTC solves this with sub-second delivery, but the setup is notoriously complex.&lt;/p&gt;

&lt;p&gt;The biggest culprits? Firewalls, misconfigured security rules, and incorrect IP configuration in the media server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution Stack
&lt;/h2&gt;

&lt;p&gt;Our architecture combines industry-standard tools for maximum reliability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OBS Studio:&lt;/strong&gt; Professional RTMP encoder for ingest&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OvenMediaEngine:&lt;/strong&gt; Lightweight, high-performance media server (container-based)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oracle Cloud (Ubuntu 22.04):&lt;/strong&gt; Reliable cloud infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebRTC:&lt;/strong&gt; Modern protocol for ultra-low latency delivery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OvenPlayer SDK:&lt;/strong&gt; Browser-based playback with automatic quality adjustment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[OBS Studio]
     |
   RTMP (1935)
     |
[OvenMediaEngine - Docker Container]
     |
     ├─ WebRTC Signalling (TCP 3333)
     └─ Media Streaming (UDP 10000-10005)
     |
[Web Browser with OvenPlayer SDK]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Oracle Cloud account (or AWS/GCP/Azure—the steps are similar)&lt;/li&gt;
&lt;li&gt;Ubuntu 22.04 LTS instance (minimum 2 vCPU, 4GB RAM)&lt;/li&gt;
&lt;li&gt;OBS Studio installed locally&lt;/li&gt;
&lt;li&gt;Basic Linux command-line knowledge&lt;/li&gt;
&lt;li&gt;A text editor (nano, vim, or your preference)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Prepare the Cloud Instance
&lt;/h2&gt;

&lt;p&gt;Launch an Ubuntu instance on your cloud provider. Before touching the terminal, open the firewall gates in your Cloud Dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Security Lists (Oracle Cloud)
&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Networking → Virtual Cloud Networks → Security Lists&lt;/strong&gt; and add these ingress rules:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Port Range&lt;/th&gt;
&lt;th&gt;Source CIDR&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;1935&lt;/td&gt;
&lt;td&gt;0.0.0.0/0&lt;/td&gt;
&lt;td&gt;RTMP Ingest from OBS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;3333&lt;/td&gt;
&lt;td&gt;0.0.0.0/0&lt;/td&gt;
&lt;td&gt;WebRTC Signalling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UDP&lt;/td&gt;
&lt;td&gt;10000-10005&lt;/td&gt;
&lt;td&gt;0.0.0.0/0&lt;/td&gt;
&lt;td&gt;WebRTC Media Streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
&lt;strong&gt;Critical Setting:&lt;/strong&gt; Ensure these rules are &lt;strong&gt;Stateful&lt;/strong&gt; (the "Stateless" option must be &lt;strong&gt;unchecked&lt;/strong&gt;). WebRTC relies on connection state tracking. If you enable Stateless mode, the server cannot maintain the connection handshake, and you'll see "Connection terminated unexpectedly" errors.&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  For AWS Users
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;EC2 → Security Groups&lt;/strong&gt;, add these inbound rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type: Custom TCP Rule | Port: 1935 | CIDR: 0.0.0.0/0
Type: Custom TCP Rule | Port: 3333 | CIDR: 0.0.0.0/0
Type: Custom UDP Rule | Port Range: 10000-10005 | CIDR: 0.0.0.0/0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Install Docker and OvenMediaEngine
&lt;/h2&gt;

&lt;p&gt;SSH into your instance and install Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Update system packages&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Install Docker&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.docker.com &lt;span class="nt"&gt;-o&lt;/span&gt; get-docker.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;sh get-docker.sh

&lt;span class="c"&gt;# Add your user to docker group (so you don't need sudo every time)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
newgrp docker

&lt;span class="c"&gt;# Verify installation&lt;/span&gt;
docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a persistent directory for OME configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create configuration directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/ome/conf
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/ome/logs

&lt;span class="c"&gt;# Get the default configuration from Docker image&lt;/span&gt;
docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; ~/ome/conf:/opt/ovenmediaengine/conf &lt;span class="se"&gt;\&lt;/span&gt;
  airensoft/ovenmediaengine:latest &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /opt/ovenmediaengine/conf/&lt;span class="k"&gt;*&lt;/span&gt; /opt/ovenmediaengine/conf/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Launch the OvenMediaEngine container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Get your public IP address&lt;/span&gt;
&lt;span class="nv"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://checkip.amazonaws.com&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Your Public IP: &lt;/span&gt;&lt;span class="nv"&gt;$PUBLIC_IP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Run the container with port mappings&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; ome &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 1935:1935 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 3333:3333 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 10000-10005:10000-10005/udp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;OME_HOST_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PUBLIC_IP&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; ~/ome/conf:/opt/ovenmediaengine/conf &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; ~/ome/logs:/opt/ovenmediaengine/logs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped &lt;span class="se"&gt;\&lt;/span&gt;
  airensoft/ovenmediaengine:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the container is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps | &lt;span class="nb"&gt;grep &lt;/span&gt;ome
docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; ome  &lt;span class="c"&gt;# View real-time logs (Ctrl+C to exit)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;
The environment variable &lt;code&gt;OME_HOST_IP&lt;/code&gt; is crucial—it tells the media server which IP address to advertise to clients. This prevents the infamous "Connection terminated unexpectedly" error caused by broadcasting internal Docker IPs.&lt;br&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Configure the Magic IP Settings
&lt;/h2&gt;

&lt;p&gt;This is where 90% of people get stuck. OvenMediaEngine must know which external IP to advertise to browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit Server.xml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano ~/ome/conf/Server.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find the &lt;code&gt;&amp;lt;IceCandidates&amp;gt;&lt;/code&gt; section (there should be two—one in &lt;code&gt;&amp;lt;Providers&amp;gt;&lt;/code&gt; and one in &lt;code&gt;&amp;lt;Publishers&amp;gt;&lt;/code&gt;). Update &lt;strong&gt;both&lt;/strong&gt; sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;IceCandidates&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;IceCandidate&amp;gt;&lt;/span&gt;$YOUR_PUBLIC_IP:10000-10005/udp&lt;span class="nt"&gt;&amp;lt;/IceCandidate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TcpRelay&amp;gt;&lt;/span&gt;$YOUR_PUBLIC_IP:3478&lt;span class="nt"&gt;&amp;lt;/TcpRelay&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;TcpForce&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/TcpForce&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/IceCandidates&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Replace &lt;code&gt;$YOUR_PUBLIC_IP&lt;/code&gt; with your actual public IP&lt;/strong&gt; (e.g., &lt;code&gt;203.0.113.45&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;strong&gt;Common Mistake:&lt;/strong&gt; Leaving the default &lt;code&gt;127.0.0.1&lt;/code&gt; or &lt;code&gt;localhost&lt;/code&gt; in this section. The browser has no idea how to reach &lt;code&gt;localhost&lt;/code&gt; on the server—it needs the public IP!&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Also, ensure the &lt;code&gt;&amp;lt;Applications&amp;gt;&lt;/code&gt; section has both &lt;code&gt;&amp;lt;Provider&amp;gt;&lt;/code&gt; (for OBS ingest) and &lt;code&gt;&amp;lt;Publisher&amp;gt;&lt;/code&gt; (for playback):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Application&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Name&amp;gt;&lt;/span&gt;app&lt;span class="nt"&gt;&amp;lt;/Name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Type&amp;gt;&lt;/span&gt;live&lt;span class="nt"&gt;&amp;lt;/Type&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Provider&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Type&amp;gt;&lt;/span&gt;rtmp&lt;span class="nt"&gt;&amp;lt;/Type&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Properties&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Port&amp;gt;&lt;/span&gt;1935&lt;span class="nt"&gt;&amp;lt;/Port&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/Properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Provider&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Publisher&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Type&amp;gt;&lt;/span&gt;webrtc&lt;span class="nt"&gt;&amp;lt;/Type&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Properties&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Port&amp;gt;&lt;/span&gt;3333&lt;span class="nt"&gt;&amp;lt;/Port&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/Properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Publisher&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Application&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the container to apply changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker restart ome
docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; ome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Disable Ubuntu's Internal Firewall
&lt;/h2&gt;

&lt;p&gt;The cloud dashboard isn't enough. Ubuntu's &lt;code&gt;iptables&lt;/code&gt; often blocks UDP traffic by default. Force the ports open with highest priority rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add rules at the TOP of the INPUT chain (priority -I 1)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT 1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 1935 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT 1 &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 3333 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT 1 &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 10000:10005 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Save rules persistently&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; iptables-persistent
&lt;span class="nb"&gt;sudo &lt;/span&gt;netfilter-persistent save

&lt;span class="c"&gt;# Verify rules are in place&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"1935|3333|10000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test connectivity from your local machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test RTMP port&lt;/span&gt;
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; YOUR_PUBLIC_IP 1935

&lt;span class="c"&gt;# Test WebRTC signalling port&lt;/span&gt;
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; YOUR_PUBLIC_IP 3333

&lt;span class="c"&gt;# Test UDP media ports (may show connection refused, which is OK for UDP)&lt;/span&gt;
nc &lt;span class="nt"&gt;-uz&lt;/span&gt; YOUR_PUBLIC_IP 10001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Configure OBS Studio
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;OBS Studio&lt;/strong&gt; on your local machine and configure the stream settings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Settings → Stream&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service:&lt;/strong&gt; Custom&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server:&lt;/strong&gt; &lt;code&gt;rtmp://YOUR_PUBLIC_IP/app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stream Key:&lt;/strong&gt; &lt;code&gt;test&lt;/code&gt; (or any identifier you want)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Configure output settings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Settings → Output → Streaming&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encoder:&lt;/strong&gt; libx264 or NVIDIA NVENC (if available)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bitrate:&lt;/strong&gt; 4000 Kbps (adjust based on your internet)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyframe Interval:&lt;/strong&gt; 2 seconds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Settings → Audio&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample Rate:&lt;/strong&gt; 48kHz (WebRTC is strict about this!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio Codec:&lt;/strong&gt; AAC (not Opus)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Click &lt;strong&gt;Start Streaming&lt;/strong&gt;. You should see &lt;code&gt;New connection from&lt;/code&gt; in the OME logs.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;
&lt;strong&gt;Pro Tip:&lt;/strong&gt; For ultra-low latency, use a &lt;strong&gt;hardware encoder&lt;/strong&gt; (NVIDIA NVENC or Intel Quick Sync). Software encoding introduces 100-200ms of extra latency.&lt;br&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Build the Frontend Player
&lt;/h2&gt;

&lt;p&gt;Create an HTML page with the OvenPlayer SDK to view your stream. Since we're using HTTP (not HTTPS), use the &lt;code&gt;ws://&lt;/code&gt; protocol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Ultra-Low Latency Stream Viewer&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/ovenplayer@latest/dist/ovenplayer.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-apple-system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlinkMacSystemFont&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;'Segoe UI'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Roboto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Oxygen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Ubuntu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Cantarell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#667eea&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#764ba2&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="m"&gt;60px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#667eea&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#764ba2&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;28px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.player-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;56.25%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* 16:9 aspect ratio */&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;#player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.info&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f8f9fa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;border-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#e9ecef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.info&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.stats&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.stat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;border-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#667eea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.stat-label&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.stat-value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.status-indicator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#dc3545&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pulse&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.status-indicator.live&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#28a745&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pulse&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;pulse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;🎬 Ultra-Low Latency Stream&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Powered by OvenMediaEngine &lt;span class="err"&gt;&amp;amp;&lt;/span&gt; WebRTC&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"player-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"player"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"status-indicator"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"statusIndicator"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                Stream Status
            &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stats"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Latency&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-value"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"latency"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;— ms&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Bitrate&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-value"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"bitrate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;— kbps&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Resolution&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-value"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"resolution"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;— &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Connection State&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"stat-value"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Connecting...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/ovenplayer@latest/dist/ovenplayer.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// Replace with your PUBLIC IP&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PUBLIC_IP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_PUBLIC_IP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// e.g., '203.0.113.45'&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;STREAM_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`ws://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PUBLIC_IP&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:3333/app/test`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🔗 Connecting to:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;STREAM_URL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;OvenPlayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;autoplay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;mute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webrtc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;STREAM_URL&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Update status and stats&lt;/span&gt;
        &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;statechanged&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;📊 State changed:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stateText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;state&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stateText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stateText&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Playing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;statusIndicator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;live&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;statusIndicator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;●&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;statusIndicator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;live&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;❌ Player error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;state&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Attempt to extract stats (varies by browser)&lt;/span&gt;
        &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;latency&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latency&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bitrate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bitrate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bitrate&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; kbps&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resolution&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this as &lt;code&gt;stream-player.html&lt;/code&gt; and open it in a browser. &lt;strong&gt;Replace &lt;code&gt;YOUR_PUBLIC_IP&lt;/code&gt; with your actual public IP address.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Enable HTTPS for Production
&lt;/h2&gt;

&lt;p&gt;For production deployments, you'll want HTTPS. Use &lt;strong&gt;Let's Encrypt&lt;/strong&gt; and &lt;strong&gt;Certbot&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Certbot&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; certbot python3-certbot-nginx

&lt;span class="c"&gt;# Obtain a certificate (requires a domain name)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot certonly &lt;span class="nt"&gt;--standalone&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; your-domain.com

&lt;span class="c"&gt;# Update your frontend to use WSS (WebSocket Secure)&lt;/span&gt;
&lt;span class="c"&gt;# Change: ws://YOUR_PUBLIC_IP:3333/app/test&lt;/span&gt;
&lt;span class="c"&gt;# To: wss://your-domain.com:3333/app/test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update OME's configuration to use TLS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Publisher&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Type&amp;gt;&lt;/span&gt;webrtc&lt;span class="nt"&gt;&amp;lt;/Type&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Properties&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Port&amp;gt;&lt;/span&gt;3333&lt;span class="nt"&gt;&amp;lt;/Port&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Tls&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;CertPath&amp;gt;&lt;/span&gt;/opt/ovenmediaengine/certs/certificate.crt&lt;span class="nt"&gt;&amp;lt;/CertPath&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;KeyPath&amp;gt;&lt;/span&gt;/opt/ovenmediaengine/certs/private.key&lt;span class="nt"&gt;&amp;lt;/KeyPath&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/Tls&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Properties&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Publisher&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Troubleshooting "Error 511: Connection terminated unexpectedly"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Diagnosis
&lt;/h3&gt;

&lt;p&gt;If your player shows "Error 511" or logs show &lt;code&gt;New client connected&lt;/code&gt; followed immediately by &lt;code&gt;Client disconnected&lt;/code&gt;, check these in order:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Verify UDP Port Range
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if UDP ports are open&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;netstat &lt;span class="nt"&gt;-uln&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"10000|10001|10002|10003|10004|10005"&lt;/span&gt;

&lt;span class="c"&gt;# If missing, re-add the iptables rules&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT 1 &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 10000:10005 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;netfilter-persistent save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Check Cloud Security Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Oracle Cloud:&lt;/strong&gt; Ensure the rule is &lt;strong&gt;NOT Stateless&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS:&lt;/strong&gt; Ensure the security group rule is present and doesn't have a restrictive source CIDR&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GCP:&lt;/strong&gt; Check the firewall rules in &lt;strong&gt;VPC Network → Firewall&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test from your local machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test if UDP port responds&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt; | nc &lt;span class="nt"&gt;-u&lt;/span&gt; YOUR_PUBLIC_IP 10001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Verify Server.xml Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if the correct IP is in Server.xml&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 3 &lt;span class="s2"&gt;"IceCandidates"&lt;/span&gt; ~/ome/conf/Server.xml

&lt;span class="c"&gt;# Should show your PUBLIC IP, not 127.0.0.1 or internal IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Check for Mixed Content Issues
&lt;/h3&gt;

&lt;p&gt;If your website is HTTPS, your stream URL &lt;strong&gt;must&lt;/strong&gt; be WSS (WebSocket Secure):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Wrong (HTTPS page + WS stream)&lt;/span&gt;
&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ws://YOUR_PUBLIC_IP:3333/app/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ Correct (HTTPS page + WSS stream)&lt;/span&gt;
&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wss://your-domain.com:3333/app/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Monitor Real-Time Logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; ome | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"New client|disconnected|error|failed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performance Optimization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reduce Latency Further
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set Keyframe Interval to 1 second in OBS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Settings → Output → Advanced → Keyframe Interval = 1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enable Hardware Encoding&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NVIDIA NVENC is 100ms faster than libx264&lt;/li&gt;
&lt;li&gt;Settings → Output → Encoder → NVIDIA NVENC H.264&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Increase Media Port Range&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have high concurrent viewers, expand the UDP range from 10000-10005 to 10000-10099&lt;/li&gt;
&lt;li&gt;Update Security Rules, iptables, and Server.xml accordingly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Memory &amp;amp; CPU Usage
&lt;/h3&gt;

&lt;p&gt;Check OME container resource usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stats ome

&lt;span class="c"&gt;# Monitor over time&lt;/span&gt;
docker stats ome &lt;span class="nt"&gt;--no-stream&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If CPU exceeds 80%, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducing input bitrate&lt;/li&gt;
&lt;li&gt;Using hardware transcoding&lt;/li&gt;
&lt;li&gt;Scaling to multiple OME instances&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Monitoring &amp;amp; Logging
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Enable Detailed Logging
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;~/ome/conf/Logger.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Logger&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LogPath&amp;gt;&lt;/span&gt;./logs/&lt;span class="nt"&gt;&amp;lt;/LogPath&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LogLevel&amp;gt;&lt;/span&gt;debug&lt;span class="nt"&gt;&amp;lt;/LogLevel&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;LogToPipe&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Conn_Monitoring&amp;gt;&lt;/span&gt;debug&lt;span class="nt"&gt;&amp;lt;/Conn_Monitoring&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;HTTP&amp;gt;&lt;/span&gt;debug&lt;span class="nt"&gt;&amp;lt;/HTTP&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;RTMP&amp;gt;&lt;/span&gt;debug&lt;span class="nt"&gt;&amp;lt;/RTMP&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;WEBRTC&amp;gt;&lt;/span&gt;debug&lt;span class="nt"&gt;&amp;lt;/WEBRTC&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/LogToPipe&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Logger&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker restart ome
docker logs ome | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set Up Log Rotation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/logrotate.d/ome &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
/home/&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;whoami&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;/ome/logs/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    create 0640 &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;whoami&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt; &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;whoami&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deployment Checklist
&lt;/h2&gt;

&lt;p&gt;Before going live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Cloud security rules are configured and &lt;strong&gt;NOT stateless&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] iptables rules are applied and saved&lt;/li&gt;
&lt;li&gt;[ ] OME container is running and public IP is in Server.xml&lt;/li&gt;
&lt;li&gt;[ ] OBS can successfully stream to RTMP endpoint&lt;/li&gt;
&lt;li&gt;[ ] WebRTC player connects without Error 511&lt;/li&gt;
&lt;li&gt;[ ] Latency is under 2 seconds&lt;/li&gt;
&lt;li&gt;[ ] HTTPS/WSS is configured for production&lt;/li&gt;
&lt;li&gt;[ ] Monitoring and logging are enabled&lt;/li&gt;
&lt;li&gt;[ ] Backup and restore procedures documented&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Production Use Cases
&lt;/h2&gt;

&lt;p&gt;This setup powers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Auctions:&lt;/strong&gt; Sub-second latency for real-time bidding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gaming Platforms:&lt;/strong&gt; Competitive gaming with minimal delay&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Financial Trading:&lt;/strong&gt; Real-time market data streaming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Webinars:&lt;/strong&gt; Q&amp;amp;A with negligible latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live Sports Betting:&lt;/strong&gt; Same-game betting during broadcasts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telemedicine:&lt;/strong&gt; Live surgical procedures and consultations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scale horizontally:&lt;/strong&gt; Deploy multiple OME instances behind a load balancer for high concurrency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add authentication:&lt;/strong&gt; Implement token-based stream access control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable recording:&lt;/strong&gt; Configure OME to record streams to disk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up SRT failover:&lt;/strong&gt; Add Secondary RTMP input for redundancy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement adaptive bitrate:&lt;/strong&gt; Configure CMAF packaging for multi-quality delivery&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Resources &amp;amp; Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://airensoft.gitbook.io/ovenmediaengine/" rel="noopener noreferrer"&gt;OvenMediaEngine Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/webrtc-best-practices/" rel="noopener noreferrer"&gt;WebRTC Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ovenplayer.com/" rel="noopener noreferrer"&gt;OvenPlayer SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://obsproject.com/wiki/Home" rel="noopener noreferrer"&gt;OBS Studio Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You've just built a professional-grade streaming infrastructure capable of sub-second latency delivery. This is production-ready code used by companies streaming millions of concurrent viewers.&lt;/p&gt;

&lt;p&gt;The key takeaways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security rules must be stateful&lt;/strong&gt; (the #1 mistake)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server.xml needs your public IP&lt;/strong&gt; (not localhost)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UDP ports are critical&lt;/strong&gt; (often forgotten)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test connectivity at every layer&lt;/strong&gt; (cloud → OS → container → player)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From here, you can build interactive experiences that were impossible with traditional RTMP. The future of live streaming is here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy streaming! 🎬&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;br&gt;
&lt;strong&gt;Have feedback?&lt;/strong&gt; Share your setup in the comments. Did you hit any snags I didn't cover? What use case are you building for?&lt;br&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Errors &amp;amp; Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error: "docker: command not found"
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Docker not installed or not in PATH&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.docker.com &lt;span class="nt"&gt;-o&lt;/span&gt; get-docker.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;sh get-docker.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error: "Connection refused" on port 1935
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# RTMP port not open in cloud security rules&lt;/span&gt;
&lt;span class="c"&gt;# Add TCP 1935 to your cloud provider's security list&lt;/span&gt;
&lt;span class="c"&gt;# Then restart OME&lt;/span&gt;
docker restart ome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error: "Cannot connect to Docker daemon"
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Docker not running or permission denied&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start docker
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;span class="c"&gt;# Log out and back in&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Latency exceeding 2 seconds
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check keyframe interval in OBS (should be 1-2 seconds)&lt;/span&gt;
&lt;span class="c"&gt;# Verify no packet loss: mtr YOUR_PUBLIC_IP&lt;/span&gt;
&lt;span class="c"&gt;# Check OME CPU usage: docker stats ome&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  OBS connection drops randomly
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check OME logs for errors&lt;/span&gt;
docker logs ome | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"error&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;exception"&lt;/span&gt;

&lt;span class="c"&gt;# Restart the container&lt;/span&gt;
docker restart ome

&lt;span class="c"&gt;# Check if iptables rules are persisted&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;netfilter-persistent save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;OME Version:&lt;/strong&gt; Latest (pull latest from Docker Hub)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Tested On:&lt;/strong&gt; Ubuntu 22.04 LTS, Oracle Cloud VM.Standard.E4.Flex&lt;/p&gt;

</description>
      <category>livestreaming</category>
      <category>webrtc</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Terminal Time Machine - Transform Your Git History Into Epic Stories 🕰️</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Tue, 03 Feb 2026 21:53:05 +0000</pubDate>
      <link>https://dev.to/mayu2008/terminal-time-machine-transform-your-git-history-into-epic-stories-17ha</link>
      <guid>https://dev.to/mayu2008/terminal-time-machine-transform-your-git-history-into-epic-stories-17ha</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; - &lt;em&gt;Project got overwhelming response with 170+ downloads within a 4 week so I have update the package and made it open source.&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Have you ever looked at &lt;code&gt;git log&lt;/code&gt; and thought, "This tells me nothing about my project's journey"?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit abc1234
Author: Mayuresh 
Date: Mon Feb 3
  fixed bug

commit def5678
Author: Mayuresh  
Date: Sun Feb 2
  update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Boring, right?&lt;/strong&gt; Every repository has an incredible story hidden in its commits - the late-night breakthroughs, the major refactors, the "aha!" moments. But git logs don't capture that narrative.&lt;/p&gt;

&lt;p&gt;That's why I built &lt;strong&gt;Terminal Time Machine&lt;/strong&gt; - a CLI tool that transforms your git history into engaging stories with beautiful ASCII visualizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 What It Does
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Terminal Time Machine&lt;/strong&gt; (&lt;code&gt;ttm&lt;/code&gt;) analyzes your git repository and generates:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📖 Narrative Stories&lt;/strong&gt; - Your commits become chapters in an epic tale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;═══════════════════════════════════════════════════
  Chapter 2: The Great Refactoring
  February 2026
═══════════════════════════════════════════════════

As the project matured, the team faced a critical decision.
The monolithic architecture that served us well in early days
now threatened to slow us down.

Over 23 commits across 8 intense days, the codebase was
reimagined. Sarah led the database migration effort, while
the team rallied around backward compatibility...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🎨 ASCII Timelines&lt;/strong&gt; - Visual representations of your history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2025  │
Jan   ├─●─────●──────────────●─ Project inception
      │ │     │              └─ First working prototype  
      │ │     └─ Core architecture decided
      │ └─ Initial commit "Hello, World!"
      │
Feb   ├───────●──────●─────────● Major refactor begins
      │       │      │         └─ Tests: 45% → 78%
      │       │      └─ Database layer complete
      │       └─ API endpoints redesigned
      │
Mar   ├─●─────────●───────────── v1.0 Released! 🎉
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;👥 Contributor Spotlights&lt;/strong&gt; - Beautiful analysis of who built what:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;╔════════════════════════════════════════════════╗
║  CONTRIBUTOR SPOTLIGHT                        ║
╚════════════════════════════════════════════════╝

📊 Statistics:
   • 234 commits (42% of total)
   • 12,847 lines added
   • Most active: February-March 2025
   • Top expertise: Backend architecture

🔥 Activity Heatmap:
   Jan  ████████░░░░░░░░
   Feb  ████████████████
   Mar  ████████░░░░░░░░
   Apr  ████░░░░░░░░░░░░
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;⚡ Smart Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎯 &lt;strong&gt;Milestone Detection&lt;/strong&gt; - Automatically identifies releases, refactors, and key moments&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Release Notes Generator&lt;/strong&gt; - Professional changelogs in seconds&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;Multiple Export Formats&lt;/strong&gt; - Markdown, HTML, JSON&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Color Themes&lt;/strong&gt; - Classic, Hacker, Sunset, Ocean&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Repository Statistics&lt;/strong&gt; - Comprehensive analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💡 Why This Matters
&lt;/h3&gt;

&lt;p&gt;As a developer and founder at &lt;strong&gt;Ambicube Limited&lt;/strong&gt; in the UK, I've seen how important it is to communicate technical work to non-technical stakeholders. Git logs are great for developers, but they don't tell the &lt;em&gt;story&lt;/em&gt; of what we've built.&lt;/p&gt;

&lt;p&gt;Terminal Time Machine bridges that gap. It helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Teams&lt;/strong&gt; onboard new members by showing project evolution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managers&lt;/strong&gt; understand velocity and contribution patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainers&lt;/strong&gt; generate beautiful release notes automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everyone&lt;/strong&gt; appreciate the journey of building software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tool turns technical data into human stories.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎬 See It In Action
&lt;/h3&gt;

&lt;h3&gt;
  
  
  📦 Try It Yourself
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; terminal-time-machine

&lt;span class="c"&gt;# Navigate to any git repository&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project

&lt;span class="c"&gt;# Generate your story&lt;/span&gt;
ttm story

&lt;span class="c"&gt;# Show timeline&lt;/span&gt;
ttm timeline

&lt;span class="c"&gt;# Analyze contributors&lt;/span&gt;
ttm contributors

&lt;span class="c"&gt;# Generate release notes&lt;/span&gt;
ttm release-notes v1.0.0..v2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔗 Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm Package:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/terminal-time-machine" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/terminal-time-machine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/mayureshsmitasuresh/terminal-time-machine" rel="noopener noreferrer"&gt;https://github.com/mayureshsmitasuresh/terminal-time-machine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://github.com/mayureshsmitasuresh/terminal-time-machine#readme" rel="noopener noreferrer"&gt;README.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📸 Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Story Mode Output:&lt;/strong&gt;&lt;br&gt;
![Story Generation]&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3fpbtwas4pljvjg82iu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3fpbtwas4pljvjg82iu.png" alt="output" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;em&gt;Narrative generation showing project evolution&lt;/em&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot CLI was &lt;strong&gt;absolutely transformative&lt;/strong&gt; for this project. As a solo developer working on this challenge, having an AI pair programmer available 24/7 made the difference between "good idea" and "shipped product."&lt;/p&gt;
&lt;h3&gt;
  
  
  🏗️ 1. Architecting the Core Story Generator
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt; I needed to transform raw git commit data into coherent narrative text. How do you group commits into logical "chapters"? How do you identify meaningful patterns?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Did:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"What's the best approach to analyze git commits 
and group them into logical chapters for a narrative story generator?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copilot's Response:&lt;/strong&gt; It suggested three key strategies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time-based clustering&lt;/strong&gt; - Group by weeks/months&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic analysis&lt;/strong&gt; - Analyze commit messages for themes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File-based grouping&lt;/strong&gt; - Commits affecting similar files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This became the foundation of my &lt;code&gt;commit-analyzer.js&lt;/code&gt; module. Copilot then helped me implement each strategy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"Write a JavaScript function that groups git commits 
by semantic similarity using commit message analysis"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; What could have taken 3-4 days of research and experimentation took 6 hours. Copilot CLI helped me understand NLP approaches I'd never used before.&lt;/p&gt;




&lt;h3&gt;
  
  
  🐛 2. Debugging the "enrichedCommits" Error
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Bug:&lt;/strong&gt; My code kept throwing &lt;code&gt;"Cannot access 'enrichedCommits' before initialization"&lt;/code&gt; - a JavaScript temporal dead zone error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Did:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot explain &lt;span class="s2"&gt;"Why am I getting 'Cannot access enrichedCommits 
before initialization' in this async function?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then pasted my problematic code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copilot's Analysis:&lt;/strong&gt; It immediately identified that I was using the variable before declaring it due to incorrect async/await ordering. It showed me the exact line and explained the fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Debugged in 5 minutes instead of potentially hours. The explanation also taught me about JavaScript's temporal dead zone, making me a better developer.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 3. Creating ASCII Art Visualizations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt; I wanted beautiful ASCII timelines but had zero experience creating them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Did:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"Create a Node.js function that generates an ASCII 
timeline from an array of git commits with dates and descriptions"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copilot's Output:&lt;/strong&gt; It generated a complete working implementation using Unicode box-drawing characters. I then iterated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"How can I add branch points and merge indicators 
to this ASCII timeline using Unicode characters?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This led to the branching visualizations you see in the tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Went from "I have no idea how to do this" to a working, beautiful visualization in under an hour.&lt;/p&gt;




&lt;h3&gt;
  
  
  💡 4. Feature Ideation
&lt;/h3&gt;

&lt;p&gt;Some of my best features came from asking Copilot "what if" questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"What are creative ways to visualize contributor 
activity patterns in a terminal application?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Copilot suggested:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Activity heatmaps (implemented! ✅)&lt;/li&gt;
&lt;li&gt;Contribution streaks (implemented! ✅)&lt;/li&gt;
&lt;li&gt;Time-of-day analysis (on roadmap)&lt;/li&gt;
&lt;li&gt;Collaboration graphs (future feature)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Added features I hadn't even thought of. The contributor spotlight feature was directly inspired by this conversation.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧪 5. Writing Tests
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt; Testing git operations is complex - how do you mock git commands?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Did:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"How do I write unit tests for a function that 
parses git log output without actually running git commands?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copilot's Guidance:&lt;/strong&gt; It explained:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using test fixtures (sample git output)&lt;/li&gt;
&lt;li&gt;Mocking the &lt;code&gt;simple-git&lt;/code&gt; library&lt;/li&gt;
&lt;li&gt;Structuring tests for async operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it generated example test cases I could adapt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Got from 0% to 85% test coverage in one day. Would have taken 3-4 days without Copilot's help.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 6. Performance Optimization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Processing 10,000+ commits was taking minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Did:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"How can I optimize this Node.js code that processes 
large arrays of git commits? Current implementation is too slow"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copilot's Suggestions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streaming instead of loading everything into memory&lt;/li&gt;
&lt;li&gt;Lazy loading for enriched commit data&lt;/li&gt;
&lt;li&gt;Caching frequently accessed data&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;Promise.all()&lt;/code&gt; for parallel processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; 10x performance improvement. The tool now handles massive repos like the Linux kernel gracefully.&lt;/p&gt;




&lt;h3&gt;
  
  
  📝 7. Documentation Generation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt; Writing comprehensive documentation is time-consuming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Did:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"Generate comprehensive CLI usage documentation 
for a tool with these commands: story, timeline, contributors, 
release-notes, export, stats"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Copilot created a well-structured documentation template with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear command descriptions&lt;/li&gt;
&lt;li&gt;Usage examples&lt;/li&gt;
&lt;li&gt;Common use cases&lt;/li&gt;
&lt;li&gt;Troubleshooting tips&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I refined and personalized it, but the foundation saved hours of work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Professional documentation completed in 2 hours instead of a full day.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎯 Overall Impact of GitHub Copilot CLI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Time Saved:&lt;/strong&gt; Estimated 2-3 weeks of development time&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quality Improved:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better architecture (learned new patterns)&lt;/li&gt;
&lt;li&gt;More features (ideas I wouldn't have thought of)&lt;/li&gt;
&lt;li&gt;Higher test coverage (85% vs. my usual 60%)&lt;/li&gt;
&lt;li&gt;Better performance (learned optimization techniques)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Learning Accelerated:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discovered NLP techniques&lt;/li&gt;
&lt;li&gt;Learned advanced async/await patterns&lt;/li&gt;
&lt;li&gt;Understood Unicode box-drawing&lt;/li&gt;
&lt;li&gt;Improved testing practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Confidence Boosted:&lt;/strong&gt; I tackled complex problems I'd normally avoid because I had an expert available to guide me through them.&lt;/p&gt;

&lt;h3&gt;
  
  
  💬 The Conversational Difference
&lt;/h3&gt;

&lt;p&gt;What made Copilot CLI special wasn't just code generation - it was the &lt;strong&gt;conversation&lt;/strong&gt;. Instead of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google search&lt;/li&gt;
&lt;li&gt;Read Stack Overflow&lt;/li&gt;
&lt;li&gt;Try solution&lt;/li&gt;
&lt;li&gt;Fail&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I could just &lt;strong&gt;ask&lt;/strong&gt; about my specific problem and get tailored guidance. It felt like pair programming with a senior developer who's always available, never judgmental, and infinitely patient.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🛠️ Built With
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; - Runtime environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commander.js&lt;/strong&gt; - CLI framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;simple-git&lt;/strong&gt; - Git operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;chalk&lt;/strong&gt; &amp;amp; &lt;strong&gt;gradient-string&lt;/strong&gt; - Beautiful terminal colors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;boxen&lt;/strong&gt; &amp;amp; &lt;strong&gt;cli-table3&lt;/strong&gt; - Elegant formatting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;inquirer&lt;/strong&gt; - Interactive prompts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ora&lt;/strong&gt; - Loading spinners&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;marked&lt;/strong&gt; &amp;amp; &lt;strong&gt;marked-terminal&lt;/strong&gt; - Markdown rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;asciichart&lt;/strong&gt; - ASCII charts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;figlet&lt;/strong&gt; - ASCII art text&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📊 Project Stats
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lines of Code:&lt;/strong&gt; ~2,800&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development Time:&lt;/strong&gt; 10 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Coverage:&lt;/strong&gt; 85%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm Downloads:&lt;/strong&gt; [Growing!]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Stars:&lt;/strong&gt; [Give me one! ⭐]&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎨 Key Features Implementation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Smart Commit Analysis&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Groups commits by semantic similarity&lt;/span&gt;
&lt;span class="c1"&gt;// Detects patterns in file changes&lt;/span&gt;
&lt;span class="c1"&gt;// Identifies refactoring vs. new features&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Milestone Detection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First commit detection&lt;/li&gt;
&lt;li&gt;Version tag parsing (semantic versioning)&lt;/li&gt;
&lt;li&gt;Major refactor identification (high churn)&lt;/li&gt;
&lt;li&gt;Documentation update recognition&lt;/li&gt;
&lt;li&gt;Test coverage improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Beautiful Output&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 color themes (Classic, Hacker, Sunset, Ocean)&lt;/li&gt;
&lt;li&gt;Responsive terminal width detection&lt;/li&gt;
&lt;li&gt;Unicode support with ASCII fallbacks&lt;/li&gt;
&lt;li&gt;Progress indicators for long operations&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm planning to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI-powered commit quality scoring&lt;/strong&gt; - Analyze commit message quality&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;More visualization types&lt;/strong&gt; - Dependency graphs, code churn heatmaps&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Web version&lt;/strong&gt; - Interactive timeline in the browser&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;GitHub/GitLab integration&lt;/strong&gt; - Include issues and PRs in the story&lt;/li&gt;
&lt;li&gt;🎤 &lt;strong&gt;Audio narration&lt;/strong&gt; - Hear your git story read aloud&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Mobile companion app&lt;/strong&gt; - View stories on mobile&lt;/li&gt;
&lt;li&gt;🎓 &lt;strong&gt;Learning mode&lt;/strong&gt; - Analyze successful open-source projects&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It Today! 🚀
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; terminal-time-machine

&lt;span class="c"&gt;# Use it&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;your-favorite-project
ttm story
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/terminal-time-machine" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/terminal-time-machine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/mayureshsmitasuresh/terminal-time-machine" rel="noopener noreferrer"&gt;https://github.com/mayureshsmitasuresh/terminal-time-machine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⭐ &lt;strong&gt;Star it if you like it!&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🐛 &lt;strong&gt;Report bugs or request features&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;Share your git stories&lt;/strong&gt; - I'd love to see them!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  About Me
&lt;/h2&gt;

&lt;p&gt;I'm &lt;strong&gt;Mayuresh Shitole&lt;/strong&gt;, a solo founder at &lt;strong&gt;Ambicube Limited UK&lt;/strong&gt; in the UK. I love building tools that make developers' lives easier and help teams communicate better about technical work.&lt;/p&gt;

&lt;p&gt;This project combines my passion for storytelling, developer tools, and beautiful terminal UIs. I believe every codebase has a story worth telling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📧 Email: &lt;a href="mailto:mayureshshitole@gmail.com"&gt;mayureshshitole@gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 GitHub: &lt;a href="https://github.com/mayureshssmitasuresh" rel="noopener noreferrer"&gt;@mayureshshitole&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🏢 Company: &lt;a href="https://ambicube.com" rel="noopener noreferrer"&gt;Ambicube Limited, UK&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Huge thanks to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; for sponsoring this challenge and building Copilot CLI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DEV Community&lt;/strong&gt; for providing this amazing platform&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You&lt;/strong&gt; for reading this far! 🙏&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Building Terminal Time Machine taught me that &lt;strong&gt;the best tools solve problems people didn't know they had&lt;/strong&gt;. Everyone accepts that git logs are boring - but they don't have to be!&lt;/p&gt;

&lt;p&gt;GitHub Copilot CLI was instrumental in turning this idea into reality. It wasn't just about writing code faster - it was about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Learning&lt;/strong&gt; new techniques&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exploring&lt;/strong&gt; ideas I'd normally avoid&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shipping&lt;/strong&gt; a polished product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Having fun&lt;/strong&gt; while building&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've ever wanted to see your git history come alive, give Terminal Time Machine a try. And if you're participating in hackathons or challenges, definitely use Copilot CLI - it's like having a senior developer on your team who never sleeps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;May your commits be meaningful and your git history epic!&lt;/strong&gt; 🕰️✨&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>High concurrency live Auction platform System Architecture</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Tue, 03 Feb 2026 01:29:43 +0000</pubDate>
      <link>https://dev.to/mayu2008/high-concurrency-live-auction-platform-system-architecture-2b6h</link>
      <guid>https://dev.to/mayu2008/high-concurrency-live-auction-platform-system-architecture-2b6h</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: The "Cloud Bill" Trap
&lt;/h2&gt;

&lt;p&gt;When building a live-streaming auction app like &lt;strong&gt;Whatnot&lt;/strong&gt;, the default advice is always: &lt;em&gt;"Just use AWS IVS or Mux."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It works great, until you do the math.&lt;/p&gt;

&lt;p&gt;For a single &lt;strong&gt;1-hour event&lt;/strong&gt; with &lt;strong&gt;10,000 viewers&lt;/strong&gt;, AWS IVS (Interactive Video Service) charges based on "minutes watched."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10,000 viewers × 60 minutes = 600,000 minutes&lt;/li&gt;
&lt;li&gt;Cost per 1,000 minutes = ~$1.50&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total Cost = $900 (₹75,000 INR) per hour&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run one event a day, your monthly bill is &lt;strong&gt;₹22 Lakhs ($27,000)&lt;/strong&gt;. For a bootstrapped startup, this is a death sentence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: The "Hybrid" Bare Metal Stack
&lt;/h2&gt;

&lt;p&gt;We optimized this by moving away from "Pay-Per-Minute" (PaaS) to "Pay-Per-Bandwidth" (Infrastructure as a Service).&lt;/p&gt;

&lt;p&gt;By switching to a self-hosted &lt;strong&gt;OvenMediaEngine (OME)&lt;/strong&gt; instance on a dedicated server with unmetered bandwidth, we dropped the cost from &lt;strong&gt;$27,000/mo&lt;/strong&gt; to &lt;strong&gt;$300/mo&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The High-Level Architecture
&lt;/h3&gt;

&lt;p&gt;We use a &lt;strong&gt;Hybrid Approach&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Video (Heavy Lifting):&lt;/strong&gt; Hosted on a massive Bare Metal server (MilesWeb/Hetzner) using &lt;strong&gt;OvenMediaEngine&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logic (The Brain):&lt;/strong&gt; A lightweight &lt;strong&gt;Rust&lt;/strong&gt; backend handling Auth, Payments, and the Auction Timer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time (The Glue):&lt;/strong&gt; WebSockets (Rust) for instant bidding, completely separate from the video stream
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD
    User[Mobile App User]
    Streamer[Live Seller]

    subgraph "Bare Metal Data Center"
      OME[OvenMediaEngine Video Server]
    end

    subgraph "Cloud API - DigitalOcean"
      Rust[Rust API &amp;amp; WebSocket Server]
      DB[(Postgres &amp;amp; Redis)]
    end

    Streamer -- "RTMP (OBS/Mobile)" --&amp;gt; OME
    OME -- "Webhook Validation" --&amp;gt; Rust
    Rust -- "200 OK" --&amp;gt; OME

    OME -- "LL-HLS (Video)" --&amp;gt; User
    User -- "WebSocket Bid (Data)" --&amp;gt; Rust
    Rust -- "Broadcast Winner" --&amp;gt; User
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Figure 1: Decoupled Video and Logic Architecture&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: The Video Engine (OvenMediaEngine)
&lt;/h2&gt;

&lt;p&gt;We chose &lt;strong&gt;OvenMediaEngine (OME)&lt;/strong&gt; because it is open-source (C++) and supports &lt;strong&gt;Sub-Second Latency&lt;/strong&gt; via LL-HLS (Low Latency HLS) and WebRTC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Configuration
&lt;/h3&gt;

&lt;p&gt;We deploy OME using Docker on a &lt;strong&gt;MilesWeb Dedicated Server&lt;/strong&gt; (32 Cores, 30TB Bandwidth).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;airensoft/ovenmediaengine:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ome&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1935:1935"&lt;/span&gt;    &lt;span class="c1"&gt;# RTMP Ingest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;    &lt;span class="c1"&gt;# LL-HLS Playback&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3333:3333"&lt;/span&gt;    &lt;span class="c1"&gt;# WebRTC Signaling&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3334:3334/udp"&lt;/span&gt; &lt;span class="c1"&gt;# WebRTC ICE&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;OME_HOST_IP=${SERVER_PUBLIC_IP}&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./conf/Server.xml:/opt/ovenmediaengine/bin/origin_conf/Server.xml&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The "Secret Sauce" Config (Server.xml)
&lt;/h3&gt;

&lt;p&gt;To get the latency down to 3 seconds (acceptable for auctions if the timer is synced separately), we tune the LL-HLS settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Application&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;n&amp;gt;&lt;/span&gt;auction&lt;span class="nt"&gt;&amp;lt;/n&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Providers&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;RTMP&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Providers&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Publishers&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;LLHLS&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;ChunkDuration&amp;gt;&lt;/span&gt;0.5&lt;span class="nt"&gt;&amp;lt;/ChunkDuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;SegmentDuration&amp;gt;&lt;/span&gt;6&lt;span class="nt"&gt;&amp;lt;/SegmentDuration&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;SegmentCount&amp;gt;&lt;/span&gt;3&lt;span class="nt"&gt;&amp;lt;/SegmentCount&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;CrossDomains&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;Url&amp;gt;&lt;/span&gt;*&lt;span class="nt"&gt;&amp;lt;/Url&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/CrossDomains&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/LLHLS&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;WebRTC&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;Timeout&amp;gt;&lt;/span&gt;30000&lt;span class="nt"&gt;&amp;lt;/Timeout&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/WebRTC&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Publishers&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Application&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: The Rust "Brain" (Stream Authentication)
&lt;/h2&gt;

&lt;p&gt;You don't want just anyone streaming to your server. We use OME's Webhook feature to validate streamers against our database.&lt;/p&gt;

&lt;p&gt;When a user starts streaming to &lt;code&gt;rtmp://server/app/stream_key&lt;/code&gt;, OME hits our Rust API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/routes/webhook.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;IntoResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OmeHook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// This is the stream_key&lt;/span&gt;
    &lt;span class="n"&gt;app_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OmeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;on_publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OmeHook&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;IntoResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Verify Stream Key in Redis/Postgres&lt;/span&gt;
    &lt;span class="c1"&gt;// let is_valid = verify_stream_key(&amp;amp;payload.name).await;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;is_valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Mock for demo&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_valid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"✅ Stream authorized: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OmeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Stream rejected: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FORBIDDEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OmeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid Stream Key"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: The Frontend (SolidStart Player)
&lt;/h2&gt;

&lt;p&gt;On the client side (SolidStart), we use &lt;strong&gt;Hls.js&lt;/strong&gt; optimized for low latency. We don't wait for the video to catch up; the Bidding Interface connects directly to the Rust WebSocket for real-time state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// components/VideoPlayer.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onMount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onCleanup&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;solid-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Hls&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hls.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AuctionPlayerProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;streamUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AuctionPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AuctionPlayerProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLVideoElement&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hls&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;onMount&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isSupported&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;hls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hls&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;lowLatencyMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Critical for &amp;lt;3s delay&lt;/span&gt;
        &lt;span class="na"&gt;backBufferLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;liveSyncDurationCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Stay close to live edge&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;streamUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Handle auto-play policies&lt;/span&gt;
      &lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MANIFEST_PARSED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Autoplay blocked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;onCleanup&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"relative w-full h-full bg-black"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;video&lt;/span&gt;
        &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;muted&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Start muted to allow autoplay&lt;/span&gt;
        &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-full object-cover"&lt;/span&gt;
        &lt;span class="na"&gt;poster&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/images/loading-auction.jpg"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Live Badge Overlay */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"absolute top-4 left-4 bg-red-600 text-white px-2 py-1 text-xs font-bold rounded"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        🔴 LIVE
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Result: Financial Breakdown
&lt;/h2&gt;

&lt;p&gt;By moving the heavy video processing to a dedicated server and keeping the logic in efficient Rust microservices, we achieved massive savings.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cost Component&lt;/th&gt;
&lt;th&gt;Cloud Native (AWS IVS)&lt;/th&gt;
&lt;th&gt;Our Hybrid Stack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Video Streaming&lt;/td&gt;
&lt;td&gt;₹23,00,000 / mo&lt;/td&gt;
&lt;td&gt;₹25,000 / mo (MilesWeb Dedicated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Servers&lt;/td&gt;
&lt;td&gt;₹15,000 / mo&lt;/td&gt;
&lt;td&gt;₹4,000 / mo (DigitalOcean)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;₹5,000 / mo&lt;/td&gt;
&lt;td&gt;₹2,000 / mo (Supabase)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~3 Seconds&lt;/td&gt;
&lt;td&gt;~3 Seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total Monthly&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~₹24 Lakhs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~₹31,000&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Cost Savings: &lt;strong&gt;99% Reduction&lt;/strong&gt; 💰
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Why This Works for Startups
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Predictable Billing:&lt;/strong&gt; We pay for the pipe (bandwidth), not the usage (minutes). A 30TB dedicated server costs the same whether you stream 100 hours or 1000 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rust Efficiency:&lt;/strong&gt; Handling 10k WebSockets on a $10 server is trivial for Rust (Axum/Tokio), whereas Node.js would require a larger cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Sovereignty:&lt;/strong&gt; Hosting in India (MilesWeb) ensures compliance and faster speeds for local users without the AWS price tag.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Separate Video from Logic:&lt;/strong&gt; Video streaming is bandwidth-heavy but computationally light. Run it on bare metal with unmetered bandwidth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Rust for Real-Time:&lt;/strong&gt; WebSocket servers in Rust can handle 10x more connections per dollar than Node.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LL-HLS is Good Enough:&lt;/strong&gt; For auctions, 3-second latency works if your bidding state is synchronized separately via WebSockets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OvenMediaEngine is Production-Ready:&lt;/strong&gt; We've been running OME for 6 months with zero downtime&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Ready to Build Your Own?
&lt;/h2&gt;

&lt;p&gt;Check out these resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/AirenSoft/OvenMediaEngine" rel="noopener noreferrer"&gt;OvenMediaEngine GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.rs/axum/latest/axum/" rel="noopener noreferrer"&gt;Rust Axum Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/video-dev/hls.js/" rel="noopener noreferrer"&gt;Hls.js for Low Latency Streaming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Questions?&lt;/strong&gt; Feel free to reach out to me on &lt;a href="https://linkedin.com/in/mayureshsmitasuresh" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or check out what we're building at &lt;a href="https://ambicube.co.uk" rel="noopener noreferrer"&gt;Ambicube Limited&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Mayuresh Smita Suresh, Founder @ Ambicube Limited UK - I have vision for building the future of live commerce. Interested? Join me!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>ovenmediaengine</category>
      <category>softwaredevelopment</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
