ViewComparator Component Test

Drag the bar to redistribute panel widths. Click the left panel to grow it; click the right panel to grow it. Total component width does not change.

Three small buttons (▲ 0 ▼) appear near the top-right corner of the right panel. They are faint until hovered or until the right panel has focus. ▼ adds space above the right panel's content, shifting it down. ▲ removes space, shifting it back up. 0 resets to no offset. With the right panel focused (click anywhere in it), Alt+↓ and Alt+↑ do the same; Escape resets. The step size defaults to 20 px and is configurable via offset-step-px.

Plain text panels

Left panel — plain text.

Drag the splitter bar left or right
to redistribute panel widths.

Click this panel to grow it by one step.
Each click transfers 40px from right to left.
Right panel — plain text.

Click this panel to grow it by one step.
Each click transfers 40px from left to right.

The total component width stays fixed at 60rem.

Figure 1. Two plain-text panels, equal initial split.

Code panels with Prism highlighting — C++ vs Rust

Same algorithm expressed in each language. Both panels scroll independently.


#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

int main() {
    std::vector<int> v = {5, 3, 8, 1, 9, 2, 7};

    std::sort(v.begin(), v.end());

    int sum = std::accumulate(v.begin(), v.end(), 0);
    double avg = static_cast<double>(sum) / v.size();

    std::cout << "sorted: ";
    for (int x : v) std::cout << x << " ";
    std::cout << "\nsum = " << sum
              << "  avg = " << avg << "\n";
    return 0;
}
    

fn main() {
    let mut v = vec![5, 3, 8, 1, 9, 2, 7];

    v.sort();

    let sum: i32 = v.iter().sum();
    let avg = sum as f64 / v.len() as f64;

    print!("sorted: ");
    for x in &v { print!("{x} "); }
    println!("\nsum = {sum}  avg = {avg}");
}
    

Figure 2. C++ (left) and Rust (right) with Prism highlighting, fixed height with scroll.

Asymmetric initial split — 30/70


// module pattern
const counter = (() => {
  let _n = 0;
  return {
    inc: () => ++_n,
    dec: () => --_n,
    val: () => _n,
  };
})();

console.log(counter.inc()); // 1
console.log(counter.inc()); // 2
console.log(counter.dec()); // 1
    

/* component container */
.container {
  display: flex;
  flex-direction: row;
  border: 2px solid var(--dark, #333);
  box-shadow: 5px 5px 5px #999;
  box-sizing: border-box;
  overflow: hidden;
}

.panel-left  { flex: none; }
.panel-right { flex: 1; min-width: 0; }

.splitter {
  flex: none;
  cursor: col-resize;
  user-select: none;
}
    

Figure 3. 30/70 initial split, wider splitter bar (8px), JavaScript and CSS panels.

Mismatched content length — offset demo

The left panel has many lines; the right has only a few. Use ▼ (or Alt+↓ with the right panel focused) to push the right panel's content down until the desired lines align. Press 0 or Escape to reset.


#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <string>
#include <sstream>

// Format a vector as a comma-separated string.
template<typename T>
std::string join(const std::vector<T>& v) {
    std::ostringstream oss;
    for (std::size_t i = 0; i < v.size(); ++i) {
        if (i) oss << ", ";
        oss << v[i];
    }
    return oss.str();
}

int main() {
    std::vector<int> v = {9, 3, 7, 1, 5};
    std::sort(v.begin(), v.end());
    int  sum = std::accumulate(v.begin(), v.end(), 0);
    double avg = static_cast<double>(sum) / v.size();
    std::cout << "sorted: " << join(v) << "\n";
    std::cout << "sum=" << sum << "  avg=" << avg << "\n";
}
    

v = sorted([9, 3, 7, 1, 5])
avg = sum(v) / len(v)
print(f"sorted: {v}")
print(f"sum={sum(v)}  avg={avg}")
    

Figure 4. Long C++ left panel vs. short Python right panel — use offset controls to align.